summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2012-11-13 11:02:30 +0100
committerJason Zaugg <jzaugg@gmail.com>2012-11-13 11:02:30 +0100
commit079296632d8ef5ecc40aafa83757231599c78783 (patch)
treeae523bd1269c22b460890298c34dc6c922e1aafa /src
parent86e045e2863b04bf4af4abb5c2ce345bcdae2b80 (diff)
downloadscala-079296632d8ef5ecc40aafa83757231599c78783.tar.gz
scala-079296632d8ef5ecc40aafa83757231599c78783.tar.bz2
scala-079296632d8ef5ecc40aafa83757231599c78783.zip
SI-6440 Address regressions around MissingRequirementError
Go back to using globalError to report when a stub's info is referenced, and only throw the MissingRequirementError when compilation really must abort due to having a StubTermSymbol in a place where a StubClassSymbol would have been a better choice. This situation arises when an entire package is missing from the classpath, as was the case in the reported bug. Adds `StoreReporterDirectTest`, which buffers messages issued during compilation for more structured interrogation. Use this in two test for manifests -- these tests were using a crude means of grepping compiler console output to focus on the relevant output, but this approach was insufficient with the new multi-line error message emitted as part of this change. Also used that base test class to add two new tests: one for the reported error (package missing), and another for a simpler error (class missing). The latter test shows how stub symbols allow code to compile if it doesn't the subset of signatures in some type that refer to a missing class. Gave the INFO/WARNING/ERROR members of Reporter sensible toString implementations; they inherit from Enumeration#Value in an unusual manner (why?) that means the built in toString of Enumeration printed `Severity@0`.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/reporters/Reporter.scala12
-rw-r--r--src/partest/scala/tools/partest/DirectTest.scala8
-rw-r--r--src/partest/scala/tools/partest/StoreReporterDirectTest.scala15
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala10
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala9
-rw-r--r--src/reflect/scala/reflect/internal/pickling/UnPickler.scala8
6 files changed, 47 insertions, 15 deletions
diff --git a/src/compiler/scala/tools/nsc/reporters/Reporter.scala b/src/compiler/scala/tools/nsc/reporters/Reporter.scala
index c5321dd728..8871ae6555 100644
--- a/src/compiler/scala/tools/nsc/reporters/Reporter.scala
+++ b/src/compiler/scala/tools/nsc/reporters/Reporter.scala
@@ -20,9 +20,15 @@ abstract class Reporter {
class Severity(val id: Int) extends severity.Value {
var count: Int = 0
}
- val INFO = new Severity(0)
- val WARNING = new Severity(1)
- val ERROR = new Severity(2)
+ 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
diff --git a/src/partest/scala/tools/partest/DirectTest.scala b/src/partest/scala/tools/partest/DirectTest.scala
index 554e7848c7..8c18809ad6 100644
--- a/src/partest/scala/tools/partest/DirectTest.scala
+++ b/src/partest/scala/tools/partest/DirectTest.scala
@@ -8,6 +8,7 @@ package scala.tools.partest
import scala.tools.nsc._
import io.Directory
import util.{BatchSourceFile, CommandLineParser}
+import reporters.{Reporter, ConsoleReporter}
/** A class for testing code which is embedded as a string.
* It allows for more complete control over settings, compiler
@@ -38,9 +39,12 @@ abstract class DirectTest extends App {
// new compiler
def newCompiler(args: String*): Global = {
val settings = newSettings((CommandLineParser tokenize ("-d \"" + testOutput.path + "\" " + extraSettings)) ++ args.toList)
- if (settings.Yrangepos.value) new Global(settings) with interactive.RangePositions
- else new Global(settings)
+ if (settings.Yrangepos.value) new Global(settings, reporter(settings)) with interactive.RangePositions
+ else new Global(settings, reporter(settings))
}
+
+ def reporter(settings: Settings): Reporter = new ConsoleReporter(settings)
+
def newSources(sourceCodes: String*) = sourceCodes.toList.zipWithIndex map {
case (src, idx) => new BatchSourceFile("newSource" + (idx + 1), src)
}
diff --git a/src/partest/scala/tools/partest/StoreReporterDirectTest.scala b/src/partest/scala/tools/partest/StoreReporterDirectTest.scala
new file mode 100644
index 0000000000..7f3604c86c
--- /dev/null
+++ b/src/partest/scala/tools/partest/StoreReporterDirectTest.scala
@@ -0,0 +1,15 @@
+package scala.tools.partest
+
+import scala.tools.nsc.Settings
+import scala.tools.nsc.reporters.StoreReporter
+import scala.collection.mutable
+
+trait StoreReporterDirectTest extends DirectTest {
+ lazy val storeReporter: StoreReporter = new scala.tools.nsc.reporters.StoreReporter()
+
+ /** Discards all but the first message issued at a given position. */
+ def filteredInfos: Seq[storeReporter.Info] = storeReporter.infos.groupBy(_.pos).map(_._2.head).toList
+
+ /** Hook into [[scala.tools.partest.DirectTest]] to install the custom reporter */
+ override def reporter(settings: Settings) = storeReporter
+}
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index 67b2d05224..06bf54c1f8 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -3103,12 +3103,18 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
)
}
trait StubSymbol extends Symbol {
- override final def failIfStub() = fail(())
protected def missingMessage: String
+
+ /** Fail the stub by throwing a [[scala.reflect.internal.MissingRequirementError]]. */
+ override final def failIfStub() = {MissingRequirementError.signal(missingMessage)} //
+
+ /** Fail the stub by reporting an error to the reporter, setting the IS_ERROR flag
+ * on this symbol, and returning the dummy value `alt`.
+ */
private def fail[T](alt: T): T = {
// Avoid issuing lots of redundant errors
if (!hasFlag(IS_ERROR)) {
- MissingRequirementError.signal(missingMessage)
+ globalError(missingMessage)
if (settings.debug.value)
(new Throwable).printStackTrace
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index 57212bab55..d5347705a6 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -1385,10 +1385,11 @@ trait Types extends api.Types { self: SymbolTable =>
/** A class for this-types of the form <sym>.this.type
*/
abstract case class ThisType(sym: Symbol) extends SingletonType with ThisTypeApi {
- // SI-6640 allow StubSymbols to reveal what's missing from the classpath
- // before we trip the assertion.
- sym.failIfStub()
- assert(sym.isClass, sym)
+ if (!sym.isClass) {
+ // SI-6640 allow StubSymbols to reveal what's missing from the classpath before we trip the assertion.
+ sym.failIfStub()
+ assert(false, sym)
+ }
//assert(sym.isClass && !sym.isModuleClass || sym.isRoot, sym)
override def isTrivial: Boolean = sym.isPackageClass
diff --git a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
index 5464a68205..f3a5053a91 100644
--- a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
+++ b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
@@ -234,10 +234,10 @@ abstract class UnPickler {
adjust(mirrorThatLoaded(owner).missingHook(owner, name)) orElse {
// (5) Create a stub symbol to defer hard failure a little longer.
val missingMessage =
- s"""|A signature in $filename refers to ${name.longString} in ${owner.fullLocationString}
- |which is not available. It may be completely missing from the current classpath,
- |or the version on the classpath might be incompatible with the version used when
- |compiling $filename.""".stripMargin
+ s"""|bad symbolic reference. A signature in $filename refers to ${name.longString}
+ |in ${owner.kindString} ${owner.fullName} which is not available.
+ |It may be completely missing from the current classpath, or the version on
+ |the classpath might be incompatible with the version used when compiling $filename.""".stripMargin
owner.newStubSymbol(name, missingMessage)
}
}