summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@gmail.com>2015-02-02 15:37:24 +0100
committerLukas Rytz <lukas.rytz@gmail.com>2015-02-07 07:45:51 +0100
commitcd8f2f327106c7e2944afa7ac8b7675262626c1e (patch)
treec4d820e34fd0a975655d7b30f0975e30fe990fdd /test
parent1437aa88241d5e99900a86b25c6ce385c2708570 (diff)
downloadscala-cd8f2f327106c7e2944afa7ac8b7675262626c1e.tar.gz
scala-cd8f2f327106c7e2944afa7ac8b7675262626c1e.tar.bz2
scala-cd8f2f327106c7e2944afa7ac8b7675262626c1e.zip
Fix InnerClass/EnclosingMethod for trait impl and specialized classes
Trait implementation classes and specialized classes are always considered top-level in terms of the InnerClass / EnclosingMethod attributes. These attributes describe source-level properties, and such classes are a compilation artifact. Note that the same is true for delambdafy:method closure classes (they are always top-level).
Diffstat (limited to 'test')
-rw-r--r--test/files/jvm/innerClassAttribute/Classes_1.scala37
-rw-r--r--test/files/jvm/innerClassAttribute/Test.scala89
2 files changed, 124 insertions, 2 deletions
diff --git a/test/files/jvm/innerClassAttribute/Classes_1.scala b/test/files/jvm/innerClassAttribute/Classes_1.scala
index 7b5f5d93b9..e58fd6e26f 100644
--- a/test/files/jvm/innerClassAttribute/Classes_1.scala
+++ b/test/files/jvm/innerClassAttribute/Classes_1.scala
@@ -240,3 +240,40 @@ trait SI_9124 {
val f1 = { new A { def f5 = 0 }; 1 } // encl class SI_9124, no encl meth
private val f2 = { new A { def f6 = 0 }; 1 } // like above
}
+
+trait ImplClassesAreTopLevel {
+ // all impl classes are top-level, so they don't appear in any InnerClass entry, and none of them have an EnclosingMethod attr
+ trait B1 { def f = 1 }
+ { trait B2 { def f = 1 }; new B2 {} }
+ val m = {
+ trait B3 { def f = 1 }
+ new B3 {}
+ }
+ def n = {
+ trait B4 { def f = 1 }
+ new B4 {}
+ }
+}
+
+class SpecializedClassesAreTopLevel {
+ // all specialized classes are top-level
+ class A[@specialized(Int) T]; new A[Int]
+
+ object T {
+ class B[@specialized(Int) T]; new B[Int]
+ }
+
+ // these crash the compiler, SI-7625
+
+ // { class B[@specialized(Int) T]; new B[Int] }
+
+ // val m: Object = {
+ // class C[@specialized(Int) T]
+ // new C[Int]
+ // }
+
+ // def n: Object = {
+ // class D[@specialized(Int) T]
+ // new D[Int]
+ // }
+}
diff --git a/test/files/jvm/innerClassAttribute/Test.scala b/test/files/jvm/innerClassAttribute/Test.scala
index 5dacd2d830..16e5d40052 100644
--- a/test/files/jvm/innerClassAttribute/Test.scala
+++ b/test/files/jvm/innerClassAttribute/Test.scala
@@ -18,6 +18,14 @@ object Test extends BytecodeTest {
def ownInnerClassNode(n: String) = innerClassNodes(n).filter(_.name == n).head
+ def testInner(cls: String, fs: (InnerClassNode => Unit)*) = {
+ val ns = innerClassNodes(cls)
+ assert(ns.length == fs.length, ns)
+ (ns zip fs.toList) foreach { case (n, f) => f(n) }
+ }
+
+
+
final case class EnclosingMethod(name: String, descriptor: String, outerClass: String)
def enclosingMethod(className: String) = {
val n = loadClassNode(className)
@@ -318,12 +326,11 @@ object Test extends BytecodeTest {
}
def testA24() {
- val List(defsCls, abs, conc, defsApi, defsApiImpl) = innerClassNodes("A24$DefinitionsClass")
+ val List(defsCls, abs, conc, defsApi) = innerClassNodes("A24$DefinitionsClass")
assertMember(defsCls, "A24", "DefinitionsClass")
assertMember(abs, "A24$DefinitionsClass", "Abs$")
assertMember(conc, "A24$DefinitionsClass", "Conc$")
assertMember(defsApi, "A24Base", "DefinitionsApi", flags = publicAbstractInterface)
- assertMember(defsApiImpl, "A24Base", "DefinitionsApi$class", flags = Flags.ACC_PUBLIC | Flags.ACC_ABSTRACT)
}
def testSI_9105() {
@@ -423,6 +430,82 @@ object Test extends BytecodeTest {
assertMember(ownInnerClassNode("SI_9124$O$"), "SI_9124", "O$")
}
+ def testImplClassesTopLevel() {
+ val classes = List(
+ "ImplClassesAreTopLevel$$anon$14",
+ "ImplClassesAreTopLevel$$anon$15",
+ "ImplClassesAreTopLevel$$anon$16",
+ "ImplClassesAreTopLevel$B1$class",
+ "ImplClassesAreTopLevel$B1",
+ "ImplClassesAreTopLevel$B2$1$class",
+ "ImplClassesAreTopLevel$B2$1",
+ "ImplClassesAreTopLevel$B3$1$class",
+ "ImplClassesAreTopLevel$B3$1",
+ "ImplClassesAreTopLevel$B4$class",
+ "ImplClassesAreTopLevel$B4$1",
+ "ImplClassesAreTopLevel$class",
+ "ImplClassesAreTopLevel")
+
+ classes.filter(_.endsWith("$class")).foreach(assertNoEnclosingMethod)
+ classes.flatMap(innerClassNodes).foreach(icn => assert(!icn.name.endsWith("$class"), icn))
+
+ assertNoEnclosingMethod("ImplClassesAreTopLevel$B1") // member, no encl meth attr
+
+ // no encl meth, but encl class
+ List("ImplClassesAreTopLevel$B2$1", "ImplClassesAreTopLevel$B3$1",
+ "ImplClassesAreTopLevel$$anon$14", "ImplClassesAreTopLevel$$anon$15").foreach(assertEnclosingMethod(_, "ImplClassesAreTopLevel", null, null))
+
+ // encl meth n
+ List("ImplClassesAreTopLevel$B4$1", "ImplClassesAreTopLevel$$anon$16").foreach(assertEnclosingMethod(_, "ImplClassesAreTopLevel", "n", "()Ljava/lang/Object;"))
+
+ val an14 = assertAnonymous(_: InnerClassNode, "ImplClassesAreTopLevel$$anon$14")
+ val an15 = assertAnonymous(_: InnerClassNode, "ImplClassesAreTopLevel$$anon$15")
+ val an16 = assertAnonymous(_: InnerClassNode, "ImplClassesAreTopLevel$$anon$16")
+ val b1 = assertMember(_: InnerClassNode, "ImplClassesAreTopLevel", "B1", flags = publicAbstractInterface)
+ val b2 = assertLocal(_ : InnerClassNode, "ImplClassesAreTopLevel$B2$1", "B2$1", flags = publicAbstractInterface)
+ val b3 = assertLocal(_ : InnerClassNode, "ImplClassesAreTopLevel$B3$1", "B3$1", flags = publicAbstractInterface)
+ val b4 = assertLocal(_ : InnerClassNode, "ImplClassesAreTopLevel$B4$1", "B4$1", flags = publicAbstractInterface)
+
+ testInner("ImplClassesAreTopLevel$$anon$14", an14, b3)
+ testInner("ImplClassesAreTopLevel$$anon$15", an15, b2)
+ testInner("ImplClassesAreTopLevel$$anon$16", an16, b4)
+
+ testInner("ImplClassesAreTopLevel$B1$class", b1)
+ testInner("ImplClassesAreTopLevel$B2$1$class", b2)
+ testInner("ImplClassesAreTopLevel$B3$1$class", b3)
+ testInner("ImplClassesAreTopLevel$B4$class", b4)
+
+ testInner("ImplClassesAreTopLevel$B1", b1)
+ testInner("ImplClassesAreTopLevel$B2$1", b2)
+ testInner("ImplClassesAreTopLevel$B3$1", b3)
+ testInner("ImplClassesAreTopLevel$B4$1", b4)
+
+ testInner("ImplClassesAreTopLevel$class", an14, an15, an16)
+ testInner("ImplClassesAreTopLevel", an14, an15, an16, b1, b2, b3, b4)
+ }
+
+ def testSpecializedClassesTopLevel() {
+ val cls = List(
+ "SpecializedClassesAreTopLevel$A$mcI$sp",
+ "SpecializedClassesAreTopLevel$A",
+ "SpecializedClassesAreTopLevel$T$",
+ "SpecializedClassesAreTopLevel$T$B$mcI$sp",
+ "SpecializedClassesAreTopLevel$T$B",
+ "SpecializedClassesAreTopLevel")
+
+ // all classes are members, no local (can't test local, they crash in specialize)
+ cls.foreach(assertNoEnclosingMethod)
+ cls.flatMap(innerClassNodes).foreach(icn => assert(!icn.name.endsWith("$sp"), icn))
+
+ val a = assertMember(_: InnerClassNode, "SpecializedClassesAreTopLevel", "A")
+ val t = assertMember(_: InnerClassNode, "SpecializedClassesAreTopLevel", "T$")
+ val b = assertMember(_: InnerClassNode, "SpecializedClassesAreTopLevel$T$", "B", Some("SpecializedClassesAreTopLevel$T$B"))
+
+ List("SpecializedClassesAreTopLevel$A$mcI$sp", "SpecializedClassesAreTopLevel$A").foreach(testInner(_, a))
+ testInner("SpecializedClassesAreTopLevel", a, t)
+ List("SpecializedClassesAreTopLevel$T$", "SpecializedClassesAreTopLevel$T$B$mcI$sp", "SpecializedClassesAreTopLevel$T$B").foreach(testInner(_, t, b))
+ }
+
def show(): Unit = {
testA1()
testA2()
@@ -448,5 +531,7 @@ object Test extends BytecodeTest {
testA24()
testSI_9105()
testSI_9124()
+ testImplClassesTopLevel()
+ testSpecializedClassesTopLevel()
}
}