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.scala13
-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.scala5
-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.scala45
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala84
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala58
-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.scala95
-rw-r--r--src/compiler/scala/tools/reflect/FormatInterpolator.scala20
-rw-r--r--src/library/scala/collection/Iterable.scala2
-rw-r--r--src/library/scala/collection/SetLike.scala7
-rw-r--r--src/library/scala/collection/Traversable.scala2
-rw-r--r--src/library/scala/collection/convert/DecorateAsScala.scala6
-rw-r--r--src/library/scala/collection/convert/WrapAsScala.scala8
-rw-r--r--src/library/scala/collection/convert/Wrappers.scala11
-rw-r--r--src/library/scala/collection/immutable/Iterable.scala1
-rw-r--r--src/library/scala/collection/immutable/List.scala6
-rw-r--r--src/library/scala/collection/immutable/Traversable.scala2
-rw-r--r--src/library/scala/collection/mutable/SetLike.scala17
-rw-r--r--src/library/scala/collection/mutable/UnrolledBuffer.scala48
-rw-r--r--src/library/scala/concurrent/ExecutionContext.scala72
-rw-r--r--src/library/scala/concurrent/duration/Duration.scala2
-rw-r--r--src/library/scala/io/BufferedSource.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Internals.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Positions.scala11
-rw-r--r--src/reflect/scala/reflect/internal/Printers.scala41
-rw-r--r--src/reflect/scala/reflect/internal/ReificationSupport.scala2
-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/internal/pickling/UnPickler.scala42
-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/DocFactory.scala6
-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/duration-tck.scala5
-rw-r--r--test/files/jvm/serialization-new.check2
-rw-r--r--test/files/jvm/serialization.check2
-rw-r--r--test/files/neg/aladdin1055.check7
-rw-r--r--test/files/neg/aladdin1055.flags1
-rw-r--r--test/files/neg/aladdin1055/A.scala6
-rw-r--r--test/files/neg/aladdin1055/Test_1.scala5
-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/t8035-no-adapted-args.check21
-rw-r--r--test/files/neg/t8035-no-adapted-args.flags1
-rw-r--r--test/files/neg/t8035-no-adapted-args.scala6
-rw-r--r--test/files/neg/t8675.check11
-rw-r--r--test/files/neg/t8675.scala24
-rw-r--r--test/files/neg/t8675b.check6
-rw-r--r--test/files/neg/t8675b.scala22
-rw-r--r--test/files/neg/unchecked-refinement.check3
-rw-r--r--test/files/pos/t8708/Either_1.scala6
-rw-r--r--test/files/pos/t8708/Test_2.scala13
-rw-r--r--test/files/run/colltest.check2
-rw-r--r--test/files/run/inferred-type-constructors.check2
-rw-r--r--test/files/run/macro-rangepos-subpatterns.check1
-rw-r--r--test/files/run/macro-rangepos-subpatterns.flags1
-rw-r--r--test/files/run/macro-rangepos-subpatterns/Macros_1.scala18
-rw-r--r--test/files/run/macro-rangepos-subpatterns/Test_2.scala5
-rw-r--r--test/files/run/names-defaults.check3
-rw-r--r--test/files/run/names-defaults.scala4
-rw-r--r--test/files/run/richs.check2
-rw-r--r--test/files/run/stringinterpolation_macro-run.check4
-rw-r--r--test/files/run/stringinterpolation_macro-run.scala1
-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/files/run/t8608-no-format.scala15
-rw-r--r--test/files/run/t8690.check2
-rw-r--r--test/files/run/t8690.scala12
-rw-r--r--test/files/run/t8708_b.check8
-rw-r--r--test/files/run/t8708_b/A_1.scala8
-rw-r--r--test/files/run/t8708_b/Test_2.scala21
-rw-r--r--test/files/scalacheck/quasiquotes/TermConstructionProps.scala12
-rw-r--r--test/junit/scala/reflect/internal/PrintersTest.scala77
-rw-r--r--test/junit/scala/tools/nsc/symtab/SymbolTableForUnitTesting.scala12
135 files changed, 1322 insertions, 651 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..25e13a1314 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
}
}
@@ -186,7 +186,16 @@ abstract class Pickler extends SubComponent {
val (locals, globals) = sym.children partition (_.isLocalClass)
val children =
if (locals.isEmpty) globals
- else globals + sym.newClassWithInfo(tpnme.LOCAL_CHILD, List(sym.tpe), EmptyScope, pos = sym.pos)
+ else {
+ // The LOCAL_CHILD was introduced in 12a2b3b to fix Aladdin bug 1055. When a sealed
+ // class/trait has local subclasses, a single <local child> class symbol is added
+ // as pickled child (instead of a reference to the anonymous class; that was done
+ // initially, but seems not to work, as the bug shows).
+ // Adding the LOCAL_CHILD is necessary to retain exhaustivity warnings under separate
+ // compilation. See test neg/aladdin1055.
+ val parents = (if (sym.isTrait) List(definitions.ObjectTpe) else Nil) ::: List(sym.tpe)
+ globals + sym.newClassWithInfo(tpnme.LOCAL_CHILD, parents, EmptyScope, pos = sym.pos)
+ }
putChildren(sym, children.toList sortBy (_.sealedSortName))
}
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..2f4d228347 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Adaptations.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Adaptations.scala
@@ -77,12 +77,13 @@ 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."))
- !settings.noAdaptedArgs || !(args.isEmpty && settings.future)
+ // return `true` if the adaptation should be kept
+ !(settings.noAdaptedArgs || (args.isEmpty && settings.future))
}
}
}
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..b6387fd56b 100644
--- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
@@ -379,18 +379,37 @@ trait NamesDefaults { self: Analyzer =>
def makeNamedTypes(syms: List[Symbol]) = syms map (sym => NamedType(sym.name, sym.tpe))
- def missingParams[T](args: List[T], params: List[Symbol], argName: T => Option[Name] = nameOfNamedArg _): (List[Symbol], Boolean) = {
- val namedArgs = args.dropWhile(arg => {
- val n = argName(arg)
- n.isEmpty || params.forall(p => p.name != n.get)
- })
- val namedParams = params.drop(args.length - namedArgs.length)
- // missing: keep those with a name which doesn't exist in namedArgs
- val missingParams = namedParams.filter(p => namedArgs.forall(arg => {
+ /**
+ * Returns the parameter symbols of an invocation expression that are not defined by the list
+ * of arguments.
+ *
+ * @param args The list of arguments
+ * @param params The list of parameter sybols of the invoked method
+ * @param argName A function that extracts the name of an argument expression, if it is a named argument.
+ */
+ def missingParams[T](args: List[T], params: List[Symbol], argName: T => Option[Name]): (List[Symbol], Boolean) = {
+ // The argument list contains first a mix of positional args and named args that are on the
+ // right parameter position, and then a number or named args on different positions.
+
+ // collect all named arguments whose position does not match the parameter they define
+ val namedArgsOnChangedPosition = args.zip(params) dropWhile {
+ case (arg, param) =>
+ val n = argName(arg)
+ // drop the argument if
+ // - it's not named, or
+ // - it's named, but defines the parameter on its current position, or
+ // - it's named, but none of the parameter names matches (treated as a positional argument, an assignment expression)
+ n.isEmpty || n.get == param.name || params.forall(_.name != n.get)
+ } map (_._1)
+
+ val paramsWithoutPositionalArg = params.drop(args.length - namedArgsOnChangedPosition.length)
+
+ // missing parameters: those with a name which is not specified in one of the namedArgsOnChangedPosition
+ val missingParams = paramsWithoutPositionalArg.filter(p => namedArgsOnChangedPosition.forall { arg =>
val n = argName(arg)
n.isEmpty || n.get != p.name
- }))
- val allPositional = missingParams.length == namedParams.length
+ })
+ val allPositional = missingParams.length == paramsWithoutPositionalArg.length
(missingParams, allPositional)
}
@@ -407,7 +426,7 @@ trait NamesDefaults { self: Analyzer =>
previousArgss: List[List[Tree]], params: List[Symbol],
pos: scala.reflect.internal.util.Position, context: Context): (List[Tree], List[Symbol]) = {
if (givenArgs.length < params.length) {
- val (missing, positional) = missingParams(givenArgs, params)
+ val (missing, positional) = missingParams(givenArgs, params, nameOfNamedArg)
if (missing forall (_.hasDefault)) {
val defaultArgs = missing flatMap (p => {
val defGetter = defaultGetter(p, context)
@@ -536,8 +555,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 9b9e641cad..d3a41b9570 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
@@ -12,21 +12,47 @@ import scala.collection.{ mutable, immutable }
import mutable.ListBuffer
import symtab.Flags._
-/** This phase adds super accessors for all super calls that either
+/** This phase performs the following functions, each of which could be split out in a
+ * mini-phase:
+ *
+ * (1) Adds super accessors for all super calls that either
* appear in a trait or have as a target a member of some outer class.
- * It also replaces references to parameter accessors with aliases
- * by super references to these aliases. The phase also checks that
- * symbols accessed from super are not abstract, or are overridden by
- * an abstract override. Finally, the phase also mangles the names
- * of class-members which are private up to an enclosing non-package
- * class, in order to avoid overriding conflicts.
*
- * This phase also sets SPECIALIZED flag on type parameters with
+ * (2) Converts references to parameter fields that have the same name as a corresponding
+ * public parameter field in a superclass to a reference to the superclass
+ * field (corresponding = super class field is initialized with subclass field).
+ * This info is pre-computed by the `alias` field in Typer. `dotc` follows a different
+ * route; it computes everything in SuperAccessors and changes the subclass field
+ * to a forwarder instead of manipulating references. This is more modular.
+ *
+ * (3) Adds protected accessors if the access to the protected member happens
+ * in a class which is not a subclass of the member's owner.
+ *
+ * (4) Mangles the names of class-members which are
+ * private up to an enclosing non-package class, in order to avoid overriding conflicts.
+ * This is a dubious, and it would be better to deprecate class-qualified privates.
+ *
+ * (5) This phase also sets SPECIALIZED flag on type parameters with
* `@specialized` annotation. We put this logic here because the
* flag must be set before pickling.
*
- * @author Martin Odersky
- * @version 1.0
+ * It also checks that:
+ *
+ * (1) Symbols accessed from super are not abstract, or are overridden by
+ * an abstract override.
+ *
+ * (2) If a symbol accessed accessed from super is defined in a real class (not a trait),
+ * there are no abstract members which override this member in Java's rules
+ * (see SI-4989; such an access would lead to illegal bytecode)
+ *
+ * (3) Super calls do not go to some synthetic members of Any (see isDisallowed)
+ *
+ * (4) Super calls do not go to synthetic field accessors
+ *
+ * (5) A class and its companion object do not both define a class or module with the
+ * same name.
+ *
+ * TODO: Rename phase to "Accessors" because it handles more than just super accessors
*/
abstract class SuperAccessors extends transform.Transform with transform.TypingTransformers {
import global._
@@ -98,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)
}
@@ -113,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")
}
}
@@ -226,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.")
@@ -284,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 66b1c2d87a..65f11a360e 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.
@@ -3263,25 +3248,25 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
* to that. This is the last thing which is tried (after
* default arguments)
*/
- def tryTupleApply: Tree = (
+ def tryTupleApply: Tree = {
if (eligibleForTupleConversion(paramTypes, argslen) && !phase.erasedTypes) {
val tupleArgs = List(atPos(tree.pos.makeTransparent)(gen.mkTuple(args)))
// expected one argument, but got 0 or >1 ==> try applying to tuple
// the inner "doTypedApply" does "extractUndetparams" => restore when it fails
val savedUndetparams = context.undetparams
silent(_.doTypedApply(tree, fun, tupleArgs, mode, pt)) map { t =>
- // Depending on user options, may warn or error here if
- // a Unit or tuple was inserted.
- val keepTree = (
- !mode.typingExprNotFun
- || t.symbol == null
- || checkValidAdaptation(t, args)
- )
- if (keepTree) t else EmptyTree
+ // Depending on user options, may warn or error here if
+ // a Unit or tuple was inserted.
+ val keepTree = (
+ !mode.typingExprNotFun // why? introduced in 4e488a60, doc welcome
+ || t.symbol == null // ditto
+ || checkValidAdaptation(t, args)
+ )
+ if (keepTree) t else EmptyTree
} orElse { _ => context.undetparams = savedUndetparams ; EmptyTree }
}
else EmptyTree
- )
+ }
/* Treats an application which uses named or default arguments.
* Also works if names + a vararg used: when names are used, the vararg
@@ -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)
@@ -4399,7 +4384,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
if (retry) {
val Select(qual, name) = fun
tryTypedArgs(args, forArgMode(fun, mode)) match {
- case Some(args1) =>
+ case Some(args1) if !args1.exists(arg => arg.exists(_.isErroneous)) =>
val qual1 =
if (!pt.isError) adaptToArguments(qual, name, args1, pt, reportAmbiguous = true, saveErrors = true)
else qual
@@ -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..b445f1e2bb 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
}
}
@@ -182,13 +182,23 @@ abstract class FormatInterpolator {
case (part, n) => copyPart(part, n)
}
- //q"{..$evals; ${fstring.toString}.format(..$ids)}"
- locally {
+ //q"{..$evals; new StringOps(${fstring.toString}).format(..$ids)}"
+ val format = fstring.toString
+ if (ids.isEmpty && !format.contains("%")) Literal(Constant(format))
+ else {
+ val scalaPackage = Select(Ident(nme.ROOTPKG), TermName("scala"))
+ val newStringOps = Select(
+ New(Select(Select(Select(scalaPackage,
+ TermName("collection")), TermName("immutable")), TypeName("StringOps"))),
+ termNames.CONSTRUCTOR
+ )
val expr =
Apply(
Select(
- Literal(Constant(fstring.toString)),
- newTermName("format")),
+ Apply(
+ newStringOps,
+ List(Literal(Constant(format)))),
+ TermName("format")),
ids.toList
)
val p = c.macroApplication.pos
diff --git a/src/library/scala/collection/Iterable.scala b/src/library/scala/collection/Iterable.scala
index a5ab8efd5c..afbffd36c6 100644
--- a/src/library/scala/collection/Iterable.scala
+++ b/src/library/scala/collection/Iterable.scala
@@ -38,7 +38,7 @@ trait Iterable[+A] extends Traversable[A]
}
/** $factoryInfo
- * The current default implementation of a $Coll is a `Vector`.
+ * The current default implementation of a $Coll is a `List`.
* @define coll iterable collection
* @define Coll `Iterable`
*/
diff --git a/src/library/scala/collection/SetLike.scala b/src/library/scala/collection/SetLike.scala
index 0c5c7e0b29..3e549f72cd 100644
--- a/src/library/scala/collection/SetLike.scala
+++ b/src/library/scala/collection/SetLike.scala
@@ -17,6 +17,9 @@ import parallel.ParSet
/** A template trait for sets.
*
* $setNote
+ * '''Implementation note:'''
+ * This trait provides most of the operations of a `Set` independently of its representation.
+ * It is typically inherited by concrete implementations of sets.
* $setTags
* @since 2.8
*
@@ -24,10 +27,6 @@ import parallel.ParSet
*
* A set is a collection that contains no duplicate elements.
*
- * '''Implementation note:'''
- * This trait provides most of the operations of a `Set` independently of its representation.
- * It is typically inherited by concrete implementations of sets.
- *
* To implement a concrete set, you need to provide implementations of the
* following methods:
* {{{
diff --git a/src/library/scala/collection/Traversable.scala b/src/library/scala/collection/Traversable.scala
index b53724c568..a35750a35f 100644
--- a/src/library/scala/collection/Traversable.scala
+++ b/src/library/scala/collection/Traversable.scala
@@ -87,7 +87,7 @@ trait Traversable[+A] extends TraversableLike[A, Traversable[A]]
}
/** $factoryInfo
- * The current default implementation of a $Coll is a `Vector`.
+ * The current default implementation of a $Coll is a `List`.
*/
object Traversable extends TraversableFactory[Traversable] { self =>
diff --git a/src/library/scala/collection/convert/DecorateAsScala.scala b/src/library/scala/collection/convert/DecorateAsScala.scala
index c724831c54..5448f5f91c 100644
--- a/src/library/scala/collection/convert/DecorateAsScala.scala
+++ b/src/library/scala/collection/convert/DecorateAsScala.scala
@@ -135,6 +135,12 @@ trait DecorateAsScala {
* If the Java `Map` was previously obtained from an implicit or explicit
* call of `asMap(scala.collection.mutable.Map)` then the original
* Scala `Map` will be returned.
+ *
+ * If the wrapped map is synchronized (e.g. from `java.util.Collections.synchronizedMap`),
+ * it is your responsibility to wrap all
+ * non-atomic operations with `underlying.synchronized`.
+ * This includes `get`, as `java.util.Map`'s API does not allow for an
+ * atomic `get` when `null` values may be present.
*
* @param m The `Map` to be converted.
* @return An object with an `asScala` method that returns a Scala mutable
diff --git a/src/library/scala/collection/convert/WrapAsScala.scala b/src/library/scala/collection/convert/WrapAsScala.scala
index d4ab451b0d..ab151a6778 100644
--- a/src/library/scala/collection/convert/WrapAsScala.scala
+++ b/src/library/scala/collection/convert/WrapAsScala.scala
@@ -133,7 +133,13 @@ trait WrapAsScala {
* If the Java `Map` was previously obtained from an implicit or
* explicit call of `mapAsScalaMap(scala.collection.mutable.Map)` then
* the original Scala Map will be returned.
- *
+ *
+ * If the wrapped map is synchronized (e.g. from `java.util.Collections.synchronizedMap`),
+ * it is your responsibility to wrap all
+ * non-atomic operations with `underlying.synchronized`.
+ * This includes `get`, as `java.util.Map`'s API does not allow for an
+ * atomic `get` when `null` values may be present.
+ *
* @param m The Map to be converted.
* @return A Scala mutable Map view of the argument.
*/
diff --git a/src/library/scala/collection/convert/Wrappers.scala b/src/library/scala/collection/convert/Wrappers.scala
index 7d1d6b3781..9f9732c62f 100644
--- a/src/library/scala/collection/convert/Wrappers.scala
+++ b/src/library/scala/collection/convert/Wrappers.scala
@@ -288,6 +288,13 @@ private[collection] trait Wrappers {
override def empty: Repr = null.asInstanceOf[Repr]
}
+ /** Wraps a Java map as a Scala one. If the map is to support concurrent access,
+ * use [[JConcurrentMapWrapper]] instead. If the wrapped map is synchronized
+ * (e.g. from `java.util.Collections.synchronizedMap`), it is your responsibility
+ * to wrap all non-atomic operations with `underlying.synchronized`.
+ * This includes `get`, as `java.util.Map`'s API does not allow for an
+ * atomic `get` when `null` values may be present.
+ */
case class JMapWrapper[A, B](underlying : ju.Map[A, B]) extends mutable.AbstractMap[A, B] with JMapWrapperLike[A, B, JMapWrapper[A, B]] {
override def empty = JMapWrapper(new ju.HashMap[A, B])
}
@@ -314,6 +321,10 @@ private[collection] trait Wrappers {
def replace(k: A, oldval: B, newval: B) = underlying.replace(k, oldval, newval)
}
+ /** Wraps a concurrent Java map as a Scala one. Single-element concurrent
+ * access is supported; multi-element operations such as maps and filters
+ * are not guaranteed to be atomic.
+ */
case class JConcurrentMapWrapper[A, B](underlying: juc.ConcurrentMap[A, B]) extends mutable.AbstractMap[A, B] with JMapWrapperLike[A, B, JConcurrentMapWrapper[A, B]] with concurrent.Map[A, B] {
override def get(k: A) = {
val v = underlying get k
diff --git a/src/library/scala/collection/immutable/Iterable.scala b/src/library/scala/collection/immutable/Iterable.scala
index 6e4eb1e45f..df322396d0 100644
--- a/src/library/scala/collection/immutable/Iterable.scala
+++ b/src/library/scala/collection/immutable/Iterable.scala
@@ -35,6 +35,7 @@ trait Iterable[+A] extends Traversable[A]
}
/** $factoryInfo
+ * The current default implementation of a $Coll is a `List`.
* @define Coll `immutable.Iterable`
* @define coll immutable iterable collection
*/
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/immutable/Traversable.scala b/src/library/scala/collection/immutable/Traversable.scala
index 775d635fae..5fc0607a00 100644
--- a/src/library/scala/collection/immutable/Traversable.scala
+++ b/src/library/scala/collection/immutable/Traversable.scala
@@ -29,7 +29,7 @@ trait Traversable[+A] extends scala.collection.Traversable[A]
}
/** $factoryInfo
- * The current default implementation of a $Coll is a `Vector`.
+ * The current default implementation of a $Coll is a `List`.
* @define coll immutable traversable collection
* @define Coll `immutable.Traversable`
*/
diff --git a/src/library/scala/collection/mutable/SetLike.scala b/src/library/scala/collection/mutable/SetLike.scala
index d749167870..a377b03124 100644
--- a/src/library/scala/collection/mutable/SetLike.scala
+++ b/src/library/scala/collection/mutable/SetLike.scala
@@ -16,19 +16,20 @@ import scala.annotation.migration
import parallel.mutable.ParSet
/** A template trait for mutable sets of type `mutable.Set[A]`.
+ *
+ * This trait provides most of the operations of a `mutable.Set` independently of its representation.
+ * It is typically inherited by concrete implementations of sets.
+ *
+ * $setNote
+ *
* @tparam A the type of the elements of the set
* @tparam This the type of the set itself.
*
- * $setnote
- *
* @author Martin Odersky
* @version 2.8
* @since 2.8
*
- * @define setnote
- * @note
- * This trait provides most of the operations of a `mutable.Set` independently of its representation.
- * It is typically inherited by concrete implementations of sets.
+ * @define setNote
*
* To implement a concrete mutable set, you need to provide implementations
* of the following methods:
@@ -36,13 +37,13 @@ import parallel.mutable.ParSet
* def contains(elem: A): Boolean
* def iterator: Iterator[A]
* def += (elem: A): this.type
- * def -= (elem: A): this.type</pre>
+ * def -= (elem: A): this.type
* }}}
* If you wish that methods like `take`,
* `drop`, `filter` return the same kind of set,
* you should also override:
* {{{
- * def empty: This</pre>
+ * def empty: This
* }}}
* It is also good idea to override methods `foreach` and
* `size` for efficiency.
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/library/scala/concurrent/ExecutionContext.scala b/src/library/scala/concurrent/ExecutionContext.scala
index 4674c9174b..11d3bb8b02 100644
--- a/src/library/scala/concurrent/ExecutionContext.scala
+++ b/src/library/scala/concurrent/ExecutionContext.scala
@@ -61,28 +61,44 @@ or import scala.concurrent.ExecutionContext.Implicits.global.""")
trait ExecutionContext {
/** Runs a block of code on this execution context.
+ *
+ * @param runnable the task to execute
*/
def execute(runnable: Runnable): Unit
/** Reports that an asynchronous computation failed.
+ *
+ * @param cause the cause of the failure
*/
def reportFailure(@deprecatedName('t) cause: Throwable): Unit
- /** Prepares for the execution of a task. Returns the prepared
- * execution context. A valid implementation of `prepare` is one
- * that simply returns `this`.
+ /** Prepares for the execution of a task. Returns the prepared execution context.
+ *
+ * `prepare` should be called at the site where an `ExecutionContext` is received (for
+ * example, through an implicit method parameter). The returned execution context may
+ * then be used to execute tasks. The role of `prepare` is to save any context relevant
+ * to an execution's ''call site'', so that this context may be restored at the
+ * ''execution site''. (These are often different: for example, execution may be
+ * suspended through a `Promise`'s future until the `Promise` is completed, which may
+ * be done in another thread, on another stack.)
+ *
+ * Note: a valid implementation of `prepare` is one that simply returns `this`.
+ *
+ * @return the prepared execution context
*/
def prepare(): ExecutionContext = this
}
/**
- * An [[ExecutionContext]] that is also a Java [[Executor]].
+ * An [[ExecutionContext]] that is also a
+ * Java [[http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executor.html Executor]].
*/
trait ExecutionContextExecutor extends ExecutionContext with Executor
/**
- * An [[ExecutionContext]] that is also a Java [[ExecutorService]].
+ * An [[ExecutionContext]] that is also a
+ * Java [[http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html ExecutorService]].
*/
trait ExecutionContextExecutorService extends ExecutionContextExecutor with ExecutorService
@@ -91,38 +107,70 @@ trait ExecutionContextExecutorService extends ExecutionContextExecutor with Exec
*/
object ExecutionContext {
/**
- * This is the explicit global ExecutionContext,
- * call this when you want to provide the global ExecutionContext explicitly
+ * The explicit global `ExecutionContext`. Invoke `global` when you want to provide the global
+ * `ExecutionContext` explicitly.
+ *
+ * The default `ExecutionContext` implementation is backed by a port of
+ * [[http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166-4jdk7docs/java/util/concurrent/ForkJoinPool.html java.util.concurrent.ForkJoinPool]].
+ *
+ * @return the global `ExecutionContext`
*/
def global: ExecutionContextExecutor = Implicits.global
object Implicits {
/**
- * This is the implicit global ExecutionContext,
- * import this when you want to provide the global ExecutionContext implicitly
+ * The implicit global `ExecutionContext`. Import `global` when you want to provide the global
+ * `ExecutionContext` implicitly.
+ *
+ * The default `ExecutionContext` implementation is backed by a port of
+ * [[http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166-4jdk7docs/java/util/concurrent/ForkJoinPool.html java.util.concurrent.ForkJoinPool]].
*/
implicit lazy val global: ExecutionContextExecutor = impl.ExecutionContextImpl.fromExecutor(null: Executor)
}
/** Creates an `ExecutionContext` from the given `ExecutorService`.
+ *
+ * @param e the `ExecutorService` to use
+ * @param reporter a function for error reporting
+ * @return the `ExecutionContext` using the given `ExecutorService`
*/
def fromExecutorService(e: ExecutorService, reporter: Throwable => Unit): ExecutionContextExecutorService =
impl.ExecutionContextImpl.fromExecutorService(e, reporter)
- /** Creates an `ExecutionContext` from the given `ExecutorService` with the default Reporter.
+ /** Creates an `ExecutionContext` from the given `ExecutorService` with the [[scala.concurrent.ExecutionContext$.defaultReporter default reporter]].
+ *
+ * If it is guaranteed that none of the executed tasks are blocking, a single-threaded `ExecutorService`
+ * can be used to create an `ExecutionContext` as follows:
+ *
+ * {{{
+ * import java.util.concurrent.Executors
+ * val ec = ExecutionContext.fromExecutorService(Executors.newSingleThreadExecutor())
+ * }}}
+ *
+ * @param e the `ExecutorService` to use
+ * @return the `ExecutionContext` using the given `ExecutorService`
*/
def fromExecutorService(e: ExecutorService): ExecutionContextExecutorService = fromExecutorService(e, defaultReporter)
/** Creates an `ExecutionContext` from the given `Executor`.
+ *
+ * @param e the `Executor` to use
+ * @param reporter a function for error reporting
+ * @return the `ExecutionContext` using the given `Executor`
*/
def fromExecutor(e: Executor, reporter: Throwable => Unit): ExecutionContextExecutor =
impl.ExecutionContextImpl.fromExecutor(e, reporter)
- /** Creates an `ExecutionContext` from the given `Executor` with the default Reporter.
+ /** Creates an `ExecutionContext` from the given `Executor` with the [[scala.concurrent.ExecutionContext$.defaultReporter default reporter]].
+ *
+ * @param e the `Executor` to use
+ * @return the `ExecutionContext` using the given `Executor`
*/
def fromExecutor(e: Executor): ExecutionContextExecutor = fromExecutor(e, defaultReporter)
- /** The default reporter simply prints the stack trace of the `Throwable` to System.err.
+ /** The default reporter simply prints the stack trace of the `Throwable` to [[http://docs.oracle.com/javase/8/docs/api/java/lang/System.html#err System.err]].
+ *
+ * @return the function for error reporting
*/
def defaultReporter: Throwable => Unit = _.printStackTrace()
}
diff --git a/src/library/scala/concurrent/duration/Duration.scala b/src/library/scala/concurrent/duration/Duration.scala
index 1b50b7fa56..2eded9f060 100644
--- a/src/library/scala/concurrent/duration/Duration.scala
+++ b/src/library/scala/concurrent/duration/Duration.scala
@@ -621,7 +621,7 @@ final class FiniteDuration(val length: Long, val unit: TimeUnit) extends Duratio
}
def -(other: Duration) = other match {
case x: FiniteDuration => add(-x.length, x.unit)
- case _ => other
+ case _ => -other
}
def *(factor: Double) =
diff --git a/src/library/scala/io/BufferedSource.scala b/src/library/scala/io/BufferedSource.scala
index 1c87a1f421..52fa525b24 100644
--- a/src/library/scala/io/BufferedSource.scala
+++ b/src/library/scala/io/BufferedSource.scala
@@ -93,7 +93,7 @@ class BufferedSource(inputStream: InputStream, bufferSize: Int)(implicit val cod
val buf = new Array[Char](bufferSize)
var n = 0
while (n != -1) {
- n = charReader.read(buf)
+ n = allReader.read(buf)
if (n>0) sb.appendAll(buf, 0, n)
}
sb.result
diff --git a/src/reflect/scala/reflect/internal/Internals.scala b/src/reflect/scala/reflect/internal/Internals.scala
index e9916cf7d1..26f3bfd9d0 100644
--- a/src/reflect/scala/reflect/internal/Internals.scala
+++ b/src/reflect/scala/reflect/internal/Internals.scala
@@ -129,7 +129,7 @@ trait Internals extends api.Internals {
def typeBounds(lo: Type, hi: Type): TypeBounds = self.TypeBounds(lo, hi)
def boundedWildcardType(bounds: TypeBounds): BoundedWildcardType = self.BoundedWildcardType(bounds)
- def subpatterns(tree: Tree): Option[List[Tree]] = tree.attachments.get[SubpatternsAttachment].map(_.patterns.map(_.duplicate))
+ def subpatterns(tree: Tree): Option[List[Tree]] = tree.attachments.get[SubpatternsAttachment].map(_.patterns.map(duplicateAndKeepPositions))
type Decorators = MacroDecoratorApi
lazy val decorators: Decorators = new MacroDecoratorApi {
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/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala
index fcc377ba32..2ce861898f 100644
--- a/src/reflect/scala/reflect/internal/Printers.scala
+++ b/src/reflect/scala/reflect/internal/Printers.scala
@@ -596,18 +596,26 @@ trait Printers extends api.Printers { self: SymbolTable =>
}
}
- protected def emptyTree(tree: Tree) = tree match {
- case EmptyTree | build.SyntacticEmptyTypeTree() => true
- case _ => false
+ object EmptyTypeTree {
+ def unapply(tt: TypeTree): Boolean = tt match {
+ case build.SyntacticEmptyTypeTree() if tt.wasEmpty || tt.isEmpty => true
+ case _ => false
+ }
}
+ protected def isEmptyTree(tree: Tree) =
+ tree match {
+ case EmptyTree | EmptyTypeTree() => true
+ case _ => false
+ }
+
protected def originalTypeTrees(trees: List[Tree]) =
- trees.filter(!emptyTree(_)) map {
- case tt: TypeTree => tt.original
- case tree => tree
+ trees.filter(!isEmptyTree(_)) map {
+ case tt: TypeTree if tt.original != null => tt.original
+ case tree => tree
}
- val defaultClasses = List(tpnme.AnyRef)
+ val defaultClasses = List(tpnme.AnyRef, tpnme.Object)
val defaultTraitsForCase = List(tpnme.Product, tpnme.Serializable)
protected def removeDefaultTypesFromList(trees: List[Tree])(classesToRemove: List[Name] = defaultClasses)(traitsToRemove: List[Name]) = {
def removeDefaultTraitsFromList(trees: List[Tree], traitsToRemove: List[Name]): List[Tree] =
@@ -623,9 +631,10 @@ trait Printers extends api.Printers { self: SymbolTable =>
removeDefaultTraitsFromList(removeDefaultClassesFromList(trees, classesToRemove), traitsToRemove)
}
- protected def removeDefaultClassesFromList(trees: List[Tree], classesToRemove: List[Name] = defaultClasses) =
+ protected def removeDefaultClassesFromList(trees: List[Tree], classesToRemove: List[Name] = defaultClasses) =
originalTypeTrees(trees) filter {
case Select(Ident(sc), name) => !(classesToRemove.contains(name) && sc == nme.scala_)
+ case tt: TypeTree if tt.tpe != null => !(classesToRemove contains(newTypeName(tt.tpe.toString())))
case _ => true
}
@@ -637,7 +646,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
}
override def printOpt(prefix: String, tree: Tree) =
- if (!emptyTree(tree)) super.printOpt(prefix, tree)
+ if (!isEmptyTree(tree)) super.printOpt(prefix, tree)
override def printColumn(ts: List[Tree], start: String, sep: String, end: String) = {
super.printColumn(ts.filter(!syntheticToRemove(_)), start, sep, end)
@@ -952,7 +961,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
def printTp = print("(", tp, ")")
tp match {
- case EmptyTree | build.SyntacticEmptyTypeTree() => printTp
+ case EmptyTree | EmptyTypeTree() => printTp
// case for untypechecked trees
case Annotated(annot, arg) if (expr ne null) && (arg ne null) && expr.equalsStructure(arg) => printTp // remove double arg - 5: 5: @unchecked
case tt: TypeTree if tt.original.isInstanceOf[Annotated] => printTp
@@ -963,7 +972,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
// print only fun when targs are TypeTrees with empty original
case TypeApply(fun, targs) =>
- if (targs.exists(emptyTree(_))) {
+ if (targs.exists(isEmptyTree(_))) {
print(fun)
} else super.printTree(tree)
@@ -984,8 +993,8 @@ trait Printers extends api.Printers { self: SymbolTable =>
case treeInfo.Unapplied(body) =>
body match {
case Select(qual, name) if name == nme.unapply => print(qual)
- case TypeApply(Select(qual, name), args) if name == nme.unapply || name == nme.unapplySeq =>
- print(TypeApply(qual, args))
+ case TypeApply(Select(qual, name), _) if name == nme.unapply || name == nme.unapplySeq =>
+ print(qual)
case _ => print(body)
}
case _ => print(fun)
@@ -1061,7 +1070,11 @@ trait Printers extends api.Printers { self: SymbolTable =>
print("(", qualifier, ")#", blankForOperatorName(selector), printedName(selector))
case tt: TypeTree =>
- if (!emptyTree(tt)) print(tt.original)
+ if (!isEmptyTree(tt)) {
+ val original = tt.original
+ if (original != null) print(original)
+ else super.printTree(tree)
+ }
case AppliedTypeTree(tp, args) =>
// it's possible to have (=> String) => String type but Function1[=> String, String] is not correct
diff --git a/src/reflect/scala/reflect/internal/ReificationSupport.scala b/src/reflect/scala/reflect/internal/ReificationSupport.scala
index ad8a2594dd..2caa30d27e 100644
--- a/src/reflect/scala/reflect/internal/ReificationSupport.scala
+++ b/src/reflect/scala/reflect/internal/ReificationSupport.scala
@@ -97,6 +97,8 @@ trait ReificationSupport { self: SymbolTable =>
def toStats(tree: Tree): List[Tree] = tree match {
case EmptyTree => Nil
case SyntacticBlock(stats) => stats
+ case defn if defn.isDef => defn :: Nil
+ case imp: Import => imp :: Nil
case _ => throw new IllegalArgumentException(s"can't flatten $tree")
}
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/internal/pickling/UnPickler.scala b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
index 64a1a44722..b808666360 100644
--- a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
+++ b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
@@ -290,6 +290,25 @@ abstract class UnPickler {
def pflags = flags & PickledFlags
def finishSym(sym: Symbol): Symbol = {
+ /**
+ * member symbols (symbols owned by a class) are added to the class's scope, with a number
+ * of exceptions:
+ *
+ * (.) ...
+ * (1) `local child` represents local child classes, see comment in Pickler.putSymbol.
+ * Since it is not a member, it should not be entered in the owner's scope.
+ */
+ def shouldEnterInOwnerScope = {
+ sym.owner.isClass &&
+ sym != classRoot &&
+ sym != moduleRoot &&
+ !sym.isModuleClass &&
+ !sym.isRefinementClass &&
+ !sym.isTypeParameter &&
+ !sym.isExistentiallyBound &&
+ sym.rawname != tpnme.LOCAL_CHILD // (1)
+ }
+
markFlagsCompleted(sym)(mask = AllFlags)
sym.privateWithin = privateWithin
sym.info = (
@@ -302,8 +321,7 @@ abstract class UnPickler {
newLazyTypeRefAndAlias(inforef, readNat())
}
)
- if (sym.owner.isClass && sym != classRoot && sym != moduleRoot &&
- !sym.isModuleClass && !sym.isRefinementClass && !sym.isTypeParameter && !sym.isExistentiallyBound)
+ if (shouldEnterInOwnerScope)
symScope(sym.owner) enter sym
sym
@@ -681,10 +699,24 @@ abstract class UnPickler {
private val p = phase
protected def completeInternal(sym: Symbol) : Unit = try {
val tp = at(i, () => readType(sym.isTerm)) // after NMT_TRANSITION, revert `() => readType(sym.isTerm)` to `readType`
- if (p ne null)
- slowButSafeEnteringPhase(p) (sym setInfo tp)
+
+ // This is a temporary fix allowing to read classes generated by an older, buggy pickler.
+ // See the generation of the LOCAL_CHILD class in Pickler.scala. In an earlier version, the
+ // pickler did not add the ObjectTpe superclass, it used a trait as the first parent. This
+ // tripped an assertion in AddInterfaces which checks that the first parent is not a trait.
+ // This workaround can probably be removed in 2.12, because the 2.12 compiler is supposed
+ // to only read classfiles generated by 2.12.
+ val fixLocalChildTp = if (sym.rawname == tpnme.LOCAL_CHILD) tp match {
+ case ClassInfoType(superClass :: traits, decls, typeSymbol) if superClass.typeSymbol.isTrait =>
+ ClassInfoType(definitions.ObjectTpe :: superClass :: traits, decls, typeSymbol)
+ case _ => tp
+ } else tp
+
+ if (p ne null) {
+ slowButSafeEnteringPhase(p)(sym setInfo fixLocalChildTp)
+ }
if (currentRunId != definedAtRunId)
- sym.setInfo(adaptToNewRunMap(tp))
+ sym.setInfo(adaptToNewRunMap(fixLocalChildTp))
}
catch {
case e: MissingRequirementError => throw toTypeError(e)
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/DocFactory.scala b/src/scaladoc/scala/tools/nsc/doc/DocFactory.scala
index dce52af56a..47ddfb8aa9 100644
--- a/src/scaladoc/scala/tools/nsc/doc/DocFactory.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/DocFactory.scala
@@ -95,11 +95,11 @@ class DocFactory(val reporter: Reporter, val settings: doc.Settings) { processor
val documentError: PartialFunction[Throwable, Unit] = {
case NoCompilerRunException =>
reporter.info(null, "No documentation generated with unsuccessful compiler run", force = false)
- case _: ClassNotFoundException =>
- ()
+ case e @ (_:ClassNotFoundException | _:IllegalAccessException | _:InstantiationException | _:SecurityException | _:ClassCastException) =>
+ reporter.error(null, s"Cannot load the doclet class ${settings.docgenerator.value} (specified with ${settings.docgenerator.name}): $e. Leaving the default settings will generate the html version of scaladoc.")
}
- /** Generate document(s) for all `files` containing scaladoc documenataion.
+ /** Generate document(s) for all `files` containing scaladoc documentation.
* @param files The list of paths (relative to the compiler's source path, or absolute) of files to document. */
def document(files: List[String]) {
def generate() = {
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/duration-tck.scala b/test/files/jvm/duration-tck.scala
index 3bc8a2c100..7db6c49964 100644
--- a/test/files/jvm/duration-tck.scala
+++ b/test/files/jvm/duration-tck.scala
@@ -61,6 +61,11 @@ object Test extends App {
minf - inf mustBe minf
minf + minf mustBe minf
+ for (i <- Seq(zero, one, two, three)) {
+ i - inf mustBe minf
+ i - minf mustBe inf
+ }
+
inf.compareTo(inf) mustBe 0
inf.compareTo(one) mustBe 1
inf.compareTo(minf) mustBe 1
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/aladdin1055.check b/test/files/neg/aladdin1055.check
new file mode 100644
index 0000000000..41782ae987
--- /dev/null
+++ b/test/files/neg/aladdin1055.check
@@ -0,0 +1,7 @@
+Test_1.scala:2: warning: match may not be exhaustive.
+It would fail on the following input: (_ : this.<local child>)
+ def foo(t: A.T) = t match {
+ ^
+error: No warnings can be incurred under -Xfatal-warnings.
+one warning found
+one error found
diff --git a/test/files/neg/aladdin1055.flags b/test/files/neg/aladdin1055.flags
new file mode 100644
index 0000000000..e8fb65d50c
--- /dev/null
+++ b/test/files/neg/aladdin1055.flags
@@ -0,0 +1 @@
+-Xfatal-warnings \ No newline at end of file
diff --git a/test/files/neg/aladdin1055/A.scala b/test/files/neg/aladdin1055/A.scala
new file mode 100644
index 0000000000..862336e30c
--- /dev/null
+++ b/test/files/neg/aladdin1055/A.scala
@@ -0,0 +1,6 @@
+object A {
+ sealed trait T { def f: Int }
+ class TT extends T { def f = 0 }
+
+ def foo = new T { def f = 1 } // local subclass of sealed trait T
+}
diff --git a/test/files/neg/aladdin1055/Test_1.scala b/test/files/neg/aladdin1055/Test_1.scala
new file mode 100644
index 0000000000..39d9b1dc98
--- /dev/null
+++ b/test/files/neg/aladdin1055/Test_1.scala
@@ -0,0 +1,5 @@
+object Test {
+ def foo(t: A.T) = t match {
+ case a: A.TT => 0
+ }
+}
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/t8035-no-adapted-args.check b/test/files/neg/t8035-no-adapted-args.check
new file mode 100644
index 0000000000..43637b2c1f
--- /dev/null
+++ b/test/files/neg/t8035-no-adapted-args.check
@@ -0,0 +1,21 @@
+t8035-no-adapted-args.scala:4: warning: No automatic adaptation here: use explicit parentheses.
+ signature: Test.f[T](x: T): Int
+ given arguments: 1, 2, 3
+ after adaptation: Test.f((1, 2, 3): (Int, Int, Int))
+ f(1, 2, 3)
+ ^
+t8035-no-adapted-args.scala:4: error: too many arguments for method f: (x: (Int, Int, Int))Int
+ f(1, 2, 3)
+ ^
+t8035-no-adapted-args.scala:5: warning: No automatic adaptation here: use explicit parentheses.
+ signature: Test.f[T](x: T): Int
+ given arguments: <none>
+ after adaptation: Test.f((): Unit)
+ f()
+ ^
+t8035-no-adapted-args.scala:5: error: not enough arguments for method f: (x: Unit)Int.
+Unspecified value parameter x.
+ f()
+ ^
+two warnings found
+two errors found
diff --git a/test/files/neg/t8035-no-adapted-args.flags b/test/files/neg/t8035-no-adapted-args.flags
new file mode 100644
index 0000000000..b3e8c505e2
--- /dev/null
+++ b/test/files/neg/t8035-no-adapted-args.flags
@@ -0,0 +1 @@
+-Yno-adapted-args \ No newline at end of file
diff --git a/test/files/neg/t8035-no-adapted-args.scala b/test/files/neg/t8035-no-adapted-args.scala
new file mode 100644
index 0000000000..82690ebe94
--- /dev/null
+++ b/test/files/neg/t8035-no-adapted-args.scala
@@ -0,0 +1,6 @@
+object Test {
+ def f[T](x: T) = 0
+
+ f(1, 2, 3)
+ f()
+}
diff --git a/test/files/neg/t8675.check b/test/files/neg/t8675.check
new file mode 100644
index 0000000000..4e44fba918
--- /dev/null
+++ b/test/files/neg/t8675.check
@@ -0,0 +1,11 @@
+t8675.scala:13: error: type mismatch;
+ found : Boolean(true)
+ required: String
+ a.update(0, x[A]({new isString(true)})) // !!! allowed
+ ^
+t8675.scala:22: error: type mismatch;
+ found : Boolean(true)
+ required: String
+ new X().m(x[A]({new isString(true)})) // !!! allowed
+ ^
+two errors found
diff --git a/test/files/neg/t8675.scala b/test/files/neg/t8675.scala
new file mode 100644
index 0000000000..ca9bb57ffa
--- /dev/null
+++ b/test/files/neg/t8675.scala
@@ -0,0 +1,24 @@
+class A(s: String) {
+ def foo(x: A) = x
+}
+
+class isString(s: String)
+
+class Test {
+
+ def x[A](a: Any): A = ???
+
+ def test {
+ val a = Array[A]()
+ a.update(0, x[A]({new isString(true)})) // !!! allowed
+
+ // boils down to
+ class X {
+ def m(p: Any) {}
+ }
+ implicit class XOps(x: X) {
+ def m(p: Any) {}
+ }
+ new X().m(x[A]({new isString(true)})) // !!! allowed
+ }
+}
diff --git a/test/files/neg/t8675b.check b/test/files/neg/t8675b.check
new file mode 100644
index 0000000000..cb7ac8af59
--- /dev/null
+++ b/test/files/neg/t8675b.check
@@ -0,0 +1,6 @@
+t8675b.scala:19: error: missing parameter type for expanded function
+The argument types of an anonymous function must be fully known. (SLS 8.5)
+Expected type was: List[Test.Reportable1[?,?]] => Boolean
+ for (path: List[Any] <- (null : Engine1).asRequirement.pathsIncludingSelf.toList) {
+ ^
+one error found
diff --git a/test/files/neg/t8675b.scala b/test/files/neg/t8675b.scala
new file mode 100644
index 0000000000..2c5015b1d0
--- /dev/null
+++ b/test/files/neg/t8675b.scala
@@ -0,0 +1,22 @@
+object Test {
+ trait Engine1
+
+ implicit class EngineTools1[Params, R](e: Engine1) {
+ def asRequirement: Requirement1[Params, R] = ???
+ }
+ trait Requirement1[Params, R] {
+ def pathsIncludingSelf: Traversable[List[Reportable1[Params, R]]]
+ }
+ trait Reportable1[Params, R]
+
+ // "missing paramater type" error was swallowed in 2.11.0 leading to a crash
+ // in the backend.
+ //
+ // This error is itself a regression (or at least a change) in 2.11.0-M7,
+ // specifically in SI-7944. The type paramaters to the implicit view
+ // `EngineTools1` are undetermined, and are now treated as type variables
+ // in the expected type of the closure argument to `withFilter`.
+ for (path: List[Any] <- (null : Engine1).asRequirement.pathsIncludingSelf.toList) {
+ ???
+ }
+}
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/pos/t8708/Either_1.scala b/test/files/pos/t8708/Either_1.scala
new file mode 100644
index 0000000000..000ed6e7c2
--- /dev/null
+++ b/test/files/pos/t8708/Either_1.scala
@@ -0,0 +1,6 @@
+sealed trait \/[+A, +B]
+
+sealed trait EitherT[F[+_], +A, +B]
+object EitherT {
+ def apply[F[+_], A, B](a: F[A \/ B]): EitherT[F, A, B] = new EitherT[F, A, B] { val run = a }
+}
diff --git a/test/files/pos/t8708/Test_2.scala b/test/files/pos/t8708/Test_2.scala
new file mode 100644
index 0000000000..d0e56b9a37
--- /dev/null
+++ b/test/files/pos/t8708/Test_2.scala
@@ -0,0 +1,13 @@
+import scala.language.higherKinds
+
+trait ClientTypes[M[+_]] {
+ final type Context[+A] = EitherT[M, String, A]
+ object Context {
+ def apply[A](ca: M[String \/ A]): Context[A] = EitherT[M, String, A](ca)
+ }
+
+ final type StatefulContext[+A] = EitherT[Context, String, A]
+ object StatefulContext {
+ def apply[A](state: Context[String \/ A]): StatefulContext[A] = ???
+ }
+}
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/macro-rangepos-subpatterns.check b/test/files/run/macro-rangepos-subpatterns.check
new file mode 100644
index 0000000000..760e15d019
--- /dev/null
+++ b/test/files/run/macro-rangepos-subpatterns.check
@@ -0,0 +1 @@
+The width of the subpattern is: 2
diff --git a/test/files/run/macro-rangepos-subpatterns.flags b/test/files/run/macro-rangepos-subpatterns.flags
new file mode 100644
index 0000000000..fcf951d907
--- /dev/null
+++ b/test/files/run/macro-rangepos-subpatterns.flags
@@ -0,0 +1 @@
+-Yrangepos \ No newline at end of file
diff --git a/test/files/run/macro-rangepos-subpatterns/Macros_1.scala b/test/files/run/macro-rangepos-subpatterns/Macros_1.scala
new file mode 100644
index 0000000000..0f30862347
--- /dev/null
+++ b/test/files/run/macro-rangepos-subpatterns/Macros_1.scala
@@ -0,0 +1,18 @@
+import scala.reflect.macros.whitebox.Context
+import language.experimental.macros
+
+object Extractor {
+ def unapply(x: Any): Any = macro unapplyImpl
+ def unapplyImpl(c: Context)(x: c.Tree) = {
+ import c.universe._
+ import internal._
+ val pos = subpatterns(x).get.head.pos
+ q"""
+ new {
+ def isEmpty = false
+ def get = ${"The width of the subpattern is: " + (pos.end - pos.start + 1)}
+ def unapply(x: Any) = this
+ }.unapply($x)
+ """
+ }
+}
diff --git a/test/files/run/macro-rangepos-subpatterns/Test_2.scala b/test/files/run/macro-rangepos-subpatterns/Test_2.scala
new file mode 100644
index 0000000000..7b076e6632
--- /dev/null
+++ b/test/files/run/macro-rangepos-subpatterns/Test_2.scala
@@ -0,0 +1,5 @@
+object Test extends App {
+ 42 match {
+ case Extractor(a) => println(a)
+ }
+}
diff --git a/test/files/run/names-defaults.check b/test/files/run/names-defaults.check
index 97cfa4e520..c358dc5849 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
@@ -124,3 +124,4 @@ List(1, 2)
3
3
(1,0), (1,2)
+1 1 0
diff --git a/test/files/run/names-defaults.scala b/test/files/run/names-defaults.scala
index 05cd4a540c..b7ed490cbc 100644
--- a/test/files/run/names-defaults.scala
+++ b/test/files/run/names-defaults.scala
@@ -401,6 +401,10 @@ object Test extends App {
C4441a().copy()
C4441b()().copy()()
+ // SI-8117
+ def f8177(a: Int = 0, b: Int = 0, c: Int = 0) = s"$a $b $c"
+ println(f8177(a = 1, 1))
+
// DEFINITIONS
def test1(a: Int, b: String) = println(a +": "+ b)
def test2(u: Int, v: Int)(k: String, l: Int) = println(l +": "+ k +", "+ (u + v))
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/stringinterpolation_macro-run.check b/test/files/run/stringinterpolation_macro-run.check
index ead61e76ac..c7f46bac87 100644
--- a/test/files/run/stringinterpolation_macro-run.check
+++ b/test/files/run/stringinterpolation_macro-run.check
@@ -63,5 +63,9 @@ She is 4 feet tall.
05/26/12
05/26/12
%
+ mind
+------
+matter
+
7 7 9
7 9 9
diff --git a/test/files/run/stringinterpolation_macro-run.scala b/test/files/run/stringinterpolation_macro-run.scala
index a6def98540..e18375d521 100644
--- a/test/files/run/stringinterpolation_macro-run.scala
+++ b/test/files/run/stringinterpolation_macro-run.scala
@@ -115,6 +115,7 @@ println(f"""${"1234"}%TD""")
// literals and arg indexes
println(f"%%")
+println(f" mind%n------%nmatter%n")
println(f"${7}%d %<d ${9}%d")
println(f"${7}%d %2$$d ${9}%d")
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/files/run/t8608-no-format.scala b/test/files/run/t8608-no-format.scala
new file mode 100644
index 0000000000..71c369a7ea
--- /dev/null
+++ b/test/files/run/t8608-no-format.scala
@@ -0,0 +1,15 @@
+
+import scala.tools.partest.JavapTest
+
+object Test extends JavapTest {
+ def code = """
+ |f"hello, world"
+ |:javap -prv -
+ """.stripMargin
+
+ // no format
+ override def yah(res: Seq[String]) = {
+ // note: avoid the word "information"
+ res forall (!_.contains("StringOps.format"))
+ }
+}
diff --git a/test/files/run/t8690.check b/test/files/run/t8690.check
new file mode 100644
index 0000000000..72f076c4d8
--- /dev/null
+++ b/test/files/run/t8690.check
@@ -0,0 +1,2 @@
+non-empty iterator
+abcdef
diff --git a/test/files/run/t8690.scala b/test/files/run/t8690.scala
new file mode 100644
index 0000000000..ab8b45b2a7
--- /dev/null
+++ b/test/files/run/t8690.scala
@@ -0,0 +1,12 @@
+import scala.io.Source
+import java.io.ByteArrayInputStream
+
+object Test extends App {
+ val txt = "abcdef"
+
+ val in = new ByteArrayInputStream(txt.getBytes());
+ val source = Source.fromInputStream(in);
+ println(source.toString) // forces the BufferedSource to look at the head of the input
+
+ println(source.mkString) // used to return "bcdef" ...
+}
diff --git a/test/files/run/t8708_b.check b/test/files/run/t8708_b.check
new file mode 100644
index 0000000000..30be62a307
--- /dev/null
+++ b/test/files/run/t8708_b.check
@@ -0,0 +1,8 @@
+Scope{
+ def <init>: <?>;
+ sealed abstract trait T extends ;
+ def foo: <?>
+}
+Scope{
+ def f: <?>
+}
diff --git a/test/files/run/t8708_b/A_1.scala b/test/files/run/t8708_b/A_1.scala
new file mode 100644
index 0000000000..e767420f9e
--- /dev/null
+++ b/test/files/run/t8708_b/A_1.scala
@@ -0,0 +1,8 @@
+package p
+
+class C {
+
+ sealed trait T { def f: Int }
+
+ def foo: T = new T { def f = 1 }
+}
diff --git a/test/files/run/t8708_b/Test_2.scala b/test/files/run/t8708_b/Test_2.scala
new file mode 100644
index 0000000000..c978490609
--- /dev/null
+++ b/test/files/run/t8708_b/Test_2.scala
@@ -0,0 +1,21 @@
+import scala.tools.partest._
+import java.io.{Console => _, _}
+
+object Test extends DirectTest {
+
+ override def extraSettings: String = "-usejavacp -cp " + testOutput.path
+
+ override def code = ""
+
+ override def show(): Unit = {
+ val g = newCompiler()
+ withRun(g)(r => {
+ val c = g.rootMirror.getRequiredClass("p.C")
+ println(c.info.decls)
+ val t = c.info.member(g.newTypeName("T"))
+ // this test ensrues that the <local child> dummy class symbol is not entered in the
+ // scope of trait T during unpickling.
+ println(t.info.decls)
+ })
+ }
+}
diff --git a/test/files/scalacheck/quasiquotes/TermConstructionProps.scala b/test/files/scalacheck/quasiquotes/TermConstructionProps.scala
index 45392de582..409f07037e 100644
--- a/test/files/scalacheck/quasiquotes/TermConstructionProps.scala
+++ b/test/files/scalacheck/quasiquotes/TermConstructionProps.scala
@@ -310,4 +310,16 @@ object TermConstructionProps extends QuasiquoteProperties("term construction") {
val cases = List(cq"a => b", cq"c => d")
assertEqAst(q"{ case ..$cases }", "{ case a => b case c => d }")
}
+
+ property("SI-8609 a") = test {
+ val q1 = q"val x = 1"
+ val q2 = q"..$q1; val y = 2"
+ assert(q2 ≈ q"{ val x = 1; val y = 2 }")
+ }
+
+ property("SI-8609 b") = test {
+ val q1 = q"import foo.bar"
+ val q2 = q"..$q1; val y = 2"
+ assert(q2 ≈ q"{ import foo.bar; val y = 2 }")
+ }
}
diff --git a/test/junit/scala/reflect/internal/PrintersTest.scala b/test/junit/scala/reflect/internal/PrintersTest.scala
index 4587417a99..1458b942dc 100644
--- a/test/junit/scala/reflect/internal/PrintersTest.scala
+++ b/test/junit/scala/reflect/internal/PrintersTest.scala
@@ -33,10 +33,10 @@ object PrinterHelper {
def wrapCode(source: String) = {
val context = sm"""
|trait PrintersContext {
- | class baz extends scala.annotation.StaticAnnotation;
- | class foo1[A, B] extends scala.annotation.StaticAnnotation;
- | class foo2[A, B](a: scala.Int)(b: scala.Int) extends scala.annotation.StaticAnnotation;
- | class foo3[Af, Bf](a: scala.Int)(b: scala.Float, c: PrintersContext.this.foo1[Af, Bf]) extends scala.annotation.StaticAnnotation;
+ | class baz extends scala.annotation.Annotation with scala.annotation.StaticAnnotation;
+ | class foo1[A, B] extends scala.annotation.Annotation with scala.annotation.StaticAnnotation;
+ | class foo2[A, B](a: scala.Int)(b: scala.Int) extends scala.annotation.Annotation with scala.annotation.StaticAnnotation;
+ | class foo3[Af, Bf](a: scala.Int)(b: scala.Float, c: PrintersContext.this.foo1[Af, Bf]) extends scala.annotation.Annotation with scala.annotation.StaticAnnotation;
| trait A1;
| trait B1;
|${source.trim.lines map {" " + _} mkString s"$LF"}
@@ -54,8 +54,12 @@ object PrinterHelper {
}
}
- def assertTreeCode(tree: Tree)(code: String) = {
- assertEquals("using quasiquote or given tree"+LF, code.trim, normalizeEOL(showCode(tree)))
+ def assertTreeCode(tree: Tree, typecheck: Boolean = false)(code: String) = {
+ if (typecheck) {
+ assertEquals("using quasiquote or given tree (typechecked)"+LF, code.trim, normalizeEOL(showCode(toolbox.typecheck(tree))))
+ } else {
+ assertEquals("using quasiquote or given tree"+LF, code.trim, normalizeEOL(showCode(tree)))
+ }
}
def assertPrintedCode(source: String, checkTypedTree: Boolean = true, wrapCode: Boolean = false) = {
@@ -312,17 +316,17 @@ trait BasePrintTests {
@Test def testFunc1 = assertResultCode(
code = "List(1, 2, 3).map((i: Int) => i - 1)")(
parsedCode = "List(1, 2, 3).map(((i: Int) => i.-(1)))",
- typedCode = sm"scala.collection.immutable.List.apply(1, 2, 3).map(((i: scala.Int) => i.-(1)))(scala.collection.immutable.List.canBuildFrom)")
+ typedCode = sm"scala.collection.immutable.List.apply[Int](1, 2, 3).map[Int, List[Int]](((i: scala.Int) => i.-(1)))(scala.collection.immutable.List.canBuildFrom[Int])")
@Test def testFunc2 = assertResultCode(
code = "val sum: Seq[Int] => Int = _ reduceLeft (_+_)")(
parsedCode = "val sum: _root_.scala.Function1[Seq[Int], Int] = ((x$1) => x$1.reduceLeft(((x$2, x$3) => x$2.+(x$3))))",
- typedCode = "val sum: _root_.scala.Function1[scala.`package`.Seq[scala.Int], scala.Int] = ((x$1) => x$1.reduceLeft(((x$2, x$3) => x$2.+(x$3))))")
+ typedCode = "val sum: _root_.scala.Function1[scala.`package`.Seq[scala.Int], scala.Int] = ((x$1: Seq[Int]) => x$1.reduceLeft[Int](((x$2: Int, x$3: Int) => x$2.+(x$3))))")
@Test def testFunc3 = assertResultCode(
code = "List(1, 2, 3) map (_ - 1)")(
parsedCode = "List(1, 2, 3).map(((x$1) => x$1.-(1))) ",
- typedCode = "scala.collection.immutable.List.apply(1, 2, 3).map(((x$1) => x$1.-(1)))(scala.collection.immutable.List.canBuildFrom)")
+ typedCode = "scala.collection.immutable.List.apply[Int](1, 2, 3).map[Int, List[Int]](((x$1: Int) => x$1.-(1)))(scala.collection.immutable.List.canBuildFrom[Int])")
@Test def testFunc4 = assertResultCode(
code = "val x: String => Int = ((str: String) => 1)")(
@@ -401,7 +405,8 @@ trait ClassPrintTests {
@Test def testClassWithImplicitParams = assertPrintedCode("class X(var i: scala.Int)(implicit val d: scala.Double, var f: scala.Float)")
- @Test def testClassWithEarly = assertPrintedCode(sm"""
+ @Test def testClassWithEarly =
+ assertPrintedCode(sm"""
|class X(var i: scala.Int) extends {
| val a = i;
| type B
@@ -419,15 +424,22 @@ trait ClassPrintTests {
| throw Throw2.this.e
|}""")
- /*
- class Test {
- val (a, b) = (1, 2)
- }
- */
- @Test def testClassWithAssignmentWithTuple1 = assertPrintedCode(sm"""
+ @Test def testClassWithAssignmentWithTuple1 = assertResultCode(sm"""
|class Test {
- | private[this] val x$$1 = (scala.Tuple2.apply(1, 2): @scala.unchecked) match {
- | case scala.Tuple2((a @ _), (b @ _)) => scala.Tuple2.apply(a, b)
+ | val (a, b) = (1, 2)
+ |}""")(
+ parsedCode = sm"""
+ |class Test {
+ | private[this] val x$$1 = (scala.Tuple2(1, 2): @scala.unchecked) match {
+ | case scala.Tuple2((a @ _), (b @ _)) => scala.Tuple2(a, b)
+ | };
+ | val a = x$$1._1;
+ | val b = x$$1._2
+ |}""",
+ typedCode = sm"""
+ |class Test {
+ | private[this] val x$$1 = (scala.Tuple2.apply[Int, Int](1, 2): @scala.unchecked) match {
+ | case scala.Tuple2((a @ _), (b @ _)) => scala.Tuple2.apply[Int, Int](a, b)
| };
| val a = Test.this.x$$1._1;
| val b = Test.this.x$$1._2
@@ -448,8 +460,8 @@ trait ClassPrintTests {
|}""",
typedCode = sm"""
|class Test {
- | private[this] val x$$1 = (scala.Predef.ArrowAssoc(1).->(2): @scala.unchecked) match {
- | case scala.Tuple2((a @ _), (b @ _)) => scala.Tuple2.apply(a, b)
+ | private[this] val x$$1 = (scala.Predef.ArrowAssoc[Int](1).->[Int](2): @scala.unchecked) match {
+ | case scala.Tuple2((a @ _), (b @ _)) => scala.Tuple2.apply[Int, Int](a, b)
| };
| val a = Test.this.x$$1._1;
| val b = Test.this.x$$1._2
@@ -462,8 +474,8 @@ trait ClassPrintTests {
*/
@Test def testClassWithPatternMatchInAssignment = assertPrintedCode(sm"""
|class Test {
- | private[this] val x$$1 = (scala.collection.immutable.List.apply(1, 3, 5): @scala.unchecked) match {
- | case scala.collection.immutable.List((one @ _), (three @ _), (five @ _)) => scala.Tuple3.apply(one, three, five)
+ | private[this] val x$$1 = (scala.collection.immutable.List.apply[scala.Int](1, 3, 5): @scala.unchecked) match {
+ | case scala.collection.immutable.List((one @ _), (three @ _), (five @ _)) => scala.Tuple3.apply[scala.Int, scala.Int, scala.Int](one, three, five)
| };
| val one = Test.this.x$$1._1;
| val three = Test.this.x$$1._2;
@@ -626,7 +638,7 @@ trait ClassPrintTests {
@Test def testObjectWithPatternMatch1 = assertPrintedCode(sm"""
|object PM1 {
- | scala.collection.immutable.List.apply(1, 2) match {
+ | scala.collection.immutable.List.apply[scala.Int](1, 2) match {
| case (i @ _) => i
| }
|}""")
@@ -715,7 +727,7 @@ trait ClassPrintTests {
|}""",
typedCode = sm"""
|object PM5 {
- | scala.collection.immutable.List.apply(1, 2) match {
+ | scala.collection.immutable.List.apply[Int](1, 2) match {
| case scala.`package`.::((x @ _), (xs @ _)) => x
| }
|}""")
@@ -756,7 +768,7 @@ trait ClassPrintTests {
@Test def testObjectWithPatternMatch8 = assertPrintedCode(sm"""
|{
| object Extractor {
- | def unapply(i: scala.Int) = scala.Some.apply(i)
+ | def unapply(i: scala.Int) = scala.Some.apply[scala.Int](i)
| };
| object PM9 {
| 42 match {
@@ -991,7 +1003,7 @@ trait ValAndDefPrintTests {
@Test def testDefWithLazyVal2 = assertPrintedCode(sm"""
|def a = {
- | lazy val test = {
+ | lazy val test: Unit = {
| scala.Predef.println();
| scala.Predef.println()
| };
@@ -1161,4 +1173,17 @@ trait QuasiTreesPrintTests {
|case class X(x: Int, s: String) {
| def y = "test"
|}""")
+
+ @Test def testQuasiCaseClassWithTypes1 = assertTreeCode(q"""case class X(x: ${typeOf[Int]}, s: ${typeOf[String]}){ def y = "test" }""")(sm"""
+ |case class X(x: Int, s: String) {
+ | def y = "test"
+ |}""")
+
+ @Test def testQuasiCaseClassWithTypes2 = assertTreeCode(q"""case class X(x: ${typeOf[Int]}, s: ${typeOf[String]}){ def y = "test" }""", typecheck = true)(sm"""
+ |{
+ | case class X(x: Int, s: String) {
+ | def y = "test"
+ | };
+ | ()
+ |}""")
} \ No newline at end of file
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)