From 079296632d8ef5ecc40aafa83757231599c78783 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Tue, 13 Nov 2012 11:02:30 +0100 Subject: 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`. --- test/files/neg/t5148.check | 10 +++- test/files/run/t6440.check | 5 +- test/files/run/t6440.scala | 47 +++++++++++++++-- test/files/run/t6440b.check | 4 ++ test/files/run/t6440b.scala | 61 ++++++++++++++++++++++ ...tags_without_scala_reflect_typetag_lookup.check | 5 +- ...tags_without_scala_reflect_typetag_lookup.scala | 14 +++-- ...ut_scala_reflect_typetag_manifest_interop.check | 5 +- ...ut_scala_reflect_typetag_manifest_interop.scala | 15 +++--- 9 files changed, 139 insertions(+), 27 deletions(-) create mode 100644 test/files/run/t6440b.check create mode 100644 test/files/run/t6440b.scala (limited to 'test') diff --git a/test/files/neg/t5148.check b/test/files/neg/t5148.check index 6edfdf2b1e..25107c4dbe 100644 --- a/test/files/neg/t5148.check +++ b/test/files/neg/t5148.check @@ -1,3 +1,9 @@ -error: bad symbolic reference to value global in class IMain - referenced from t5148.scala (a classfile may be missing) -error: bad symbolic reference to value memberHandlers in class IMain - referenced from t5148.scala (a classfile may be missing) +error: bad symbolic reference. A signature in Imports.class refers to term global +in class scala.tools.nsc.interpreter.IMain 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 Imports.class. +error: bad symbolic reference. A signature in Imports.class refers to term memberHandlers +in class scala.tools.nsc.interpreter.IMain 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 Imports.class. two errors found diff --git a/test/files/run/t6440.check b/test/files/run/t6440.check index b5684daee4..69c253eab4 100644 --- a/test/files/run/t6440.check +++ b/test/files/run/t6440.check @@ -1 +1,4 @@ -Stream((), ?) +pos: source-newSource1,line-9,offset=109 bad symbolic reference. A signature in U.class refers to term pack1 +in package 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 U.class. ERROR diff --git a/test/files/run/t6440.scala b/test/files/run/t6440.scala index 2b690f31e1..5a3a4150d9 100644 --- a/test/files/run/t6440.scala +++ b/test/files/run/t6440.scala @@ -1,7 +1,48 @@ -object Test { +import scala.tools.partest._ +import java.io.File - def main(args: Array[String]): Unit = { - println(Stream.continually(()).filterNot(_ => false).take(2)) +object Test extends StoreReporterDirectTest { + def code = ??? + + def compileCode(code: String) = { + val classpath = List(sys.props("partest.lib"), testOutput.path) mkString sys.props("path.separator") + compileString(newCompiler("-cp", classpath, "-d", testOutput.path))(code) } + def library1 = """ + package pack1 + trait T + """ + + def library2 = """ + package pack2 + trait U extends pack1.T + """ + + def app = """ + package pack3 + object X { + trait U + } + import X._ + import pack2._ + + trait V extends U + """ + + def show(): Unit = { + Seq(library1, library2) foreach compileCode + assert(filteredInfos.isEmpty, filteredInfos) + + // blow away the entire package + val pack1 = new File(testOutput.path, "pack1") + val tClass = new File(pack1, "T.class") + assert(tClass.exists) + assert(tClass.delete()) + assert(pack1.delete()) + + // bad symbolic reference error expected (but no stack trace!) + compileCode(app) + println(filteredInfos.mkString("\n")) + } } diff --git a/test/files/run/t6440b.check b/test/files/run/t6440b.check new file mode 100644 index 0000000000..9771ce5efb --- /dev/null +++ b/test/files/run/t6440b.check @@ -0,0 +1,4 @@ +pos: NoPosition bad symbolic reference. A signature in U.class refers to type T +in package pack1 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 U.class. ERROR diff --git a/test/files/run/t6440b.scala b/test/files/run/t6440b.scala new file mode 100644 index 0000000000..974aca2844 --- /dev/null +++ b/test/files/run/t6440b.scala @@ -0,0 +1,61 @@ +import scala.tools.partest._ +import java.io.File + +object Test extends StoreReporterDirectTest { + def code = ??? + + def compileCode(code: String) = { + val classpath = List(sys.props("partest.lib"), testOutput.path) mkString sys.props("path.separator") + compileString(newCompiler("-cp", classpath, "-d", testOutput.path))(code) + } + + def library1 = """ + package pack1 + trait T + class U { + def t = new T {} + def one = 1 + } + """ + + def library2 = """ + package pack2 + object V { + def u = new pack1.U + } + """ + + def app1 = """ + package pack3 + object Test { + pack2.V.u.one // okay + } + """ + + def app2 = """ + package pack3 + object Test { + pack2.V.u.t // we have to fail if T.class is misisng + } + """ + + def show(): Unit = { + compileCode(library1) + val pack1 = new File(testOutput.path, "pack1") + val tClass = new File(pack1, "T.class") + assert(tClass.exists) + assert(tClass.delete()) + + // allowed to compile, no direct reference to `T` + compileCode(library2) + assert(filteredInfos.isEmpty, filteredInfos) + + // allowed to compile, no direct reference to `T` + compileCode(app1) + assert(filteredInfos.isEmpty, filteredInfos) + + // bad symbolic reference error expected (but no stack trace!) + compileCode(app2) + println(filteredInfos.mkString("\n")) + } +} diff --git a/test/files/run/typetags_without_scala_reflect_typetag_lookup.check b/test/files/run/typetags_without_scala_reflect_typetag_lookup.check index 53df68cfc2..8c558ced60 100644 --- a/test/files/run/typetags_without_scala_reflect_typetag_lookup.check +++ b/test/files/run/typetags_without_scala_reflect_typetag_lookup.check @@ -1,3 +1,2 @@ -newSource1:9: error: could not find implicit value for evidence parameter of type reflect.runtime.package.universe.TypeTag[Int] - Library.foo[Int] - ^ + +pos: source-newSource1,line-9,offset=466 could not find implicit value for evidence parameter of type reflect.runtime.package.universe.TypeTag[Int] ERROR diff --git a/test/files/run/typetags_without_scala_reflect_typetag_lookup.scala b/test/files/run/typetags_without_scala_reflect_typetag_lookup.scala index e51ecdb180..1fbdc62a1e 100644 --- a/test/files/run/typetags_without_scala_reflect_typetag_lookup.scala +++ b/test/files/run/typetags_without_scala_reflect_typetag_lookup.scala @@ -1,6 +1,6 @@ import scala.tools.partest._ -object Test extends DirectTest { +object Test extends StoreReporterDirectTest { def code = ??? def library = """ @@ -32,14 +32,12 @@ object Test extends DirectTest { } def show(): Unit = { - val prevErr = System.err - val baos = new java.io.ByteArrayOutputStream(); - System.setErr(new java.io.PrintStream(baos)); compileLibrary(); + println(filteredInfos.mkString("\n")) + storeReporter.infos.clear() compileApp(); - // we should get bad symbolic reference errors, because we're trying to call a method that can't be unpickled + // we should get bad symbolic reference errors, because we're trying to use an implicit that can't be unpickled // but we don't know the number of these errors and their order, so I just ignore them all - baos.toString.split("\n") filter (!_.startsWith("error: bad symbolic reference")) foreach println - System.setErr(prevErr) + println(filteredInfos.filterNot(_.msg.contains("bad symbolic reference")).mkString("\n")) } -} \ No newline at end of file +} diff --git a/test/files/run/typetags_without_scala_reflect_typetag_manifest_interop.check b/test/files/run/typetags_without_scala_reflect_typetag_manifest_interop.check index 729c0715df..acfecce628 100644 --- a/test/files/run/typetags_without_scala_reflect_typetag_manifest_interop.check +++ b/test/files/run/typetags_without_scala_reflect_typetag_manifest_interop.check @@ -1,3 +1,2 @@ -newSource1:9: error: No Manifest available for App.this.T. - manifest[T] - ^ + +pos: source-newSource1,line-9,offset=479 No Manifest available for App.this.T. ERROR diff --git a/test/files/run/typetags_without_scala_reflect_typetag_manifest_interop.scala b/test/files/run/typetags_without_scala_reflect_typetag_manifest_interop.scala index e984127583..6804baa0c3 100644 --- a/test/files/run/typetags_without_scala_reflect_typetag_manifest_interop.scala +++ b/test/files/run/typetags_without_scala_reflect_typetag_manifest_interop.scala @@ -1,6 +1,7 @@ import scala.tools.partest._ +import scala.tools.nsc.Settings -object Test extends DirectTest { +object Test extends StoreReporterDirectTest { def code = ??? def library = """ @@ -29,18 +30,18 @@ object Test extends DirectTest { """ def compileApp() = { val classpath = List(sys.props("partest.lib"), testOutput.path) mkString sys.props("path.separator") + val global = newCompiler("-cp", classpath, "-d", testOutput.path) compileString(newCompiler("-cp", classpath, "-d", testOutput.path))(app) + //global.reporter.ERROR.foreach(println) } def show(): Unit = { - val prevErr = System.err - val baos = new java.io.ByteArrayOutputStream(); - System.setErr(new java.io.PrintStream(baos)); compileLibrary(); + println(filteredInfos.mkString("\n")) + storeReporter.infos.clear() compileApp(); // we should get bad symbolic reference errors, because we're trying to use an implicit that can't be unpickled // but we don't know the number of these errors and their order, so I just ignore them all - baos.toString.split("\n") filter (!_.startsWith("error: bad symbolic reference")) foreach println - System.setErr(prevErr) + println(filteredInfos.filterNot (_.msg.contains("bad symbolic reference")).mkString("\n")) } -} \ No newline at end of file +} -- cgit v1.2.3