summaryrefslogtreecommitdiff
path: root/src/reflect
diff options
context:
space:
mode:
Diffstat (limited to 'src/reflect')
-rw-r--r--src/reflect/scala/reflect/internal/Positions.scala11
-rw-r--r--src/reflect/scala/reflect/internal/Reporting.scala113
-rw-r--r--src/reflect/scala/reflect/internal/SymbolTable.scala9
-rw-r--r--src/reflect/scala/reflect/internal/Variances.scala2
-rw-r--r--src/reflect/scala/reflect/runtime/JavaUniverse.scala18
5 files changed, 134 insertions, 19 deletions
diff --git a/src/reflect/scala/reflect/internal/Positions.scala b/src/reflect/scala/reflect/internal/Positions.scala
index 01fba1efc1..c16d8778d9 100644
--- a/src/reflect/scala/reflect/internal/Positions.scala
+++ b/src/reflect/scala/reflect/internal/Positions.scala
@@ -23,13 +23,10 @@ import scala.collection.mutable.ListBuffer
* Otherwise, the singleton consisting of the node itself.
*/
trait Positions extends api.Positions { self: SymbolTable =>
-
type Position = scala.reflect.internal.util.Position
val NoPosition = scala.reflect.internal.util.NoPosition
implicit val PositionTag = ClassTag[Position](classOf[Position])
- def inform(msg: String): Unit
-
def useOffsetPositions: Boolean = true
/** A position that wraps a set of trees.
@@ -100,7 +97,7 @@ trait Positions extends api.Positions { self: SymbolTable =>
inform("\nWhile validating #" + tree.id)
inform(treeStatus(tree))
inform("\nChildren:")
- tree.children map (t => " " + treeStatus(t, tree)) foreach inform
+ tree.children foreach (t => inform(" " + treeStatus(t, tree)))
inform("=======")
throw new ValidateException(msg)
}
@@ -109,7 +106,7 @@ trait Positions extends api.Positions { self: SymbolTable =>
if (!tree.isEmpty && tree.canHaveAttrs) {
if (settings.Yposdebug && (settings.verbose || settings.Yrangepos))
- println("[%10s] %s".format("validate", treeStatus(tree, encltree)))
+ inform("[%10s] %s".format("validate", treeStatus(tree, encltree)))
if (!tree.pos.isDefined)
positionError("Unpositioned tree #"+tree.id) {
@@ -176,7 +173,7 @@ trait Positions extends api.Positions { self: SymbolTable =>
case r :: rs1 =>
assert(!t.pos.isTransparent)
if (r.isFree && (r.pos includes t.pos)) {
-// println("subdividing "+r+"/"+t.pos)
+// inform("subdividing "+r+"/"+t.pos)
maybeFree(t.pos.end, r.pos.end) ::: List(Range(t.pos, t)) ::: maybeFree(r.pos.start, t.pos.start) ::: rs1
} else {
if (!r.isFree && (r.pos overlaps t.pos)) conflicting += r.tree
@@ -225,7 +222,7 @@ trait Positions extends api.Positions { self: SymbolTable =>
}
} catch {
case ex: Exception =>
- println("error while set children pos "+pos+" of "+trees)
+ inform("error while set children pos "+pos+" of "+trees)
throw ex
}
diff --git a/src/reflect/scala/reflect/internal/Reporting.scala b/src/reflect/scala/reflect/internal/Reporting.scala
new file mode 100644
index 0000000000..423127803e
--- /dev/null
+++ b/src/reflect/scala/reflect/internal/Reporting.scala
@@ -0,0 +1,113 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2014 LAMP/EPFL, Typesafe Inc.
+ * @author Adriaan Moors
+ */
+
+package scala
+package reflect
+package internal
+
+/** Provides delegates to the reporter doing the actual work.
+ * All forwarding methods should be marked final,
+ * but some subclasses out of our reach stil override them.
+ *
+ * Eventually, this interface should be reduced to one method: `reporter`,
+ * and clients should indirect themselves (reduce duplication of forwarders).
+ */
+trait Reporting { self : Positions =>
+ def reporter: Reporter
+ def currentRun: RunReporting
+
+ trait RunReporting {
+ val reporting: PerRunReporting = PerRunReporting
+ }
+
+ type PerRunReporting <: PerRunReportingBase
+ protected def PerRunReporting: PerRunReporting
+ abstract class PerRunReportingBase {
+ def deprecationWarning(pos: Position, msg: String): Unit
+
+ /** Have we already supplemented the error message of a compiler crash? */
+ private[this] var supplementedError = false
+ def supplementErrorMessage(errorMessage: String): String =
+ if (supplementedError) errorMessage
+ else {
+ supplementedError = true
+ supplementTyperState(errorMessage)
+ }
+
+ }
+
+ // overridden in Global
+ def supplementTyperState(errorMessage: String): String = errorMessage
+
+ def supplementErrorMessage(errorMessage: String) = currentRun.reporting.supplementErrorMessage(errorMessage)
+
+ @deprecatedOverriding("This forwards to the corresponding method in reporter -- override reporter instead", "2.11.2")
+ def inform(msg: String): Unit = inform(NoPosition, msg)
+ @deprecatedOverriding("This forwards to the corresponding method in reporter -- override reporter instead", "2.11.2")
+ def warning(msg: String): Unit = warning(NoPosition, msg)
+ // globalError(msg: String) used to abort -- not sure that was a good idea, so I made it more regular
+ // (couldn't find any uses that relied on old behavior)
+ @deprecatedOverriding("This forwards to the corresponding method in reporter -- override reporter instead", "2.11.2")
+ def globalError(msg: String): Unit = globalError(NoPosition, msg)
+
+ def abort(msg: String): Nothing = {
+ val augmented = supplementErrorMessage(msg)
+ // Needs to call error to make sure the compile fails.
+ globalError(augmented)
+ throw new FatalError(augmented)
+ }
+
+ @deprecatedOverriding("This forwards to the corresponding method in reporter -- override reporter instead", "2.11.2")
+ def inform(pos: Position, msg: String) = reporter.echo(pos, msg)
+ @deprecatedOverriding("This forwards to the corresponding method in reporter -- override reporter instead", "2.11.2")
+ def warning(pos: Position, msg: String) = reporter.warning(pos, msg)
+ @deprecatedOverriding("This forwards to the corresponding method in reporter -- override reporter instead", "2.11.2")
+ def globalError(pos: Position, msg: String) = reporter.error(pos, msg)
+}
+
+import util.Position
+
+/** Report information, warnings and errors.
+ *
+ * This describes the (future) external interface for issuing information, warnings and errors.
+ * Currently, scala.tools.nsc.Reporter is used by sbt/ide/partest.
+ */
+abstract class Reporter {
+ protected def info0(pos: Position, msg: String, severity: Severity, force: Boolean): Unit
+
+ def echo(pos: Position, msg: String): Unit = info0(pos, msg, INFO, force = true)
+ def warning(pos: Position, msg: String): Unit = info0(pos, msg, WARNING, force = false)
+ def error(pos: Position, msg: String): Unit = info0(pos, msg, ERROR, force = false)
+
+ type Severity
+ val INFO: Severity
+ val WARNING: Severity
+ val ERROR: Severity
+
+ def count(severity: Severity): Int
+ def resetCount(severity: Severity): Unit
+
+ def hasErrors: Boolean = count(ERROR) > 0
+ def hasWarnings: Boolean = count(WARNING) > 0
+
+ def reset(): Unit = {
+ resetCount(INFO)
+ resetCount(WARNING)
+ resetCount(ERROR)
+ }
+
+ def flush(): Unit = { }
+}
+
+// TODO: move into superclass once partest cuts tie on Severity
+abstract class ReporterImpl extends Reporter {
+ class Severity(val id: Int)(name: String) { var count: Int = 0 ; override def toString = name}
+ object INFO extends Severity(0)("INFO")
+ object WARNING extends Severity(1)("WARNING")
+ object ERROR extends Severity(2)("ERROR")
+
+ def count(severity: Severity): Int = severity.count
+ def resetCount(severity: Severity): Unit = severity.count = 0
+}
diff --git a/src/reflect/scala/reflect/internal/SymbolTable.scala b/src/reflect/scala/reflect/internal/SymbolTable.scala
index c76dedbff4..ed5c68fe82 100644
--- a/src/reflect/scala/reflect/internal/SymbolTable.scala
+++ b/src/reflect/scala/reflect/internal/SymbolTable.scala
@@ -46,16 +46,12 @@ abstract class SymbolTable extends macros.Universe
with pickling.Translations
with FreshNames
with Internals
+ with Reporting
{
val gen = new InternalTreeGen { val global: SymbolTable.this.type = SymbolTable.this }
def log(msg: => AnyRef): Unit
- def deprecationWarning(pos: Position, msg: String): Unit = warning(msg)
- def warning(msg: String): Unit = Console.err.println(msg)
- def inform(msg: String): Unit = Console.err.println(msg)
- def globalError(msg: String): Unit = abort(msg)
- def abort(msg: String): Nothing = throw new FatalError(supplementErrorMessage(msg))
protected def elapsedMessage(msg: String, start: Long) =
msg + " in " + (TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) - start) + "ms"
@@ -82,9 +78,6 @@ abstract class SymbolTable extends macros.Universe
/** Prints a stack trace if -Ydebug or equivalent was given, otherwise does nothing. */
def debugStack(t: Throwable): Unit = devWarning(throwableAsString(t))
- /** Overridden when we know more about what was happening during a failure. */
- def supplementErrorMessage(msg: String): String = msg
-
private[scala] def printCaller[T](msg: String)(result: T) = {
Console.err.println("%s: %s\nCalled from: %s".format(msg, result,
(new Throwable).getStackTrace.drop(2).take(50).mkString("\n")))
diff --git a/src/reflect/scala/reflect/internal/Variances.scala b/src/reflect/scala/reflect/internal/Variances.scala
index cfe2ad8b87..12b765b7a6 100644
--- a/src/reflect/scala/reflect/internal/Variances.scala
+++ b/src/reflect/scala/reflect/internal/Variances.scala
@@ -79,7 +79,7 @@ trait Variances {
// Unsound pre-2.11 behavior preserved under -Xsource:2.10
if (settings.isScala211 || sym.isOverridingSymbol) Invariant
else {
- deprecationWarning(sym.pos, s"Construct depends on unsound variance analysis and will not compile in scala 2.11 and beyond")
+ currentRun.reporting.deprecationWarning(sym.pos, s"Construct depends on unsound variance analysis and will not compile in scala 2.11 and beyond")
Bivariant
}
)
diff --git a/src/reflect/scala/reflect/runtime/JavaUniverse.scala b/src/reflect/scala/reflect/runtime/JavaUniverse.scala
index b5446694ed..fe39e1f245 100644
--- a/src/reflect/scala/reflect/runtime/JavaUniverse.scala
+++ b/src/reflect/scala/reflect/runtime/JavaUniverse.scala
@@ -14,15 +14,27 @@ import scala.reflect.api.{TreeCreator, TypeCreator, Universe}
* @contentDiagram hideNodes "*Api" "*Extractor"
*/
class JavaUniverse extends InternalSymbolTable with JavaUniverseForce with ReflectSetup with RuntimeSymbolTable { self =>
-
- override def inform(msg: String): Unit = log(msg)
def picklerPhase = SomePhase
def erasurePhase = SomePhase
lazy val settings = new Settings
- private val isLogging = sys.props contains "scala.debug.reflect"
+ private val isLogging = sys.props contains "scala.debug.reflect"
def log(msg: => AnyRef): Unit = if (isLogging) Console.err.println("[reflect] " + msg)
+ // TODO: why put output under isLogging? Calls to inform are already conditional on debug/verbose/...
+ import scala.reflect.internal.{Reporter, ReporterImpl}
+ override def reporter: Reporter = new ReporterImpl {
+ protected def info0(pos: Position, msg: String, severity: Severity, force: Boolean): Unit = log(msg)
+ }
+
+ // minimal Run to get Reporting wired
+ def currentRun = new RunReporting {}
+ class PerRunReporting extends PerRunReportingBase {
+ def deprecationWarning(pos: Position, msg: String): Unit = reporter.warning(pos, msg)
+ }
+ protected def PerRunReporting = new PerRunReporting
+
+
type TreeCopier = InternalTreeCopierOps
implicit val TreeCopierTag: ClassTag[TreeCopier] = ClassTag[TreeCopier](classOf[TreeCopier])
def newStrictTreeCopier: TreeCopier = new StrictTreeCopier