diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2014-03-10 16:39:26 +0100 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2014-03-11 18:07:04 +0100 |
commit | 7b72f95a9e328ae6a5c85ee69c0cff668a004d43 (patch) | |
tree | 5386bfa9153af5b3419e7ab1ef81a8d84b62e672 /test | |
parent | 5720e97b95da57c9549698a9038efb79092394ad (diff) | |
download | scala-7b72f95a9e328ae6a5c85ee69c0cff668a004d43.tar.gz scala-7b72f95a9e328ae6a5c85ee69c0cff668a004d43.tar.bz2 scala-7b72f95a9e328ae6a5c85ee69c0cff668a004d43.zip |
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.
Diffstat (limited to 'test')
-rw-r--r-- | test/files/run/t8196.check | 3 | ||||
-rw-r--r-- | test/files/run/t8196.scala | 30 |
2 files changed, 33 insertions, 0 deletions
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() +} |