Skip to content
This repository was archived by the owner on Sep 19, 2023. It is now read-only.

Commit c6e1849

Browse files
author
Srikanth Adayapalam
committed
8292159: TYPE_USE annotations on generic type arguments of record components discarded
Reviewed-by: vromero Backport-of: 4d9a1cd26fa0cda902aafcccd6e02bd7bc60bbb3
1 parent 491bdee commit c6e1849

File tree

3 files changed

+72
-3
lines changed

3 files changed

+72
-3
lines changed

src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
import com.sun.tools.javac.code.Attribute.TypeCompound;
3434
import com.sun.tools.javac.code.Symbol.ClassSymbol;
35+
import com.sun.tools.javac.code.Symbol.RecordComponent;
3536
import com.sun.tools.javac.code.Symbol.TypeSymbol;
3637
import com.sun.tools.javac.code.Type.ArrayType;
3738
import com.sun.tools.javac.code.Type.CapturedType;
@@ -84,6 +85,7 @@
8485
import com.sun.tools.javac.util.Log;
8586
import com.sun.tools.javac.util.Names;
8687

88+
import static com.sun.tools.javac.code.Flags.RECORD;
8789
import static com.sun.tools.javac.code.Kinds.Kind.*;
8890

8991
/**
@@ -1302,6 +1304,16 @@ public void visitVarDef(final JCVariableDecl tree) {
13021304
if (!sigOnly) {
13031305
scan(tree.init);
13041306
}
1307+
1308+
// Now that type and declaration annotations have been segregated into their own buckets ...
1309+
if (sigOnly) {
1310+
if (tree.sym != null && tree.sym.getKind() == ElementKind.FIELD && (tree.sym.flags_field & RECORD) != 0) {
1311+
RecordComponent rc = ((ClassSymbol)tree.sym.owner).getRecordComponent(tree.sym);
1312+
rc.setTypeAttributes(tree.sym.getRawTypeAttributes());
1313+
// to get all the type annotations applied to the type
1314+
rc.type = tree.sym.type;
1315+
}
1316+
}
13051317
}
13061318

13071319
@Override

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2998,9 +2998,15 @@ private void validateAnnotation(JCAnnotation a, JCTree declarationTree, Symbol s
29982998
rc.appendAttributes(s.getRawAttributes().stream().filter(anno ->
29992999
Arrays.stream(getTargetNames(anno.type.tsym)).anyMatch(name -> name == names.RECORD_COMPONENT)
30003000
).collect(List.collector()));
3001-
rc.setTypeAttributes(s.getRawTypeAttributes());
3002-
// to get all the type annotations applied to the type
3003-
rc.type = s.type;
3001+
3002+
/* At this point, we used to carry over any type annotations from the VARDEF to the record component, but
3003+
* that is problematic, since we get here only when *some* annotation is applied to the SE5 (declaration)
3004+
* annotation location, inadvertently failing to carry over the type annotations when the VarDef has no
3005+
* annotations in the SE5 annotation location.
3006+
*
3007+
* Now type annotations are assigned to record components in a method that would execute irrespective of
3008+
* whether there are SE5 annotations on a VarDef viz com.sun.tools.javac.code.TypeAnnotations.TypeAnnotationPositions.visitVarDef
3009+
*/
30043010
}
30053011
}
30063012
}

test/langtools/tools/javac/records/RecordCompilationTests.java

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1479,6 +1479,57 @@ record R(@Anno String s) {}
14791479
setCompileOptions(previousOptions);
14801480
}
14811481

1482+
// JDK-8292159: TYPE_USE annotations on generic type arguments
1483+
// of record components discarded
1484+
public void testOnlyTypeAnnotationsOnComponentField() throws Exception {
1485+
String code =
1486+
"""
1487+
import java.lang.annotation.*;
1488+
import java.util.List;
1489+
@Target({ElementType.TYPE_USE})
1490+
@Retention(RetentionPolicy.RUNTIME)
1491+
@interface Anno { }
1492+
record R(List<@Anno String> s) {}
1493+
""";
1494+
1495+
File dir = assertOK(true, code);
1496+
1497+
ClassFile classFile = ClassFile.read(findClassFileOrFail(dir, "R.class"));
1498+
1499+
// field first
1500+
Assert.check(classFile.fields.length == 1);
1501+
Field field = classFile.fields[0];
1502+
checkTypeAnno(
1503+
classFile,
1504+
(RuntimeVisibleTypeAnnotations_attribute) findAttributeOrFail(field.attributes, RuntimeVisibleTypeAnnotations_attribute.class),
1505+
"FIELD",
1506+
"Anno");
1507+
1508+
// checking for the annotation on the corresponding parameter of the canonical constructor
1509+
Method init = findMethodOrFail(classFile, "<init>");
1510+
checkTypeAnno(
1511+
classFile,
1512+
(RuntimeVisibleTypeAnnotations_attribute) findAttributeOrFail(init.attributes, RuntimeVisibleTypeAnnotations_attribute.class),
1513+
"METHOD_FORMAL_PARAMETER", "Anno");
1514+
1515+
// checking for the annotation in the accessor
1516+
Method accessor = findMethodOrFail(classFile, "s");
1517+
checkTypeAnno(
1518+
classFile,
1519+
(RuntimeVisibleTypeAnnotations_attribute) findAttributeOrFail(accessor.attributes, RuntimeVisibleTypeAnnotations_attribute.class),
1520+
"METHOD_RETURN", "Anno");
1521+
1522+
// checking for the annotation in the Record attribute
1523+
Record_attribute record = (Record_attribute) findAttributeOrFail(classFile.attributes, Record_attribute.class);
1524+
Assert.check(record.component_count == 1);
1525+
checkTypeAnno(
1526+
classFile,
1527+
(RuntimeVisibleTypeAnnotations_attribute) findAttributeOrFail(
1528+
record.component_info_arr[0].attributes,
1529+
RuntimeVisibleTypeAnnotations_attribute.class),
1530+
"FIELD", "Anno");
1531+
}
1532+
14821533
private void checkTypeAnno(ClassFile classFile,
14831534
RuntimeTypeAnnotations_attribute rtAnnos,
14841535
String positionType,

0 commit comments

Comments
 (0)