diff options
author | Lukas Rytz <lukas.rytz@gmail.com> | 2015-06-19 20:28:40 +0200 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@gmail.com> | 2015-06-19 21:07:39 +0200 |
commit | 63812c18b23de60039fd3267e4806449ea679972 (patch) | |
tree | 9071968f72064df97f565f31cd9364b84324c1f5 /test/files | |
parent | 305dd96c08041e9fa096cd56dfc4de80284e6fba (diff) | |
download | scala-63812c18b23de60039fd3267e4806449ea679972.tar.gz scala-63812c18b23de60039fd3267e4806449ea679972.tar.bz2 scala-63812c18b23de60039fd3267e4806449ea679972.zip |
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).
Diffstat (limited to 'test/files')
-rw-r--r-- | test/files/run/t9359.check | 18 | ||||
-rw-r--r-- | test/files/run/t9359/A_1.java | 19 | ||||
-rw-r--r-- | test/files/run/t9359/B_2.java | 19 | ||||
-rw-r--r-- | test/files/run/t9359/Test_2.scala | 28 |
4 files changed, 84 insertions, 0 deletions
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)) + } + } +} |