8292159: TYPE_USE annotations on generic type arguments of record components discarded
Reviewed-by: vromero
This commit is contained in:
parent
210fe49e25
commit
4d9a1cd26f
src/jdk.compiler/share/classes/com/sun/tools/javac
test/langtools/tools/javac/records
@ -32,6 +32,7 @@ import javax.tools.JavaFileObject;
|
||||
|
||||
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;
|
||||
@ -84,6 +85,7 @@ import com.sun.tools.javac.util.ListBuffer;
|
||||
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.*;
|
||||
|
||||
/**
|
||||
@ -1302,6 +1304,16 @@ public class TypeAnnotations {
|
||||
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
|
||||
|
@ -3005,9 +3005,15 @@ public class Check {
|
||||
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
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1566,6 +1566,57 @@ public class RecordCompilationTests extends CompilationTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
// 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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user