summaryrefslogtreecommitdiff
path: root/test/files/jvm/innerClassAttribute/Classes_1.scala
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@gmail.com>2014-07-01 16:28:24 +0200
committerLukas Rytz <lukas.rytz@gmail.com>2014-09-01 14:29:17 +0200
commite3107465c3e8ac80d1cc6a759e2f3298c2531424 (patch)
tree5aacf420f8845cabed5088b2209ed1e5a9b74c51 /test/files/jvm/innerClassAttribute/Classes_1.scala
parent2606bd921e434a6d8edb21f7f04dbfb10045026e (diff)
downloadscala-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/innerClassAttribute/Classes_1.scala')
-rw-r--r--test/files/jvm/innerClassAttribute/Classes_1.scala92
1 files changed, 90 insertions, 2 deletions
diff --git a/test/files/jvm/innerClassAttribute/Classes_1.scala b/test/files/jvm/innerClassAttribute/Classes_1.scala
index 0875d9160c..9c3ea7f013 100644
--- a/test/files/jvm/innerClassAttribute/Classes_1.scala
+++ b/test/files/jvm/innerClassAttribute/Classes_1.scala
@@ -74,7 +74,7 @@ class A14 {
object A15 {
def f = {
- class B { // static (does not have an outer pointer)
+ class B { // non-static, even though it doesn't have an outer pointer
class C // non-static
}
}
@@ -90,10 +90,98 @@ class A16 {
class V extends A6
new A6 { }
}
+
+ new A6 { }
}
class A17 {
object B {
- class C // not static, has an outer pointer.
+ class C // not static, also has an outer pointer.
+ }
+}
+
+class A18 {
+ def f = {
+ def g = {
+ class A
+ new A6 { }
+ val y = {
+ if ((new Object).hashCode() == 1) {class B {} ; new B} else 2
+ if ((new Object).hashCode() == 1) new A6 { } else "haifish"
+ }
+ }
+ }
+}
+
+class A19 {
+ ((x: Int) => x + 3)
+
+ val x = {
+ ((x: Int) => x + 1)
+ }
+
+ {
+ ((x: Int) => x + 2)
+ }
+}
+
+class A20 {
+ () => {
+ {() => ()}
+ {() => () => 1}
+ }
+}
+
+class A21 {
+ class I1
+ def f = { class J1 }
+}
+object A21 {
+ class I2
+ object I3 {
+ class J2 // static
+ }
+ def g = { class J3 } // non-static
+ val x = { class J4 } // non-static
+ {
+ class J5 // non-static (!)
+ new J5
+ }
+}
+
+class A22 {
+ class C
+ object C {
+ class D // inner class of C$, not of C. Not added to the inner class table of C, only to C$
+ }
+}
+
+class A23 {
+ def f = {
+ val a = new Java_A_1()
+ val c = new Java_A_1.C()
+ val d = new Java_A_1.C.D()
+ val e = new c.E()
+ val f = new a.F()
+ val g = new f.G()
+ }
+}
+
+trait A24Sym
+
+trait A24Base {
+ // trait with concrete members: interface plus (absract) impl class
+ trait DefinitionsApi {
+ def Abs: A24Sym
+ def Conc: A24Sym = new A24Sym { }
+ }
+}
+
+trait A24 extends A24Base {
+ class DefinitionsClass extends DefinitionsApi {
+ // bridge methods are generated for Abs and Conc. there used to be a bug: the bridge symbol was a ModuleSymbol,
+ // calling companionClass would return NoSymbol. i changed erasure to make the bridge symbol is a MethodSymbol.
+ object Abs extends A24Sym
+ override object Conc extends A24Sym
}
}