diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala | 3 | ||||
-rw-r--r-- | test/files/run/t8582.check | 46 | ||||
-rw-r--r-- | test/files/run/t8582.scala | 71 | ||||
-rw-r--r-- | test/pending/run/t8582-bcode.check | 2 | ||||
-rw-r--r-- | test/pending/run/t8582-bcode.flags | 1 | ||||
-rw-r--r-- | test/pending/run/t8582-bcode.scala | 16 |
6 files changed, 114 insertions, 25 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala index dae53bc0e5..ee9be5b11c 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala @@ -116,12 +116,13 @@ abstract class BCodeSkelBuilder extends BCodeHelpers { addClassFields() innerClassBufferASM ++= trackMemberClasses(claszSymbol, Nil) - gen(cd.impl) + addInnerClassesASM(cnode, innerClassBufferASM.toList) if (AsmUtils.traceClassEnabled && cnode.name.contains(AsmUtils.traceClassPattern)) AsmUtils.traceClass(cnode) + cnode.innerClasses assert(cd.symbol == claszSymbol, "Someone messed up BCodePhase.claszSymbol during genPlainClass().") } // end of method genPlainClass() diff --git a/test/files/run/t8582.check b/test/files/run/t8582.check index 7e96756986..564f482ff8 100644 --- a/test/files/run/t8582.check +++ b/test/files/run/t8582.check @@ -1,2 +1,44 @@ -class p1.p2.Singleton$Singleton$ -List(class p1.p2.Singleton$Singleton$Singleton$) +getClass on module gives module class + class p1.p2.Singleton$Singleton$ + +Nested module classes are found through reflection + p1.p2.Singleton$Singleton$: List(class p1.p2.Singleton$Singleton$Singleton$) + +Reflection can find direct nested classes (A1-B1-C1) + A1: List(class A1$B1) + A1$B1: List(class A1$B1$C1) + A1$B1$C1: List() + +Reflection can find direct nested classes (A2-B2-C2) + A2: List(class A2$B2) + A2$B2: List(class A2$B2$C2) + A2$B2$C2: List() + +Mirror classes have the same InnerClass attributes as the corresponding module class: + className[p1/p2/Singleton$Singleton$] outerClassName[p1/p2/Singleton] innerName[Singleton$] access[9] +Module class + className[p1/p2/Singleton$Singleton$] outerClassName[p1/p2/Singleton] innerName[Singleton$] access[9] + +An outer class has a InnerClass attribute for direct nested classes + className[A1$B1] outerClassName[A1] innerName[B1] access[1] +A nested class has an InnerClass attribute for itself (and also for its nested classes) + className[A1$B1] outerClassName[A1] innerName[B1] access[1] + className[A1$B1$C1] outerClassName[A1$B1] innerName[C1] access[1] +C1 is a nested class, so it has an InnerClass attribute for itself. +Because that attribute leads to an entry for B1 in the constant pool, C1 needs an InnerClass attribute for B1. + className[A1$B1] outerClassName[A1] innerName[B1] access[1] + className[A1$B1$C1] outerClassName[A1$B1] innerName[C1] access[1] + +The BeanInfo class has the same InnerClass attributes as the corresponding bean + className[A1$B1] outerClassName[A1] innerName[B1] access[1] + className[A1$B1$C1] outerClassName[A1$B1] innerName[C1] access[1] + +Class A2 mentions class C2 in the constant pool (due to method f), therefore it needs an InnerClass attribute for C1 + className[A2$B2] outerClassName[A2] innerName[B2] access[1] + className[A2$B2$C2] outerClassName[A2$B2] innerName[C2] access[1] +B2 + className[A2$B2] outerClassName[A2] innerName[B2] access[1] + className[A2$B2$C2] outerClassName[A2$B2] innerName[C2] access[1] +C2 + className[A2$B2] outerClassName[A2] innerName[B2] access[1] + className[A2$B2$C2] outerClassName[A2$B2] innerName[C2] access[1] diff --git a/test/files/run/t8582.scala b/test/files/run/t8582.scala index 844ab8ac14..8a57ef7952 100644 --- a/test/files/run/t8582.scala +++ b/test/files/run/t8582.scala @@ -1,3 +1,6 @@ +import scala.tools.partest.BytecodeTest +import scala.collection.JavaConverters._ + package p1 { package p2 { object Singleton { @@ -8,9 +11,71 @@ package p1 { } } +class A1 { + class B1 { + @scala.beans.BeanInfo + class C1 + } +} + +class A2 { + class B2 { + class C2 + } + def f: B2#C2 = null +} + -object Test extends App { +object Test extends BytecodeTest { import p1.p2._ - println(Singleton.Singleton.getClass) - println(Singleton.Singleton.getClass.getDeclaredClasses.toList) + + def nested(c: Class[_]) = s" ${c.getName}: ${c.getDeclaredClasses.toList}" + + def nprintln(s: String) = println("\n"+s) + def printInner(cname: String): Unit = { + val cnode = loadClassNode(cname) + println(cnode.innerClasses.asScala.toList.map(i => s"className[${i.name}] outerClassName[${i.outerName}] innerName[${i.innerName}] access[${i.access}]").mkString(" ", "\n ", "")) + } + + def show() { + + println("getClass on module gives module class") + println(" " + Singleton.Singleton.getClass) + + nprintln("Nested module classes are found through reflection") + println(nested(Singleton.Singleton.getClass)) + + nprintln("Reflection can find direct nested classes (A1-B1-C1)") + println(nested(classOf[A1])) + println(nested(classOf[A1#B1])) + println(nested(classOf[A1#B1#C1])) + + nprintln("Reflection can find direct nested classes (A2-B2-C2)") + println(nested(classOf[A2])) + println(nested(classOf[A2#B2])) + println(nested(classOf[A2#B2#C2])) + + nprintln("Mirror classes have the same InnerClass attributes as the corresponding module class:") + printInner("p1.p2.Singleton") // mirror class + println("Module class") + printInner("p1.p2.Singleton$") + + nprintln("An outer class has a InnerClass attribute for direct nested classes") + printInner("A1") + println("A nested class has an InnerClass attribute for itself (and also for its nested classes)") + printInner("A1$B1") + println("C1 is a nested class, so it has an InnerClass attribute for itself.\n"+ + "Because that attribute leads to an entry for B1 in the constant pool, C1 needs an InnerClass attribute for B1.") + printInner("A1$B1$C1") + + nprintln("The BeanInfo class has the same InnerClass attributes as the corresponding bean") + printInner("A1$B1$C1BeanInfo") + + nprintln("Class A2 mentions class C2 in the constant pool (due to method f), therefore it needs an InnerClass attribute for C1") + printInner("A2") + println("B2") + printInner("A2$B2") + println("C2") + printInner("A2$B2$C2") + } } diff --git a/test/pending/run/t8582-bcode.check b/test/pending/run/t8582-bcode.check deleted file mode 100644 index 7e96756986..0000000000 --- a/test/pending/run/t8582-bcode.check +++ /dev/null @@ -1,2 +0,0 @@ -class p1.p2.Singleton$Singleton$ -List(class p1.p2.Singleton$Singleton$Singleton$) diff --git a/test/pending/run/t8582-bcode.flags b/test/pending/run/t8582-bcode.flags deleted file mode 100644 index c30091d3de..0000000000 --- a/test/pending/run/t8582-bcode.flags +++ /dev/null @@ -1 +0,0 @@ --Ybackend:GenBCode diff --git a/test/pending/run/t8582-bcode.scala b/test/pending/run/t8582-bcode.scala deleted file mode 100644 index 844ab8ac14..0000000000 --- a/test/pending/run/t8582-bcode.scala +++ /dev/null @@ -1,16 +0,0 @@ -package p1 { - package p2 { - object Singleton { - object Singleton { - object Singleton - } - } - } -} - - -object Test extends App { - import p1.p2._ - println(Singleton.Singleton.getClass) - println(Singleton.Singleton.getClass.getDeclaredClasses.toList) -} |