Bug 571082 - [16] Implicit canonical constructor bindings don't get the
annotations from record declaration
Change-Id: I827731874f89e75296d238aa3cdbf3c0904c90a3
Signed-off-by: Jay Arthanareeswaran <jarthana@in.ibm.com>
diff --git a/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar b/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar
index 6015cd8..2484202 100644
--- a/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar
+++ b/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar
Binary files differ
diff --git a/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/RecordElementProcessor.java b/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/RecordElementProcessor.java
index 7b70533..6a86926 100644
--- a/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/RecordElementProcessor.java
+++ b/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/RecordElementProcessor.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2020 IBM Corporation.
+ * Copyright (c) 2020, 2021 IBM Corporation.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
*
* SPDX-License-Identifier: EPL-2.0
*
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
@@ -128,6 +132,10 @@
testRecords4();
testRecords5();
testRecords6();
+ testRecords7();
+ testRecords8();
+ testRecords9();
+ testRecords10();
}
public void testPreviewFlagTrue() throws IOException {
@@ -521,45 +529,68 @@
assertTrue("Test returned negative", result);
}
public void testRecords9() {
- String[] arr1 = new String[] { "x", "bigInt", "r1", "floatValue", "c", "recordInstance" };
- TypeKind[] arr2 = new TypeKind[] { TypeKind.INT, TypeKind.DECLARED, TypeKind.DECLARED, TypeKind.FLOAT,
- TypeKind.DECLARED, TypeKind.DECLARED };
- List<String> names = Arrays.asList(arr1);
- List<TypeKind> types = Arrays.asList(arr2);
+ String[] arr1 = new String[] { "x", "bigInt", "r1", "floatValue", "c", "recordInstance" };
+ TypeKind[] arr2 = new TypeKind[] { TypeKind.INT, TypeKind.DECLARED, TypeKind.DECLARED, TypeKind.FLOAT,
+ TypeKind.DECLARED, TypeKind.DECLARED };
+ List<String> names = Arrays.asList(arr1);
+ List<TypeKind> types = Arrays.asList(arr2);
- Element record = _elementUtils.getTypeElement("records.R3");
- List<? extends Element> allElements = record.getEnclosedElements();
- List<RecordComponentElement> components = ElementFilter.recordComponentsIn(allElements);
- List<ExecutableElement> accessors = components.stream().map
- (RecordComponentElement::getAccessor).collect(Collectors.toList());
- assertEquals("Size mismatch", names.size(), accessors.size());
- for (ExecutableElement accessor : accessors) {
- String name = accessor.getSimpleName().toString();
- int indexOf = names.indexOf(name);
- assertSame("Type kind not same for \"" + name + "\".", types.get(indexOf), accessor.getReturnType().getKind());
- assertTrue("should be executable type for \"" + name + "\".", (accessor.asType() instanceof ExecutableType));
- assertNull("should be null", accessor.getDefaultValue());
- List<? extends AnnotationMirror> mirrors = accessor.getAnnotationMirrors();
- if (name.equals("c") || name.equals("bigInt") || name.equals("r1")) {
- assertEquals("annotations count mismatch for \"" + name + "\".", 1, mirrors.size());
- Set<? extends ExecutableElement> accessorAnnotations = mirrors.get(0)
- .getElementValues().keySet();
- assertEquals("annotations type element mismatch for \"" + name + "\".", 1, accessorAnnotations.size());
- int val = (int) accessorAnnotations.toArray(new ExecutableElement[0])[0].getDefaultValue()
- .getValue();
- assertEquals("Incorrect default value for \"" + name + "\".", 1, val);
- }
- if (name.equals("floatValue") || name.equals("x")) {
- assertEquals("annotations count mismatch for \"" + name + "\".", 0, mirrors.size());
- }
- if (name.equals("recordInstance")) {
- assertEquals("annotations count mismatch for \"" + name + "\".", 2, mirrors.size());
- }
- assertTrue("Parameters should be empty for \"" + name + "\".", accessor.getParameters().isEmpty());
- assertTrue("Thrown types should be empty for \"" + name + "\".", accessor.getThrownTypes().isEmpty());
- assertTrue("Type parameters should be empty for \"" + name + "\".", accessor.getTypeParameters().isEmpty());
- assertFalse("Should not be default for \"" + name + "\".", accessor.isDefault());
- assertFalse("Should not be varargs for \"" + name + "\".", accessor.isVarArgs());
- }
+ Element record = _elementUtils.getTypeElement("records.R3");
+ List<? extends Element> allElements = record.getEnclosedElements();
+ List<RecordComponentElement> components = ElementFilter.recordComponentsIn(allElements);
+ List<ExecutableElement> accessors = components.stream().map
+ (RecordComponentElement::getAccessor).collect(Collectors.toList());
+ assertEquals("Size mismatch", names.size(), accessors.size());
+ for (ExecutableElement accessor : accessors) {
+ String name = accessor.getSimpleName().toString();
+ int indexOf = names.indexOf(name);
+ assertSame("Type kind not same for \"" + name + "\".", types.get(indexOf), accessor.getReturnType().getKind());
+ assertTrue("should be executable type for \"" + name + "\".", (accessor.asType() instanceof ExecutableType));
+ assertNull("should be null", accessor.getDefaultValue());
+ List<? extends AnnotationMirror> mirrors = accessor.getAnnotationMirrors();
+ if (name.equals("c") || name.equals("bigInt") || name.equals("r1")) {
+ assertEquals("annotations count mismatch for \"" + name + "\".", 1, mirrors.size());
+ Set<? extends ExecutableElement> accessorAnnotations = mirrors.get(0)
+ .getElementValues().keySet();
+ assertEquals("annotations type element mismatch for \"" + name + "\".", 1, accessorAnnotations.size());
+ int val = (int) accessorAnnotations.toArray(new ExecutableElement[0])[0].getDefaultValue()
+ .getValue();
+ assertEquals("Incorrect default value for \"" + name + "\".", 1, val);
+ }
+ if (name.equals("floatValue") || name.equals("x")) {
+ assertEquals("annotations count mismatch for \"" + name + "\".", 0, mirrors.size());
+ }
+ if (name.equals("recordInstance")) {
+ assertEquals("annotations count mismatch for \"" + name + "\".", 2, mirrors.size());
+ }
+ assertTrue("Parameters should be empty for \"" + name + "\".", accessor.getParameters().isEmpty());
+ assertTrue("Thrown types should be empty for \"" + name + "\".", accessor.getThrownTypes().isEmpty());
+ assertTrue("Type parameters should be empty for \"" + name + "\".", accessor.getTypeParameters().isEmpty());
+ assertFalse("Should not be default for \"" + name + "\".", accessor.isDefault());
+ assertFalse("Should not be varargs for \"" + name + "\".", accessor.isVarArgs());
+ }
+ }
+ public void testRecords10() {
+ Set<? extends Element> elements = roundEnv.getRootElements();
+ TypeElement record = null;
+ for (Element element : elements) {
+ if ("R4".equals(element.getSimpleName().toString())) {
+ record = (TypeElement) element;
+ }
+ }
+ assertNotNull("TypeElement for record should not be null", record);
+
+ List<? extends Element> enclosedElements = record.getEnclosedElements();
+ List<ExecutableElement> methodsIn = ElementFilter.constructorsIn(enclosedElements);
+ assertEquals("incorrect method", 1, methodsIn.size());
+ ExecutableElement m = methodsIn.get(0);
+ verifyAnnotations(m, new String[]{});
+ TypeMirror asType = m.asType();
+ verifyAnnotations(asType, new String[]{});
+ List<? extends VariableElement> parameters = m.getParameters();
+ assertEquals("incorrect parameters", 1, parameters.size());
+ VariableElement var = parameters.get(0);
+ assertEquals("component name incorrect", "i", var.getSimpleName().toString());
+ verifyAnnotations(var, new String[]{"@Marker4()"});
}
}
diff --git a/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/records/mod.records/records/R4.java b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/records/mod.records/records/R4.java
new file mode 100644
index 0000000..7c500dd
--- /dev/null
+++ b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/records/mod.records/records/R4.java
@@ -0,0 +1,12 @@
+package records;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+record R4(@Marker4 int... i) {}
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE_USE, ElementType.PARAMETER})
+@interface Marker4 {}
diff --git a/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/RecordElementsTests.java b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/RecordElementsTests.java
index 1d58418..bd8a10f 100644
--- a/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/RecordElementsTests.java
+++ b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/RecordElementsTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2020 IBM Corporation.
+ * Copyright (c) 2020, 2021 IBM Corporation.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
*
* SPDX-License-Identifier: EPL-2.0
*
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
@@ -32,108 +36,116 @@
public void testPreviewFlagTrue() throws IOException {
JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
- internalTestWithPreview(compiler, MODULE_PROC, "15", "testPreviewFlagTrue", null, "records", true);
+ internalTestWithPreview(compiler, MODULE_PROC, "16", "testPreviewFlagTrue", null, "records", true);
}
public void testRecords1() throws IOException {
JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
- internalTestWithPreview(compiler, MODULE_PROC, "15", "testRecords1", null, "records", true);
+ internalTestWithPreview(compiler, MODULE_PROC, "16", "testRecords1", null, "records", true);
}
public void testRecords1Javac() throws Exception {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
- internalTestWithPreview(compiler, MODULE_PROC, "15", "testRecords1", null, "records", true);
+ internalTestWithPreview(compiler, MODULE_PROC, "16", "testRecords1", null, "records", true);
}
public void testRecords2() throws IOException {
JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
- internalTestWithPreview(compiler, MODULE_PROC, "15", "testRecords2", null, "records", true);
+ internalTestWithPreview(compiler, MODULE_PROC, "16", "testRecords2", null, "records", true);
}
public void testRecords2Javac() throws Exception {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
- internalTestWithPreview(compiler, MODULE_PROC, "15", "testRecords2", null, "records", true);
+ internalTestWithPreview(compiler, MODULE_PROC, "16", "testRecords2", null, "records", true);
}
public void testRecords3() throws IOException {
JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
- internalTestWithPreview(compiler, MODULE_PROC, "15", "testRecords3", null, "records", true);
+ internalTestWithPreview(compiler, MODULE_PROC, "16", "testRecords3", null, "records", true);
}
public void testRecords3Javac() throws Exception {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
- internalTestWithPreview(compiler, MODULE_PROC, "15", "testRecords3", null, "records", true);
+ internalTestWithPreview(compiler, MODULE_PROC, "16", "testRecords3", null, "records", true);
}
public void testRecords3a() throws IOException {
JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
- internalTestWithPreview(compiler, MODULE_PROC, "15", "testRecords3a", null, "records", true);
+ internalTestWithPreview(compiler, MODULE_PROC, "16", "testRecords3a", null, "records", true);
}
public void testRecords3aJavac() throws Exception {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
- internalTestWithPreview(compiler, MODULE_PROC, "15", "testRecords3a", null, "records", true);
+ internalTestWithPreview(compiler, MODULE_PROC, "16", "testRecords3a", null, "records", true);
}
public void testRecords4() throws IOException {
JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
- internalTestWithPreview(compiler, MODULE_PROC, "15", "testRecords4", null, "records", true);
+ internalTestWithPreview(compiler, MODULE_PROC, "16", "testRecords4", null, "records", true);
}
public void testRecords4Javac() throws Exception {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
- internalTestWithPreview(compiler, MODULE_PROC, "15", "testRecords4", null, "records", true);
+ internalTestWithPreview(compiler, MODULE_PROC, "16", "testRecords4", null, "records", true);
}
public void testRecords4a() throws IOException {
JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
- internalTestWithPreview(compiler, MODULE_PROC, "15", "testRecords4a", null, "records", true);
+ internalTestWithPreview(compiler, MODULE_PROC, "16", "testRecords4a", null, "records", true);
}
public void testRecords4aJavac() throws Exception {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
- internalTestWithPreview(compiler, MODULE_PROC, "15", "testRecords4a", null, "records", true);
+ internalTestWithPreview(compiler, MODULE_PROC, "16", "testRecords4a", null, "records", true);
}
public void testRecords5() throws IOException {
JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
- internalTestWithPreview(compiler, MODULE_PROC, "15", "testRecords5", null, "records", true);
+ internalTestWithPreview(compiler, MODULE_PROC, "16", "testRecords5", null, "records", true);
}
public void testRecords5Javac() throws IOException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
- internalTestWithPreview(compiler, MODULE_PROC, "15", "testRecords5", null, "records", true);
+ internalTestWithPreview(compiler, MODULE_PROC, "16", "testRecords5", null, "records", true);
}
public void testRecords5a() throws IOException {
JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
- internalTestWithPreview(compiler, MODULE_PROC, "15", "testRecords5a", null, "records", true);
+ internalTestWithPreview(compiler, MODULE_PROC, "16", "testRecords5a", null, "records", true);
}
public void testRecords5aJavac() throws IOException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
- internalTestWithPreview(compiler, MODULE_PROC, "15", "testRecords5a", null, "records", true);
+ internalTestWithPreview(compiler, MODULE_PROC, "16", "testRecords5a", null, "records", true);
}
public void testRecords6() throws IOException {
JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
- internalTestWithPreview(compiler, MODULE_PROC, "15", "testRecords6", null, "records", true);
+ internalTestWithPreview(compiler, MODULE_PROC, "16", "testRecords6", null, "records", true);
}
public void testRecords6Javac() throws IOException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
- internalTestWithPreview(compiler, MODULE_PROC, "15", "testRecords6", null, "records", true);
+ internalTestWithPreview(compiler, MODULE_PROC, "16", "testRecords6", null, "records", true);
}
public void testRecords7() throws IOException {
JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
- internalTestWithPreview(compiler, MODULE_PROC, "15", "testRecords7", null, "records", true);
+ internalTestWithPreview(compiler, MODULE_PROC, "16", "testRecords7", null, "records", true);
}
public void testRecords7Javac() throws IOException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
- internalTestWithPreview(compiler, MODULE_PROC, "15", "testRecords7", null, "records", true);
+ internalTestWithPreview(compiler, MODULE_PROC, "16", "testRecords7", null, "records", true);
}
public void testRecords8() throws IOException {
JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
- internalTestWithPreview(compiler, MODULE_PROC, "15", "testRecords8", null, "records", true);
+ internalTestWithPreview(compiler, MODULE_PROC, "16", "testRecords8", null, "records", true);
}
public void testRecords8Javac() throws IOException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
- internalTestWithPreview(compiler, MODULE_PROC, "15", "testRecords8", null, "records", true);
+ internalTestWithPreview(compiler, MODULE_PROC, "16", "testRecords8", null, "records", true);
}
public void testRecords9() throws IOException {
JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
- internalTestWithPreview(compiler, MODULE_PROC, "15", "testRecords9", null, "records", true);
+ internalTestWithPreview(compiler, MODULE_PROC, "16", "testRecords9", null, "records", true);
}
public void testRecords9Javac() throws IOException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
- internalTestWithPreview(compiler, MODULE_PROC, "15", "testRecords9", null, "records", true);
+ internalTestWithPreview(compiler, MODULE_PROC, "16", "testRecords9", null, "records", true);
+ }
+ public void testRecords10() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTestWithPreview(compiler, MODULE_PROC, "16", "testRecords10", null, "records", true);
+ }
+ public void testRecords10Javac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ internalTestWithPreview(compiler, MODULE_PROC, "16", "testRecords10", null, "records", true);
}
protected void internalTestWithPreview(JavaCompiler compiler, String processor, String compliance,
String testMethod, String testClass, String resourceArea, boolean preview) throws IOException {
- if (!isRunning15()) {
+ if (!isRunning16()) {
return;
}
System.clearProperty(processor);
@@ -162,9 +174,9 @@
// if not, it will set it to an error value.
assertEquals("succeeded", System.getProperty(processor));
}
- public boolean isRunning15() {
+ public boolean isRunning16() {
String specVersion = System.getProperty("java.specification.version");
- return CompilerOptions.VERSION_15.equals(specVersion);
+ return CompilerOptions.VERSION_16.equals(specVersion);
}
/* (non-Javadoc)
* @see junit.framework.TestCase#setUp()
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java
index 5db2554..2af91cb 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2020 IBM Corporation and others.
+ * Copyright (c) 2000, 2021 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
*
* SPDX-License-Identifier: EPL-2.0
*
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
* Contributors:
* IBM Corporation - initial API and implementation
* Matt McCutchen - partial fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=122995
@@ -883,7 +887,8 @@
LocalVariableBinding local = (LocalVariableBinding) recipient;
// Note for JDK>=14, this could be LVB or RCB, hence typecasting to VB
long otherLocalTagBits = ((VariableBinding) annotationRecipient).tagBits;
- local.tagBits = otherLocalTagBits;
+ // Make sure we retain the TagBits.IsArgument bit
+ local.tagBits = otherLocalTagBits | (local.tagBits & TagBits.IsArgument);
if ((otherLocalTagBits & TagBits.AnnotationSuppressWarnings) == 0) {
// None of the annotations is a SuppressWarnings annotation
// need to fill the instances array