diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2014-03-25 11:23:59 +0100 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2014-03-25 11:23:59 +0100 |
commit | 876590b2be42a77fc23e5c57fc155d5772265be7 (patch) | |
tree | 4c7ecb96786ddbcc5ef56619f831299229a1be5e | |
parent | daa77d15dd11f086ea578f05ab29fb18119ec02d (diff) | |
parent | 540963f5648f49ea73e1064b0d5185edb1f7884d (diff) | |
download | scala-876590b2be42a77fc23e5c57fc155d5772265be7.tar.gz scala-876590b2be42a77fc23e5c57fc155d5772265be7.tar.bz2 scala-876590b2be42a77fc23e5c57fc155d5772265be7.zip |
Merge pull request #3614 from retronym/ticket/8196
SI-8196 Runtime reflection robustness for STATIC impl details
-rw-r--r-- | bincompat-forward.whitelist.conf | 5 | ||||
-rw-r--r-- | src/reflect/scala/reflect/runtime/JavaMirrors.scala | 11 | ||||
-rw-r--r-- | test/files/run/t8196.check | 3 | ||||
-rw-r--r-- | test/files/run/t8196.scala | 51 |
4 files changed, 66 insertions, 4 deletions
diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf index 087fa07b37..7879ecfd84 100644 --- a/bincompat-forward.whitelist.conf +++ b/bincompat-forward.whitelist.conf @@ -173,6 +173,11 @@ filter { { matchName="scala.reflect.runtime.SymbolLoaders.isInvalidClassName" problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.runtime.JavaMirrors#JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$followStatic" + problemName=MissingMethodProblem } + ] } diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala index 6fdb238462..9c0781ca06 100644 --- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala +++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala @@ -685,8 +685,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni module.moduleClass setInfo new ClassInfoType(List(), newScope, module.moduleClass) } - def enter(sym: Symbol, mods: Int) = - (if (jModifier.isStatic(mods)) module.moduleClass else clazz).info.decls enter sym + def enter(sym: Symbol, mods: Int) = followStatic(clazz, module, mods).info.decls enter sym def enterEmptyCtorIfNecessary(): Unit = { if (jclazz.getConstructors.isEmpty) @@ -733,8 +732,12 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni * If Java modifiers `mods` contain STATIC, return the module class * of the companion module of `clazz`, otherwise the class `clazz` itself. */ - private def followStatic(clazz: Symbol, mods: Int) = - if (jModifier.isStatic(mods)) clazz.companionModule.moduleClass else clazz + private def followStatic(clazz: Symbol, mods: Int): Symbol = followStatic(clazz, clazz.companionModule, mods) + + private def followStatic(clazz: Symbol, module: Symbol, mods: Int): Symbol = + // SI-8196 `orElse(clazz)` needed for implementation details of the backend, such as the static + // field containing the cache for structural calls. + if (jModifier.isStatic(mods)) module.moduleClass.orElse(clazz) else clazz /** Methods which need to be treated with care * because they either are getSimpleName or call getSimpleName: 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..e219ac166b --- /dev/null +++ b/test/files/run/t8196.scala @@ -0,0 +1,51 @@ +import scala.reflect.runtime.{ universe => ru } + +object Test extends App { + + trait FormTrait { + + 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 + () + } + + 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() +} |