summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bincompat-forward.whitelist.conf20
-rw-r--r--src/compiler/scala/reflect/macros/contexts/Parsers.scala17
-rw-r--r--src/compiler/scala/tools/nsc/CompilationUnits.scala40
-rw-r--r--src/compiler/scala/tools/nsc/CompileServer.scala4
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala181
-rw-r--r--src/compiler/scala/tools/nsc/Reporting.scala123
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala10
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Scanners.scala6
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala4
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala4
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala10
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVMASM.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/InlineExceptionHandlers.scala4
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/Inliners.scala2
-rw-r--r--src/compiler/scala/tools/nsc/javac/JavaParsers.scala6
-rw-r--r--src/compiler/scala/tools/nsc/javac/JavaScanners.scala6
-rw-r--r--src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala11
-rw-r--r--src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala3
-rw-r--r--src/compiler/scala/tools/nsc/reporters/Reporter.scala100
-rw-r--r--src/compiler/scala/tools/nsc/reporters/StoreReporter.scala3
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/CleanUp.scala8
-rw-r--r--src/compiler/scala/tools/nsc/transform/Constructors.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala10
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/LambdaLift.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/TailCalls.scala6
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala10
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/MatchWarnings.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala6
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/ScalacPatternExpanders.scala10
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Adaptations.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Checkable.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala20
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala84
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala12
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala20
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala73
-rw-r--r--src/compiler/scala/tools/reflect/FormatInterpolator.scala2
-rw-r--r--src/library/scala/collection/immutable/List.scala6
-rw-r--r--src/library/scala/collection/mutable/UnrolledBuffer.scala48
-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
-rw-r--r--src/repl/scala/tools/nsc/interpreter/IMain.scala8
-rw-r--r--src/repl/scala/tools/nsc/interpreter/JavapClass.scala96
-rw-r--r--src/repl/scala/tools/nsc/interpreter/ReplReporter.scala19
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/ScaladocAnalyzer.scala6
-rw-r--r--test/files/jvm/deprecation.check2
-rw-r--r--test/files/jvm/serialization-new.check2
-rw-r--r--test/files/jvm/serialization.check2
-rw-r--r--test/files/neg/checksensible.check3
-rw-r--r--test/files/neg/overloaded-implicit.check3
-rw-r--r--test/files/neg/t1909-object.check4
-rw-r--r--test/files/neg/t5675.check4
-rw-r--r--test/files/neg/t6567.check3
-rw-r--r--test/files/neg/unchecked-refinement.check3
-rw-r--r--test/files/run/colltest.check2
-rw-r--r--test/files/run/inferred-type-constructors.check2
-rw-r--r--test/files/run/names-defaults.check2
-rw-r--r--test/files/run/richs.check2
-rw-r--r--test/files/run/t2212.check2
-rw-r--r--test/files/run/t3996.check2
-rw-r--r--test/files/run/t4080.check2
-rw-r--r--test/files/run/t4461.check2
-rw-r--r--test/files/run/t4813.check2
-rw-r--r--test/files/run/t6111.check2
-rw-r--r--test/files/run/t6690.check2
-rw-r--r--test/files/run/t6863.check2
-rw-r--r--test/files/run/t8196.check2
-rw-r--r--test/files/run/t8549.check2
-rw-r--r--test/junit/scala/tools/nsc/symtab/SymbolTableForUnitTesting.scala12
89 files changed, 749 insertions, 534 deletions
diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf
index 3cd985aeae..30dac79974 100644
--- a/bincompat-forward.whitelist.conf
+++ b/bincompat-forward.whitelist.conf
@@ -234,6 +234,26 @@ filter {
{
matchName="scala.reflect.runtime.SynchronizedOps.newNestedScope"
problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.runtime.JavaUniverse"
+ problemName=MissingTypesProblem
+ },
+ {
+ matchName="scala.reflect.runtime.JavaUniverse.reporter"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.runtime.JavaUniverse$PerRunReporting"
+ problemName=MissingClassProblem
+ },
+ {
+ matchName="scala.reflect.runtime.JavaUniverse.currentRun"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.runtime.JavaUniverse.PerRunReporting"
+ problemName=MissingMethodProblem
}
]
}
diff --git a/src/compiler/scala/reflect/macros/contexts/Parsers.scala b/src/compiler/scala/reflect/macros/contexts/Parsers.scala
index 88cfea8157..f4584f3627 100644
--- a/src/compiler/scala/reflect/macros/contexts/Parsers.scala
+++ b/src/compiler/scala/reflect/macros/contexts/Parsers.scala
@@ -9,12 +9,15 @@ trait Parsers {
def parse(code: String) = {
val sreporter = new StoreReporter()
- val unit = new CompilationUnit(newSourceFile(code, "<macro>")) { override def reporter = sreporter }
- val parser = newUnitParser(unit)
- val tree = gen.mkTreeOrBlock(parser.parseStatsOrPackages())
- sreporter.infos.foreach {
- case sreporter.Info(pos, msg, sreporter.ERROR) => throw ParseException(pos, msg)
- }
- tree
+ val oldReporter = global.reporter
+ try {
+ global.reporter = sreporter
+ val parser = newUnitParser(new CompilationUnit(newSourceFile(code, "<macro>")))
+ val tree = gen.mkTreeOrBlock(parser.parseStatsOrPackages())
+ sreporter.infos.foreach {
+ case sreporter.Info(pos, msg, sreporter.ERROR) => throw ParseException(pos, msg)
+ }
+ tree
+ } finally global.reporter = oldReporter
}
} \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/CompilationUnits.scala b/src/compiler/scala/tools/nsc/CompilationUnits.scala
index c2caed70a0..f23bca77cd 100644
--- a/src/compiler/scala/tools/nsc/CompilationUnits.scala
+++ b/src/compiler/scala/tools/nsc/CompilationUnits.scala
@@ -123,31 +123,23 @@ trait CompilationUnits { global: Global =>
*/
val icode: LinkedHashSet[icodes.IClass] = new LinkedHashSet
- def reporter = global.reporter
+ @deprecated("Call global.reporter.echo directly instead.", "2.11.2")
+ final def echo(pos: Position, msg: String): Unit = reporter.echo(pos, msg)
+ @deprecated("Call global.reporter.error (or typer.context.error) directly instead.", "2.11.2")
+ final def error(pos: Position, msg: String): Unit = reporter.error(pos, msg)
+ @deprecated("Call global.reporter.warning (or typer.context.warning) directly instead.", "2.11.2")
+ final def warning(pos: Position, msg: String): Unit = reporter.warning(pos, msg)
+
+ @deprecated("Call global.currentRun.reporting.deprecationWarning directly instead.", "2.11.2")
+ final def deprecationWarning(pos: Position, msg: String): Unit = currentRun.reporting.deprecationWarning(pos, msg)
+ @deprecated("Call global.currentRun.reporting.uncheckedWarning directly instead.", "2.11.2")
+ final def uncheckedWarning(pos: Position, msg: String): Unit = currentRun.reporting.uncheckedWarning(pos, msg)
+
+ // called by ScalaDocAnalyzer, overridden by the IDE (in Reporter)
+ // TODO: don't use reporter to communicate comments from parser to IDE!
+ @deprecated("This method will be removed.", "2.11.2")
+ final def comment(pos: Position, msg: String): Unit = reporter.comment(pos, msg)
- def echo(pos: Position, msg: String) =
- reporter.echo(pos, msg)
-
- def error(pos: Position, msg: String) =
- reporter.error(pos, msg)
-
- 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)
-
- def comment(pos: Position, msg: String) =
- 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 cb785de4b3..572e579aca 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
@@ -291,8 +273,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
log(s"!!!$pos_s $msg") // such warnings always at least logged
}
- def informComplete(msg: String): Unit = reporter.withoutTruncating(inform(msg))
-
def logError(msg: String, t: Throwable): Unit = ()
override def shouldLogAtThisPhase = settings.log.isSetByUser && (
@@ -351,9 +331,9 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
}
if (settings.verbose || settings.Ylogcp) {
- // Uses the "do not truncate" inform
- informComplete("[search path for source files: " + classPath.sourcepaths.mkString(",") + "]")
- informComplete("[search path for class files: " + classPath.asClasspathString + "]")
+ reporter.echo(
+ s"[search path for source files: ${classPath.sourcepaths.mkString(",")}]\n"+
+ s"[search path for class files: ${classPath.asClasspathString}")
}
// The current division between scala.reflect.* and scala.tools.nsc.* is pretty
@@ -1112,45 +1092,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"
+ override 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
*/
@@ -1162,19 +1138,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)
@@ -1192,7 +1155,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
/** A Run is a single execution of the compiler on a set of units.
*/
- class Run extends RunContextApi {
+ class Run extends RunContextApi with RunReporting {
/** Have been running into too many init order issues with Run
* during erroneous conditions. Moved all these vals up to the
* top of the file so at least they're not trivially null.
@@ -1201,24 +1164,10 @@ 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
-
- var reportedFeature = Set[Symbol]()
-
- /** Has any macro expansion used a fallback during this run? */
- var seenMacroExpansionsFallingBack = false
-
- /** 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]
@@ -1416,6 +1365,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
refreshProgress()
}
+ // for sbt
def cancel() { reporter.cancelled = true }
private def currentProgress = (phasec * size) + unitc
@@ -1481,10 +1431,10 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
private def checkDeprecatedSettings(unit: CompilationUnit) {
// issue warnings for any usage of deprecated settings
settings.userSetSettings filter (_.isDeprecated) foreach { s =>
- unit.deprecationWarning(NoPosition, s.name + " is deprecated: " + s.deprecationMessage.get)
+ currentRun.reporting.deprecationWarning(NoPosition, s.name + " is deprecated: " + s.deprecationMessage.get)
}
if (settings.target.value.contains("jvm-1.5"))
- unit.deprecationWarning(NoPosition, settings.target.name + ":" + settings.target.value + " is deprecated: use target for Java 1.6 or above.")
+ currentRun.reporting.deprecationWarning(NoPosition, settings.target.name + ":" + settings.target.value + " is deprecated: use target for Java 1.6 or above.")
}
/* An iterator returning all the units being compiled in this run */
@@ -1565,26 +1515,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
}
}
- def reportCompileErrors() {
- if (!reporter.hasErrors && reporter.hasWarnings && settings.fatalWarnings)
- globalError("No warnings can be incurred under -Xfatal-warnings.")
-
- if (reporter.hasErrors) {
- for ((sym, file) <- symSource.iterator) {
- sym.reset(new loaders.SourcefileLoader(file))
- if (sym.isTerm)
- sym.moduleClass reset loaders.moduleClassLoader
- }
- }
- else {
- 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
- }
- }
/** Caching member symbols that are def-s in Defintions because they might change from Run to Run. */
val runDefinitions: definitions.RunDefinitions = new definitions.RunDefinitions
@@ -1597,7 +1527,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
def checkDeprecations() = {
checkDeprecatedSettings(newCompilationUnit(""))
- reportCompileErrors()
+ reporting.summarizeErrors()
}
val units = sources map scripted map (new CompilationUnit(_))
@@ -1621,7 +1551,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
checkDeprecatedSettings(unitbuf.head)
globalPhase = fromPhase
- while (globalPhase.hasNext && !reporter.hasErrors) {
+ while (globalPhase.hasNext && !reporter.hasErrors) {
val startTime = currentTime
phase = globalPhase
globalPhase.run()
@@ -1667,6 +1597,8 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
advancePhase()
}
+ reporting.summarizeErrors()
+
if (traceSymbolActivity)
units map (_.body) foreach (traceSymbols recordSymbolsInTree _)
@@ -1674,8 +1606,15 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
if (settings.Yshow.isDefault)
showMembers()
- reportCompileErrors()
+ if (reporter.hasErrors) {
+ for ((sym, file) <- symSource.iterator) {
+ sym.reset(new loaders.SourcefileLoader(file))
+ if (sym.isTerm)
+ sym.moduleClass reset loaders.moduleClassLoader
+ }
+ }
symSource.keys foreach (x => resetPackageClass(x.owner))
+
informTime("total", startTime)
// Clear any sets or maps created via perRunCaches.
diff --git a/src/compiler/scala/tools/nsc/Reporting.scala b/src/compiler/scala/tools/nsc/Reporting.scala
new file mode 100644
index 0000000000..0263586418
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/Reporting.scala
@@ -0,0 +1,123 @@
+/* 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 }
+import scala.reflect.internal.util.StringOps.countElementsAsString
+
+/** Provides delegates to the reporter doing the actual work.
+ * PerRunReporting implements per-Run stateful info tracking and reporting
+ *
+ * TODO: make reporting configurable
+ */
+trait Reporting extends scala.reflect.internal.Reporting { self: ast.Positions with CompilationUnits with scala.reflect.internal.Symbols =>
+ def settings: Settings
+
+ // 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)
+
+ // a new instance of this class is created for every Run (access the current instance via `currentRun.reporting`)
+ protected def PerRunReporting = new PerRunReporting
+ class PerRunReporting extends PerRunReportingBase {
+ /** 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 warningVerb = if (numWarnings == 1) "was" else "were"
+ val warningCount = countElementsAsString(numWarnings, s"$what warning")
+
+ reporter.warning(NoPosition, s"there $warningVerb $warningCount; 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)
+
+ // TODO: remove in favor of the overload that takes a Symbol, give that argument a default (NoSymbol)
+ 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)
+
+ // behold! the symbol that caused the deprecation warning (may not be deprecated itself)
+ def deprecationWarning(pos: Position, sym: Symbol, msg: String): Unit = _deprecationWarnings.warn(pos, msg)
+ def deprecationWarning(pos: Position, sym: Symbol): Unit = {
+ val suffix = sym.deprecationMessage match { case Some(msg) => ": "+ msg case _ => "" }
+ deprecationWarning(pos, sym, s"$sym${sym.locationString} is deprecated$suffix")
+ }
+
+ 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)
+
+ }
+} \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index ffc45b21ea..883fd31dbc 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -205,11 +205,11 @@ self =>
override def newScanner() = new UnitScanner(unit, patches)
override def warning(offset: Offset, msg: String) {
- unit.warning(o2p(offset), msg)
+ reporter.warning(o2p(offset), msg)
}
override def deprecationWarning(offset: Offset, msg: String) {
- unit.deprecationWarning(o2p(offset), msg)
+ currentRun.reporting.deprecationWarning(o2p(offset), msg)
}
private var smartParsing = false
@@ -224,17 +224,17 @@ self =>
val syntaxErrors = new ListBuffer[(Int, String)]
def showSyntaxErrors() =
for ((offset, msg) <- syntaxErrors)
- unit.error(o2p(offset), msg)
+ reporter.error(o2p(offset), msg)
override def syntaxError(offset: Offset, msg: String) {
if (smartParsing) syntaxErrors += ((offset, msg))
- else unit.error(o2p(offset), msg)
+ else reporter.error(o2p(offset), msg)
}
override def incompleteInputError(msg: String) {
val offset = source.content.length - 1
if (smartParsing) syntaxErrors += ((offset, msg))
- else unit.incompleteInputError(o2p(offset), msg)
+ else currentRun.reporting.incompleteInputError(o2p(offset), msg)
}
/** parse unit. If there are inbalanced braces,
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
index e8d46704c3..572497ac90 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
@@ -1259,9 +1259,9 @@ trait Scanners extends ScannersCommon {
class UnitScanner(val unit: CompilationUnit, patches: List[BracePatch]) extends SourceFileScanner(unit.source) {
def this(unit: CompilationUnit) = this(unit, List())
- override def deprecationWarning(off: Offset, msg: String) = unit.deprecationWarning(unit.position(off), msg)
- override def error (off: Offset, msg: String) = unit.error(unit.position(off), msg)
- override def incompleteInputError(off: Offset, msg: String) = unit.incompleteInputError(unit.position(off), msg)
+ override def deprecationWarning(off: Offset, msg: String) = currentRun.reporting.deprecationWarning(unit.position(off), msg)
+ override def error (off: Offset, msg: String) = reporter.error(unit.position(off), msg)
+ override def incompleteInputError(off: Offset, msg: String) = currentRun.reporting.incompleteInputError(unit.position(off), msg)
private var bracePatches: List[BracePatch] = patches
diff --git a/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala b/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala
index 3a695c6f59..64b762696e 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 (currentRun.reporting.incompleteHandled) newUnitParser(unit).parse()
else newUnitParser(unit).smartParse()
}
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index 0ad3c2c76b..d9f56b47fa 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -680,7 +680,7 @@ abstract class GenICode extends SubComponent {
val dims = arr.dimensions
var elemKind = arr.elementKind
if (args.length > dims)
- unit.error(tree.pos, "too many arguments for array constructor: found " + args.length +
+ reporter.error(tree.pos, "too many arguments for array constructor: found " + args.length +
" but array has only " + dims + " dimension(s)")
if (args.length != dims)
for (i <- args.length until dims) elemKind = ARRAY(elemKind)
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
index bffa4bc51d..4583462b71 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
@@ -504,7 +504,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
case nextCleanup :: rest =>
if (saveReturnValue) {
if (insideCleanupBlock) {
- cunit.warning(r.pos, "Return statement found in finally-clause, discarding its return-value in favor of that of a more deeply nested return.")
+ reporter.warning(r.pos, "Return statement found in finally-clause, discarding its return-value in favor of that of a more deeply nested return.")
bc drop returnType
} else {
// regarding return value, the protocol is: in place of a `return-stmt`, a sequence of `adapt, store, jump` are inserted.
@@ -602,7 +602,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
var elemKind = arr.elementType
val argsSize = args.length
if (argsSize > dims) {
- cunit.error(app.pos, s"too many arguments for array constructor: found ${args.length} but array has only $dims dimension(s)")
+ reporter.error(app.pos, s"too many arguments for array constructor: found ${args.length} but array has only $dims dimension(s)")
}
if (argsSize < dims) {
/* In one step:
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
index 51bfdf0027..31a392ed55 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
@@ -38,7 +38,7 @@ abstract class BCodeHelpers extends BCodeTypes with BytecodeWriters {
outputDirectory(csym)
} catch {
case ex: Throwable =>
- cunit.error(cunit.body.pos, s"Couldn't create file for class $cName\n${ex.getMessage}")
+ reporter.error(cunit.body.pos, s"Couldn't create file for class $cName\n${ex.getMessage}")
null
}
}
@@ -141,7 +141,7 @@ abstract class BCodeHelpers extends BCodeTypes with BytecodeWriters {
*/
def apply(sym: Symbol, csymCompUnit: CompilationUnit): Boolean = {
def fail(msg: String, pos: Position = sym.pos) = {
- csymCompUnit.warning(sym.pos,
+ reporter.warning(sym.pos,
sym.name +
s" has a main method with parameter type Array[String], but ${sym.fullName('.')} will not be a runnable program.\n Reason: $msg"
// TODO: make this next claim true, if possible
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala
index effc68c5e3..8845ffa0cd 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala
@@ -570,7 +570,7 @@ abstract class BCodeSkelBuilder extends BCodeHelpers {
if (params.size > MaximumJvmParameters) {
// SI-7324
- cunit.error(methSymbol.pos, s"Platform restriction: a parameter list's length cannot exceed $MaximumJvmParameters.")
+ reporter.error(methSymbol.pos, s"Platform restriction: a parameter list's length cannot exceed $MaximumJvmParameters.")
return
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
index 988c04f514..b0fb3069c1 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
@@ -113,7 +113,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {
// Warn when classes will overwrite one another on case-insensitive systems.
for ((_, v1 :: v2 :: _) <- sortedClasses groupBy (_.symbol.javaClassName.toString.toLowerCase)) {
- v1.cunit.warning(v1.symbol.pos,
+ reporter.warning(v1.symbol.pos,
s"Class ${v1.symbol.javaClassName} differs only in case from ${v2.symbol.javaClassName}. " +
"Such classes will overwrite one another on case-insensitive filesystems.")
}
@@ -141,7 +141,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {
try emitFor(c)
catch {
case e: FileConflictException =>
- c.cunit.error(c.symbol.pos, s"error writing ${c.symbol}: ${e.getMessage}")
+ reporter.error(c.symbol.pos, s"error writing ${c.symbol}: ${e.getMessage}")
}
sortedClasses = sortedClasses.tail
classes -= c.symbol // GC opportunity
@@ -1363,7 +1363,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {
if (m.symbol.isStaticConstructor || definitions.isGetClass(m.symbol)) return
if (m.params.size > MaximumJvmParameters) {
- getCurrentCUnit().error(m.symbol.pos, s"Platform restriction: a parameter list's length cannot exceed $MaximumJvmParameters.")
+ reporter.error(m.symbol.pos, s"Platform restriction: a parameter list's length cannot exceed $MaximumJvmParameters.")
return
}
@@ -3245,7 +3245,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {
}
if(!isValidSignature) {
- unit.warning(sym.pos,
+ reporter.warning(sym.pos,
"""|compiler bug: created invalid generic signature for %s in %s
|signature: %s
|if this is reproducible, please report bug at https://issues.scala-lang.org/
@@ -3258,7 +3258,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {
val normalizedTpe = enteringErasure(erasure.prepareSigMap(memberTpe))
val bytecodeTpe = owner.thisType.memberInfo(sym)
if (!sym.isType && !sym.isConstructor && !(erasure.erasure(sym)(normalizedTpe) =:= bytecodeTpe)) {
- unit.warning(sym.pos,
+ reporter.warning(sym.pos,
"""|compiler bug: created generic signature for %s in %s that does not conform to its erasure
|signature: %s
|original type: %s
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala
index 9b292fee7f..a401de05e5 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala
@@ -156,7 +156,7 @@ abstract class GenBCode extends BCodeSyncAndTry {
case None =>
caseInsensitively.put(lowercaseJavaClassName, claszSymbol)
case Some(dupClassSym) =>
- item.cunit.warning(
+ reporter.warning(
claszSymbol.pos,
s"Class ${claszSymbol.javaClassName} differs only in case from ${dupClassSym.javaClassName}. " +
"Such classes will overwrite one another on case-insensitive filesystems."
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVMASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVMASM.scala
index 01c4ff5a52..2bcde7f7b9 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVMASM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVMASM.scala
@@ -27,7 +27,7 @@ trait GenJVMASM {
protected def isJavaEntryPoint(icls: IClass) = {
val sym = icls.symbol
def fail(msg: String, pos: Position = sym.pos) = {
- icls.cunit.warning(sym.pos,
+ reporter.warning(sym.pos,
sym.name + " has a main method with parameter type Array[String], but " + sym.fullName('.') + " will not be a runnable program.\n" +
" Reason: " + msg
// TODO: make this next claim true, if possible
diff --git a/src/compiler/scala/tools/nsc/backend/opt/InlineExceptionHandlers.scala b/src/compiler/scala/tools/nsc/backend/opt/InlineExceptionHandlers.scala
index 235e954f88..425c10d153 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/InlineExceptionHandlers.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/InlineExceptionHandlers.scala
@@ -182,7 +182,7 @@ abstract class InlineExceptionHandlers extends SubComponent {
// in other words: what's on the stack MUST conform to what's in the THROW(..)!
if (!canReplaceHandler) {
- currentClass.cunit.warning(NoPosition, "Unable to inline the exception handler inside incorrect" +
+ reporter.warning(NoPosition, "Unable to inline the exception handler inside incorrect" +
" block:\n" + bblock.iterator.mkString("\n") + "\nwith stack: " + typeInfo + " just " +
"before instruction index " + index)
}
@@ -383,7 +383,7 @@ abstract class InlineExceptionHandlers extends SubComponent {
Some((exceptionLocal, copy))
case _ =>
- currentClass.cunit.warning(NoPosition, "Unable to inline the exception handler due to incorrect format:\n" +
+ reporter.warning(NoPosition, "Unable to inline the exception handler due to incorrect format:\n" +
handler.iterator.mkString("\n"))
None
}
diff --git a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
index f6de522d09..8df3969c49 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
@@ -195,7 +195,7 @@ abstract class Inliners extends SubComponent {
/** The current iclass */
private var currentIClazz: IClass = _
- private def warn(pos: Position, msg: String) = currentIClazz.cunit.inlinerWarning(pos, msg)
+ private def warn(pos: Position, msg: String) = currentRun.reporting.inlinerWarning(pos, msg)
private def ownedName(sym: Symbol): String = exitingUncurry {
val count = (
diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
index a61ad392ee..37b00aa9a3 100644
--- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
+++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
@@ -26,10 +26,10 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
def freshName(prefix: String): Name = freshTermName(prefix)
def freshTermName(prefix: String): TermName = unit.freshTermName(prefix)
def freshTypeName(prefix: String): TypeName = unit.freshTypeName(prefix)
- def deprecationWarning(off: Int, msg: String) = unit.deprecationWarning(off, msg)
+ def deprecationWarning(off: Int, msg: String) = currentRun.reporting.deprecationWarning(off, msg)
implicit def i2p(offset : Int) : Position = Position.offset(unit.source, offset)
- def warning(pos : Int, msg : String) : Unit = unit.warning(pos, msg)
- def syntaxError(pos: Int, msg: String) : Unit = unit.error(pos, msg)
+ def warning(pos : Int, msg : String) : Unit = reporter.warning(pos, msg)
+ def syntaxError(pos: Int, msg: String) : Unit = reporter.error(pos, msg)
}
abstract class JavaParser extends ParserCommon {
diff --git a/src/compiler/scala/tools/nsc/javac/JavaScanners.scala b/src/compiler/scala/tools/nsc/javac/JavaScanners.scala
index c5401219dd..bddcf6567c 100644
--- a/src/compiler/scala/tools/nsc/javac/JavaScanners.scala
+++ b/src/compiler/scala/tools/nsc/javac/JavaScanners.scala
@@ -860,9 +860,9 @@ trait JavaScanners extends ast.parser.ScannersCommon {
class JavaUnitScanner(unit: CompilationUnit) extends JavaScanner {
in = new JavaCharArrayReader(unit.source.content, !settings.nouescape.value, syntaxError)
init()
- def error (pos: Int, msg: String) = unit. error(pos, msg)
- def incompleteInputError(pos: Int, msg: String) = unit.incompleteInputError(pos, msg)
- def deprecationWarning(pos: Int, msg: String) = unit.deprecationWarning(pos, msg)
+ def error (pos: Int, msg: String) = reporter.error(pos, msg)
+ def incompleteInputError(pos: Int, msg: String) = currentRun.reporting.incompleteInputError(pos, msg)
+ def deprecationWarning(pos: Int, msg: String) = currentRun.reporting.deprecationWarning(pos, msg)
implicit def g2p(pos: Int): Position = Position.offset(unit.source, pos)
}
}
diff --git a/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala b/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala
index 16d432438a..6c592ead0d 100644
--- a/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala
+++ b/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala
@@ -62,12 +62,13 @@ abstract class AbstractReporter extends Reporter {
*/
private def testAndLog(pos: Position, severity: Severity, msg: String): Boolean =
pos != null && pos.isDefined && {
- val fpos = pos.focus
+ val fpos = pos.focus
val suppress = positions(fpos) match {
- case ERROR => true // already error at position
- case highest if highest > severity => true // already message higher than present severity
- case `severity` => messages(fpos) contains msg // already issued this exact message
- case _ => false // good to go
+ case ERROR => true // already error at position
+ case highest
+ if highest.id > severity.id => true // already message higher than present severity
+ case `severity` => messages(fpos) contains msg // already issued this exact message
+ case _ => false // good to go
}
suppress || {
diff --git a/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala b/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala
index 3f210a543c..0b218b711c 100644
--- a/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala
+++ b/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala
@@ -12,8 +12,7 @@ import scala.reflect.internal.util._
import StringOps._
/**
- * This class implements a Reporter that displays messages on a text
- * console.
+ * This class implements a Reporter that displays messages on a text console.
*/
class ConsoleReporter(val settings: Settings, reader: BufferedReader, writer: PrintWriter) extends AbstractReporter {
def this(settings: Settings) = this(settings, Console.in, new PrintWriter(Console.err, true))
diff --git a/src/compiler/scala/tools/nsc/reporters/Reporter.scala b/src/compiler/scala/tools/nsc/reporters/Reporter.scala
index 68362c066d..5b576a547d 100644
--- a/src/compiler/scala/tools/nsc/reporters/Reporter.scala
+++ b/src/compiler/scala/tools/nsc/reporters/Reporter.scala
@@ -8,76 +8,50 @@ package reporters
import scala.reflect.internal.util._
-/**
- * This interface provides methods to issue information, warning and
- * error messages.
+/** Report information, warnings and errors.
+ *
+ * This describes the internal interface for issuing information, warnings and errors.
+ * The only abstract method in this class must be info0.
+ *
+ * TODO: Move external clients (sbt/ide/partest) to reflect.internal.Reporter
+ * This interface should be considered private to the compiler.
*/
-abstract class Reporter {
- protected def info0(pos: Position, msg: String, severity: Severity, force: Boolean): Unit
-
- object severity extends Enumeration
- class Severity(val id: Int) extends severity.Value {
- var count: Int = 0
- }
- val INFO = new Severity(0) {
- override def toString: String = "INFO"
- }
- val WARNING = new Severity(1) {
- override def toString: String = "WARNING"
- }
- val ERROR = new Severity(2) {
- override def toString: String = "ERROR"
- }
-
- /** Whether very long lines can be truncated. This exists so important
- * debugging information (like printing the classpath) is not rendered
- * invisible due to the max message length.
- */
- private var _truncationOK: Boolean = true
- def truncationOK = _truncationOK
- def withoutTruncating[T](body: => T): T = {
- val saved = _truncationOK
- _truncationOK = false
- try body
- finally _truncationOK = saved
- }
-
- 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
- }
-
- var cancelled = false
- def hasErrors = ERROR.count > 0 || cancelled
- def hasWarnings = WARNING.count > 0
+abstract class Reporter extends scala.reflect.internal.Reporter {
+ /** Informational messages. If `!force`, they may be suppressed. */
+ final def info(pos: Position, msg: String, force: Boolean): Unit = info0(pos, msg, INFO, force)
/** For sending a message which should not be labeled as a warning/error,
* but also shouldn't require -verbose to be visible.
*/
- def echo(msg: String): Unit = info(NoPosition, msg, force = true)
- def echo(pos: Position, msg: String): Unit = info(pos, msg, force = true)
+ def echo(msg: String): Unit = info(NoPosition, msg, force = true)
- /** Informational messages, suppressed unless -verbose or force=true. */
- def info(pos: Position, msg: String, force: Boolean): Unit = info0(pos, msg, INFO, force)
+ // overridden by sbt, IDE -- should not be in the reporting interface
+ // (IDE receives comments from ScaladocAnalyzer using this hook method)
+ // TODO: IDE should override a hook method in the parser instead
+ def comment(pos: Position, msg: String): Unit = {}
- /** Warnings and errors. */
- def warning(pos: Position, msg: String): Unit = withoutTruncating(info0(pos, msg, WARNING, force = false))
- def error(pos: Position, msg: String): Unit = withoutTruncating(info0(pos, msg, ERROR, force = false))
- def incompleteInputError(pos: Position, msg: String): Unit = {
- if (incompleteHandled) incompleteHandler(pos, msg)
- else error(pos, msg)
- }
+ // used by sbt (via unit.cancel) to cancel a compile (see hasErrors)
+ // TODO: figure out how sbt uses this, come up with a separate interface for controlling the build
+ var cancelled: Boolean = false
- def comment(pos: Position, msg: String) { }
- def flush() { }
- def reset() {
- INFO.count = 0
- ERROR.count = 0
- WARNING.count = 0
- cancelled = false
+ override def hasErrors: Boolean = super.hasErrors || cancelled
+
+ override def reset(): Unit = {
+ super.reset()
+ cancelled = false
}
+
+ // the below is copy/pasted from ReporterImpl for now
+ // partest expects this inner class
+ // TODO: rework partest to use the scala.reflect.internal interface,
+ // remove duplication here, and consolidate reflect.internal.{ReporterImpl & ReporterImpl}
+ 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")
+ // reason for copy/paste: this is used by partest (must be a val, not an object)
+ // TODO: use count(ERROR) in scala.tools.partest.nest.DirectCompiler#errorCount, rather than ERROR.count
+ lazy val ERROR = new Severity(2)("ERROR")
+
+ def count(severity: Severity): Int = severity.count
+ def resetCount(severity: Severity): Unit = severity.count = 0
}
diff --git a/src/compiler/scala/tools/nsc/reporters/StoreReporter.scala b/src/compiler/scala/tools/nsc/reporters/StoreReporter.scala
index 04c5bdf824..24a61cb171 100644
--- a/src/compiler/scala/tools/nsc/reporters/StoreReporter.scala
+++ b/src/compiler/scala/tools/nsc/reporters/StoreReporter.scala
@@ -10,8 +10,7 @@ import scala.collection.mutable
import scala.reflect.internal.util.Position
/**
- * This class implements a Reporter that displays messages on a text
- * console.
+ * This class implements a Reporter that stores its reports in the set `infos`.
*/
class StoreReporter extends Reporter {
case class Info(pos: Position, msg: String, severity: Severity) {
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
index 592c5497b5..2fc00fe068 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
@@ -69,7 +69,7 @@ abstract class Pickler extends SubComponent {
// OPT: do this only as a recovery after fatal error. Checking in advance was expensive.
if (t.isErroneous) {
if (settings.debug) e.printStackTrace()
- unit.error(t.pos, "erroneous or inaccessible type")
+ reporter.error(t.pos, "erroneous or inaccessible type")
return
}
}
diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
index f14fce5de9..1664fe0e0d 100644
--- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala
+++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
@@ -76,7 +76,7 @@ abstract class CleanUp extends Statics with Transform with ast.TreeDSL {
val qual0 = ad.qual
val params = ad.args
if (settings.logReflectiveCalls)
- unit.echo(ad.pos, "method invocation uses reflection")
+ reporter.echo(ad.pos, "method invocation uses reflection")
val typedPos = typedWithPos(ad.pos) _
@@ -360,13 +360,13 @@ abstract class CleanUp extends Statics with Transform with ast.TreeDSL {
assert(params.length == mparams.length, ((params, mparams)))
(mparams, resType)
case tpe @ OverloadedType(pre, alts) =>
- unit.warning(ad.pos, s"Overloaded type reached the backend! This is a bug in scalac.\n Symbol: ${ad.symbol}\n Overloads: $tpe\n Arguments: " + ad.args.map(_.tpe))
+ reporter.warning(ad.pos, s"Overloaded type reached the backend! This is a bug in scalac.\n Symbol: ${ad.symbol}\n Overloads: $tpe\n Arguments: " + ad.args.map(_.tpe))
alts filter (_.paramss.flatten.size == params.length) map (_.tpe) match {
case mt @ MethodType(mparams, resType) :: Nil =>
- unit.warning(NoPosition, "Only one overload has the right arity, proceeding with overload " + mt)
+ reporter.warning(NoPosition, "Only one overload has the right arity, proceeding with overload " + mt)
(mparams, resType)
case _ =>
- unit.error(ad.pos, "Cannot resolve overload.")
+ reporter.error(ad.pos, "Cannot resolve overload.")
(Nil, NoType)
}
}
diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala
index 391bce5abb..f471440293 100644
--- a/src/compiler/scala/tools/nsc/transform/Constructors.scala
+++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala
@@ -54,7 +54,7 @@ abstract class Constructors extends Statics with Transform with ast.TreeDSL {
def check(tree: Tree) = {
for (t <- tree) t match {
case t: RefTree if uninitializedVals(t.symbol.accessedOrSelf) && t.qualifier.symbol == clazz =>
- unit.warning(t.pos, s"Reference to uninitialized ${t.symbol.accessedOrSelf}")
+ reporter.warning(t.pos, s"Reference to uninitialized ${t.symbol.accessedOrSelf}")
case _ =>
}
}
@@ -685,7 +685,7 @@ abstract class Constructors extends Statics with Transform with ast.TreeDSL {
// mangling before we introduce more of it.
val conflict = clazz.info.nonPrivateMember(acc.name) filter (s => s.isGetter && !s.isOuterField && s.enclClass.isTrait)
if (conflict ne NoSymbol)
- unit.error(acc.pos, "parameter '%s' requires field but conflicts with %s".format(acc.name, conflict.fullLocationString))
+ reporter.error(acc.pos, "parameter '%s' requires field but conflicts with %s".format(acc.name, conflict.fullLocationString))
copyParam(acc, parameter(acc))
}
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 2f2142027f..ec4deb6be0 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -488,7 +488,7 @@ abstract class Erasure extends AddInterfaces
|| (checkBridgeOverrides(member, other, bridge) match {
case Nil => true
case es if member.owner.isAnonymousClass => resolveAnonymousBridgeClash(member, bridge); true
- case es => for ((pos, msg) <- es) unit.error(pos, msg); false
+ case es => for ((pos, msg) <- es) reporter.error(pos, msg); false
})
)
@@ -724,7 +724,7 @@ abstract class Erasure extends AddInterfaces
)
val when = if (exitingRefchecks(lowType matches highType)) "" else " after erasure: " + exitingPostErasure(highType)
- unit.error(pos,
+ reporter.error(pos,
s"""|$what:
|${exitingRefchecks(highString)} and
|${exitingRefchecks(lowString)}
@@ -865,7 +865,7 @@ abstract class Erasure extends AddInterfaces
fn match {
case TypeApply(sel @ Select(qual, name), List(targ)) =>
if (qual.tpe != null && isPrimitiveValueClass(qual.tpe.typeSymbol) && targ.tpe != null && targ.tpe <:< AnyRefTpe)
- unit.error(sel.pos, "isInstanceOf cannot test if value types are references.")
+ reporter.error(sel.pos, "isInstanceOf cannot test if value types are references.")
def mkIsInstanceOf(q: () => Tree)(tp: Type): Tree =
Apply(
@@ -952,7 +952,7 @@ abstract class Erasure extends AddInterfaces
case nme.length => nme.array_length
case nme.update => nme.array_update
case nme.clone_ => nme.array_clone
- case _ => unit.error(tree.pos, "Unexpected array member, no translation exists.") ; nme.NO_NAME
+ case _ => reporter.error(tree.pos, "Unexpected array member, no translation exists.") ; nme.NO_NAME
}
gen.mkRuntimeCall(arrayMethodName, qual :: args)
}
@@ -1055,7 +1055,7 @@ abstract class Erasure extends AddInterfaces
qual match {
case Super(_, _) =>
// Insert a cast here at your peril -- see SI-5162.
- unit.error(tree.pos, s"Unable to access ${tree.symbol.fullLocationString} with a super reference.")
+ reporter.error(tree.pos, s"Unable to access ${tree.symbol.fullLocationString} with a super reference.")
tree
case _ =>
// Todo: Figure out how qual.tpe could be null in the check above (it does appear in build where SwingWorker.this
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
index 0447e23e9e..c291961447 100644
--- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
@@ -481,7 +481,7 @@ abstract class ExplicitOuter extends InfoTransform
// since we can't fix SI-4440 properly (we must drop the outer accessors of final classes when there's no immediate reference to them in sight)
// at least don't crash... this duplicates maybeOmittable from constructors
(acc.owner.isEffectivelyFinal && !acc.isOverridingSymbol)) {
- unit.uncheckedWarning(tree.pos, "The outer reference in this type test cannot be checked at run time.")
+ currentRun.reporting.uncheckedWarning(tree.pos, "The outer reference in this type test cannot be checked at run time.")
transform(TRUE) // urgh... drop condition if there's no accessor (or if it may disappear after constructors)
} else {
// println("(base, acc)= "+(base, acc))
diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
index 2235a93ca4..228c9da624 100644
--- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
@@ -127,7 +127,7 @@ abstract class ExtensionMethods extends Transform with TypingTransformers {
def checkNonCyclic(pos: Position, seen: Set[Symbol], clazz: Symbol): Unit =
if (seen contains clazz)
- unit.error(pos, "value class may not unbox to itself")
+ reporter.error(pos, "value class may not unbox to itself")
else {
val unboxed = definitions.underlyingOfValueClass(clazz).typeSymbol
if (unboxed.isDerivedValueClass) checkNonCyclic(pos, seen + clazz, unboxed)
diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
index e38c034f4d..f85d8222f0 100644
--- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
+++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
@@ -339,7 +339,7 @@ abstract class LambdaLift extends InfoTransform {
if (clazz.isStaticOwner) clazz.fullLocationString
else s"the unconstructed `this` of ${clazz.fullLocationString}"
val msg = s"Implementation restriction: access of ${sym.fullLocationString} from ${currentClass.fullLocationString}, would require illegal premature access to $what"
- currentUnit.error(curTree.pos, msg)
+ reporter.error(curTree.pos, msg)
}
val qual =
if (clazz == currentClass) gen.mkAttributedThis(clazz)
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index 313d0a6e61..7927875583 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -336,7 +336,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
rebindSuper(clazz, mixinMember.alias, mixinClass) match {
case NoSymbol =>
- unit.error(clazz.pos, "Member %s of mixin %s is missing a concrete super implementation.".format(
+ reporter.error(clazz.pos, "Member %s of mixin %s is missing a concrete super implementation.".format(
mixinMember.alias, mixinClass))
case alias1 =>
superAccessor.asInstanceOf[TermSymbol] setAlias alias1
diff --git a/src/compiler/scala/tools/nsc/transform/TailCalls.scala b/src/compiler/scala/tools/nsc/transform/TailCalls.scala
index d9d1192772..ef534f70fd 100644
--- a/src/compiler/scala/tools/nsc/transform/TailCalls.scala
+++ b/src/compiler/scala/tools/nsc/transform/TailCalls.scala
@@ -96,7 +96,7 @@ abstract class TailCalls extends Transform {
val failReason = failReasons(ctx)
val failPos = failPositions(ctx)
- unit.error(failPos, s"could not optimize @tailrec annotated $method: $failReason")
+ reporter.error(failPos, s"could not optimize @tailrec annotated $method: $failReason")
}
/** Has the label been accessed? Then its symbol is in this set. */
@@ -268,14 +268,14 @@ abstract class TailCalls extends Transform {
tree match {
case ValDef(_, _, _, _) =>
if (tree.symbol.isLazy && tree.symbol.hasAnnotation(TailrecClass))
- unit.error(tree.pos, "lazy vals are not tailcall transformed")
+ reporter.error(tree.pos, "lazy vals are not tailcall transformed")
super.transform(tree)
case dd @ DefDef(_, name, _, vparamss0, _, rhs0) if isEligible(dd) =>
val newCtx = new DefDefTailContext(dd)
if (newCtx.isMandatory && !(newCtx containsRecursiveCall rhs0))
- unit.error(tree.pos, "@tailrec annotated method contains no recursive calls")
+ reporter.error(tree.pos, "@tailrec annotated method contains no recursive calls")
debuglog(s"Considering $name for tailcalls, with labels in tailpos: ${newCtx.tailLabels}")
val newRHS = transform(rhs0, newCtx)
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index d77c6b54a9..2209aac00f 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -93,7 +93,7 @@ abstract class UnCurry extends InfoTransform
override def transform(tree: Tree): Tree = (
try postTransform(mainTransform(tree))
catch { case ex: TypeError =>
- unit.error(ex.pos, ex.msg)
+ reporter.error(ex.pos, ex.msg)
debugStack(ex)
EmptyTree
}
@@ -174,7 +174,7 @@ abstract class UnCurry extends InfoTransform
cdef <- catches
if catchesThrowable(cdef) && !isSyntheticCase(cdef)
} {
- unit.warning(body.pos, "catch block may intercept non-local return from " + meth)
+ reporter.warning(body.pos, "catch block may intercept non-local return from " + meth)
}
Block(List(keyDef), tryCatch)
@@ -706,10 +706,10 @@ abstract class UnCurry extends InfoTransform
*/
private def saveRepeatedParams(dd: DefDef): Unit =
if (dd.symbol.isConstructor)
- unit.error(dd.symbol.pos, "A constructor cannot be annotated with a `varargs` annotation.")
+ reporter.error(dd.symbol.pos, "A constructor cannot be annotated with a `varargs` annotation.")
else treeInfo.repeatedParams(dd) match {
case Nil =>
- unit.error(dd.symbol.pos, "A method without repeated parameters cannot be annotated with the `varargs` annotation.")
+ reporter.error(dd.symbol.pos, "A method without repeated parameters cannot be annotated with the `varargs` annotation.")
case reps =>
repeatedParams(dd.symbol) = reps
}
@@ -782,7 +782,7 @@ abstract class UnCurry extends InfoTransform
// check if the method with that name and those arguments already exists in the template
currentClass.info.member(forwsym.name).alternatives.find(s => s != forwsym && s.tpe.matches(forwsym.tpe)) match {
- case Some(s) => unit.error(dd.symbol.pos,
+ case Some(s) => reporter.error(dd.symbol.pos,
"A method with a varargs annotation produces a forwarder method with the same signature "
+ s.tpe + " as an existing method.")
case None =>
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala
index e1a663ea41..6f81cbe152 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala
@@ -51,7 +51,7 @@ trait TreeAndTypeAnalysis extends Debugging {
// This is a pretty poor approximation.
def unsoundAssumptionUsed = binder.name != nme.WILDCARD && !(pt <:< pat.tpe)
if (settings.lint && unsoundAssumptionUsed)
- global.currentUnit.warning(pat.pos,
+ reporter.warning(pat.pos,
sm"""The value matched by $pat is bound to ${binder.name}, which may be used under the
|unsound assumption that it has type ${pat.tpe}, whereas we can only safely
|count on it having type $pt, as the pattern is matched using `==` (see SI-1503).""")
@@ -398,7 +398,7 @@ trait MatchAnalysis extends MatchApproximation {
import global.definitions._
trait MatchAnalyzer extends MatchApproximator {
- def uncheckedWarning(pos: Position, msg: String) = global.currentUnit.uncheckedWarning(pos, msg)
+ def uncheckedWarning(pos: Position, msg: String) = currentRun.reporting.uncheckedWarning(pos, msg)
def warn(pos: Position, ex: AnalysisBudget.Exception, kind: String) = uncheckedWarning(pos, s"Cannot check match for $kind.\n${ex.advice}")
// TODO: model dependencies between variables: if V1 corresponds to (x: List[_]) and V2 is (x.hd), V2 cannot be assigned when V1 = null or V1 = Nil
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala
index 8ff7824159..e9c81f4728 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala
@@ -442,7 +442,7 @@ trait MatchOptimization extends MatchTreeMaking with MatchAnalysis {
val distinctAlts = distinctBy(switchableAlts)(extractConst)
if (distinctAlts.size < switchableAlts.size) {
val duplicated = switchableAlts.groupBy(extractConst).flatMap(_._2.drop(1).take(1)) // report the first duplicated
- global.currentUnit.warning(pos, s"Pattern contains duplicate alternatives: ${duplicated.mkString(", ")}")
+ reporter.warning(pos, s"Pattern contains duplicate alternatives: ${duplicated.mkString(", ")}")
}
CaseDef(Alternative(distinctAlts), guard, body)
}
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala
index 4cf8980689..0eaffe7cee 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala
@@ -154,7 +154,7 @@ trait MatchTranslation {
case SymbolBound(sym, expr) => bindingStep(sym, expr)
case Literal(Constant(_)) | Ident(_) | Select(_, _) | This(_) => equalityTestStep()
case Alternative(alts) => alternativesStep(alts)
- case _ => context.unit.error(pos, unsupportedPatternMsg) ; noStep()
+ case _ => reporter.error(pos, unsupportedPatternMsg) ; noStep()
}
def translate(): List[TreeMaker] = nextStep() merge (_.translate())
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala
index 5d8a9fecef..1974befb45 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala
@@ -558,7 +558,7 @@ trait MatchTreeMaking extends MatchCodeGen with Debugging {
}
emitSwitch(scrut, scrutSym, casesNoSubstOnly, pt, matchFailGenOverride, suppression.exhaustive).getOrElse{
- if (requireSwitch) typer.context.unit.warning(scrut.pos, "could not emit switch for @switch annotated match")
+ if (requireSwitch) reporter.warning(scrut.pos, "could not emit switch for @switch annotated match")
if (casesNoSubstOnly nonEmpty) {
// before optimizing, check casesNoSubstOnly for presence of a default case,
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchWarnings.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchWarnings.scala
index a7d7680db1..9e9372f709 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/MatchWarnings.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchWarnings.scala
@@ -67,7 +67,7 @@ trait MatchWarnings {
val cdef = it.next()
// If a default case has been seen, then every succeeding case is unreachable.
if (vpat != null)
- context.unit./*error*/warning(cdef.body.pos, "unreachable code due to " + vpat + addendum(cdef.pat))
+ reporter.warning(cdef.body.pos, "unreachable code due to " + vpat + addendum(cdef.pat)) // TODO: make configurable whether this is an error
// If this is a default case and more cases follow, warn about this one so
// we have a reason to mention its pattern variable name and any corresponding
// symbol in scope. Errors will follow from the remaining cases, at least
@@ -78,7 +78,7 @@ trait MatchWarnings {
case _ => ""
}
vpat = s"variable pattern$vpatName on line ${cdef.pat.pos.line}"
- context.unit.warning(cdef.pos, s"patterns after a variable pattern cannot match (SLS 8.1.1)" + addendum(cdef.pat))
+ reporter.warning(cdef.pos, s"patterns after a variable pattern cannot match (SLS 8.1.1)" + addendum(cdef.pat))
}
}
}
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala b/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala
index f6c960d089..ef50e083a1 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala
@@ -65,7 +65,7 @@ trait PatternMatching extends Transform
} catch {
case x: (Types#TypeError) =>
// TODO: this should never happen; error should've been reported during type checking
- unit.error(tree.pos, "error during expansion of this match (this is a scalac bug).\nThe underlying error was: "+ x.msg)
+ reporter.error(tree.pos, "error during expansion of this match (this is a scalac bug).\nThe underlying error was: "+ x.msg)
translated
}
case Try(block, catches, finalizer) =>
@@ -175,13 +175,13 @@ trait Interface extends ast.TreeDSL {
val matchOwner = typer.context.owner
def pureType(tp: Type): Type = tp
- def reportUnreachable(pos: Position) = typer.context.unit.warning(pos, "unreachable code")
+ def reportUnreachable(pos: Position) = reporter.warning(pos, "unreachable code")
def reportMissingCases(pos: Position, counterExamples: List[String]) = {
val ceString =
if (counterExamples.tail.isEmpty) "input: " + counterExamples.head
else "inputs: " + counterExamples.mkString(", ")
- typer.context.unit.warning(pos, "match may not be exhaustive.\nIt would fail on the following "+ ceString)
+ reporter.warning(pos, "match may not be exhaustive.\nIt would fail on the following "+ ceString)
}
}
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/ScalacPatternExpanders.scala b/src/compiler/scala/tools/nsc/transform/patmat/ScalacPatternExpanders.scala
index d10eff1d8d..8f21f4ecfc 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/ScalacPatternExpanders.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/ScalacPatternExpanders.scala
@@ -103,8 +103,8 @@ trait ScalacPatternExpanders {
def offerString = if (extractor.isErroneous) "" else s" offering $offering"
def arityExpected = ( if (extractor.hasSeq) "at least " else "" ) + productArity
- def err(msg: String) = currentUnit.error(tree.pos, msg)
- def warn(msg: String) = currentUnit.warning(tree.pos, msg)
+ def err(msg: String) = reporter.error(tree.pos, msg)
+ def warn(msg: String) = reporter.warning(tree.pos, msg)
def arityError(what: String) = err(s"$what patterns for $owner$offerString: expected $arityExpected, found $totalArity")
if (isStar && !isSeq)
@@ -139,8 +139,10 @@ trait ScalacPatternExpanders {
def acceptMessage = if (extractor.isErroneous) "" else s" to hold ${extractor.offeringString}"
val requiresTupling = isUnapply && patterns.totalArity == 1 && productArity > 1
- if (requiresTupling && effectivePatternArity(args) == 1)
- currentUnit.deprecationWarning(sel.pos, s"${sel.symbol.owner} expects $productArity patterns$acceptMessage but crushing into $productArity-tuple to fit single pattern (SI-6675)")
+ if (requiresTupling && effectivePatternArity(args) == 1) {
+ val sym = sel.symbol.owner
+ currentRun.reporting.deprecationWarning(sel.pos, sym, s"${sym} expects $productArity patterns$acceptMessage but crushing into $productArity-tuple to fit single pattern (SI-6675)")
+ }
val normalizedExtractor = if (requiresTupling) tupleExtractor(extractor) else extractor
validateAligned(fn, Aligned(patterns, normalizedExtractor))
diff --git a/src/compiler/scala/tools/nsc/typechecker/Adaptations.scala b/src/compiler/scala/tools/nsc/typechecker/Adaptations.scala
index 1e544e54f6..37c39c07be 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Adaptations.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Adaptations.scala
@@ -77,7 +77,7 @@ trait Adaptations {
val msg = "Adaptation of argument list by inserting () has been deprecated: " + (
if (isLeakyTarget) "leaky (Object-receiving) target makes this especially dangerous."
else "this is unlikely to be what you want.")
- context.unit.deprecationWarning(t.pos, adaptWarningMessage(msg))
+ context.deprecationWarning(t.pos, t.symbol, adaptWarningMessage(msg))
}
} else if (settings.warnAdaptedArgs)
context.warning(t.pos, adaptWarningMessage(s"Adapting argument list by creating a ${args.size}-tuple: this may not be what you want."))
diff --git a/src/compiler/scala/tools/nsc/typechecker/Checkable.scala b/src/compiler/scala/tools/nsc/typechecker/Checkable.scala
index 13884404b3..3a77cab919 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Checkable.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Checkable.scala
@@ -275,7 +275,7 @@ trait Checkable {
;
// Matching on types like case _: AnyRef { def bippy: Int } => doesn't work -- yet.
case RefinedType(_, decls) if !decls.isEmpty =>
- getContext.unit.warning(tree.pos, s"a pattern match on a refinement type is unchecked")
+ reporter.warning(tree.pos, s"a pattern match on a refinement type is unchecked")
case RefinedType(parents, _) =>
parents foreach (p => checkCheckable(tree, p, X, inPattern, canRemedy))
case _ =>
@@ -285,14 +285,14 @@ trait Checkable {
if (checker.neverMatches) {
val addendum = if (checker.neverSubClass) "" else " (but still might match its erasure)"
- getContext.unit.warning(tree.pos, s"fruitless type test: a value of type $X cannot also be a $PString$addendum")
+ reporter.warning(tree.pos, s"fruitless type test: a value of type $X cannot also be a $PString$addendum")
}
else if (checker.isUncheckable) {
val msg = (
if (checker.uncheckableType =:= P) s"abstract type $where$PString"
else s"${checker.uncheckableMessage} in type $where$PString"
)
- getContext.unit.warning(tree.pos, s"$msg is unchecked since it is eliminated by erasure")
+ reporter.warning(tree.pos, s"$msg is unchecked since it is eliminated by erasure")
}
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index 8e1ceffecd..72ca9b879a 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -66,7 +66,7 @@ trait Contexts { self: Analyzer =>
def isMask(s: ImportSelector) = s.name != nme.WILDCARD && s.rename == nme.WILDCARD
imp.tree.selectors filterNot (s => isMask(s) || used(s)) foreach { sel =>
- unit.warning(imp posOf sel, "Unused import")
+ reporter.warning(imp posOf sel, "Unused import")
}
}
allUsedSelectors --= imps
@@ -103,7 +103,7 @@ trait Contexts { self: Analyzer =>
// there must be a scala.xml package when xml literals were parsed in this unit
if (unit.hasXml && ScalaXmlPackage == NoSymbol)
- unit.error(unit.firstXmlPos, "To compile XML syntax, the scala.xml package must be on the classpath.\nPlease see http://docs.scala-lang.org/overviews/core/scala-2.11.html#scala-xml.")
+ reporter.error(unit.firstXmlPos, "To compile XML syntax, the scala.xml package must be on the classpath.\nPlease see http://docs.scala-lang.org/overviews/core/scala-2.11.html#scala-xml.")
// scala-xml needs `scala.xml.TopScope` to be in scope globally as `$scope`
// We detect `scala-xml` by looking for `scala.xml.TopScope` and
@@ -359,7 +359,7 @@ trait Contexts { self: Analyzer =>
/** Issue and clear all warnings from the report buffer */
def flushAndIssueWarnings() {
reportBuffer.warnings foreach {
- case (pos, msg) => unit.warning(pos, msg)
+ case (pos, msg) => reporter.warning(pos, msg)
}
reportBuffer.clearAllWarnings()
}
@@ -541,7 +541,7 @@ trait Contexts { self: Analyzer =>
}
private def unitError(pos: Position, msg: String): Unit =
- if (checking) onTreeCheckerError(pos, msg) else unit.error(pos, msg)
+ if (checking) onTreeCheckerError(pos, msg) else reporter.error(pos, msg)
@inline private def issueCommon(err: AbsTypeError)(pf: PartialFunction[AbsTypeError, Unit]) {
// TODO: are errors allowed to have pos == NoPosition??
@@ -589,10 +589,20 @@ trait Contexts { self: Analyzer =>
/** Issue/throw the given error message according to the current mode for error reporting. */
def warning(pos: Position, msg: String, force: Boolean = false) {
- if (reportErrors || force) unit.warning(pos, msg)
+ if (reportErrors || force) reporter.warning(pos, msg)
else if (bufferErrors) reportBuffer += (pos -> msg)
}
+ def deprecationWarning(pos: Position, sym: Symbol, msg: String): Unit =
+ currentRun.reporting.deprecationWarning(pos, sym, msg)
+ def deprecationWarning(pos: Position, sym: Symbol): Unit =
+ currentRun.reporting.deprecationWarning(pos, sym) // TODO: allow this to escalate to an error, and implicit search will ignore deprecated implicits
+
+ def featureWarning(pos: Position, featureName: String, featureDesc: String, featureTrait: Symbol, construct: => String = "", required: Boolean): Unit =
+ currentRun.reporting.featureWarning(pos, featureName, featureDesc, featureTrait, construct, required)
+
+ def echo(pos: Position, msg: String): Unit = reporter.echo(pos, msg)
+
// nextOuter determines which context is searched next for implicits
// (after `this`, which contributes `newImplicits` below.) In
// most cases, it is simply the outer context: if we're owned by
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index fc0e2c7c80..a3f1da60ce 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -558,7 +558,7 @@ trait Infer extends Checkable {
foreachWithIndex(targs) ((targ, idx) =>
targ.typeSymbol match {
case sym @ (AnyClass | AnyValClass) =>
- context.unit.warning(argumentPosition(idx), s"a type was inferred to be `${sym.name}`; this may indicate a programming error.")
+ reporter.warning(argumentPosition(idx), s"a type was inferred to be `${sym.name}`; this may indicate a programming error.")
case _ =>
}
)
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/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 099031d536..1328119aac 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -443,7 +443,7 @@ trait Namers extends MethodSynthesis {
&& clazz.exists
)
if (fails) {
- context.unit.error(tree.pos, (
+ reporter.error(tree.pos, (
s"Companions '$clazz' and '$module' must be defined in same file:\n"
+ s" Found in ${clazz.sourceFile.canonicalPath} and ${module.sourceFile.canonicalPath}")
)
@@ -718,7 +718,7 @@ trait Namers extends MethodSynthesis {
}
val owner = tree.symbol.owner
if (settings.lint && owner.isPackageObjectClass && !mods.isImplicit) {
- context.unit.warning(tree.pos,
+ reporter.warning(tree.pos,
"it is not recommended to define classes/objects inside of package objects.\n" +
"If possible, define " + tree.symbol + " in " + owner.skipPackageObject + " instead."
)
@@ -730,7 +730,7 @@ trait Namers extends MethodSynthesis {
log("enter implicit wrapper "+tree+", owner = "+owner)
enterImplicitWrapper(tree)
}
- else context.unit.error(tree.pos, "implicit classes must accept exactly one primary constructor parameter")
+ else reporter.error(tree.pos, "implicit classes must accept exactly one primary constructor parameter")
}
validateCompanionDefs(tree)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
index 284ab2f6f9..43902d1c65 100644
--- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
@@ -536,8 +536,8 @@ trait NamesDefaults { self: Analyzer =>
def matchesName(param: Symbol) = !param.isSynthetic && (
(param.name == name) || (param.deprecatedParamName match {
case Some(`name`) =>
- context0.unit.deprecationWarning(arg.pos,
- "the parameter name "+ name +" has been deprecated. Use "+ param.name +" instead.")
+ context0.deprecationWarning(arg.pos, param,
+ s"the parameter name $name has been deprecated. Use ${param.name} instead.")
true
case _ => false
})
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 4540017b62..1b3da26bf2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -147,7 +147,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
val owners = haveDefaults map (_.owner)
// constructors of different classes are allowed to have defaults
if (haveDefaults.exists(x => !x.isConstructor) || owners.distinct.size < haveDefaults.size) {
- unit.error(clazz.pos,
+ reporter.error(clazz.pos,
"in "+ clazz +
", multiple overloaded alternatives of "+ haveDefaults.head +
" define default arguments" + (
@@ -162,7 +162,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
// Check for doomed attempt to overload applyDynamic
if (clazz isSubClass DynamicClass) {
for ((_, m1 :: m2 :: _) <- (clazz.info member nme.applyDynamic).alternatives groupBy (_.typeParams.length)) {
- unit.error(m1.pos, "implementation restriction: applyDynamic cannot be overloaded except by methods with different numbers of type parameters, e.g. applyDynamic[T1](method: String)(arg: T1) and applyDynamic[T1, T2](method: String)(arg1: T1, arg2: T2)")
+ reporter.error(m1.pos, "implementation restriction: applyDynamic cannot be overloaded except by methods with different numbers of type parameters, e.g. applyDynamic[T1](method: String)(arg: T1) and applyDynamic[T1, T2](method: String)(arg1: T1, arg2: T2)")
}
}
@@ -172,7 +172,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
// implicit classes leave both a module symbol and a method symbol as residue
val alts = clazz.info.decl(sym.name).alternatives filterNot (_.isModule)
if (alts.size > 1)
- alts foreach (x => unit.warning(x.pos, "parameterized overloaded implicit methods are not visible as view bounds"))
+ alts foreach (x => reporter.warning(x.pos, "parameterized overloaded implicit methods are not visible as view bounds"))
}
}
}
@@ -281,10 +281,10 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
mixinOverrideErrors.toList match {
case List() =>
case List(MixinOverrideError(_, msg)) =>
- unit.error(clazz.pos, msg)
+ reporter.error(clazz.pos, msg)
case MixinOverrideError(member, msg) :: others =>
val others1 = others.map(_.member.name.decode).filter(member.name.decode != _).distinct
- unit.error(
+ reporter.error(
clazz.pos,
msg+(if (others1.isEmpty) ""
else ";\n other members with override errors are: "+(others1 mkString ", ")))
@@ -347,7 +347,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
)
}
def emitOverrideError(fullmsg: String) {
- if (member.owner == clazz) unit.error(member.pos, fullmsg)
+ if (member.owner == clazz) reporter.error(member.pos, fullmsg)
else mixinOverrideErrors += new MixinOverrideError(member, fullmsg)
}
@@ -464,7 +464,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
checkOverrideDeprecated()
if (settings.warnNullaryOverride) {
if (other.paramss.isEmpty && !member.paramss.isEmpty) {
- unit.warning(member.pos, "non-nullary method overrides nullary method")
+ reporter.warning(member.pos, "non-nullary method overrides nullary method")
}
}
}
@@ -496,7 +496,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
typer.infer.checkKindBounds(high :: Nil, lowType :: Nil, rootType, low.owner) match { // (1.7.2)
case Nil =>
case kindErrors =>
- unit.error(member.pos,
+ reporter.error(member.pos,
"The kind of "+member.keyString+" "+member.varianceString + member.nameString+
" does not conform to the expected kind of " + other.defString + other.locationString + "." +
kindErrors.toList.mkString("\n", ", ", ""))
@@ -507,7 +507,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
typer.infer.checkKindBounds(low :: Nil, lowType.normalize :: Nil, rootType, low.owner) match {
case Nil =>
case kindErrors =>
- unit.error(member.pos,
+ reporter.error(member.pos,
"The kind of the right-hand side "+lowType.normalize+" of "+low.keyString+" "+
low.varianceString + low.nameString+ " does not conform to its expected kind."+
kindErrors.toList.mkString("\n", ", ", ""))
@@ -546,7 +546,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
if (other.hasDeprecatedOverridingAnnotation) {
val suffix = other.deprecatedOverridingMessage map (": " + _) getOrElse ""
val msg = s"overriding ${other.fullLocationString} is deprecated$suffix"
- unit.deprecationWarning(member.pos, msg)
+ currentRun.reporting.deprecationWarning(member.pos, other, msg)
}
}
}
@@ -754,7 +754,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
checkNoAbstractDecls(clazz)
if (abstractErrors.nonEmpty)
- unit.error(clazz.pos, abstractErrorMessage)
+ reporter.error(clazz.pos, abstractErrorMessage)
}
else if (clazz.isTrait && !(clazz isSubClass AnyValClass)) {
// For non-AnyVal classes, prevent abstract methods in interfaces that override
@@ -765,7 +765,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
// override a concrete method in Object. The jvm, however, does not.
val overridden = decl.matchingSymbol(ObjectClass, ObjectTpe)
if (overridden.isFinal)
- unit.error(decl.pos, "trait cannot redefine final method from class AnyRef")
+ reporter.error(decl.pos, "trait cannot redefine final method from class AnyRef")
}
}
@@ -818,7 +818,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
// for (bc <- clazz.info.baseClasses.tail) Console.println("" + bc + " has " + bc.info.decl(member.name) + ":" + bc.info.decl(member.name).tpe);//DEBUG
val nonMatching: List[Symbol] = clazz.info.member(member.name).alternatives.filterNot(_.owner == clazz).filterNot(_.isFinal)
- def issueError(suffix: String) = unit.error(member.pos, member.toString() + " overrides nothing" + suffix)
+ def issueError(suffix: String) = reporter.error(member.pos, member.toString() + " overrides nothing" + suffix)
nonMatching match {
case Nil =>
issueError("")
@@ -871,7 +871,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
case _ :: Nil =>
;// OK
case tp1 :: tp2 :: _ =>
- unit.error(clazz.pos, "illegal inheritance;\n " + clazz +
+ reporter.error(clazz.pos, "illegal inheritance;\n " + clazz +
" inherits different type instances of " + baseClass +
":\n" + tp1 + " and " + tp2)
explainTypes(tp1, tp2)
@@ -888,7 +888,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
case _ => "type "+tp
}
override def issueVarianceError(base: Symbol, sym: Symbol, required: Variance) {
- currentRun.currentUnit.error(base.pos,
+ reporter.error(base.pos,
s"${sym.variance} $sym occurs in $required position in ${tpString(base.info)} of $base")
}
}
@@ -956,7 +956,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
def checkImplicitViewOptionApply(pos: Position, fn: Tree, args: List[Tree]): Unit = if (settings.lint) (fn, args) match {
case (tap@TypeApply(fun, targs), List(view: ApplyImplicitView)) if fun.symbol == currentRun.runDefinitions.Option_apply =>
- unit.warning(pos, s"Suspicious application of an implicit view (${view.fun}) in the argument to Option.apply.") // SI-6567
+ reporter.warning(pos, s"Suspicious application of an implicit view (${view.fun}) in the argument to Option.apply.") // SI-6567
case _ =>
}
@@ -1031,7 +1031,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
def nonSensibleWarning(what: String, alwaysEqual: Boolean) = {
val msg = alwaysEqual == (name == nme.EQ || name == nme.eq)
- unit.warning(pos, s"comparing $what using `${name.decode}' will always yield $msg")
+ reporter.warning(pos, s"comparing $what using `${name.decode}' will always yield $msg")
isNonSensible = true
}
def nonSensible(pre: String, alwaysEqual: Boolean) =
@@ -1046,7 +1046,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
}
def unrelatedTypes() = if (!isNonSensible) {
val weaselWord = if (isEitherValueClass) "" else " most likely"
- unit.warning(pos, s"$typesString are unrelated: they will$weaselWord $unrelatedMsg")
+ reporter.warning(pos, s"$typesString are unrelated: they will$weaselWord $unrelatedMsg")
}
if (nullCount == 2) // null == null
@@ -1141,7 +1141,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
&& callsSelf
)
if (trivialInifiniteLoop)
- unit.warning(valOrDef.rhs.pos, s"${valOrDef.symbol.fullLocationString} does nothing other than call itself recursively")
+ reporter.warning(valOrDef.rhs.pos, s"${valOrDef.symbol.fullLocationString} does nothing other than call itself recursively")
}
// Transformation ------------------------------------------------------------
@@ -1231,7 +1231,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
finally if (currentLevel.maxindex > 0) {
// An implementation restriction to avoid VerifyErrors and lazyvals mishaps; see SI-4717
debuglog("refsym = " + currentLevel.refsym)
- unit.error(currentLevel.refpos, "forward reference not allowed from self constructor invocation")
+ reporter.error(currentLevel.refpos, "forward reference not allowed from self constructor invocation")
}
case ModuleDef(_, _, _) => eliminateModuleDefs(tree)
case ValDef(_, _, _, _) =>
@@ -1241,7 +1241,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
val lazySym = tree.symbol.lazyAccessorOrSelf
if (lazySym.isLocalToBlock && index <= currentLevel.maxindex) {
debuglog("refsym = " + currentLevel.refsym)
- unit.error(currentLevel.refpos, "forward reference extends over definition of " + lazySym)
+ reporter.error(currentLevel.refpos, "forward reference extends over definition of " + lazySym)
}
tree1 :: Nil
}
@@ -1255,7 +1255,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
try typer.infer.checkBounds(tree0, pre, owner, tparams, argtps, "")
catch {
case ex: TypeError =>
- unit.error(tree0.pos, ex.getMessage())
+ reporter.error(tree0.pos, ex.getMessage())
if (settings.explaintypes) {
val bounds = tparams map (tp => tp.info.instantiateTypeParams(tparams, argtps).bounds)
(argtps, bounds).zipped map ((targ, bound) => explainTypes(bound.lo, targ))
@@ -1287,11 +1287,9 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
private def checkUndesiredProperties(sym: Symbol, pos: Position) {
// If symbol is deprecated, and the point of reference is not enclosed
// in either a deprecated member or a scala bridge method, issue a warning.
- if (sym.isDeprecated && !currentOwner.ownerChain.exists(x => x.isDeprecated || x.hasBridgeAnnotation)) {
- unit.deprecationWarning(pos, "%s%s is deprecated%s".format(
- sym, sym.locationString, sym.deprecationMessage map (": " + _) getOrElse "")
- )
- }
+ if (sym.isDeprecated && !currentOwner.ownerChain.exists(x => x.isDeprecated || x.hasBridgeAnnotation))
+ currentRun.reporting.deprecationWarning(pos, sym)
+
// Similar to deprecation: check if the symbol is marked with @migration
// indicating it has changed semantics between versions.
if (sym.hasMigrationAnnotation && settings.Xmigration.value != NoScalaVersion) {
@@ -1299,12 +1297,12 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
settings.Xmigration.value < ScalaVersion(sym.migrationVersion.get)
catch {
case e : NumberFormatException =>
- unit.warning(pos, s"${sym.fullLocationString} has an unparsable version number: ${e.getMessage()}")
+ reporter.warning(pos, s"${sym.fullLocationString} has an unparsable version number: ${e.getMessage()}")
// if we can't parse the format on the migration annotation just conservatively assume it changed
true
}
if (changed)
- unit.warning(pos, s"${sym.fullLocationString} has changed semantics in version ${sym.migrationVersion.get}:\n${sym.migrationMessage.get}")
+ reporter.warning(pos, s"${sym.fullLocationString} has changed semantics in version ${sym.migrationVersion.get}:\n${sym.migrationMessage.get}")
}
// See an explanation of compileTimeOnly in its scaladoc at scala.annotation.compileTimeOnly.
if (sym.isCompileTimeOnly) {
@@ -1312,7 +1310,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
sm"""Reference to ${sym.fullLocationString} should not have survived past type checking,
|it should have been processed and eliminated during expansion of an enclosing macro."""
// The getOrElse part should never happen, it's just here as a backstop.
- unit.error(pos, sym.compileTimeOnlyMessage getOrElse defaultMsg)
+ reporter.error(pos, sym.compileTimeOnlyMessage getOrElse defaultMsg)
}
}
@@ -1323,7 +1321,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
&& sym.accessedOrSelf.isVal
)
if (settings.lint.value && isLikelyUninitialized)
- unit.warning(pos, s"Selecting ${sym} from ${sym.owner}, which extends scala.DelayedInit, is likely to yield an uninitialized value")
+ reporter.warning(pos, s"Selecting ${sym} from ${sym.owner}, which extends scala.DelayedInit, is likely to yield an uninitialized value")
}
private def lessAccessible(otherSym: Symbol, memberSym: Symbol): Boolean = (
@@ -1355,7 +1353,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
if (memberSym.isDeferred) "may be unable to provide a concrete implementation of"
else "may be unable to override"
- unit.warning(memberSym.pos,
+ reporter.warning(memberSym.pos,
"%s%s references %s %s.".format(
memberSym.fullLocationString, comparison,
accessFlagsToString(otherSym), otherSym
@@ -1390,7 +1388,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
tree match {
case DefDef(_, name, _, params :: _, _, _) =>
if (settings.lint && !treeInfo.isLeftAssoc(name.decodedName) && params.exists(p => isByName(p.symbol)))
- unit.warning(tree.pos,
+ reporter.warning(tree.pos,
"by-name parameters will be evaluated eagerly when called as a right-associative infix operator. For more details, see SI-1980.")
case _ =>
}
@@ -1407,10 +1405,10 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
symbol.allOverriddenSymbols.filter(sym =>
!sym.isDeprecated && !sym.isDeferred)
if(!concrOvers.isEmpty)
- unit.deprecationWarning(
+ currentRun.reporting.deprecationWarning(
tree.pos,
- symbol.toString + " overrides concrete, non-deprecated symbol(s):" +
- concrOvers.map(_.name.decode).mkString(" ", ", ", ""))
+ symbol,
+ s"${symbol.toString} overrides concrete, non-deprecated symbol(s): ${concrOvers.map(_.name.decode).mkString(", ")}")
}
}
private def isRepeatedParamArg(tree: Tree) = currentApplication match {
@@ -1471,7 +1469,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
applyChecks(sym.annotations)
// validate implicitNotFoundMessage
analyzer.ImplicitNotFoundMsg.check(sym) foreach { warn =>
- unit.warning(tree.pos, f"Invalid implicitNotFound message for ${sym}%s${sym.locationString}%s:%n$warn")
+ reporter.warning(tree.pos, f"Invalid implicitNotFound message for ${sym}%s${sym.locationString}%s:%n$warn")
}
case tpt@TypeTree() =>
@@ -1596,7 +1594,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
|| sym.allOverriddenSymbols.exists(over => !(over.tpe.resultType =:= sym.tpe.resultType))
)
if (!isOk)
- unit.warning(sym.pos, s"side-effecting nullary methods are discouraged: suggest defining as `def ${sym.name.decode}()` instead")
+ reporter.warning(sym.pos, s"side-effecting nullary methods are discouraged: suggest defining as `def ${sym.name.decode}()` instead")
case _ => ()
}
@@ -1604,15 +1602,15 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
private def checkAnyValSubclass(clazz: Symbol) = {
if (clazz.isDerivedValueClass) {
if (clazz.isTrait)
- unit.error(clazz.pos, "Only classes (not traits) are allowed to extend AnyVal")
+ reporter.error(clazz.pos, "Only classes (not traits) are allowed to extend AnyVal")
else if (clazz.hasAbstractFlag)
- unit.error(clazz.pos, "`abstract' modifier cannot be used with value classes")
+ reporter.error(clazz.pos, "`abstract' modifier cannot be used with value classes")
}
}
private def checkUnexpandedMacro(t: Tree) =
if (!t.isDef && t.hasSymbolField && t.symbol.isTermMacro)
- unit.error(t.pos, "macro has not been expanded")
+ reporter.error(t.pos, "macro has not been expanded")
override def transform(tree: Tree): Tree = {
val savedLocalTyper = localTyper
@@ -1707,7 +1705,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
tree
case treeInfo.WildcardStarArg(_) if !isRepeatedParamArg(tree) =>
- unit.error(tree.pos, "no `: _*' annotation allowed here\n"+
+ reporter.error(tree.pos, "no `: _*' annotation allowed here\n"+
"(such annotations are only allowed in arguments to *-parameters)")
tree
@@ -1780,7 +1778,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
} catch {
case ex: TypeError =>
if (settings.debug) ex.printStackTrace()
- unit.error(tree.pos, ex.getMessage())
+ reporter.error(tree.pos, ex.getMessage())
tree
} finally {
localTyper = savedLocalTyper
diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
index b6d37ab9a7..d3a41b9570 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
@@ -124,7 +124,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
if (other == NoSymbol)
other = linked.info.decl(sym.name.toTermName).filter(_.isModule)
if (other != NoSymbol)
- unit.error(sym.pos, "name clash: "+sym.owner+" defines "+sym+
+ reporter.error(sym.pos, "name clash: "+sym.owner+" defines "+sym+
"\nand its companion "+sym.owner.companionModule+" also defines "+
other)
}
@@ -139,14 +139,14 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
val member = sym.overridingSymbol(clazz)
if (mix != tpnme.EMPTY || member == NoSymbol ||
!(member.isAbstractOverride && member.isIncompleteIn(clazz)))
- unit.error(sel.pos, ""+sym.fullLocationString+" is accessed from super. It may not be abstract "+
+ reporter.error(sel.pos, ""+sym.fullLocationString+" is accessed from super. It may not be abstract "+
"unless it is overridden by a member declared `abstract' and `override'")
} else if (mix == tpnme.EMPTY && !sym.owner.isTrait){
// SI-4989 Check if an intermediate class between `clazz` and `sym.owner` redeclares the method as abstract.
val intermediateClasses = clazz.info.baseClasses.tail.takeWhile(_ != sym.owner)
intermediateClasses.map(sym.overridingSymbol).find(s => s.isDeferred && !s.isAbstractOverride && !s.owner.isTrait).foreach {
absSym =>
- unit.error(sel.pos, s"${sym.fullLocationString} cannot be directly accessed from ${clazz} because ${absSym.owner} redeclares it as abstract")
+ reporter.error(sel.pos, s"${sym.fullLocationString} cannot be directly accessed from ${clazz} because ${absSym.owner} redeclares it as abstract")
}
}
@@ -252,7 +252,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
qual.symbol.ancestors foreach { parent =>
parent.info.decls filterNot (x => x.isPrivate || x.isLocalToThis) foreach { m2 =>
if (sym.name == m2.name && m2.isGetter && m2.accessed.isMutable) {
- unit.warning(sel.pos,
+ reporter.warning(sel.pos,
sym.accessString + " " + sym.fullLocationString + " shadows mutable " + m2.name
+ " inherited from " + m2.owner + ". Changes to " + m2.name + " will not be visible within "
+ sym.owner + " - you may want to give them distinct names.")
@@ -310,9 +310,9 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
case Super(_, mix) =>
if (sym.isValue && !sym.isMethod || sym.hasAccessorFlag) {
if (!settings.overrideVars)
- unit.error(tree.pos, "super may be not be used on " + sym.accessedOrSelf)
+ reporter.error(tree.pos, "super may be not be used on " + sym.accessedOrSelf)
} else if (isDisallowed(sym)) {
- unit.error(tree.pos, "super not allowed here: use this." + name.decode + " instead")
+ reporter.error(tree.pos, "super not allowed here: use this." + name.decode + " instead")
}
transformSuperSelect(sel)
diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
index a2f52e1905..399a4ca8d5 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
@@ -17,7 +17,7 @@ abstract class TreeCheckers extends Analyzer {
override protected def onTreeCheckerError(pos: Position, msg: String) {
if (settings.fatalWarnings)
- currentUnit.warning(pos, "\n** Error during internal checking:\n" + msg)
+ reporter.warning(pos, "\n** Error during internal checking:\n" + msg)
}
case class DiffResult[T](lost: List[T], gained: List[T]) {
@@ -170,7 +170,7 @@ abstract class TreeCheckers extends Analyzer {
)
- def errorFn(pos: Position, msg: Any): Unit = currentUnit.warning(pos, "[check: %s] %s".format(phase.prev, msg))
+ def errorFn(pos: Position, msg: Any): Unit = reporter.warning(pos, "[check: %s] %s".format(phase.prev, msg))
def errorFn(msg: Any): Unit = errorFn(NoPosition, msg)
def informFn(msg: Any) {
diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
index 60346e7be1..7440f69e93 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
@@ -41,9 +41,9 @@ trait TypeDiagnostics {
* indicate that the restriction may be lifted in the future.
*/
def restrictionWarning(pos: Position, unit: CompilationUnit, msg: String): Unit =
- unit.warning(pos, "Implementation restriction: " + msg)
+ reporter.warning(pos, "Implementation restriction: " + msg)
def restrictionError(pos: Position, unit: CompilationUnit, msg: String): Unit =
- unit.error(pos, "Implementation restriction: " + msg)
+ reporter.error(pos, "Implementation restriction: " + msg)
/** A map of Positions to addendums - if an error involves a position in
* the map, the addendum should also be printed.
@@ -435,12 +435,8 @@ trait TypeDiagnostics {
trait TyperDiagnostics {
self: Typer =>
- private def contextError(context0: Analyzer#Context, pos: Position, msg: String) = context0.error(pos, msg)
- private def contextError(context0: Analyzer#Context, pos: Position, err: Throwable) = context0.error(pos, err)
- private def contextWarning(pos: Position, msg: String) = context.unit.warning(pos, msg)
-
def permanentlyHiddenWarning(pos: Position, hidden: Name, defn: Symbol) =
- contextWarning(pos, "imported `%s' is permanently hidden by definition of %s".format(hidden, defn.fullLocationString))
+ context.warning(pos, "imported `%s' is permanently hidden by definition of %s".format(hidden, defn.fullLocationString))
object checkUnused {
val ignoreNames = Set[TermName]("readResolve", "readObject", "writeObject", "writeReplace")
@@ -542,15 +538,15 @@ trait TypeDiagnostics {
else if (sym.isModule) "object"
else "term"
)
- unit.warning(pos, s"$why $what in ${sym.owner} is never used")
+ reporter.warning(pos, s"$why $what in ${sym.owner} is never used")
}
p.unsetVars foreach { v =>
- unit.warning(v.pos, s"local var ${v.name} in ${v.owner} is never set - it could be a val")
+ reporter.warning(v.pos, s"local var ${v.name} in ${v.owner} is never set - it could be a val")
}
p.unusedTypes foreach { t =>
val sym = t.symbol
val why = if (sym.isPrivate) "private" else "local"
- unit.warning(t.pos, s"$why ${sym.fullLocationString} is never used")
+ reporter.warning(t.pos, s"$why ${sym.fullLocationString} is never used")
}
}
}
@@ -627,13 +623,13 @@ trait TypeDiagnostics {
case Import(expr, _) => expr.pos
case _ => ex.pos
}
- contextError(context0, pos, cyclicReferenceMessage(sym, info.tree) getOrElse ex.getMessage())
+ context0.error(pos, cyclicReferenceMessage(sym, info.tree) getOrElse ex.getMessage())
if (sym == ObjectClass)
throw new FatalError("cannot redefine root "+sym)
}
case _ =>
- contextError(context0, ex.pos, ex)
+ context0.error(ex.pos, ex)
}
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 9a4d5e3c06..2c31ef2e8e 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)
+ context.featureWarning(pos, featureName, featureDesc, featureTrait, construct, required)
}
OK
}
@@ -955,10 +941,9 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
}
def adaptConstant(value: Constant): Tree = {
val sym = tree.symbol
- if (sym != null && sym.isDeprecated) {
- val msg = sym.toString + sym.locationString + " is deprecated: " + sym.deprecationMessage.getOrElse("")
- unit.deprecationWarning(tree.pos, msg)
- }
+ if (sym != null && sym.isDeprecated)
+ context.deprecationWarning(tree.pos, sym)
+
treeCopy.Literal(tree, value)
}
@@ -1066,7 +1051,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
case coercion =>
def msg = "inferred view from " + tree.tpe + " to " + pt + " = " + coercion + ":" + coercion.tpe
if (settings.logImplicitConv)
- unit.echo(tree.pos, msg)
+ context.echo(tree.pos, msg)
debuglog(msg)
val silentContext = context.makeImplicit(context.ambiguousErrors)
@@ -1226,7 +1211,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
case EmptyTree => qual
case coercion =>
if (settings.logImplicitConv)
- unit.echo(qual.pos,
+ context.echo(qual.pos,
"applied implicit conversion from %s to %s = %s".format(
qual.tpe, searchTemplate, coercion.symbol.defString))
@@ -1291,7 +1276,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
private def validateNoCaseAncestor(clazz: Symbol) = {
if (!phase.erasedTypes) {
for (ancestor <- clazz.ancestors find (_.isCase)) {
- unit.error(clazz.pos, (
+ context.error(clazz.pos, (
"case %s has case ancestor %s, but case-to-case inheritance is prohibited."+
" To overcome this limitation, use extractors to pattern match on non-leaf nodes."
).format(clazz, ancestor.fullName))
@@ -1308,7 +1293,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
val isValueClass = !clazz.isTrait
def where = if (isValueClass) "value class" else "universal trait extending from class Any"
def implRestriction(tree: Tree, what: String) =
- unit.error(tree.pos, s"implementation restriction: $what is not allowed in $where" +
+ context.error(tree.pos, s"implementation restriction: $what is not allowed in $where" +
"\nThis restriction is planned to be removed in subsequent releases.")
/**
* Deeply traverses the tree in search of constructs that are not allowed
@@ -1337,7 +1322,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
}
}
for (stat <- body) {
- def notAllowed(what: String) = unit.error(stat.pos, s"$what is not allowed in $where")
+ def notAllowed(what: String) = context.error(stat.pos, s"$what is not allowed in $where")
stat match {
// see https://issues.scala-lang.org/browse/SI-6444
// see https://issues.scala-lang.org/browse/SI-6463
@@ -1365,9 +1350,9 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
private def validateDerivedValueClass(clazz: Symbol, body: List[Tree]) = {
if (clazz.isTrait)
- unit.error(clazz.pos, "only classes (not traits) are allowed to extend AnyVal")
+ context.error(clazz.pos, "only classes (not traits) are allowed to extend AnyVal")
if (!clazz.isStatic)
- unit.error(clazz.pos, "value class may not be a "+
+ context.error(clazz.pos, "value class may not be a "+
(if (clazz.owner.isTerm) "local class" else "member of another class"))
if (!clazz.isPrimitiveValueClass) {
clazz.primaryConstructor.paramss match {
@@ -1375,26 +1360,26 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
val decls = clazz.info.decls
val paramAccessor = clazz.constrParamAccessors.head
if (paramAccessor.isMutable)
- unit.error(paramAccessor.pos, "value class parameter must not be a var")
+ context.error(paramAccessor.pos, "value class parameter must not be a var")
val accessor = decls.toList.find(x => x.isMethod && x.accessedOrSelf == paramAccessor)
accessor match {
case None =>
- unit.error(paramAccessor.pos, "value class parameter must be a val and not be private[this]")
+ context.error(paramAccessor.pos, "value class parameter must be a val and not be private[this]")
case Some(acc) if acc.isProtectedLocal =>
- unit.error(paramAccessor.pos, "value class parameter must not be protected[this]")
+ context.error(paramAccessor.pos, "value class parameter must not be protected[this]")
case Some(acc) =>
if (acc.tpe.typeSymbol.isDerivedValueClass)
- unit.error(acc.pos, "value class may not wrap another user-defined value class")
+ context.error(acc.pos, "value class may not wrap another user-defined value class")
checkEphemeral(clazz, body filterNot (stat => stat.symbol != null && stat.symbol.accessedOrSelf == paramAccessor))
}
case _ =>
- unit.error(clazz.pos, "value class needs to have exactly one val parameter")
+ context.error(clazz.pos, "value class needs to have exactly one val parameter")
}
}
for (tparam <- clazz.typeParams)
if (tparam hasAnnotation definitions.SpecializedClass)
- unit.error(tparam.pos, "type parameter of value class may not be specialized")
+ context.error(tparam.pos, "type parameter of value class may not be specialized")
}
/** Typechecks a parent type reference.
@@ -1690,7 +1675,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
if (!isPastTyper && psym.hasDeprecatedInheritanceAnnotation && !sameSourceFile) {
val suffix = psym.deprecatedInheritanceMessage map (": " + _) getOrElse ""
val msg = s"inheritance from ${psym.fullLocationString} is deprecated$suffix"
- unit.deprecationWarning(parent.pos, msg)
+ context.deprecationWarning(parent.pos, psym, msg)
}
if (psym.isSealed && !phase.erasedTypes)
@@ -1757,7 +1742,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
if ((clazz isNonBottomSubClass ClassfileAnnotationClass) && (clazz != ClassfileAnnotationClass)) {
if (!clazz.owner.isPackageClass)
- unit.error(clazz.pos, "inner classes cannot be classfile annotations")
+ context.error(clazz.pos, "inner classes cannot be classfile annotations")
else restrictionWarning(cdef.pos, unit,
"""|subclassing Classfile does not
|make your annotation visible at runtime. If that is what
@@ -1812,7 +1797,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
private def ensurePredefParentsAreInSameSourceFile(template: Template) = {
val parentSyms = template.parents map (_.symbol) filterNot (_ == AnyRefClass)
if (parentSyms exists (_.associatedFile != PredefModule.associatedFile))
- unit.error(template.pos, s"All parents of Predef must be defined in ${PredefModule.associatedFile}.")
+ context.error(template.pos, s"All parents of Predef must be defined in ${PredefModule.associatedFile}.")
}
/** In order to override this in the TreeCheckers Typer so synthetics aren't re-added
* all the time, it is exposed here the module/class typing methods go through it.
@@ -1883,7 +1868,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
ConstrArgsInParentOfTraitError(parents1.head, clazz)
if ((clazz isSubClass ClassfileAnnotationClass) && !clazz.isTopLevel)
- unit.error(clazz.pos, "inner classes cannot be classfile annotations")
+ context.error(clazz.pos, "inner classes cannot be classfile annotations")
if (!phase.erasedTypes && !clazz.info.resultType.isError) // @S: prevent crash for duplicated type members
checkFinitary(clazz.info.resultType.asInstanceOf[ClassInfoType])
@@ -1911,7 +1896,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
if (clazz.isTrait) {
for (decl <- clazz.info.decls if decl.isTerm && decl.isEarlyInitialized) {
- unit.warning(decl.pos, "Implementation restriction: early definitions in traits are not initialized before the super class is initialized.")
+ context.warning(decl.pos, "Implementation restriction: early definitions in traits are not initialized before the super class is initialized.")
}
}
@@ -2099,7 +2084,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
case xs => xs.map(_.nameString).mkString(" (of ", " with ", ")")
}
def fail(pos: Position, msg: String): Boolean = {
- unit.error(pos, msg)
+ context.error(pos, msg)
false
}
/* Have to examine all parameters in all lists.
@@ -3680,7 +3665,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
}
if (annType.typeSymbol == DeprecatedAttr && argss.flatten.size < 2)
- unit.deprecationWarning(ann.pos, "@deprecated now takes two arguments; see the scaladoc.")
+ context.deprecationWarning(ann.pos, DeprecatedAttr, "@deprecated now takes two arguments; see the scaladoc.")
if ((typedAnn.tpe == null) || typedAnn.tpe.isErroneous) ErroneousAnnotation
else annInfo(typedAnn)
@@ -4254,7 +4239,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
// it is non-Unit) so we have to retype it. Fortunately it won't come up much
// unless the warning is legitimate.
if (typed(expr).tpe.typeSymbol != UnitClass)
- unit.warning(tree.pos, "enclosing method " + name + " has result type Unit: return value discarded")
+ context.warning(tree.pos, "enclosing method " + name + " has result type Unit: return value discarded")
}
val res = treeCopy.Return(tree, checkDead(expr1)).setSymbol(enclMethod.owner)
val tp = pluginsTypedReturn(NothingTpe, this, res, restpt.tpe)
@@ -4712,10 +4697,10 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
// temporarily use `filter` as an alternative for `withFilter`
def tryWithFilterAndFilter(tree: Select, qual: Tree): Tree = {
- def warn() = unit.deprecationWarning(tree.pos, s"`withFilter' method does not yet exist on ${qual.tpe.widen}, using `filter' method instead")
+ def warn(sym: Symbol) = context.deprecationWarning(tree.pos, sym, s"`withFilter' method does not yet exist on ${qual.tpe.widen}, using `filter' method instead")
silent(_ => typedSelect(tree, qual, nme.withFilter)) orElse { _ =>
silent(_ => typed1(Select(qual, nme.filter) setPos tree.pos, mode, pt)) match {
- case SilentResultValue(res) => warn() ; res
+ case SilentResultValue(res) => warn(res.symbol) ; res
case SilentTypeError(err) => WithFilterError(tree, err)
}
}
@@ -5492,11 +5477,11 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
val commonMessage = "macro defs must have explicitly specified return types"
def reportFailure() = {
ddef.symbol.setFlag(IS_ERROR)
- unit.error(ddef.pos, commonMessage)
+ context.error(ddef.pos, commonMessage)
}
def reportWarning(inferredType: Type) = {
val explanation = s"inference of $inferredType from macro impl's c.Expr[$inferredType] is deprecated and is going to stop working in 2.12"
- unit.deprecationWarning(ddef.pos, s"$commonMessage ($explanation)")
+ context.deprecationWarning(ddef.pos, ddef.symbol, s"$commonMessage ($explanation)")
}
computeMacroDefTypeFromMacroImplRef(ddef, rhs1) match {
case ErrorType => ErrorType
diff --git a/src/compiler/scala/tools/reflect/FormatInterpolator.scala b/src/compiler/scala/tools/reflect/FormatInterpolator.scala
index e0f9bb6044..57be1afdfe 100644
--- a/src/compiler/scala/tools/reflect/FormatInterpolator.scala
+++ b/src/compiler/scala/tools/reflect/FormatInterpolator.scala
@@ -117,7 +117,7 @@ abstract class FormatInterpolator {
c.error(errPoint, msg("unsupported"))
s0
} else {
- c.enclosingUnit.deprecationWarning(errPoint, msg("deprecated"))
+ currentRun.reporting.deprecationWarning(errPoint, msg("deprecated"))
try StringContext.treatEscapes(s0) catch escapeHatch
}
}
diff --git a/src/library/scala/collection/immutable/List.scala b/src/library/scala/collection/immutable/List.scala
index 930e13a9d3..aa9dec2761 100644
--- a/src/library/scala/collection/immutable/List.scala
+++ b/src/library/scala/collection/immutable/List.scala
@@ -190,11 +190,9 @@ sealed abstract class List[+A] extends AbstractSeq[A]
// Overridden methods from IterableLike and SeqLike or overloaded variants of such methods
- override def ++[B >: A, That](that: GenTraversableOnce[B])(implicit bf: CanBuildFrom[List[A], B, That]): That = {
- val b = bf(this)
- if (b.isInstanceOf[ListBuffer[_]]) (this ::: that.seq.toList).asInstanceOf[That]
+ override def ++[B >: A, That](that: GenTraversableOnce[B])(implicit bf: CanBuildFrom[List[A], B, That]): That =
+ if (bf eq List.ReusableCBF) (this ::: that.seq.toList).asInstanceOf[That]
else super.++(that)
- }
override def +:[B >: A, That](elem: B)(implicit bf: CanBuildFrom[List[A], B, That]): That = bf match {
case _: List.GenericCanBuildFrom[_] => (elem :: this).asInstanceOf[That]
diff --git a/src/library/scala/collection/mutable/UnrolledBuffer.scala b/src/library/scala/collection/mutable/UnrolledBuffer.scala
index 1f89199bdc..693c47d86e 100644
--- a/src/library/scala/collection/mutable/UnrolledBuffer.scala
+++ b/src/library/scala/collection/mutable/UnrolledBuffer.scala
@@ -300,27 +300,33 @@ object UnrolledBuffer extends ClassTagTraversableFactory[UnrolledBuffer] {
if (next eq null) true else false // checks if last node was thrown out
} else false
- @tailrec final def insertAll(idx: Int, t: scala.collection.Traversable[T], buffer: UnrolledBuffer[T]): Unit = if (idx < size) {
- // divide this node at the appropriate position and insert all into head
- // update new next
- val newnextnode = new Unrolled[T](0, new Array(array.length), null, buff)
- Array.copy(array, idx, newnextnode.array, 0, size - idx)
- newnextnode.size = size - idx
- newnextnode.next = next
-
- // update this
- nullout(idx, size)
- size = idx
- next = null
-
- // insert everything from iterable to this
- var curr = this
- for (elem <- t) curr = curr append elem
- curr.next = newnextnode
-
- // try to merge the last node of this with the newnextnode
- if (curr.tryMergeWithNext()) buffer.lastPtr = curr
- } else insertAll(idx - size, t, buffer)
+ @tailrec final def insertAll(idx: Int, t: scala.collection.Traversable[T], buffer: UnrolledBuffer[T]): Unit = {
+ if (idx < size) {
+ // divide this node at the appropriate position and insert all into head
+ // update new next
+ val newnextnode = new Unrolled[T](0, new Array(array.length), null, buff)
+ Array.copy(array, idx, newnextnode.array, 0, size - idx)
+ newnextnode.size = size - idx
+ newnextnode.next = next
+
+ // update this
+ nullout(idx, size)
+ size = idx
+ next = null
+
+ // insert everything from iterable to this
+ var curr = this
+ for (elem <- t) curr = curr append elem
+ curr.next = newnextnode
+
+ // try to merge the last node of this with the newnextnode
+ if (curr.tryMergeWithNext()) buffer.lastPtr = curr
+ }
+ else if (idx == size) {
+ var curr = this
+ for (elem <- t) curr = curr append elem
+ } else insertAll(idx - size, t, buffer)
+ }
private def nullout(from: Int, until: Int) {
var idx = from
while (idx < until) {
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
diff --git a/src/repl/scala/tools/nsc/interpreter/IMain.scala b/src/repl/scala/tools/nsc/interpreter/IMain.scala
index 47d97dd4dd..8ea8759ee5 100644
--- a/src/repl/scala/tools/nsc/interpreter/IMain.scala
+++ b/src/repl/scala/tools/nsc/interpreter/IMain.scala
@@ -110,7 +110,7 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
lazy val reporter: ReplReporter = new ReplReporter(this)
import formatting._
- import reporter.{ printMessage, withoutTruncating }
+ import reporter.{ printMessage, printUntruncatedMessage }
// This exists mostly because using the reporter too early leads to deadlock.
private def echo(msg: String) { Console println msg }
@@ -609,7 +609,7 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
}
else {
// don't truncate stack traces
- withoutTruncating(printMessage(result))
+ printUntruncatedMessage(result)
IR.Error
}
}
@@ -793,7 +793,7 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
}
((pos, msg)) :: loop(filtered)
}
- val warnings = loop(run.allConditionalWarnings flatMap (_.warnings))
+ val warnings = loop(run.reporting.allConditionalWarnings)
if (warnings.nonEmpty)
mostRecentWarnings = warnings
}
@@ -1121,7 +1121,7 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
def apply(line: String): Result = debugging(s"""parse("$line")""") {
var isIncomplete = false
- reporter.withIncompleteHandler((_, _) => isIncomplete = true) {
+ currentRun.reporting.withIncompleteHandler((_, _) => isIncomplete = true) {
reporter.reset()
val trees = newUnitParser(line).parseStats()
if (reporter.hasErrors) Error
diff --git a/src/repl/scala/tools/nsc/interpreter/JavapClass.scala b/src/repl/scala/tools/nsc/interpreter/JavapClass.scala
index 915fd57bf8..3cb6ba11c1 100644
--- a/src/repl/scala/tools/nsc/interpreter/JavapClass.scala
+++ b/src/repl/scala/tools/nsc/interpreter/JavapClass.scala
@@ -41,16 +41,16 @@ class JavapClass(
* Byte data for filename args is retrieved with findBytes.
*/
def apply(args: Seq[String]): List[JpResult] = {
- val (options, claases) = args partition (s => (s startsWith "-") && s.length > 1)
+ val (options, classes) = args partition (s => (s startsWith "-") && s.length > 1)
val (flags, upgraded) = upgrade(options)
import flags.{ app, fun, help, raw }
- val targets = if (fun && !help) FunFinder(loader, intp).funs(claases) else claases
- if (help || claases.isEmpty)
+ val targets = if (fun && !help) FunFinder(loader, intp).funs(classes) else classes
+ if (help || classes.isEmpty)
List(JpResult(JavapTool.helper(printWriter)))
else if (targets.isEmpty)
List(JpResult("No anonfuns found."))
else
- tool(raw, upgraded)(targets map (claas => targeted(claas, app)))
+ tool(raw, upgraded)(targets map (klass => targeted(klass, app)))
}
/** Cull our tool options. */
@@ -67,17 +67,18 @@ class JavapClass(
case f: Failure[_] => (path, Failure(f.exception))
}
- /** Find bytes. Handle "-", "-app", "Foo#bar" (by ignoring member), "#bar" (by taking "bar"). */
+ /** Find bytes. Handle "-", "-app", "Foo#bar" (by ignoring member), "#bar" (by taking "bar").
+ * @return the path to use for filtering, and the byte array
+ */
private def bytesFor(path: String, app: Boolean) = Try {
def last = intp.get.mostRecentVar // fail if no intp
- def req = path match {
- case "-" => last
- case HashSplit(prefix, member) =>
- if (prefix != null) prefix
- else if (member != null) member
- else "#"
+ val req = path match {
+ case "-" => last
+ case HashSplit(prefix, _) if prefix != null => prefix
+ case HashSplit(_, member) if member != null => member
+ case s => s
}
- val targetedBytes = if (app) findAppBody(req) else (req, findBytes(req))
+ val targetedBytes = if (app) findAppBody(req) else (path, findBytes(req))
if (targetedBytes._2.isEmpty) throw new FileNotFoundException(s"Could not find class bytes for '$path'")
targetedBytes
}
@@ -217,27 +218,36 @@ class JavapClass(
// if apply is added here, it's for other than -fun: javap Foo#, perhaps m#?
val filterOn = target.splitHashMember._2 map { s => if (s.isEmpty) "apply" else s }
var filtering = false // true if in region matching filter
- // true to output
- def checkFilter(line: String) = if (filterOn.isEmpty) true else {
+ // turn filtering on/off given the pattern of interest
+ def filterStatus(line: String, pattern: String) = {
// cheap heuristic, todo maybe parse for the java sig.
// method sigs end in paren semi
def isAnyMethod = line.endsWith(");")
def isOurMethod = {
val lparen = line.lastIndexOf('(')
val blank = line.lastIndexOf(' ', lparen)
- (blank >= 0 && line.substring(blank+1, lparen) == filterOn.get)
- }
- filtering = if (filtering) {
- // next blank line terminates section
- // for -public, next line is next method, more or less
- line.trim.nonEmpty && !isAnyMethod
- } else {
- isAnyMethod && isOurMethod
+ if (blank < 0) false
+ else {
+ val method = line.substring(blank+1, lparen)
+ (method == pattern || ((method startsWith pattern+"$") && (method endsWith "$sp")))
+ }
}
+ filtering =
+ if (filtering) {
+ // next blank line terminates section
+ // for -public, next line is next method, more or less
+ line.trim.nonEmpty && !isAnyMethod
+ } else {
+ isAnyMethod && isOurMethod
+ }
filtering
}
- for (line <- Source.fromString(preamble + written).getLines(); if checkFilter(line))
- printWriter write line+lineSeparator
+ // do we output this line?
+ def checkFilter(line: String) = filterOn map (filterStatus(line, _)) getOrElse true
+ for {
+ line <- Source.fromString(preamble + written).getLines()
+ if checkFilter(line)
+ } printWriter write f"$line%n"
printWriter.flush()
}
}
@@ -275,7 +285,7 @@ class JavapClass(
override def apply(raw: Boolean, options: Seq[String])(inputs: Seq[Input]): List[JpResult] =
(inputs map {
- case (claas, Success(ba)) => JpResult(showable(raw, claas, newPrinter(new ByteArrayInputStream(ba), newEnv(options))))
+ case (klass, Success(ba)) => JpResult(showable(raw, klass, newPrinter(new ByteArrayInputStream(ba), newEnv(options))))
case (_, Failure(e)) => JpResult(e.toString)
}).toList orFailed List(noToolError)
}
@@ -290,10 +300,10 @@ class JavapClass(
//object TaskResult extends Enumeration {
// val Ok, Error, CmdErr, SysErr, Abnormal = Value
//}
- val TaskClaas = loader.tryToInitializeClass[Task](JavapTool.Tool).orNull
- override protected def failed = TaskClaas eq null
+ val TaskClass = loader.tryToInitializeClass[Task](JavapTool.Tool).orNull
+ override protected def failed = TaskClass eq null
- val TaskCtor = TaskClaas.getConstructor(
+ val TaskCtor = TaskClass.getConstructor(
classOf[Writer],
classOf[JavaFileManager],
classOf[DiagnosticListener[_]],
@@ -344,8 +354,12 @@ class JavapClass(
import Kind._
import StandardLocation._
import JavaFileManager.Location
- import java.net.URI
- def uri(name: String): URI = new URI(name) // new URI("jfo:" + name)
+ import java.net.{ URI, URISyntaxException }
+
+ // name#fragment is OK, but otherwise fragile
+ def uri(name: String): URI =
+ try new URI(name) // new URI("jfo:" + name)
+ catch { case _: URISyntaxException => new URI("dummy") }
def inputNamed(name: String): Try[ByteAry] = (managed find (_._1 == name)).get._2
def managedFile(name: String, kind: Kind) = kind match {
@@ -379,19 +393,19 @@ class JavapClass(
def showable(raw: Boolean, target: String): Showable = showWithPreamble(raw, target, reporter.reportable(raw))
// eventually, use the tool interface
- def task(options: Seq[String], claases: Seq[String], inputs: Seq[Input]): Task = {
+ def task(options: Seq[String], classes: Seq[String], inputs: Seq[Input]): Task = {
//ServiceLoader.load(classOf[javax.tools.DisassemblerTool]).
- //getTask(writer, fileManager, reporter, options.asJava, claases.asJava)
+ //getTask(writer, fileManager, reporter, options.asJava, classes.asJava)
import JavaConverters.asJavaIterableConverter
- TaskCtor.newInstance(writer, fileManager(inputs), reporter, options.asJava, claases.asJava)
+ TaskCtor.newInstance(writer, fileManager(inputs), reporter, options.asJava, classes.asJava)
.orFailed (throw new IllegalStateException)
}
// a result per input
- private def applyOne(raw: Boolean, options: Seq[String], claas: String, inputs: Seq[Input]): Try[JpResult] =
+ private def applyOne(raw: Boolean, options: Seq[String], klass: String, inputs: Seq[Input]): Try[JpResult] =
Try {
- task(options, Seq(claas), inputs).call()
+ task(options, Seq(klass), inputs).call()
} map {
- case true => JpResult(showable(raw, claas))
+ case true => JpResult(showable(raw, klass))
case _ => JpResult(reporter.reportable(raw))
} recoverWith {
case e: java.lang.reflect.InvocationTargetException => e.getCause match {
@@ -402,7 +416,7 @@ class JavapClass(
reporter.clear()
}
override def apply(raw: Boolean, options: Seq[String])(inputs: Seq[Input]): List[JpResult] = (inputs map {
- case (claas, Success(_)) => applyOne(raw, options, claas, inputs).get
+ case (klass, Success(_)) => applyOne(raw, options, klass, inputs).get
case (_, Failure(e)) => JpResult(e.toString)
}).toList orFailed List(noToolError)
}
@@ -534,6 +548,7 @@ class JavapClass(
private def isTaskable(cl: ScalaClassLoader) = hasClass(cl, Tool)
+ /** Select the tool implementation for this platform. */
def apply() = if (isTaskable(loader)) new JavapTool7 else new JavapTool6
}
}
@@ -545,7 +560,8 @@ object JavapClass {
intp: Option[IMain] = None
) = new JavapClass(loader, printWriter, intp)
- val HashSplit = "(.*?)(?:#([^#]*))?".r
+ val HashSplit = "([^#]+)?(?:#(.+)?)?".r
+
// We enjoy flexibility in specifying either a fully-qualified class name com.acme.Widget
// or a resource path com/acme/Widget.class; but not widget.out
implicit class MaybeClassLike(val s: String) extends AnyVal {
@@ -580,11 +596,11 @@ object JavapClass {
/* only the file location from which the given class is loaded */
def locate(k: String): Option[Path] = {
Try {
- val claas = try cl loadClass k catch {
+ val klass = try cl loadClass k catch {
case _: NoClassDefFoundError => null // let it snow
}
// cf ScalaClassLoader.originOfClass
- claas.getProtectionDomain.getCodeSource.getLocation
+ klass.getProtectionDomain.getCodeSource.getLocation
} match {
case Success(null) => None
case Success(loc) if loc.isFile => Some(Path(new JFile(loc.toURI)))
diff --git a/src/repl/scala/tools/nsc/interpreter/ReplReporter.scala b/src/repl/scala/tools/nsc/interpreter/ReplReporter.scala
index b20166d070..88372334d6 100644
--- a/src/repl/scala/tools/nsc/interpreter/ReplReporter.scala
+++ b/src/repl/scala/tools/nsc/interpreter/ReplReporter.scala
@@ -9,11 +9,29 @@ package interpreter
import reporters._
import IMain._
+import scala.reflect.internal.util.Position
+
/** Like ReplGlobal, a layer for ensuring extra functionality.
*/
class ReplReporter(intp: IMain) extends ConsoleReporter(intp.settings, Console.in, new ReplStrippingWriter(intp)) {
def printUntruncatedMessage(msg: String) = withoutTruncating(printMessage(msg))
+ /** Whether very long lines can be truncated. This exists so important
+ * debugging information (like printing the classpath) is not rendered
+ * invisible due to the max message length.
+ */
+ private var _truncationOK: Boolean = !intp.settings.verbose
+ def truncationOK = _truncationOK
+ def withoutTruncating[T](body: => T): T = {
+ val saved = _truncationOK
+ _truncationOK = false
+ try body
+ finally _truncationOK = saved
+ }
+
+ override def warning(pos: Position, msg: String): Unit = withoutTruncating(super.warning(pos, msg))
+ override def error(pos: Position, msg: String): Unit = withoutTruncating(super.error(pos, msg))
+
override def printMessage(msg: String) {
// Avoiding deadlock if the compiler starts logging before
// the lazy val is complete.
@@ -31,4 +49,5 @@ class ReplReporter(intp: IMain) extends ConsoleReporter(intp.settings, Console.i
if (intp.totalSilence) ()
else super.displayPrompt()
}
+
}
diff --git a/src/scaladoc/scala/tools/nsc/doc/ScaladocAnalyzer.scala b/src/scaladoc/scala/tools/nsc/doc/ScaladocAnalyzer.scala
index e5c64c6f45..10c382e169 100644
--- a/src/scaladoc/scala/tools/nsc/doc/ScaladocAnalyzer.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/ScaladocAnalyzer.scala
@@ -39,12 +39,12 @@ trait ScaladocAnalyzer extends Analyzer {
for (useCase <- comment.useCases) {
typer1.silent(_.asInstanceOf[ScaladocTyper].defineUseCases(useCase)) match {
case SilentTypeError(err) =>
- unit.warning(useCase.pos, err.errMsg)
+ reporter.warning(useCase.pos, err.errMsg)
case _ =>
}
for (useCaseSym <- useCase.defined) {
if (sym.name != useCaseSym.name)
- unit.warning(useCase.pos, "@usecase " + useCaseSym.name.decode + " does not match commented symbol: " + sym.name.decode)
+ reporter.warning(useCase.pos, "@usecase " + useCaseSym.name.decode + " does not match commented symbol: " + sym.name.decode)
}
}
}
@@ -191,7 +191,7 @@ abstract class ScaladocSyntaxAnalyzer[G <: Global](val global: G) extends Syntax
}
def isDirty = unclean(unmooredParser parseComment doc)
if ((doc ne null) && (settings.lint || isDirty))
- unit.warning(doc.pos, "discarding unmoored doc comment")
+ reporter.warning(doc.pos, "discarding unmoored doc comment")
}
override def flushDoc(): DocComment = (try lastDoc finally lastDoc = null)
diff --git a/test/files/jvm/deprecation.check b/test/files/jvm/deprecation.check
index 3c27d4d082..d57b6b55a5 100644
--- a/test/files/jvm/deprecation.check
+++ b/test/files/jvm/deprecation.check
@@ -1,3 +1,3 @@
-warning: there were 4 deprecation warnings; re-run with -deprecation for details
+warning: there were four deprecation warnings; re-run with -deprecation for details
Note: deprecation/Use_2.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
diff --git a/test/files/jvm/serialization-new.check b/test/files/jvm/serialization-new.check
index 8ec5754ea2..1555135926 100644
--- a/test/files/jvm/serialization-new.check
+++ b/test/files/jvm/serialization-new.check
@@ -1,4 +1,4 @@
-warning: there were 2 deprecation warnings; re-run with -deprecation for details
+warning: there were two deprecation warnings; re-run with -deprecation for details
a1 = Array[1,2,3]
_a1 = Array[1,2,3]
arrayEquals(a1, _a1): true
diff --git a/test/files/jvm/serialization.check b/test/files/jvm/serialization.check
index 8ec5754ea2..1555135926 100644
--- a/test/files/jvm/serialization.check
+++ b/test/files/jvm/serialization.check
@@ -1,4 +1,4 @@
-warning: there were 2 deprecation warnings; re-run with -deprecation for details
+warning: there were two deprecation warnings; re-run with -deprecation for details
a1 = Array[1,2,3]
_a1 = Array[1,2,3]
arrayEquals(a1, _a1): true
diff --git a/test/files/neg/checksensible.check b/test/files/neg/checksensible.check
index e5f1a38d96..7de22fef54 100644
--- a/test/files/neg/checksensible.check
+++ b/test/files/neg/checksensible.check
@@ -97,6 +97,7 @@ checksensible.scala:84: warning: comparing values of types EqEqRefTest.this.C3 a
checksensible.scala:95: warning: comparing values of types Unit and Int using `!=' will always yield true
while ((c = in.read) != -1)
^
+warning: there were three deprecation warnings; re-run with -deprecation for details
error: No warnings can be incurred under -Xfatal-warnings.
-33 warnings found
+34 warnings found
one error found
diff --git a/test/files/neg/overloaded-implicit.check b/test/files/neg/overloaded-implicit.check
index ca0870705d..0e6617d904 100644
--- a/test/files/neg/overloaded-implicit.check
+++ b/test/files/neg/overloaded-implicit.check
@@ -4,6 +4,7 @@ overloaded-implicit.scala:2: warning: parameterized overloaded implicit methods
overloaded-implicit.scala:3: warning: parameterized overloaded implicit methods are not visible as view bounds
implicit def imp1[T](x: Set[T]): Map[T, T] = Map()
^
+warning: there were four feature warnings; re-run with -feature for details
error: No warnings can be incurred under -Xfatal-warnings.
-two warnings found
+three warnings found
one error found
diff --git a/test/files/neg/t1909-object.check b/test/files/neg/t1909-object.check
index 401c1f7ebf..7141c84d4b 100644
--- a/test/files/neg/t1909-object.check
+++ b/test/files/neg/t1909-object.check
@@ -1,4 +1,6 @@
-t1909-object.scala:4: error: !!! SI-1909 Unable to STATICally lift object InnerTrouble$1, which is defined in the self- or super-constructor call of class Kaboom. A VerifyError is likely.
+t1909-object.scala:4: warning: !!! SI-1909 Unable to STATICally lift object InnerTrouble$1, which is defined in the self- or super-constructor call of class Kaboom. A VerifyError is likely.
object InnerTrouble
^
+error: No warnings can be incurred under -Xfatal-warnings.
+one warning found
one error found
diff --git a/test/files/neg/t5675.check b/test/files/neg/t5675.check
index 13226935dc..3b3b2fa04c 100644
--- a/test/files/neg/t5675.check
+++ b/test/files/neg/t5675.check
@@ -1,2 +1,4 @@
-error: there was one feature warning; re-run with -feature for details
+warning: there was one feature warning; re-run with -feature for details
+error: No warnings can be incurred under -Xfatal-warnings.
+one warning found
one error found
diff --git a/test/files/neg/t6567.check b/test/files/neg/t6567.check
index a733d75354..f42f157371 100644
--- a/test/files/neg/t6567.check
+++ b/test/files/neg/t6567.check
@@ -4,6 +4,7 @@ t6567.scala:8: warning: Suspicious application of an implicit view (Test.this.a2
t6567.scala:10: warning: Suspicious application of an implicit view (Test.this.a2b) in the argument to Option.apply.
val b: Option[B] = Option(a)
^
+warning: there was one feature warning; re-run with -feature for details
error: No warnings can be incurred under -Xfatal-warnings.
-two warnings found
+three warnings found
one error found
diff --git a/test/files/neg/unchecked-refinement.check b/test/files/neg/unchecked-refinement.check
index e85a51f44d..0bb944621b 100644
--- a/test/files/neg/unchecked-refinement.check
+++ b/test/files/neg/unchecked-refinement.check
@@ -10,6 +10,7 @@ unchecked-refinement.scala:23: warning: a pattern match on a refinement type is
unchecked-refinement.scala:24: warning: a pattern match on a refinement type is unchecked
/* nowarn - todo */ case x: AnyRef { def size: Int } if b => x.size // this could/should do a static conformance test and not warn
^
+warning: there was one feature warning; re-run with -feature for details
error: No warnings can be incurred under -Xfatal-warnings.
-four warnings found
+5 warnings found
one error found
diff --git a/test/files/run/colltest.check b/test/files/run/colltest.check
index 46e4017eb6..9579d781aa 100644
--- a/test/files/run/colltest.check
+++ b/test/files/run/colltest.check
@@ -1,4 +1,4 @@
-warning: there were 2 deprecation warnings; re-run with -deprecation for details
+warning: there were two deprecation warnings; re-run with -deprecation for details
true
false
true
diff --git a/test/files/run/inferred-type-constructors.check b/test/files/run/inferred-type-constructors.check
index 67075a59a9..4a63853bd9 100644
--- a/test/files/run/inferred-type-constructors.check
+++ b/test/files/run/inferred-type-constructors.check
@@ -1,4 +1,4 @@
-warning: there were 2 feature warnings; re-run with -feature for details
+warning: there were two feature warnings; re-run with -feature for details
p.Iterable[Int]
p.Set[Int]
p.Seq[Int]
diff --git a/test/files/run/names-defaults.check b/test/files/run/names-defaults.check
index 97cfa4e520..25999c488a 100644
--- a/test/files/run/names-defaults.check
+++ b/test/files/run/names-defaults.check
@@ -1,7 +1,7 @@
names-defaults.scala:269: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
spawn(b = { val ttt = 1; ttt }, a = 0)
^
-warning: there were 4 deprecation warnings; re-run with -deprecation for details
+warning: there were four deprecation warnings; re-run with -deprecation for details
1: @
get: $
get: 2
diff --git a/test/files/run/richs.check b/test/files/run/richs.check
index bcaf8bdb8d..cf265ae007 100644
--- a/test/files/run/richs.check
+++ b/test/files/run/richs.check
@@ -1,4 +1,4 @@
-warning: there were 2 deprecation warnings; re-run with -deprecation for details
+warning: there were two deprecation warnings; re-run with -deprecation for details
RichCharTest1:
true
diff --git a/test/files/run/t2212.check b/test/files/run/t2212.check
index f7e80439c7..1465f1341a 100644
--- a/test/files/run/t2212.check
+++ b/test/files/run/t2212.check
@@ -1,4 +1,4 @@
-warning: there were 2 deprecation warnings; re-run with -deprecation for details
+warning: there were two deprecation warnings; re-run with -deprecation for details
LinkedList(1)
LinkedList(1)
true
diff --git a/test/files/run/t3996.check b/test/files/run/t3996.check
index 2e8e558f88..a9ecc29fea 100644
--- a/test/files/run/t3996.check
+++ b/test/files/run/t3996.check
@@ -1 +1 @@
-warning: there were 2 deprecation warnings; re-run with -deprecation for details
+warning: there were two deprecation warnings; re-run with -deprecation for details
diff --git a/test/files/run/t4080.check b/test/files/run/t4080.check
index c642cc67da..462e925b76 100644
--- a/test/files/run/t4080.check
+++ b/test/files/run/t4080.check
@@ -1,2 +1,2 @@
-warning: there were 3 deprecation warnings; re-run with -deprecation for details
+warning: there were three deprecation warnings; re-run with -deprecation for details
LinkedList(1, 0, 2, 3)
diff --git a/test/files/run/t4461.check b/test/files/run/t4461.check
index c44b0fc077..346993af6f 100644
--- a/test/files/run/t4461.check
+++ b/test/files/run/t4461.check
@@ -1,4 +1,4 @@
-warning: there were 4 deprecation warnings; re-run with -deprecation for details
+warning: there were four deprecation warnings; re-run with -deprecation for details
Include(End,1)
Include(End,2)
Include(End,3)
diff --git a/test/files/run/t4813.check b/test/files/run/t4813.check
index 2e8e558f88..a9ecc29fea 100644
--- a/test/files/run/t4813.check
+++ b/test/files/run/t4813.check
@@ -1 +1 @@
-warning: there were 2 deprecation warnings; re-run with -deprecation for details
+warning: there were two deprecation warnings; re-run with -deprecation for details
diff --git a/test/files/run/t6111.check b/test/files/run/t6111.check
index 21a5b19ea0..5880658001 100644
--- a/test/files/run/t6111.check
+++ b/test/files/run/t6111.check
@@ -1,3 +1,3 @@
-warning: there were 2 deprecation warnings; re-run with -deprecation for details
+warning: there were two deprecation warnings; re-run with -deprecation for details
(8,8)
(x,x)
diff --git a/test/files/run/t6690.check b/test/files/run/t6690.check
index 2e8e558f88..a9ecc29fea 100644
--- a/test/files/run/t6690.check
+++ b/test/files/run/t6690.check
@@ -1 +1 @@
-warning: there were 2 deprecation warnings; re-run with -deprecation for details
+warning: there were two deprecation warnings; re-run with -deprecation for details
diff --git a/test/files/run/t6863.check b/test/files/run/t6863.check
index 37de2e6e51..d4df5f7a74 100644
--- a/test/files/run/t6863.check
+++ b/test/files/run/t6863.check
@@ -10,4 +10,4 @@ t6863.scala:46: warning: comparing values of types Unit and Unit using `==' will
t6863.scala:59: warning: comparing values of types Unit and Unit using `==' will always yield true
assert({ () => x }.apply == ())
^
-warning: there were 4 deprecation warnings; re-run with -deprecation for details
+warning: there were four deprecation warnings; re-run with -deprecation for details
diff --git a/test/files/run/t8196.check b/test/files/run/t8196.check
index f021a3619f..d11dc27e68 100644
--- a/test/files/run/t8196.check
+++ b/test/files/run/t8196.check
@@ -1,7 +1,7 @@
t8196.scala:26: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
form2.g1 // comment this line in order to make the test pass
^
-warning: there were 2 feature warnings; re-run with -feature for details
+warning: there were two feature warnings; re-run with -feature for details
Scope{
final private val f1: Int
}
diff --git a/test/files/run/t8549.check b/test/files/run/t8549.check
index 2e8e558f88..a9ecc29fea 100644
--- a/test/files/run/t8549.check
+++ b/test/files/run/t8549.check
@@ -1 +1 @@
-warning: there were 2 deprecation warnings; re-run with -deprecation for details
+warning: there were two deprecation warnings; re-run with -deprecation for details
diff --git a/test/junit/scala/tools/nsc/symtab/SymbolTableForUnitTesting.scala b/test/junit/scala/tools/nsc/symtab/SymbolTableForUnitTesting.scala
index 25d8c4667f..91868a5683 100644
--- a/test/junit/scala/tools/nsc/symtab/SymbolTableForUnitTesting.scala
+++ b/test/junit/scala/tools/nsc/symtab/SymbolTableForUnitTesting.scala
@@ -72,6 +72,18 @@ class SymbolTableForUnitTesting extends SymbolTable {
def picklerPhase: scala.reflect.internal.Phase = SomePhase
def erasurePhase: scala.reflect.internal.Phase = SomePhase
+ // Members declared in scala.reflect.internal.Reporting
+ def reporter = new scala.reflect.internal.ReporterImpl {
+ protected def info0(pos: Position, msg: String, severity: Severity, force: Boolean): Unit = println(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
+
// Members declared in scala.reflect.internal.SymbolTable
def currentRunId: Int = 1
def log(msg: => AnyRef): Unit = println(msg)