Skip to content

Commit

Permalink
migrate to java.util.Optional based Position
Browse files Browse the repository at this point in the history
  • Loading branch information
eed3si9n committed Feb 17, 2017
1 parent 14f76c2 commit 0dee711
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 132 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ package xsbt

import xsbti.{ F0, Logger, Maybe }
import java.io.File
import sbt.util.InterfaceUtil.o2jo
import java.util.Optional

private object DelegatingReporter {
def apply(settings: scala.tools.nsc.Settings, delegate: xsbti.Reporter): DelegatingReporter =
Expand Down Expand Up @@ -73,13 +75,13 @@ private final class DelegatingReporter(warnFatal: Boolean, noWarn: Boolean, priv
}
private[this] def position(sourcePath0: Option[String], sourceFile0: Option[File], line0: Option[Int], lineContent0: String, offset0: Option[Int], pointer0: Option[Int], pointerSpace0: Option[String]) =
new xsbti.Position {
val line = o2mi(line0)
val line = o2oi(line0)
val lineContent = lineContent0
val offset = o2mi(offset0)
val sourcePath = o2m(sourcePath0)
val sourceFile = o2m(sourceFile0)
val pointer = o2mi(pointer0)
val pointerSpace = o2m(pointerSpace0)
val offset = o2oi(offset0)
val sourcePath = o2jo(sourcePath0)
val sourceFile = o2jo(sourceFile0)
val pointer = o2oi(pointer0)
val pointerSpace = o2jo(pointerSpace0)
override def toString =
(sourcePath0, line0) match {
case (Some(s), Some(l)) => s + ":" + l
Expand All @@ -97,6 +99,5 @@ private final class DelegatingReporter(warnFatal: Boolean, noWarn: Boolean, priv
}

import java.lang.{ Integer => I }
private[this] def o2mi(opt: Option[Int]): Maybe[I] = opt match { case None => Maybe.nothing[I]; case Some(s) => Maybe.just[I](s) }
private[this] def o2m[S](opt: Option[S]): Maybe[S] = opt match { case None => Maybe.nothing[S]; case Some(s) => Maybe.just(s) }
private[this] def o2oi(opt: Option[Int]): Optional[I] = opt match { case None => Optional.empty[I]; case Some(s) => Optional.ofNullable[I](s) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@

package xsbt

import xsbti.{ F0, Logger, Maybe }
import java.io.File
import sbt.util.InterfaceUtil.o2jo
import java.util.Optional

private object DelegatingReporter {
def apply(settings: scala.tools.nsc.Settings, delegate: xsbti.Reporter): DelegatingReporter =
Expand Down Expand Up @@ -70,13 +71,13 @@ private final class DelegatingReporter(warnFatal: Boolean, noWarn: Boolean, priv
}
private[this] def position(sourcePath0: Option[String], sourceFile0: Option[File], line0: Option[Int], lineContent0: String, offset0: Option[Int], pointer0: Option[Int], pointerSpace0: Option[String]) =
new xsbti.Position {
val line = o2mi(line0)
val line = o2oi(line0)
val lineContent = lineContent0
val offset = o2mi(offset0)
val sourcePath = o2m(sourcePath0)
val sourceFile = o2m(sourceFile0)
val pointer = o2mi(pointer0)
val pointerSpace = o2m(pointerSpace0)
val offset = o2oi(offset0)
val sourcePath = o2jo(sourcePath0)
val sourceFile = o2jo(sourceFile0)
val pointer = o2oi(pointer0)
val pointerSpace = o2jo(pointerSpace0)
override def toString =
(sourcePath0, line0) match {
case (Some(s), Some(l)) => s + ":" + l
Expand All @@ -94,6 +95,5 @@ private final class DelegatingReporter(warnFatal: Boolean, noWarn: Boolean, priv
}

import java.lang.{ Integer => I }
private[this] def o2mi(opt: Option[Int]): Maybe[I] = opt match { case None => Maybe.nothing[I]; case Some(s) => Maybe.just[I](s) }
private[this] def o2m[S](opt: Option[S]): Maybe[S] = opt match { case None => Maybe.nothing[S]; case Some(s) => Maybe.just(s) }
private[this] def o2oi(opt: Option[Int]): Optional[I] = opt match { case None => Optional.empty[I]; case Some(s) => Optional.ofNullable[I](s) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,12 @@ package inc
// see licenses/LICENSE_Scala
// Original author: Martin Odersky

import xsbti.{ Maybe, Position, Problem, Reporter, Severity }
import java.io.File
import xsbti.{ Position, Problem, Severity }
import java.util.EnumMap
import scala.collection.mutable
import LoggerReporter._
import sbt.util.Logger
import sbt.internal.util.ManagedLogger
import Logger.{ m2o, o2m, position, problem }
import sbt.util.InterfaceUtil.{ jo2o, problem }
import Severity.{ Error, Info => SInfo, Warn }

object LoggerReporter {
Expand All @@ -33,11 +31,11 @@ object LoggerReporter {
o match { case pk: PositionKey => equalsKey(pk); case _ => false }

def equalsKey(o: PositionKey) =
m2o(pos.offset) == m2o(o.offset) &&
m2o(pos.sourceFile) == m2o(o.sourceFile)
jo2o(pos.offset) == jo2o(o.offset) &&
jo2o(pos.sourceFile) == jo2o(o.sourceFile)
override def hashCode =
m2o(pos.offset).hashCode * 31
m2o(pos.sourceFile).hashCode
jo2o(pos.offset).hashCode * 31
jo2o(pos.sourceFile).hashCode
}

def countElementsAsString(n: Int, elements: String): String =
Expand Down Expand Up @@ -81,11 +79,13 @@ class LoggerReporter(maximumErrors: Int, log: ManagedLogger, sourcePositionMappe

def inc(sev: Severity) = count.put(sev, count.get(sev) + 1)

def display(pos: Position, msg: String, severity: Severity): Unit = {
inc(severity)
if (severity != Error || maximumErrors <= 0 || count.get(severity) <= maximumErrors)
print(severityLogger(severity), pos, msg)
}
def display(pos: Position, msg: String, severity: Severity): Unit =
{
inc(severity)
if (severity != Error || maximumErrors <= 0 || count.get(severity) <= maximumErrors) {
print(severityLogger(severity), pos, msg)
}
}
def severityLogger(severity: Severity): (=> String) => Unit =
m =>
{
Expand All @@ -97,23 +97,23 @@ class LoggerReporter(maximumErrors: Int, log: ManagedLogger, sourcePositionMappe
}

def print(log: (=> String) => Unit, pos: Position, msg: String): Unit = {
if (pos.sourcePath.isEmpty && pos.line.isEmpty)
if (!pos.sourcePath.isPresent && !pos.line.isPresent)
log(msg)
else {
val sourcePrefix = m2o(pos.sourcePath).getOrElse("")
val columnNumber = m2o(pos.pointer).map(_.toInt + 1).getOrElse(1)
val lineNumberString = m2o(pos.line).map(":" + _ + ":" + columnNumber + ":").getOrElse(":") + " "
val sourcePrefix = jo2o(pos.sourcePath).getOrElse("")
val columnNumber = jo2o(pos.pointer).map(_.toInt + 1).getOrElse(1)
val lineNumberString = jo2o(pos.line).map(":" + _ + ":" + columnNumber + ":").getOrElse(":") + " "
log(sourcePrefix + lineNumberString + msg)
val lineContent = pos.lineContent
if (!lineContent.isEmpty) {
log(lineContent)
for (space <- m2o(pos.pointerSpace))
for (space <- jo2o(pos.pointerSpace))
log(space + "^") // pointer to the column position of the error/warning
}
}
}

def log(pos: Position, msg: String, severity: Severity): Unit =
override def log(pos: Position, msg: String, severity: Severity): Unit =
{
val mappedPos = sourcePositionMapper(pos)
allProblems += problem("", mappedPos, msg, severity)
Expand All @@ -129,7 +129,7 @@ class LoggerReporter(maximumErrors: Int, log: ManagedLogger, sourcePositionMappe

def testAndLog(pos: Position, severity: Severity): Boolean =
{
if (pos.offset.isEmpty || pos.sourceFile.isEmpty)
if (!pos.offset.isPresent || !pos.sourceFile.isPresent)
false
else {
val key = new PositionKey(pos)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ package internal
package inc
package javac

import java.util.Optional
import java.io.File
import javax.tools.{ Diagnostic, JavaFileObject, DiagnosticListener }

import sbt.util.Logger
import xsbti.{ Severity, Reporter, Maybe }
import sbt.util.InterfaceUtil.o2jo
import xsbti.{ Severity, Reporter }
import javax.tools.Diagnostic.NOPOS

/**
Expand Down Expand Up @@ -51,16 +51,7 @@ final class DiagnosticsReporter(reporter: Reporter) extends DiagnosticListener[J
case _ => getRawMessage
}
}
private def fixSource[T <: JavaFileObject](source: T): Option[String] = {
try Option(source).map(_.toUri.normalize).map(new File(_)).map(_.getAbsolutePath)
catch {
case t: IllegalArgumentException =>
// Oracle JDK6 has a super dumb notion of what a URI is. In fact, it's not even a legimitate URL, but a dump
// of the filename in a "I hope this works to toString it" kind of way. This appears to work in practice
// but we may need to re-evaluate.
Option(source).map(_.toUri.toString)
}
}

override def report(d: Diagnostic[_ <: JavaFileObject]): Unit = {
val severity =
d.getKind match {
Expand All @@ -69,66 +60,77 @@ final class DiagnosticsReporter(reporter: Reporter) extends DiagnosticListener[J
case _ => Severity.Info
}
val msg = fixedDiagnosticMessage(d)
val pos: xsbti.Position =
new xsbti.Position {
// https://docs.oracle.com/javase/7/docs/api/javax/tools/Diagnostic.html
// Negative values (except NOPOS) and 0 are not valid line or column numbers,
// except that you can cause this number to occur by putting "abc {}" in A.java.
// This will cause Invalid position: 0 masking the actual error message
// a/A.java:1: class, interface, or enum expected
private[this] def checkNoPos(n: Long): Option[Long] =
n match {
case NOPOS => None
case x if x <= 0 => None
case x => Option(x)
}
val pos: xsbti.Position = new PositionImpl(d)
if (severity == Severity.Error) errorEncountered = true
reporter.log(pos, msg, severity)
}

override val line: Maybe[Integer] = Logger.o2m(checkNoPos(d.getLineNumber) map { x => new Integer(x.toInt) })
def startPosition: Option[Long] = checkNoPos(d.getStartPosition)
def endPosition: Option[Long] = checkNoPos(d.getEndPosition)
override val offset: Maybe[Integer] = Logger.o2m(checkNoPos(d.getPosition) map { x => new Integer(x.toInt) })
override def lineContent: String = {
def getDiagnosticLine: Option[String] =
try {
// See com.sun.tools.javac.api.ClientCodeWrapper.DiagnosticSourceUnwrapper
val diagnostic = d.getClass.getField("d").get(d)
// See com.sun.tools.javac.util.JCDiagnostic#getDiagnosticSource
val getDiagnosticSourceMethod = diagnostic.getClass.getDeclaredMethod("getDiagnosticSource")
val getPositionMethod = diagnostic.getClass.getDeclaredMethod("getPosition")
(Option(getDiagnosticSourceMethod.invoke(diagnostic)), Option(getPositionMethod.invoke(diagnostic))) match {
case (Some(diagnosticSource), Some(position: java.lang.Long)) =>
// See com.sun.tools.javac.util.DiagnosticSource
val getLineMethod = diagnosticSource.getClass.getMethod("getLine", Integer.TYPE)
Option(getLineMethod.invoke(diagnosticSource, new Integer(position.intValue()))).map(_.toString)
case _ => None
}
} catch {
// TODO - catch ReflectiveOperationException once sbt is migrated to JDK7
case ignored: Throwable => None
}
private class PositionImpl(d: Diagnostic[_ <: JavaFileObject]) extends xsbti.Position {
// https://docs.oracle.com/javase/7/docs/api/javax/tools/Diagnostic.html
// Negative values (except NOPOS) and 0 are not valid line or column numbers,
// except that you can cause this number to occur by putting "abc {}" in A.java.
// This will cause Invalid position: 0 masking the actual error message
// a/A.java:1: class, interface, or enum expected
private[this] def checkNoPos(n: Long): Option[Long] =
n match {
case NOPOS => None
case x if x <= 0 => None
case x => Option(x)
}

def getExpression: String =
Option(d.getSource) match {
case Some(source: JavaFileObject) =>
(Option(source.getCharContent(true)), startPosition, endPosition) match {
case (Some(cc), Some(start), Some(end)) => cc.subSequence(start.toInt, end.toInt).toString
case _ => ""
}
case _ => ""
}
override val line: Optional[Integer] = o2jo(checkNoPos(d.getLineNumber) map { x => new Integer(x.toInt) })
def startPosition: Option[Long] = checkNoPos(d.getStartPosition)
def endPosition: Option[Long] = checkNoPos(d.getEndPosition)
override val offset: Optional[Integer] = o2jo(checkNoPos(d.getPosition) map { x => new Integer(x.toInt) })
override def lineContent: String = {
def getDiagnosticLine: Option[String] =
try {
// See com.sun.tools.javac.api.ClientCodeWrapper.DiagnosticSourceUnwrapper
val diagnostic = d.getClass.getField("d").get(d)
// See com.sun.tools.javac.util.JCDiagnostic#getDiagnosticSource
val getDiagnosticSourceMethod = diagnostic.getClass.getDeclaredMethod("getDiagnosticSource")
val getPositionMethod = diagnostic.getClass.getDeclaredMethod("getPosition")
(Option(getDiagnosticSourceMethod.invoke(diagnostic)), Option(getPositionMethod.invoke(diagnostic))) match {
case (Some(diagnosticSource), Some(position: java.lang.Long)) =>
// See com.sun.tools.javac.util.DiagnosticSource
val getLineMethod = diagnosticSource.getClass.getMethod("getLine", Integer.TYPE)
Option(getLineMethod.invoke(diagnosticSource, new Integer(position.intValue()))).map(_.toString)
case _ => None
}
} catch {
// TODO - catch ReflectiveOperationException once sbt is migrated to JDK7
case ignored: Throwable => None
}

getDiagnosticLine.getOrElse(getExpression)
def getExpression: String =
Option(d.getSource) match {
case Some(source: JavaFileObject) =>
(Option(source.getCharContent(true)), startPosition, endPosition) match {
case (Some(cc), Some(start), Some(end)) => cc.subSequence(start.toInt, end.toInt).toString
case _ => ""
}
case _ => ""
}
private val sourceUri = fixSource(d.getSource)
override val sourcePath = Logger.o2m(sourceUri)
override val sourceFile = Logger.o2m(sourceUri.map(new File(_)))
override val pointer = Logger.o2m(Option.empty[Integer])
override val pointerSpace = Logger.o2m(Option.empty[String])
override def toString =
if (sourceUri.isDefined) s"${sourceUri.get}:${if (line.isDefined) line.get else -1}"
else ""

getDiagnosticLine.getOrElse(getExpression)
}
private val sourceUri: Option[String] = fixSource(d.getSource)
override val sourcePath: Optional[String] = o2jo(sourceUri)
override val sourceFile: Optional[File] = o2jo(sourceUri.map(new File(_)))
override val pointer: Optional[Integer] = o2jo(Option.empty[Integer])
override val pointerSpace: Optional[String] = o2jo(Option.empty[String])
override def toString: String =
if (sourceUri.isDefined) s"${sourceUri.get}:${if (line.isPresent) line.get else -1}"
else ""
private def fixSource[T <: JavaFileObject](source: T): Option[String] = {
try Option(source).map(_.toUri.normalize).map(new File(_)).map(_.getAbsolutePath)
catch {
case t: IllegalArgumentException =>
// Oracle JDK6 has a super dumb notion of what a URI is. In fact, it's not even a legimitate URL, but a dump
// of the filename in a "I hope this works to toString it" kind of way. This appears to work in practice
// but we may need to re-evaluate.
Option(source).map(_.toUri.toString)
}
if (severity == Severity.Error) errorEncountered = true
reporter.log(pos, msg, severity)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,31 @@ package javac

import java.io.File

import sbt.util.Logger.o2m
import java.util.Optional
import sbt.util.InterfaceUtil.o2jo
import xsbti.{ Problem, Severity, Maybe, Position }

/** A wrapper around xsbti.Position so we can pass in Java input. */
final case class JavaPosition(_sourceFilePath: String, _line: Int, _contents: String, _offset: Int) extends Position {
def line: Maybe[Integer] = o2m(Some(_line))
def line: Optional[Integer] = o2jo(Some(_line))
def lineContent: String = _contents
def offset: Maybe[Integer] = o2m(Some(_offset))
def pointer: Maybe[Integer] = o2m(None)
def pointerSpace: Maybe[String] = o2m(None)
def sourcePath: Maybe[String] = o2m(Option(_sourceFilePath))
def sourceFile: Maybe[File] = o2m(Option(new File(_sourceFilePath)))
def offset: Optional[Integer] = o2jo(Some(_offset))
def pointer: Optional[Integer] = o2jo(None)
def pointerSpace: Optional[String] = o2jo(None)
def sourcePath: Optional[String] = o2jo(Option(_sourceFilePath))
def sourceFile: Optional[File] = o2jo(Option(new File(_sourceFilePath)))
override def toString = s"${_sourceFilePath}:${_line}:${_offset}"
}

/** A position which has no information, because there is none. */
object JavaNoPosition extends Position {
def line: Maybe[Integer] = o2m(None)
def line: Optional[Integer] = o2jo(None)
def lineContent: String = ""
def offset: Maybe[Integer] = o2m(None)
def pointer: Maybe[Integer] = o2m(None)
def pointerSpace: Maybe[String] = o2m(None)
def sourcePath: Maybe[String] = o2m(None)
def sourceFile: Maybe[File] = o2m(None)
def offset: Optional[Integer] = o2jo(None)
def pointer: Optional[Integer] = o2jo(None)
def pointerSpace: Optional[String] = o2jo(None)
def sourcePath: Optional[String] = o2jo(None)
def sourceFile: Optional[File] = o2jo(None)
override def toString = "NoPosition"
}

Expand Down
Loading

0 comments on commit 0dee711

Please sign in to comment.