summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2014-06-10 16:24:37 +0200
committerAdriaan Moors <adriaan.moors@typesafe.com>2014-07-04 15:49:05 +0200
commit98216be3f3e546fc320ab5182ac5c129707db1ce (patch)
tree1c20acf20ecfdfa37dd49ed53d82039af58c9e29 /src/compiler
parentf2b76e80094219db1f72a7a56d02f21bab1fc9eb (diff)
downloadscala-98216be3f3e546fc320ab5182ac5c129707db1ce.tar.gz
scala-98216be3f3e546fc320ab5182ac5c129707db1ce.tar.bz2
scala-98216be3f3e546fc320ab5182ac5c129707db1ce.zip
Move reporting logic into Reporting trait
Move code from Global/SymbolTable to separate Reporting traits to start carving out an interface in scala.reflect.internal.Reporting, with internals in scala.tools.nsc. Reporting is mixed into the cake. It contains a nested class PerRunReporting. Should do the same for debugging/logging. The idea is that CompilationUnit and Global forward all reporting to Reporter. The Reporting trait contains these forwarders, and PerRunReporting, which accumulates warning state during a run. In the process, I slightly changed the behavior of `globalError` in reflect.internal.SymbolTable: it used to abort, weirdly. I assume that was dummy behavior to avoid introducing an abstract method. It's immediately overridden in Global, and I couldn't find any other subclasses, so I don't think the behavior in SymbolTable was ever observed. Provide necessary hooks for scala.reflect.macros.Parsers#parse. See scala/reflect/macros/contexts/Parsers.scala's parse method, which overrides the reporter to detect when parsing goes wrong. This should be refactored, but that goes beyond the scope of this PR. Don't pop empty macro context stack. (Ran into this while reworking -Xfatal-warnings logic.) Fix -Xfatal-warnings behavior (and check files): it wasn't meant to influence warning reporting, except for emitting one final error; if necessary to fail the compile (when warnings but no errors were reported). Warnings should stay warnings. This was refactored in fbbbb22946, but we soon seem to have relapsed. An hour of gitfu did not lead to where it went wrong. Must've been a merge.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/reflect/macros/contexts/Parsers.scala5
-rw-r--r--src/compiler/scala/tools/nsc/CompilationUnits.scala37
-rw-r--r--src/compiler/scala/tools/nsc/CompileServer.scala4
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala150
-rw-r--r--src/compiler/scala/tools/nsc/Reporting.scala132
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala2
-rw-r--r--src/compiler/scala/tools/nsc/reporters/Reporter.scala15
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala16
9 files changed, 203 insertions, 162 deletions
diff --git a/src/compiler/scala/reflect/macros/contexts/Parsers.scala b/src/compiler/scala/reflect/macros/contexts/Parsers.scala
index 88cfea8157..9975bd22a0 100644
--- a/src/compiler/scala/reflect/macros/contexts/Parsers.scala
+++ b/src/compiler/scala/reflect/macros/contexts/Parsers.scala
@@ -9,7 +9,10 @@ trait Parsers {
def parse(code: String) = {
val sreporter = new StoreReporter()
- val unit = new CompilationUnit(newSourceFile(code, "<macro>")) { override def reporter = sreporter }
+ val unit = new CompilationUnit(newSourceFile(code, "<macro>")) {
+ override def reporter = sreporter
+ override def reporting = new PerRunReporting { override def reporter = sreporter }
+ }
val parser = newUnitParser(unit)
val tree = gen.mkTreeOrBlock(parser.parseStatsOrPackages())
sreporter.infos.foreach {
diff --git a/src/compiler/scala/tools/nsc/CompilationUnits.scala b/src/compiler/scala/tools/nsc/CompilationUnits.scala
index 924bb54ddb..ae1b94dfa1 100644
--- a/src/compiler/scala/tools/nsc/CompilationUnits.scala
+++ b/src/compiler/scala/tools/nsc/CompilationUnits.scala
@@ -123,32 +123,27 @@ trait CompilationUnits { global: Global =>
*/
val icode: LinkedHashSet[icodes.IClass] = new LinkedHashSet
- def reporter = global.reporter
+ // reporter and its forwarded methods
+ def reporter = global.reporter
+ def reporting = currentRun.reporting
- def echo(pos: Position, msg: String) =
- reporter.echo(pos, msg)
+ def echo(pos: Position, msg: String): Unit = reporter.echo(pos, msg)
+ def error(pos: Position, msg: String): Unit = reporter.error(pos, msg)
+ def warning(pos: Position, msg: String): Unit = reporter.warning(pos, msg)
- def error(pos: Position, msg: String) =
- reporter.error(pos, msg)
+ def deprecationWarning(pos: Position, msg: String): Unit = reporting.deprecationWarning(pos, msg)
+ def uncheckedWarning(pos: Position, msg: String): Unit = reporting.uncheckedWarning(pos, msg)
+ def inlinerWarning(pos: Position, msg: String): Unit = reporting.inlinerWarning(pos, msg)
+ def featureWarning(pos: Position, featureName: String, featureDesc: String, featureTrait: Symbol, construct: => String = "",
+ required: Boolean): Unit = reporting.featureWarning(pos, featureName, featureDesc, featureTrait, construct, required)
- def warning(pos: Position, msg: String) =
- reporter.warning(pos, msg)
-
- def deprecationWarning(pos: Position, msg: String) =
- currentRun.deprecationWarnings0.warn(pos, msg)
-
- def uncheckedWarning(pos: Position, msg: String) =
- currentRun.uncheckedWarnings0.warn(pos, msg)
-
- def inlinerWarning(pos: Position, msg: String) =
- currentRun.inlinerWarnings.warn(pos, msg)
-
- def incompleteInputError(pos: Position, msg:String) =
- reporter.incompleteInputError(pos, msg)
+ // repl
+ def incompleteHandled: Boolean = reporting.incompleteHandled
+ def incompleteInputError(pos: Position, msg:String): Unit = reporting.incompleteInputError(pos, msg)
// used by the IDE -- TODO: don't use reporter to communicate comments from parser to IDE!
- def comment(pos: Position, msg: String): Unit =
- reporter.comment(pos, msg)
+ def comment(pos: Position, msg: String): Unit = reporter.comment(pos, msg)
+
/** Is this about a .java source file? */
lazy val isJava = source.file.name.endsWith(".java")
diff --git a/src/compiler/scala/tools/nsc/CompileServer.scala b/src/compiler/scala/tools/nsc/CompileServer.scala
index 6f068e179c..1f3a4237eb 100644
--- a/src/compiler/scala/tools/nsc/CompileServer.scala
+++ b/src/compiler/scala/tools/nsc/CompileServer.scala
@@ -7,7 +7,7 @@ package scala.tools.nsc
import java.io.PrintStream
import scala.tools.nsc.reporters.{Reporter, ConsoleReporter}
-import scala.reflect.internal.util.FakePos //Position
+import scala.reflect.internal.util.{FakePos, Position}
import scala.tools.util.SocketServer
import settings.FscSettings
@@ -37,7 +37,7 @@ class StandardCompileServer extends SocketServer {
/** Create a new compiler instance */
def newGlobal(settings: Settings, reporter: Reporter) =
new Global(settings, reporter) {
- override def inform(msg: String) = out.println(msg)
+ override def inform(pos: Position, msg: String) = out.println(msg)
}
override def timeout() {
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 836203e80d..daf69ffc3f 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -44,7 +44,8 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
with Trees
with Printers
with DocComments
- with Positions { self =>
+ with Positions
+ with Reporting { self =>
// the mirror --------------------------------------------------
@@ -227,20 +228,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
*/
def registerTopLevelSym(sym: Symbol) {}
-// ------------------ Reporting -------------------------------------
-
- // not deprecated yet, but a method called "error" imported into
- // nearly every trait really must go. For now using globalError.
- def error(msg: String) = globalError(msg)
-
- override def inform(msg: String) = inform(NoPosition, msg)
- override def globalError(msg: String) = globalError(NoPosition, msg)
- override def warning(msg: String) = warning(NoPosition, msg)
- override def deprecationWarning(pos: Position, msg: String) = currentUnit.deprecationWarning(pos, msg)
-
- def globalError(pos: Position, msg: String) = reporter.error(pos, msg)
- def warning(pos: Position, msg: String) = if (settings.fatalWarnings) globalError(pos, msg) else reporter.warning(pos, msg)
- def inform(pos: Position, msg: String) = reporter.echo(pos, msg)
+// ------------------ Debugging -------------------------------------
// Getting in front of Predef's asserts to supplement with more info.
// This has the happy side effect of masking the one argument forms
@@ -263,12 +251,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
require(requirement, "")
}
- // Needs to call error to make sure the compile fails.
- override def abort(msg: String): Nothing = {
- error(msg)
- super.abort(msg)
- }
-
@inline final def ifDebug(body: => Unit) {
if (settings.debug)
body
@@ -1063,6 +1045,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
def currentUnit: CompilationUnit = if (currentRun eq null) NoCompilationUnit else currentRun.currentUnit
def currentSource: SourceFile = if (currentUnit.exists) currentUnit.source else lastSeenSourceFile
def currentFreshNameCreator = currentUnit.fresh
+ def currentReporting = currentRun.reporting
def isGlobalInitialized = (
definitions.isDefinitionsInitialized
@@ -1110,45 +1093,41 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
/** Don't want to introduce new errors trying to report errors,
* so swallow exceptions.
*/
- override def supplementErrorMessage(errorMessage: String): String = {
- if (currentRun.supplementedError) errorMessage
- else try {
- currentRun.supplementedError = true
- val tree = analyzer.lastTreeToTyper
- val sym = tree.symbol
- val tpe = tree.tpe
- val site = lastSeenContext.enclClassOrMethod.owner
- val pos_s = if (tree.pos.isDefined) s"line ${tree.pos.line} of ${tree.pos.source.file}" else "<unknown>"
- val context_s = try {
- // Taking 3 before, 3 after the fingered line.
- val start = 0 max (tree.pos.line - 3)
- val xs = scala.reflect.io.File(tree.pos.source.file.file).lines drop start take 7
- val strs = xs.zipWithIndex map { case (line, idx) => f"${start + idx}%6d $line" }
- strs.mkString("== Source file context for tree position ==\n\n", "\n", "")
- }
- catch { case t: Exception => devWarning("" + t) ; "<Cannot read source file>" }
-
- val info1 = formatExplain(
- "while compiling" -> currentSource.path,
- "during phase" -> ( if (globalPhase eq phase) phase else "globalPhase=%s, enteringPhase=%s".format(globalPhase, phase) ),
- "library version" -> scala.util.Properties.versionString,
- "compiler version" -> Properties.versionString,
- "reconstructed args" -> settings.recreateArgs.mkString(" ")
- )
- val info2 = formatExplain(
- "last tree to typer" -> tree.summaryString,
- "tree position" -> pos_s,
- "tree tpe" -> tpe,
- "symbol" -> Option(sym).fold("null")(_.debugLocationString),
- "symbol definition" -> Option(sym).fold("null")(s => s.defString + s" (a ${s.shortSymbolClass})"),
- "symbol package" -> sym.enclosingPackage.fullName,
- "symbol owners" -> ownerChainString(sym),
- "call site" -> (site.fullLocationString + " in " + site.enclosingPackage)
- )
- ("\n " + errorMessage + "\n" + info1) :: info2 :: context_s :: Nil mkString "\n\n"
+ def supplementTyperState(errorMessage: String): String = try {
+ val tree = analyzer.lastTreeToTyper
+ val sym = tree.symbol
+ val tpe = tree.tpe
+ val site = lastSeenContext.enclClassOrMethod.owner
+ val pos_s = if (tree.pos.isDefined) s"line ${tree.pos.line} of ${tree.pos.source.file}" else "<unknown>"
+ val context_s = try {
+ // Taking 3 before, 3 after the fingered line.
+ val start = 0 max (tree.pos.line - 3)
+ val xs = scala.reflect.io.File(tree.pos.source.file.file).lines drop start take 7
+ val strs = xs.zipWithIndex map { case (line, idx) => f"${start + idx}%6d $line" }
+ strs.mkString("== Source file context for tree position ==\n\n", "\n", "")
}
- catch { case _: Exception | _: TypeError => errorMessage }
- }
+ catch { case t: Exception => devWarning("" + t) ; "<Cannot read source file>" }
+
+ val info1 = formatExplain(
+ "while compiling" -> currentSource.path,
+ "during phase" -> ( if (globalPhase eq phase) phase else "globalPhase=%s, enteringPhase=%s".format(globalPhase, phase) ),
+ "library version" -> scala.util.Properties.versionString,
+ "compiler version" -> Properties.versionString,
+ "reconstructed args" -> settings.recreateArgs.mkString(" ")
+ )
+ val info2 = formatExplain(
+ "last tree to typer" -> tree.summaryString,
+ "tree position" -> pos_s,
+ "tree tpe" -> tpe,
+ "symbol" -> Option(sym).fold("null")(_.debugLocationString),
+ "symbol definition" -> Option(sym).fold("null")(s => s.defString + s" (a ${s.shortSymbolClass})"),
+ "symbol package" -> sym.enclosingPackage.fullName,
+ "symbol owners" -> ownerChainString(sym),
+ "call site" -> (site.fullLocationString + " in " + site.enclosingPackage)
+ )
+ ("\n " + errorMessage + "\n" + info1) :: info2 :: context_s :: Nil mkString "\n\n"
+ } catch { case _: Exception | _: TypeError => errorMessage }
+
/** The id of the currently active run
*/
@@ -1160,19 +1139,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
inform("[running phase " + ph.name + " on " + currentRun.size + " compilation units]")
}
- /** Collects for certain classes of warnings during this run. */
- class ConditionalWarning(what: String, option: Settings#BooleanSetting) {
- val warnings = mutable.LinkedHashMap[Position, String]()
- def warn(pos: Position, msg: String) =
- if (option) reporter.warning(pos, msg)
- else if (!(warnings contains pos)) warnings += ((pos, msg))
- def summarize() =
- if (warnings.nonEmpty && (option.isDefault || settings.fatalWarnings)){
- val warningEvent = if (warnings.size > 1) s"were ${ warnings.size } $what warnings" else s"was one $what warning"
- warning(s"there $warningEvent; re-run with ${ option.name } for details")
- }
- }
-
def newSourceFile(code: String, filename: String = "<console>") =
new BatchSourceFile(filename, code)
@@ -1199,38 +1165,12 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
/** The currently compiled unit; set from GlobalPhase */
var currentUnit: CompilationUnit = NoCompilationUnit
- // This change broke sbt; I gave it the thrilling name of uncheckedWarnings0 so
- // as to recover uncheckedWarnings for its ever-fragile compiler interface.
- val deprecationWarnings0 = new ConditionalWarning("deprecation", settings.deprecation)
- val uncheckedWarnings0 = new ConditionalWarning("unchecked", settings.unchecked)
- val featureWarnings = new ConditionalWarning("feature", settings.feature)
- val inlinerWarnings = new ConditionalWarning("inliner", settings.YinlinerWarnings)
- val allConditionalWarnings = List(deprecationWarnings0, uncheckedWarnings0, featureWarnings, inlinerWarnings)
-
- def uncheckedWarnings: List[(Position, String)] = uncheckedWarnings0.warnings.toList // used in sbt
- def deprecationWarnings: List[(Position, String)] = deprecationWarnings0.warnings.toList // used in sbt
-
- def reportAdditionalErrors(): Unit = {
- if (!reporter.hasErrors) {
- if (reporter.hasWarnings && settings.fatalWarnings)
- globalError("No warnings can be incurred under -Xfatal-warnings.")
-
- allConditionalWarnings foreach (_.summarize())
-
- if (seenMacroExpansionsFallingBack)
- warning("some macros could not be expanded and code fell back to overridden methods;"+
- "\nrecompiling with generated classfiles on the classpath might help.")
- // todo: migrationWarnings
- }
- }
-
- var reportedFeature = Set[Symbol]()
-
- /** Has any macro expansion used a fallback during this run? */
- var seenMacroExpansionsFallingBack = false
+ val reporting = new PerRunReporting
- /** Have we already supplemented the error message of a compiler crash? */
- private[nsc] final var supplementedError = false
+ // used in sbt
+ def uncheckedWarnings: List[(Position, String)] = reporting.uncheckedWarnings
+ // used in sbt
+ def deprecationWarnings: List[(Position, String)] = reporting.deprecationWarnings
private class SyncedCompilationBuffer { self =>
private val underlying = new mutable.ArrayBuffer[CompilationUnit]
@@ -1590,7 +1530,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
def checkDeprecations() = {
checkDeprecatedSettings(newCompilationUnit(""))
- reportAdditionalErrors()
+ reporting.summarizeErrors()
}
val units = sources map scripted map (new CompilationUnit(_))
@@ -1660,7 +1600,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
advancePhase()
}
- reportAdditionalErrors()
+ reporting.summarizeErrors()
if (traceSymbolActivity)
units map (_.body) foreach (traceSymbols recordSymbolsInTree _)
diff --git a/src/compiler/scala/tools/nsc/Reporting.scala b/src/compiler/scala/tools/nsc/Reporting.scala
new file mode 100644
index 0000000000..614eb4f212
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/Reporting.scala
@@ -0,0 +1,132 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2014 LAMP/EPFL, Typesafe Inc.
+ * @author Adriaan Moors
+ */
+
+package scala
+package tools
+package nsc
+
+import reporters.{ Reporter, ConsoleReporter }
+import scala.collection.{ mutable, immutable }
+
+trait Reporting extends scala.reflect.internal.Reporting { self: ast.Positions with CompilationUnits with scala.reflect.api.Symbols =>
+ def settings: Settings
+ def reporter: Reporter
+ def currentReporting: PerRunReporting
+
+ def supplementTyperState(errorMessage: String): String
+
+ // not deprecated yet, but a method called "error" imported into
+ // nearly every trait really must go. For now using globalError.
+ def error(msg: String) = globalError(msg)
+
+ override def inform(pos: Position, msg: String) = reporter.echo(pos, msg)
+ override def warning(pos: Position, msg: String) = reporter.warning(pos, msg)
+ override def globalError(pos: Position, msg: String) = reporter.error(pos, msg)
+
+ override def deprecationWarning(pos: Position, msg: String) = currentReporting.deprecationWarning(pos, msg)
+ override def supplementErrorMessage(errorMessage: String) = currentReporting.supplementErrorMessage(errorMessage)
+
+ // a new instance of this class is created for every Run (access the current instance via `currentReporting`)
+ class PerRunReporting {
+ // NOTE: scala.reflect.macros.Parsers#parse relies on everything related to reporting going through this def...
+ // TODO: can we rework this to avoid the indirection/fragility?
+ def reporter = Reporting.this.reporter
+
+ /** Collects for certain classes of warnings during this run. */
+ private class ConditionalWarning(what: String, option: Settings#BooleanSetting) {
+ val warnings = mutable.LinkedHashMap[Position, String]()
+ def warn(pos: Position, msg: String) =
+ if (option) reporter.warning(pos, msg)
+ else if (!(warnings contains pos)) warnings += ((pos, msg))
+ def summarize() =
+ if (warnings.nonEmpty && (option.isDefault || settings.fatalWarnings)) {
+ val numWarnings = warnings.size
+ val warningEvent = // TODO use scala.reflect.internal.util.StringOps.countElementsAsString(numWarnings, s"$what warning")
+ if (numWarnings > 1) s"were $numWarnings $what warnings"
+ else s"was one $what warning"
+
+ reporter.warning(NoPosition, s"there $warningEvent; re-run with ${option.name} for details")
+ }
+ }
+
+ // This change broke sbt; I gave it the thrilling name of uncheckedWarnings0 so
+ // as to recover uncheckedWarnings for its ever-fragile compiler interface.
+ private val _deprecationWarnings = new ConditionalWarning("deprecation", settings.deprecation)
+ private val _uncheckedWarnings = new ConditionalWarning("unchecked", settings.unchecked)
+ private val _featureWarnings = new ConditionalWarning("feature", settings.feature)
+ private val _inlinerWarnings = new ConditionalWarning("inliner", settings.YinlinerWarnings)
+ private val _allConditionalWarnings = List(_deprecationWarnings, _uncheckedWarnings, _featureWarnings, _inlinerWarnings)
+
+ def deprecationWarning(pos: Position, msg: String): Unit = _deprecationWarnings.warn(pos, msg)
+ def uncheckedWarning(pos: Position, msg: String): Unit = _uncheckedWarnings.warn(pos, msg)
+ def featureWarning(pos: Position, msg: String): Unit = _featureWarnings.warn(pos, msg)
+ def inlinerWarning(pos: Position, msg: String): Unit = _inlinerWarnings.warn(pos, msg)
+
+ def deprecationWarnings = _deprecationWarnings.warnings.toList
+ def uncheckedWarnings = _uncheckedWarnings.warnings.toList
+ def featureWarnings = _featureWarnings.warnings.toList
+ def inlinerWarnings = _inlinerWarnings.warnings.toList
+
+ def allConditionalWarnings = _allConditionalWarnings flatMap (_.warnings)
+
+ private[this] var reportedFeature = Set[Symbol]()
+ def featureWarning(pos: Position, featureName: String, featureDesc: String, featureTrait: Symbol, construct: => String = "", required: Boolean): Unit = {
+ val req = if (required) "needs to" else "should"
+ val fqname = "scala.language." + featureName
+ val explain = (
+ if (reportedFeature contains featureTrait) "" else
+ s"""|
+ |This can be achieved by adding the import clause 'import $fqname'
+ |or by setting the compiler option -language:$featureName.
+ |See the Scala docs for value $fqname for a discussion
+ |why the feature $req be explicitly enabled.""".stripMargin
+ )
+ reportedFeature += featureTrait
+
+ val msg = s"$featureDesc $req be enabled\nby making the implicit value $fqname visible.$explain" replace ("#", construct)
+ if (required) reporter.error(pos, msg)
+ else featureWarning(pos, msg)
+ }
+
+ /** Has any macro expansion used a fallback during this run? */
+ var seenMacroExpansionsFallingBack = false
+
+ def summarizeErrors(): Unit = if (!reporter.hasErrors) {
+ _allConditionalWarnings foreach (_.summarize())
+
+ if (seenMacroExpansionsFallingBack)
+ reporter.warning(NoPosition, "some macros could not be expanded and code fell back to overridden methods;"+
+ "\nrecompiling with generated classfiles on the classpath might help.")
+
+ // todo: migrationWarnings
+
+ if (settings.fatalWarnings && reporter.hasWarnings)
+ reporter.error(NoPosition, "No warnings can be incurred under -Xfatal-warnings.")
+ }
+
+ // for repl
+ private[this] var incompleteHandler: (Position, String) => Unit = null
+ def withIncompleteHandler[T](handler: (Position, String) => Unit)(thunk: => T) = {
+ val saved = incompleteHandler
+ incompleteHandler = handler
+ try thunk
+ finally incompleteHandler = saved
+ }
+
+ def incompleteHandled = incompleteHandler != null
+ def incompleteInputError(pos: Position, msg: String): Unit =
+ if (incompleteHandled) incompleteHandler(pos, msg)
+ else reporter.error(pos, msg)
+
+ /** 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)
+ }
+ }
+} \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala b/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala
index 3a695c6f59..3d8a7d2e55 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala
@@ -83,7 +83,7 @@ abstract class SyntaxAnalyzer extends SubComponent with Parsers with MarkupParse
private def initialUnitBody(unit: CompilationUnit): Tree = {
if (unit.isJava) new JavaUnitParser(unit).parse()
- else if (global.reporter.incompleteHandled) newUnitParser(unit).parse()
+ else if (unit.incompleteHandled) newUnitParser(unit).parse()
else newUnitParser(unit).smartParse()
}
diff --git a/src/compiler/scala/tools/nsc/reporters/Reporter.scala b/src/compiler/scala/tools/nsc/reporters/Reporter.scala
index 1a8794d217..b617e7b530 100644
--- a/src/compiler/scala/tools/nsc/reporters/Reporter.scala
+++ b/src/compiler/scala/tools/nsc/reporters/Reporter.scala
@@ -53,15 +53,6 @@ abstract class Reporter {
override def toString: String = "ERROR"
}
- private var incompleteHandler: (Position, String) => Unit = null
- def incompleteHandled = incompleteHandler != null
- def withIncompleteHandler[T](handler: (Position, String) => Unit)(thunk: => T) = {
- val saved = incompleteHandler
- incompleteHandler = handler
- try thunk
- finally incompleteHandler = saved
- }
-
// used by sbt (via unit.cancel) to cancel a compile (see hasErrors)
var cancelled: Boolean = false
@@ -71,12 +62,6 @@ abstract class Reporter {
// overridden by sbt
def hasWarnings: Boolean = WARNING.count > 0
- // TODO
- def incompleteInputError(pos: Position, msg: String): Unit = {
- if (incompleteHandled) incompleteHandler(pos, msg)
- else error(pos, msg)
- }
-
// overridden by sbt, IDE -- should move out of this interface
// it's unrelated to reporting (IDE receives comments from ScaladocAnalyzer)
def comment(pos: Position, msg: String): Unit = {}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index ef74beec62..9c22688581 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -714,7 +714,7 @@ trait Macros extends MacroRuntimes with Traces with Helpers {
sealed abstract class MacroStatus(val result: Tree)
case class Success(expanded: Tree) extends MacroStatus(expanded)
- case class Fallback(fallback: Tree) extends MacroStatus(fallback) { currentRun.seenMacroExpansionsFallingBack = true }
+ case class Fallback(fallback: Tree) extends MacroStatus(fallback) { currentRun.reporting.seenMacroExpansionsFallingBack = true }
case class Delayed(delayed: Tree) extends MacroStatus(delayed)
case class Skipped(skipped: Tree) extends MacroStatus(skipped)
case class Failure(failure: Tree) extends MacroStatus(failure)
@@ -788,7 +788,7 @@ trait Macros extends MacroRuntimes with Traces with Helpers {
}
} catch {
case ex: Throwable =>
- popMacroContext()
+ if (openMacros.nonEmpty) popMacroContext() // weirdly we started popping on an empty stack when refactoring fatalWarnings logic
val realex = ReflectionUtils.unwrapThrowable(ex)
realex match {
case ex: AbortMacroException => MacroGeneratedAbort(expandee, ex)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 9a4d5e3c06..059b58c943 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -746,21 +746,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
if (!OK) {
val Some(AnnotationInfo(_, List(Literal(Constant(featureDesc: String)), Literal(Constant(required: Boolean))), _)) =
featureTrait getAnnotation LanguageFeatureAnnot
- val req = if (required) "needs to" else "should"
- val fqname = "scala.language." + featureName
- val explain = (
- if (currentRun.reportedFeature contains featureTrait) "" else
- s"""|
- |This can be achieved by adding the import clause 'import $fqname'
- |or by setting the compiler option -language:$featureName.
- |See the Scala docs for value $fqname for a discussion
- |why the feature $req be explicitly enabled.""".stripMargin
- )
- currentRun.reportedFeature += featureTrait
-
- val msg = s"$featureDesc $req be enabled\nby making the implicit value $fqname visible.$explain" replace ("#", construct)
- if (required) unit.error(pos, msg)
- else currentRun.featureWarnings.warn(pos, msg)
+ unit.featureWarning(pos, featureName, featureDesc, featureTrait, construct, required)
}
OK
}