From 7b72f95a9e328ae6a5c85ee69c0cff668a004d43 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Mon, 10 Mar 2014 16:39:26 +0100 Subject: SI-8196 Runtime reflection robustness for STATIC impl details Scala's runtime reflection works in few modes. The primary mode reads reads out the pickled signatures from ScalaSig annotations, if avaialable. However, these aren't available for Java-defined classes (obviously) nor for local Scala-defined classes (less obviously.), and the Scala `Symbol`s and `Types` must be reconstructed from the Java generic reflection metadata. This bug occurs in the last case, and is centered in `FromJavaClassCompleter`. In that completer, member fields and methods are given an owner based on the STATIC modifier. That makes sense for Java defined classes. I'm not 100% if it makes sense for Scala defined classes; maybe we should just skip them entirely? This patch still includes them, but makes the ownership-assignment more robust in the face of STATIC members emitted by the Scala compiler backend, such as the cache fields for structural calls. (It's reflection all the way down!). We might not have a companion module at all, so before we ended up owning those by `NoSymbol`, and before too long hit the dreaded NSDHNAO crash. That crash doesn't exist any more on 2.11 (it is demoted to a -Xdev warning), but this patch still makes sense on that branch. This commit makes `followStatic` and `enter` more robust when finding a suitable owner for static members. I've also factored out the duplicated logic between the two. --- test/files/run/t8196.check | 3 +++ test/files/run/t8196.scala | 30 ++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 test/files/run/t8196.check create mode 100644 test/files/run/t8196.scala (limited to 'test/files/run') diff --git a/test/files/run/t8196.check b/test/files/run/t8196.check new file mode 100644 index 0000000000..3286c15c91 --- /dev/null +++ b/test/files/run/t8196.check @@ -0,0 +1,3 @@ +Scope{ + final private val f1: Int +} diff --git a/test/files/run/t8196.scala b/test/files/run/t8196.scala new file mode 100644 index 0000000000..d526eafbb3 --- /dev/null +++ b/test/files/run/t8196.scala @@ -0,0 +1,30 @@ +object Test extends App { + + trait FormTrait { + import scala.reflect.runtime.{ universe => ru } + + val runtimeMirror = ru.runtimeMirror(this.getClass.getClassLoader) + val instanceMirror = runtimeMirror.reflect(this) + val members = instanceMirror.symbol.typeSignature.members + def fields = members.filter(_.typeSignature <:< ru.typeOf[Int]) + } + + val f = () => { + + class Form1 extends FormTrait { + val f1 = 5 + } + val form1 = new Form1 + + println(form1.fields) + + val form2 = new FormTrait { + val g1 = new Form1 + } + + form2.g1 // comment this line in order to make the test pass + () + } + + f() +} -- cgit v1.2.3 From 540963f5648f49ea73e1064b0d5185edb1f7884d Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Mon, 10 Mar 2014 17:00:43 +0100 Subject: SI-8195 Test case to show this is a dup of SI-8196 Which was fixed in the previous commit. --- test/files/run/t8196.scala | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'test/files/run') diff --git a/test/files/run/t8196.scala b/test/files/run/t8196.scala index d526eafbb3..e219ac166b 100644 --- a/test/files/run/t8196.scala +++ b/test/files/run/t8196.scala @@ -1,7 +1,8 @@ +import scala.reflect.runtime.{ universe => ru } + object Test extends App { trait FormTrait { - import scala.reflect.runtime.{ universe => ru } val runtimeMirror = ru.runtimeMirror(this.getClass.getClassLoader) val instanceMirror = runtimeMirror.reflect(this) @@ -26,5 +27,25 @@ object Test extends App { () } - f() + val g = () => { + // Reported as SI-8195, same root cause + trait Form { + + private val runtimeMirror = ru.runtimeMirror(this.getClass.getClassLoader) + private val instanceMirror = runtimeMirror.reflect(this) + private val members = instanceMirror.symbol.typeSignature.members + + } + + val f1 = new Form { + val a = 1 + } + + val f2 = new Form { + val b = f1.a + } + } + + f() + g() } -- cgit v1.2.3