diff options
author | Lukas Rytz <lukas.rytz@gmail.com> | 2014-07-01 16:28:24 +0200 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@gmail.com> | 2014-09-01 14:29:17 +0200 |
commit | e3107465c3e8ac80d1cc6a759e2f3298c2531424 (patch) | |
tree | 5aacf420f8845cabed5088b2209ed1e5a9b74c51 /test/files/jvm/javaReflection/Classes_1.scala | |
parent | 2606bd921e434a6d8edb21f7f04dbfb10045026e (diff) | |
download | scala-e3107465c3e8ac80d1cc6a759e2f3298c2531424.tar.gz scala-e3107465c3e8ac80d1cc6a759e2f3298c2531424.tar.bz2 scala-e3107465c3e8ac80d1cc6a759e2f3298c2531424.zip |
Fix InnerClass / EnclosingMethod attributes
This commit seems bigger than it is. Most of it is tests, and moving
some code around. The actual changes are small, but a bit subtle.
The InnerClass and EnclosingMethod attributes should now be close to
the JVM spec (which is summarized in BTypes.scala). New tests make
sure that changes to these attributes, and changes to the way Java
reflection sees Scala classfiles, don't go unnoticed.
A new file, BCodeAsmCommon, holds code that's shared between the two
backend (it could hold more, future work).
In general, the difficulty with emitting InnerClass / EnclosingMethod
is that we need to find out source-level properties. We need to make
sure to do enough phase-travelling, and work around destructive
changes to the ownerchain in lambdalift (we use originalOwner a lot).
The change to JavaMirrors is prompted by the change to the
EnclosingMethod attribute, which changes Java reflection's answer to
getEnclosingMethod and getEnclosingConstructor. Classes defined in
field initializers no longer have an enclosing method, just an
enclosing class, which broke an assumption in JavaMirrors.
There's one change in erasure. Before this change, when an object
declaration implements / overrides a method, and a bridge is required,
then the bridge method was actually a ModuleSymbol (it would get the
lateMETHOD flag and be emitted as a method anyway). This is confusing,
when iterating through the members of a class, you can find two
modules with the same name, and one of them doesn't have a module
class. Now, such bridge methods will be MethodSymbols.
Removed Symbol.originalEnclosingMethod, that is a backend thing and
doesn't need to live in the symbol API.
Diffstat (limited to 'test/files/jvm/javaReflection/Classes_1.scala')
-rw-r--r-- | test/files/jvm/javaReflection/Classes_1.scala | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/test/files/jvm/javaReflection/Classes_1.scala b/test/files/jvm/javaReflection/Classes_1.scala new file mode 100644 index 0000000000..11963e2770 --- /dev/null +++ b/test/files/jvm/javaReflection/Classes_1.scala @@ -0,0 +1,84 @@ +// See Test.scala for comments + +trait T { def f = 1 } + +class A { + // member class + class B + // member trait + trait C + // member object + object D { + class B + trait C + object D + new T { } + (() => -1) + def f = { class KB } + } + + // anonymous class, not a member + new T { } + + // anonymous function, not a member + (() => 1) + + def f = { + class E + trait F + object G + new T { } + (() => 2) + + if (new Object().hashCode == 1) { + class H + trait I + object J + new T { } + (() => 3) + } else { + () + } + } + + { + class K + trait L + object M + new T { } + (() => 4) + } + + val x = { + class N + trait O + object P + new T { } + (() => 5) + } + + def this(x: Int) { + this() + class Q + trait R + object S + new T { } + (() => () => 5) + } +} + +object AO { + class B + trait C + object D + new T { } + (() => 1) +} + +trait AT { + class B + trait C + object D + new T { } + (() => 1) +} |