diff options
author | Eugene Burmako <xeno.by@gmail.com> | 2013-10-19 11:38:56 +0200 |
---|---|---|
committer | Eugene Burmako <xeno.by@gmail.com> | 2013-10-19 12:46:31 +0200 |
commit | 5a672866379f90a5c3a9c29a86f9a7b661a3c2c6 (patch) | |
tree | 610f952a78f5e84a5a8d073ec0fb5b490b07e993 /test/files/run | |
parent | ed80616ccd9de9fead9553a93c5fbddfc1ea4275 (diff) | |
download | scala-5a672866379f90a5c3a9c29a86f9a7b661a3c2c6.tar.gz scala-5a672866379f90a5c3a9c29a86f9a7b661a3c2c6.tar.bz2 scala-5a672866379f90a5c3a9c29a86f9a7b661a3c2c6.zip |
fixes handling of fancy nested classes in runtime reflection
Replaces the `jclazz.isMemberClass` check for whether we have an
inner/nested class with `jclazz.getEnclosingClass != null`, because there
exist classes produced by javac (see the attached jar file and the test log)
which have the following properties:
* They are nested within a parent class
* getEnclosingClass returns a non-null value
* isMemberClass returns false
Previously such classes were incorrectly treated as non-nested, were
incorrectly put into an enclosing package rather than an enclosing class,
and had their names trimmed in the process, leading to situations when
a package has multiple declarations with the same name. This is now fixed.
When changing the check, we need to be careful with interpretation of
what Class.getEnclosingXXX methods return. If getEnclosingClass produces
a non-null result, this doesn't mean that the class is inner or nested,
because getEnclosingClass is also not null for local classes (the ones
with getEnclosingMethod != null || getEnclosingConstructor != null).
This is expressed in the order of pattern match clauses in `sOwner`.
Now when the bug is fixed, I also revert b18a2f8798b2, restoring a very
important integrity check in runtime reflection, which I had to disable
a couple hours ago to fix a master breakage. More details at scala-internals:
https://groups.google.com/forum/#!topic/scala-internals/hcnUFk75MgQ
Diffstat (limited to 'test/files/run')
-rw-r--r-- | test/files/run/reflection-fancy-java-classes.check | 12 | ||||
-rw-r--r-- | test/files/run/reflection-fancy-java-classes/Foo_1.java | 5 | ||||
-rw-r--r-- | test/files/run/reflection-fancy-java-classes/Test_2.scala | 20 |
3 files changed, 37 insertions, 0 deletions
diff --git a/test/files/run/reflection-fancy-java-classes.check b/test/files/run/reflection-fancy-java-classes.check new file mode 100644 index 0000000000..258208dd99 --- /dev/null +++ b/test/files/run/reflection-fancy-java-classes.check @@ -0,0 +1,12 @@ +===== JAVA POV ===== +class Foo_1$1 +getEnclosingClass = class Foo_1 +getEnclosingMethod = null +getEnclosingConstructor = null +isMemberClass = false +isLocalClass = false +isAnonymousClass = true + +===== SCALA POV ===== +class 1 +object Foo_1 diff --git a/test/files/run/reflection-fancy-java-classes/Foo_1.java b/test/files/run/reflection-fancy-java-classes/Foo_1.java new file mode 100644 index 0000000000..f6fd76124b --- /dev/null +++ b/test/files/run/reflection-fancy-java-classes/Foo_1.java @@ -0,0 +1,5 @@ +public class Foo_1 { + public static Bar bar = new Bar(); + private static class Bar { + } +}
\ No newline at end of file diff --git a/test/files/run/reflection-fancy-java-classes/Test_2.scala b/test/files/run/reflection-fancy-java-classes/Test_2.scala new file mode 100644 index 0000000000..271960ee79 --- /dev/null +++ b/test/files/run/reflection-fancy-java-classes/Test_2.scala @@ -0,0 +1,20 @@ +import scala.reflect.runtime.{universe => ru} +import scala.reflect.runtime.{currentMirror => cm} + +object Test extends App { + println("===== JAVA POV =====") + val jfancy = Class.forName("Foo_1$1") + println(jfancy) + println("getEnclosingClass = " + jfancy.getEnclosingClass) + println("getEnclosingMethod = " + jfancy.getEnclosingMethod) + println("getEnclosingConstructor = " + jfancy.getEnclosingConstructor) + println("isMemberClass = " + jfancy.isMemberClass) + println("isLocalClass = " + jfancy.isLocalClass) + println("isAnonymousClass = " + jfancy.isAnonymousClass) + + println("") + println("===== SCALA POV =====") + val sfancy = cm.classSymbol(jfancy) + println(sfancy) + println(sfancy.owner) +}
\ No newline at end of file |