From d430b03bc11c8fb279d9601fd33f5ac3ab48ed80 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Tue, 13 May 2014 15:13:39 +0200 Subject: Fix BeanInfo generation for GenBCode --- test/files/jvm/beanInfo.check | 6 ++++++ test/files/jvm/beanInfo/C_1.scala | 9 +++++++++ test/files/jvm/beanInfo/Test_2.scala | 17 +++++++++++++++++ 3 files changed, 32 insertions(+) create mode 100644 test/files/jvm/beanInfo.check create mode 100644 test/files/jvm/beanInfo/C_1.scala create mode 100644 test/files/jvm/beanInfo/Test_2.scala (limited to 'test') diff --git a/test/files/jvm/beanInfo.check b/test/files/jvm/beanInfo.check new file mode 100644 index 0000000000..d74e127711 --- /dev/null +++ b/test/files/jvm/beanInfo.check @@ -0,0 +1,6 @@ +property descriptors +x -- int -- public int p.C.x() -- null +y -- class java.lang.String -- public java.lang.String p.C.y() -- public void p.C.y_$eq(java.lang.String) +z -- class scala.collection.immutable.List -- public scala.collection.immutable.List p.C.z() -- public void p.C.z_$eq(scala.collection.immutable.List) +method descriptors +f -- public p.C p.C.f() diff --git a/test/files/jvm/beanInfo/C_1.scala b/test/files/jvm/beanInfo/C_1.scala new file mode 100644 index 0000000000..a338abea1d --- /dev/null +++ b/test/files/jvm/beanInfo/C_1.scala @@ -0,0 +1,9 @@ +package p + +@scala.beans.BeanInfo +class C { + val x: Int = 0 + var y: String = "" + var z: List[_] = Nil + def f: C = ??? +} diff --git a/test/files/jvm/beanInfo/Test_2.scala b/test/files/jvm/beanInfo/Test_2.scala new file mode 100644 index 0000000000..fa9b6e1391 --- /dev/null +++ b/test/files/jvm/beanInfo/Test_2.scala @@ -0,0 +1,17 @@ +object Test extends App { + val info = java.beans.Introspector.getBeanInfo(classOf[p.C]) + + println("property descriptors") + + val pds = info.getPropertyDescriptors + for (pd <- pds) { + println(s"${pd.getName} -- ${pd.getPropertyType} -- ${pd.getReadMethod} -- ${pd.getWriteMethod}") + } + + println("method descriptors") + + val mds = info.getMethodDescriptors + for (md <- mds) { + println(s"${md.getName} -- ${md.getMethod}") + } +} -- cgit v1.2.3 From e948073ae22167082ee672d8ac21507f7b3fa9f7 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Tue, 13 May 2014 12:31:26 +0200 Subject: 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 --- .../tools/nsc/backend/jvm/BCodeSkelBuilder.scala | 3 +- test/files/run/t8582.check | 46 +++++++++++++- test/files/run/t8582.scala | 71 +++++++++++++++++++++- test/pending/run/t8582-bcode.check | 2 - test/pending/run/t8582-bcode.flags | 1 - test/pending/run/t8582-bcode.scala | 16 ----- 6 files changed, 114 insertions(+), 25 deletions(-) delete mode 100644 test/pending/run/t8582-bcode.check delete mode 100644 test/pending/run/t8582-bcode.flags delete mode 100644 test/pending/run/t8582-bcode.scala (limited to 'test') 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) -} -- cgit v1.2.3 From fa2204e1749b21aa838350f321d5d85644be4ecf Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Tue, 13 May 2014 17:39:46 +0200 Subject: Move t8582 to test/files/jvm --- test/files/jvm/t8582.check | 44 +++++++++++++++++++++++++ test/files/jvm/t8582.scala | 81 ++++++++++++++++++++++++++++++++++++++++++++++ test/files/run/t8582.check | 44 ------------------------- test/files/run/t8582.scala | 81 ---------------------------------------------- 4 files changed, 125 insertions(+), 125 deletions(-) create mode 100644 test/files/jvm/t8582.check create mode 100644 test/files/jvm/t8582.scala delete mode 100644 test/files/run/t8582.check delete mode 100644 test/files/run/t8582.scala (limited to 'test') diff --git a/test/files/jvm/t8582.check b/test/files/jvm/t8582.check new file mode 100644 index 0000000000..564f482ff8 --- /dev/null +++ b/test/files/jvm/t8582.check @@ -0,0 +1,44 @@ +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/jvm/t8582.scala b/test/files/jvm/t8582.scala new file mode 100644 index 0000000000..8a57ef7952 --- /dev/null +++ b/test/files/jvm/t8582.scala @@ -0,0 +1,81 @@ +import scala.tools.partest.BytecodeTest +import scala.collection.JavaConverters._ + +package p1 { + package p2 { + object Singleton { + object Singleton { + object Singleton + } + } + } +} + +class A1 { + class B1 { + @scala.beans.BeanInfo + class C1 + } +} + +class A2 { + class B2 { + class C2 + } + def f: B2#C2 = null +} + + +object Test extends BytecodeTest { + import p1.p2._ + + 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/files/run/t8582.check b/test/files/run/t8582.check deleted file mode 100644 index 564f482ff8..0000000000 --- a/test/files/run/t8582.check +++ /dev/null @@ -1,44 +0,0 @@ -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 deleted file mode 100644 index 8a57ef7952..0000000000 --- a/test/files/run/t8582.scala +++ /dev/null @@ -1,81 +0,0 @@ -import scala.tools.partest.BytecodeTest -import scala.collection.JavaConverters._ - -package p1 { - package p2 { - object Singleton { - object Singleton { - object Singleton - } - } - } -} - -class A1 { - class B1 { - @scala.beans.BeanInfo - class C1 - } -} - -class A2 { - class B2 { - class C2 - } - def f: B2#C2 = null -} - - -object Test extends BytecodeTest { - import p1.p2._ - - 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") - } -} -- cgit v1.2.3