Navigation Menu

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

Commit

Permalink
8292159: TYPE_USE annotations on generic type arguments of record com…
Browse files Browse the repository at this point in the history
…ponents discarded

Reviewed-by: vromero
Backport-of: 4d9a1cd26fa0cda902aafcccd6e02bd7bc60bbb3
  • Loading branch information
Srikanth Adayapalam committed Nov 7, 2022
1 parent 491bdee commit c6e1849
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 3 deletions.
Expand Up @@ -32,6 +32,7 @@

import com.sun.tools.javac.code.Attribute.TypeCompound;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.RecordComponent;
import com.sun.tools.javac.code.Symbol.TypeSymbol;
import com.sun.tools.javac.code.Type.ArrayType;
import com.sun.tools.javac.code.Type.CapturedType;
Expand Down Expand Up @@ -84,6 +85,7 @@
import com.sun.tools.javac.util.Log;
import com.sun.tools.javac.util.Names;

import static com.sun.tools.javac.code.Flags.RECORD;
import static com.sun.tools.javac.code.Kinds.Kind.*;

/**
Expand Down Expand Up @@ -1302,6 +1304,16 @@ public void visitVarDef(final JCVariableDecl tree) {
if (!sigOnly) {
scan(tree.init);
}

// Now that type and declaration annotations have been segregated into their own buckets ...
if (sigOnly) {
if (tree.sym != null && tree.sym.getKind() == ElementKind.FIELD && (tree.sym.flags_field & RECORD) != 0) {
RecordComponent rc = ((ClassSymbol)tree.sym.owner).getRecordComponent(tree.sym);
rc.setTypeAttributes(tree.sym.getRawTypeAttributes());
// to get all the type annotations applied to the type
rc.type = tree.sym.type;
}
}
}

@Override
Expand Down
Expand Up @@ -2998,9 +2998,15 @@ private void validateAnnotation(JCAnnotation a, JCTree declarationTree, Symbol s
rc.appendAttributes(s.getRawAttributes().stream().filter(anno ->
Arrays.stream(getTargetNames(anno.type.tsym)).anyMatch(name -> name == names.RECORD_COMPONENT)
).collect(List.collector()));
rc.setTypeAttributes(s.getRawTypeAttributes());
// to get all the type annotations applied to the type
rc.type = s.type;

/* At this point, we used to carry over any type annotations from the VARDEF to the record component, but
* that is problematic, since we get here only when *some* annotation is applied to the SE5 (declaration)
* annotation location, inadvertently failing to carry over the type annotations when the VarDef has no
* annotations in the SE5 annotation location.
*
* Now type annotations are assigned to record components in a method that would execute irrespective of
* whether there are SE5 annotations on a VarDef viz com.sun.tools.javac.code.TypeAnnotations.TypeAnnotationPositions.visitVarDef
*/
}
}
}
Expand Down
51 changes: 51 additions & 0 deletions test/langtools/tools/javac/records/RecordCompilationTests.java
Expand Up @@ -1479,6 +1479,57 @@ record R(@Anno String s) {}
setCompileOptions(previousOptions);
}

// JDK-8292159: TYPE_USE annotations on generic type arguments
// of record components discarded
public void testOnlyTypeAnnotationsOnComponentField() throws Exception {
String code =
"""
import java.lang.annotation.*;
import java.util.List;
@Target({ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@interface Anno { }
record R(List<@Anno String> s) {}
""";

File dir = assertOK(true, code);

ClassFile classFile = ClassFile.read(findClassFileOrFail(dir, "R.class"));

// field first
Assert.check(classFile.fields.length == 1);
Field field = classFile.fields[0];
checkTypeAnno(
classFile,
(RuntimeVisibleTypeAnnotations_attribute) findAttributeOrFail(field.attributes, RuntimeVisibleTypeAnnotations_attribute.class),
"FIELD",
"Anno");

// checking for the annotation on the corresponding parameter of the canonical constructor
Method init = findMethodOrFail(classFile, "<init>");
checkTypeAnno(
classFile,
(RuntimeVisibleTypeAnnotations_attribute) findAttributeOrFail(init.attributes, RuntimeVisibleTypeAnnotations_attribute.class),
"METHOD_FORMAL_PARAMETER", "Anno");

// checking for the annotation in the accessor
Method accessor = findMethodOrFail(classFile, "s");
checkTypeAnno(
classFile,
(RuntimeVisibleTypeAnnotations_attribute) findAttributeOrFail(accessor.attributes, RuntimeVisibleTypeAnnotations_attribute.class),
"METHOD_RETURN", "Anno");

// checking for the annotation in the Record attribute
Record_attribute record = (Record_attribute) findAttributeOrFail(classFile.attributes, Record_attribute.class);
Assert.check(record.component_count == 1);
checkTypeAnno(
classFile,
(RuntimeVisibleTypeAnnotations_attribute) findAttributeOrFail(
record.component_info_arr[0].attributes,
RuntimeVisibleTypeAnnotations_attribute.class),
"FIELD", "Anno");
}

private void checkTypeAnno(ClassFile classFile,
RuntimeTypeAnnotations_attribute rtAnnos,
String positionType,
Expand Down

1 comment on commit c6e1849

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.