Bug 571905 - [16] record - annotation not generated in .class file for
constructor and accessor
Change-Id: Ia141d61e2ede5941b7c952426ebd3112e592a156
Signed-off-by: Manoj Palat <manpalat@in.ibm.com>
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordsRestrictedClassTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordsRestrictedClassTest.java
index 99d4c58..5048179 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordsRestrictedClassTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordsRestrictedClassTest.java
@@ -33,7 +33,7 @@
static {
// TESTS_NUMBERS = new int [] { 40 };
// TESTS_RANGE = new int[] { 1, -1 };
-// TESTS_NAMES = new String[] { "testBug571765_001"};
+// TESTS_NAMES = new String[] { "testBug571905"};
}
public static Class<?> testClass() {
@@ -8511,4 +8511,108 @@
"Syntax error on token \"record\", record expected\n" +
"----------\n");
}
+public void testBug571905_01() throws Exception {
+ runConformTest(
+ new String[] {
+ "X.java",
+ "import java.lang.annotation.*;\n" +
+ "record X( int @MyAnnot [] j) {\n" +
+ " public static void main(String[] args) {\n" +
+ " System.out.println(\"helo\");\n" +
+ " }\n" +
+ "}\n" +
+ "@Target({ElementType.TYPE_USE})\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface MyAnnot {}\n"
+ },
+ "helo");
+ String expectedOutput = // constructor
+ " \n" +
+ " // Method descriptor #10 ([I)V\n" +
+ " // Stack: 2, Locals: 2\n" +
+ " X(int[] j);\n" +
+ " 0 aload_0 [this]\n" +
+ " 1 invokespecial java.lang.Record() [12]\n" +
+ " 4 aload_0 [this]\n" +
+ " 5 aload_1 [j]\n" +
+ " 6 putfield X.j : int[] [15]\n" +
+ " 9 return\n" +
+ " Line numbers:\n" +
+ " [pc: 0, line: 2]\n" +
+ " Local variable table:\n" +
+ " [pc: 0, pc: 10] local: this index: 0 type: X\n" +
+ " [pc: 0, pc: 10] local: j index: 1 type: int[]\n" +
+ " Method Parameters:\n" +
+ " j\n" +
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #8 @MyAnnot(\n" +
+ " target type = 0x16 METHOD_FORMAL_PARAMETER\n" +
+ " method parameter index = 0\n" +
+ " )\n";
+ RecordsRestrictedClassTest.verifyClassFile(expectedOutput, "X.class", ClassFileBytesDisassembler.SYSTEM);
+ expectedOutput = // accessor
+ " public int[] j();\n" +
+ " 0 aload_0 [this]\n" +
+ " 1 getfield X.j : int[] [15]\n" +
+ " 4 areturn\n" +
+ " Line numbers:\n" +
+ " [pc: 0, line: 2]\n" +
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #8 @MyAnnot(\n" +
+ " target type = 0x14 METHOD_RETURN\n" +
+ " )\n" ;
+ RecordsRestrictedClassTest.verifyClassFile(expectedOutput, "X.class", ClassFileBytesDisassembler.SYSTEM);
+}
+public void testBug571905_02() throws Exception {
+ runConformTest(
+ new String[] {
+ "X.java",
+ "import java.lang.annotation.*;\n" +
+ "record X( int @MyAnnot ... j) {\n" +
+ " public static void main(String[] args) {\n" +
+ " System.out.println(\"helo\");\n" +
+ " }\n" +
+ "}\n" +
+ "@Target({ElementType.TYPE_USE})\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface MyAnnot {}\n"
+ },
+ "helo");
+ String expectedOutput = // constructor
+ " \n" +
+ " // Method descriptor #10 ([I)V\n" +
+ " // Stack: 2, Locals: 2\n" +
+ " X(int... j);\n" +
+ " 0 aload_0 [this]\n" +
+ " 1 invokespecial java.lang.Record() [12]\n" +
+ " 4 aload_0 [this]\n" +
+ " 5 aload_1 [j]\n" +
+ " 6 putfield X.j : int[] [15]\n" +
+ " 9 return\n" +
+ " Line numbers:\n" +
+ " [pc: 0, line: 2]\n" +
+ " Local variable table:\n" +
+ " [pc: 0, pc: 10] local: this index: 0 type: X\n" +
+ " [pc: 0, pc: 10] local: j index: 1 type: int[]\n" +
+ " Method Parameters:\n" +
+ " j\n" +
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #8 @MyAnnot(\n" +
+ " target type = 0x16 METHOD_FORMAL_PARAMETER\n" +
+ " method parameter index = 0\n" +
+ " )\n";
+ RecordsRestrictedClassTest.verifyClassFile(expectedOutput, "X.class", ClassFileBytesDisassembler.SYSTEM);
+ expectedOutput = // accessor
+ " public int[] j();\n" +
+ " 0 aload_0 [this]\n" +
+ " 1 getfield X.j : int[] [15]\n" +
+ " 4 areturn\n" +
+ " Line numbers:\n" +
+ " [pc: 0, line: 2]\n" +
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #8 @MyAnnot(\n" +
+ " target type = 0x14 METHOD_RETURN\n" +
+ " )\n" ;
+ RecordsRestrictedClassTest.verifyClassFile(expectedOutput, "X.class", ClassFileBytesDisassembler.SYSTEM);
+}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
index 502b6a7..a472ab8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
@@ -4124,16 +4124,21 @@
if (annotations != null) {
assert !methodBinding.isConstructor();
attributesNumber += generateRuntimeAnnotations(annotations, TagBits.AnnotationForMethod);
- // Now type annotations
- Supplier<List<AnnotationContext>> collector = () -> {
- List<AnnotationContext> allTypeAnnotationContexts = new ArrayList<>();
+ }
+ if ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0) {
+ List<AnnotationContext> allTypeAnnotationContexts = new ArrayList<>();
+ if (annotations != null && (comp.bits & ASTNode.HasTypeAnnotations) != 0) {
comp.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_RETURN, allTypeAnnotationContexts);
- return allTypeAnnotationContexts;
- };
+ }
+ TypeReference compType = comp.type;
+ if (compType != null && ((compType.bits & ASTNode.HasTypeAnnotations) != 0)) {
+ compType.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_RETURN, allTypeAnnotationContexts);
+ }
+ int size = allTypeAnnotationContexts.size();
attributesNumber = completeRuntimeTypeAnnotations(attributesNumber,
- comp,
- (node) -> (comp.bits & ASTNode.HasTypeAnnotations) != 0,
- collector);
+ null,
+ (node) -> size > 0,
+ () -> allTypeAnnotationContexts);
}
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
index 124ccb2..91a6287 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
@@ -367,6 +367,12 @@
// constructor.modifiers |= ClassFileConstants.AccPublic; // JLS 14 8.10.5
constructor.arguments = getArgumentsFromComponents(this.recordComponents);
+ for (int i = 0, max = constructor.arguments.length; i < max; i++) {
+ if ((constructor.arguments[i].bits & ASTNode.HasTypeAnnotations) != 0) {
+ constructor.bits |= ASTNode.HasTypeAnnotations;
+ break;
+ }
+ }
constructor.declarationSourceStart = constructor.sourceStart =
constructor.bodyStart = this.sourceStart;
constructor.declarationSourceEnd =