From 63812c18b23de60039fd3267e4806449ea679972 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Fri, 19 Jun 2015 20:28:40 +0200 Subject: SI-9359 Fix InnerClass entry flags for nested Java enums The access flags in InnerClass entries for nested Java enums were basically completely off. A first step is to use the recently introduced backend method `javaClassfileFlags`, which is now moved to BCodeAsmCommon. See its doc for an explanation. Then the flags of the enum class symbol were off. An enum is - final if none of its values has a class body - abstract if it has an abstract method (https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.9) When using the ClassfileParser: - ENUM was never added. I guess that's just an oversight. - ABSTRACT (together with SEALED) was always added. This is to enable exhaustiveness checking, see 3f7b8b5. This is a hack and we have to go through the class members in the backend to find out if the enum actually has the `ACC_ABSTRACT` flag or not. When using the JavaParser: - FINAL was never added. - ABSTRACT was never added. This commit fixes all of the above and tests cases (Java enum read from the classfile and from source). --- test/files/run/t9359.check | 18 ++++++++++++++++++ test/files/run/t9359/A_1.java | 19 +++++++++++++++++++ test/files/run/t9359/B_2.java | 19 +++++++++++++++++++ test/files/run/t9359/Test_2.scala | 28 ++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+) create mode 100644 test/files/run/t9359.check create mode 100644 test/files/run/t9359/A_1.java create mode 100644 test/files/run/t9359/B_2.java create mode 100644 test/files/run/t9359/Test_2.scala (limited to 'test') diff --git a/test/files/run/t9359.check b/test/files/run/t9359.check new file mode 100644 index 0000000000..8dcfe4f60a --- /dev/null +++ b/test/files/run/t9359.check @@ -0,0 +1,18 @@ + // access flags 0x4009 + public static enum INNERCLASS A_1$A1N A_1 A1N + + // access flags 0x4409 + public static abstract enum INNERCLASS A_1$A1N_ABSTRACT A_1 A1N_ABSTRACT + + // access flags 0x4019 + public final static enum INNERCLASS A_1$A1N_FINAL A_1 A1N_FINAL + + // access flags 0x4009 + public static enum INNERCLASS B_2$A1N B_2 A1N + + // access flags 0x4409 + public static abstract enum INNERCLASS B_2$A1N_ABSTRACT B_2 A1N_ABSTRACT + + // access flags 0x4019 + public final static enum INNERCLASS B_2$A1N_FINAL B_2 A1N_FINAL + diff --git a/test/files/run/t9359/A_1.java b/test/files/run/t9359/A_1.java new file mode 100644 index 0000000000..3ac82ed55f --- /dev/null +++ b/test/files/run/t9359/A_1.java @@ -0,0 +1,19 @@ +public class A_1 { + // nested final + public static enum A1N_FINAL { + A1N_FINAL_VAL + } + + // nested, non-final + public enum A1N { + A1N_VAL { } // value has a body, so a class extending A1N is generated + } + + // nested, non-final, abstract + public enum A1N_ABSTRACT { + A1N_ABSTRACT_VAL { + void foo() { return; } + }; + abstract void foo(); // abstract member makes the enum class abstract + } +} diff --git a/test/files/run/t9359/B_2.java b/test/files/run/t9359/B_2.java new file mode 100644 index 0000000000..d824facda9 --- /dev/null +++ b/test/files/run/t9359/B_2.java @@ -0,0 +1,19 @@ +public class B_2 { + // nested final + public enum A1N_FINAL { + A1N_FINAL_VAL + } + + // nested, non-final + public enum A1N { + A1N_VAL { } // value has a body, so a class extending A1N is generated + } + + // nested, non-final, abstract + public enum A1N_ABSTRACT { + A1N_ABSTRACT_VAL { + void foo() { return; } + }; + abstract void foo(); // abstract member makes the enum class abstract + } +} diff --git a/test/files/run/t9359/Test_2.scala b/test/files/run/t9359/Test_2.scala new file mode 100644 index 0000000000..869c51b619 --- /dev/null +++ b/test/files/run/t9359/Test_2.scala @@ -0,0 +1,28 @@ +import scala.tools.partest.BytecodeTest +import scala.tools.asm +import asm.tree.{ClassNode, InnerClassNode} +import asm.{Opcodes => Flags} +import scala.collection.JavaConverters._ + +class C { + def f1: A_1.A1N_FINAL = A_1.A1N_FINAL.A1N_FINAL_VAL + def f2: A_1.A1N = A_1.A1N.A1N_VAL + def f3: A_1.A1N_ABSTRACT = A_1.A1N_ABSTRACT.A1N_ABSTRACT_VAL + + def f4: B_2.A1N_FINAL = B_2.A1N_FINAL.A1N_FINAL_VAL + def f5: B_2.A1N = B_2.A1N.A1N_VAL + def f6: B_2.A1N_ABSTRACT = B_2.A1N_ABSTRACT.A1N_ABSTRACT_VAL +} + +object Test extends BytecodeTest { + def tost(n: InnerClassNode) = { + val t = new asm.util.Textifier + t.visitInnerClass(n.name, n.outerName, n.innerName, n.access) + t.getText.get(0); + } + def show(): Unit = { + for (n <- loadClassNode("C").innerClasses.asScala.toList.sortBy(_.name)) { + println(tost(n)) + } + } +} -- cgit v1.2.3 From 958e6259baf0ea303f6cee468be35b18107ffd41 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Sat, 20 Jun 2015 08:44:57 +0200 Subject: Fix spurious test failure under -Ybackend:GenBCode --- test/files/run/t7582.check | 5 ----- test/files/run/t7582/InlineHolder.scala | 3 +++ test/files/run/t7582b.check | 5 ----- test/files/run/t7582b/InlineHolder.scala | 3 +++ 4 files changed, 6 insertions(+), 10 deletions(-) (limited to 'test') diff --git a/test/files/run/t7582.check b/test/files/run/t7582.check index 2a11210000..0cfbf08886 100644 --- a/test/files/run/t7582.check +++ b/test/files/run/t7582.check @@ -1,6 +1 @@ -#partest !-Ybackend:GenBCode -warning: there was one inliner warning; re-run with -Yinline-warnings for details -#partest -Ybackend:GenBCode -warning: there was one inliner warning; re-run with -Yopt-warnings for details -#partest 2 diff --git a/test/files/run/t7582/InlineHolder.scala b/test/files/run/t7582/InlineHolder.scala index a18b9effaa..3cbf233ce1 100644 --- a/test/files/run/t7582/InlineHolder.scala +++ b/test/files/run/t7582/InlineHolder.scala @@ -1,3 +1,6 @@ +/* + * filter: inliner warning; re-run with + */ package p1 { object InlineHolder { @inline def inlinable = p1.PackageProtectedJava.protectedMethod() + 1 diff --git a/test/files/run/t7582b.check b/test/files/run/t7582b.check index 2a11210000..0cfbf08886 100644 --- a/test/files/run/t7582b.check +++ b/test/files/run/t7582b.check @@ -1,6 +1 @@ -#partest !-Ybackend:GenBCode -warning: there was one inliner warning; re-run with -Yinline-warnings for details -#partest -Ybackend:GenBCode -warning: there was one inliner warning; re-run with -Yopt-warnings for details -#partest 2 diff --git a/test/files/run/t7582b/InlineHolder.scala b/test/files/run/t7582b/InlineHolder.scala index a18b9effaa..3cbf233ce1 100644 --- a/test/files/run/t7582b/InlineHolder.scala +++ b/test/files/run/t7582b/InlineHolder.scala @@ -1,3 +1,6 @@ +/* + * filter: inliner warning; re-run with + */ package p1 { object InlineHolder { @inline def inlinable = p1.PackageProtectedJava.protectedMethod() + 1 -- cgit v1.2.3