summaryrefslogtreecommitdiff
path: root/test/files/run/t8582.scala
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@gmail.com>2014-05-13 12:31:26 +0200
committerLukas Rytz <lukas.rytz@gmail.com>2014-05-13 17:40:45 +0200
commite948073ae22167082ee672d8ac21507f7b3fa9f7 (patch)
tree6d1f9c6ef2888203b846cdb9a206483f5d02648f /test/files/run/t8582.scala
parentd430b03bc11c8fb279d9601fd33f5ac3ab48ed80 (diff)
downloadscala-e948073ae22167082ee672d8ac21507f7b3fa9f7.tar.gz
scala-e948073ae22167082ee672d8ac21507f7b3fa9f7.tar.bz2
scala-e948073ae22167082ee672d8ac21507f7b3fa9f7.zip
SI-8582 emit InnerClasses attribute in GenBCode
I removed the `-bcode` test since we have a build that passes `-Ybackend:GenBCode` to all tests. Short intro do the [`InnerClass` attribute][1]: - A class needs one `InnerClass` attribute for each of its nested classes - A class needs the `InnerClass` attribute for all (nested) classes that are mentioned in its constant pool The attribute for a nested class `A$B$C` consists of the long name of the outer class `A$B`, the short name of the inner class `C`, and an access flag set describig the visibility. The attribute seems to be used for reflection. [1]: http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.6
Diffstat (limited to 'test/files/run/t8582.scala')
-rw-r--r--test/files/run/t8582.scala71
1 files changed, 68 insertions, 3 deletions
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")
+ }
}