Skip to content

Commit 9d9e41f

Browse files
committed
8356894: Adjust CreateSymbols to properly handle the newly added @jdk.internal.RequiresIdentity
Reviewed-by: vromero, liach
1 parent 99e0130 commit 9d9e41f

File tree

12 files changed

+529
-30
lines changed

12 files changed

+529
-30
lines changed

make/langtools/src/classes/build/tools/symbolgenerator/CreateSymbols.java

Lines changed: 198 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@
4646
import java.io.StringWriter;
4747
import java.io.Writer;
4848
import java.lang.classfile.*;
49+
import java.lang.classfile.TypeAnnotation.TargetInfo;
50+
import java.lang.classfile.TypeAnnotation.TypePathComponent;
4951
import java.lang.classfile.attribute.*;
5052
import java.lang.classfile.constantpool.ClassEntry;
5153
import java.lang.classfile.constantpool.ConstantPoolBuilder;
@@ -991,6 +993,12 @@ private void addGenericAttributes(FeatureDescription desc, Consumer<? super Attr
991993
if (desc.runtimeAnnotations != null && !desc.runtimeAnnotations.isEmpty()) {
992994
builder.accept(RuntimeVisibleAnnotationsAttribute.of(createAnnotations(desc.runtimeAnnotations)));
993995
}
996+
if (desc.classTypeAnnotations != null && !desc.classTypeAnnotations.isEmpty()) {
997+
builder.accept(RuntimeInvisibleTypeAnnotationsAttribute.of(createTypeAnnotations(desc.classTypeAnnotations)));
998+
}
999+
if (desc.runtimeTypeAnnotations != null && !desc.runtimeTypeAnnotations.isEmpty()) {
1000+
builder.accept(RuntimeVisibleTypeAnnotationsAttribute.of(createTypeAnnotations(desc.runtimeTypeAnnotations)));
1001+
}
9941002
}
9951003

9961004
private List<Annotation> createAnnotations(List<AnnotationDescription> desc) {
@@ -1066,6 +1074,44 @@ private AnnotationValue createAttributeValue(Object value) {
10661074
default -> throw new IllegalArgumentException(value.getClass().getName());
10671075
};
10681076
}
1077+
1078+
private List<TypeAnnotation> createTypeAnnotations(List<TypeAnnotationDescription> desc) {
1079+
return desc.stream().map(this::createTypeAnnotation).collect(Collectors.toList());
1080+
}
1081+
1082+
private TypeAnnotation createTypeAnnotation(TypeAnnotationDescription desc) {
1083+
Annotation baseAnn = createAnnotation(desc.annotation);
1084+
TargetInfo targetInfo = switch ((String) desc.targetInfo.get("targetType")) {
1085+
case "CLASS_TYPE_PARAMETER" -> //TODO: test!
1086+
TargetInfo.ofClassTypeParameter((int) desc.targetInfo.get("typeParameterIndex"));
1087+
case "METHOD_TYPE_PARAMETER" ->
1088+
TargetInfo.ofMethodTypeParameter((int) desc.targetInfo.get("typeParameterIndex"));
1089+
case "CLASS_EXTENDS" ->
1090+
TargetInfo.ofClassExtends((int) desc.targetInfo.get("supertypeIndex"));
1091+
case "CLASS_TYPE_PARAMETER_BOUND" ->
1092+
TargetInfo.ofClassTypeParameterBound((int) desc.targetInfo.get("typeParameterIndex"),
1093+
(int) desc.targetInfo.get("boundIndex"));
1094+
case "METHOD_TYPE_PARAMETER_BOUND" ->
1095+
TargetInfo.ofMethodTypeParameterBound((int) desc.targetInfo.get("typeParameterIndex"),
1096+
(int) desc.targetInfo.get("boundIndex"));
1097+
case "METHOD_RETURN" ->
1098+
TargetInfo.ofMethodReturn();
1099+
case "METHOD_RECEIVER" ->
1100+
TargetInfo.ofMethodReceiver();
1101+
case "METHOD_FORMAL_PARAMETER" ->
1102+
TargetInfo.ofMethodFormalParameter((int) desc.targetInfo.get("formalParameterIndex"));
1103+
case "THROWS" ->
1104+
TargetInfo.ofThrows((int) desc.targetInfo.get("throwsTargetIndex"));
1105+
case "FIELD" ->
1106+
TargetInfo.ofField();
1107+
case String targetType ->
1108+
throw new IllegalStateException("Unsupported targetType: " + targetType);
1109+
};
1110+
1111+
List<TypePathComponent> typePath = desc.typePath.stream().map(d -> TypePathComponent.of(TypePathComponent.Kind.valueOf(d.tag()), d.index())).toList();
1112+
1113+
return TypeAnnotation.of(targetInfo, typePath, baseAnn);
1114+
}
10691115
//</editor-fold>
10701116
//</editor-fold>
10711117

@@ -2213,7 +2259,10 @@ private boolean readAttribute(FeatureDescription feature, Attribute<?> attr) {
22132259
chd.permittedSubclasses = a.permittedSubclasses().stream().map(ClassEntry::asInternalName).collect(Collectors.toList());
22142260
}
22152261
case ModuleMainClassAttribute a -> ((ModuleHeaderDescription) feature).moduleMainClass = a.mainClass().asInternalName();
2216-
case RuntimeVisibleTypeAnnotationsAttribute a -> {/* do nothing for now */}
2262+
case RuntimeInvisibleTypeAnnotationsAttribute a ->
2263+
feature.classTypeAnnotations = typeAnnotations2Descriptions(a.annotations());
2264+
case RuntimeVisibleTypeAnnotationsAttribute a ->
2265+
feature.runtimeTypeAnnotations = typeAnnotations2Descriptions(a.annotations());
22172266
default -> throw new IllegalArgumentException("Unhandled attribute: " + attr.attributeName()); // Do nothing
22182267
}
22192268

@@ -2270,6 +2319,31 @@ private AnnotationDescription annotation2Description(java.lang.classfile.Annotat
22702319

22712320
return new AnnotationDescription(annotationType, values);
22722321
}
2322+
2323+
private List<TypeAnnotationDescription> typeAnnotations2Descriptions(List<TypeAnnotation> annos) {
2324+
return annos.stream().map(ta -> {
2325+
TypeAnnotationDescription desc = new TypeAnnotationDescription();
2326+
desc.annotation = annotation2Description(ta.annotation());
2327+
desc.targetInfo = new HashMap<>();
2328+
desc.targetInfo.put("targetType", ta.targetInfo().targetType().name());
2329+
switch (ta.targetInfo()) {
2330+
case TypeAnnotation.TypeParameterTarget tpt -> desc.targetInfo.put("typeParameterIndex", tpt.typeParameterIndex());
2331+
case TypeAnnotation.SupertypeTarget st -> desc.targetInfo.put("supertypeIndex", st.supertypeIndex());
2332+
case TypeAnnotation.TypeParameterBoundTarget tpbt -> {
2333+
desc.targetInfo.put("typeParameterIndex", tpbt.typeParameterIndex());
2334+
desc.targetInfo.put("boundIndex", tpbt.boundIndex());
2335+
}
2336+
case TypeAnnotation.EmptyTarget _ -> {
2337+
// nothing to write
2338+
}
2339+
case TypeAnnotation.FormalParameterTarget fpt -> desc.targetInfo.put("formalParameterIndex", fpt.formalParameterIndex());
2340+
case TypeAnnotation.ThrowsTarget tt -> desc.targetInfo.put("throwsTargetIndex", tt.throwsTargetIndex());
2341+
default -> throw new IllegalStateException(ta.targetInfo().targetType().name());
2342+
}
2343+
desc.typePath = ta.targetPath().stream().map(tpc -> new TypeAnnotationDescription.TypePathComponentDesc(tpc.typePathKind().name(), tpc.typeArgumentIndex())).toList();
2344+
return desc;
2345+
}).toList();
2346+
}
22732347
//</editor-fold>
22742348

22752349
protected boolean includeEffectiveAccess(ClassList classes, ClassDescription clazz) {
@@ -2391,6 +2465,8 @@ static abstract class FeatureDescription {
23912465
String versions = "";
23922466
List<AnnotationDescription> classAnnotations;
23932467
List<AnnotationDescription> runtimeAnnotations;
2468+
List<TypeAnnotationDescription> classTypeAnnotations;
2469+
List<TypeAnnotationDescription> runtimeTypeAnnotations;
23942470

23952471
protected void writeAttributes(Appendable output) throws IOException {
23962472
if (flags != 0)
@@ -2413,6 +2489,18 @@ protected void writeAttributes(Appendable output) throws IOException {
24132489
output.append(quote(a.toString(), false));
24142490
}
24152491
}
2492+
if (classTypeAnnotations != null && !classTypeAnnotations.isEmpty()) {
2493+
output.append(" classTypeAnnotations ");
2494+
for (TypeAnnotationDescription a : classTypeAnnotations) {
2495+
output.append(quote(a.toString(), false));
2496+
}
2497+
}
2498+
if (runtimeTypeAnnotations != null && !runtimeTypeAnnotations.isEmpty()) {
2499+
output.append(" runtimeTypeAnnotations ");
2500+
for (TypeAnnotationDescription a : runtimeTypeAnnotations) {
2501+
output.append(quote(a.toString(), false));
2502+
}
2503+
}
24162504
}
24172505

24182506
protected boolean shouldIgnore(String baselineVersion, String version) {
@@ -2442,6 +2530,14 @@ protected void readAttributes(LineBasedReader reader) {
24422530
if (inRuntimeAnnotations != null) {
24432531
runtimeAnnotations = parseAnnotations(inRuntimeAnnotations, new int[1]);
24442532
}
2533+
String inClassTypeAnnotations = reader.attributes.get("classTypeAnnotations");
2534+
if (inClassTypeAnnotations != null) {
2535+
classTypeAnnotations = parseTypeAnnotations(inClassTypeAnnotations, new int[1]);
2536+
}
2537+
String inRuntimeTypeAnnotations = reader.attributes.get("runtimeTypeAnnotations");
2538+
if (inRuntimeTypeAnnotations != null) {
2539+
runtimeTypeAnnotations = parseTypeAnnotations(inRuntimeTypeAnnotations, new int[1]);
2540+
}
24452541
}
24462542

24472543
public abstract boolean read(LineBasedReader reader) throws IOException;
@@ -2454,6 +2550,8 @@ public int hashCode() {
24542550
hash = 89 * hash + Objects.hashCode(this.signature);
24552551
hash = 89 * hash + listHashCode(this.classAnnotations);
24562552
hash = 89 * hash + listHashCode(this.runtimeAnnotations);
2553+
hash = 89 * hash + listHashCode(this.classTypeAnnotations);
2554+
hash = 89 * hash + listHashCode(this.runtimeTypeAnnotations);
24572555
return hash;
24582556
}
24592557

@@ -2481,6 +2579,12 @@ public boolean equals(Object obj) {
24812579
if (!listEquals(this.runtimeAnnotations, other.runtimeAnnotations)) {
24822580
return false;
24832581
}
2582+
if (!listEquals(this.classTypeAnnotations, other.classTypeAnnotations)) {
2583+
return false;
2584+
}
2585+
if (!listEquals(this.runtimeTypeAnnotations, other.runtimeTypeAnnotations)) {
2586+
return false;
2587+
}
24842588
return true;
24852589
}
24862590

@@ -3285,6 +3389,8 @@ public int hashCode() {
32853389
hash = 59 * hash + Objects.hashCode(this.descriptor);
32863390
hash = 59 * hash + Objects.hashCode(this.thrownTypes);
32873391
hash = 59 * hash + Objects.hashCode(this.annotationDefaultValue);
3392+
hash = 59 * hash + Objects.hashCode(this.classParameterAnnotations);
3393+
hash = 59 * hash + Objects.hashCode(this.runtimeParameterAnnotations);
32883394
return hash;
32893395
}
32903396

@@ -3309,6 +3415,12 @@ public boolean equals(Object obj) {
33093415
if (!Objects.equals(this.annotationDefaultValue, other.annotationDefaultValue)) {
33103416
return false;
33113417
}
3418+
if (!Objects.equals(this.classParameterAnnotations, other.classParameterAnnotations)) {
3419+
return false;
3420+
}
3421+
if (!Objects.equals(this.runtimeParameterAnnotations, other.runtimeParameterAnnotations)) {
3422+
return false;
3423+
}
33123424
return true;
33133425
}
33143426

@@ -3636,6 +3748,40 @@ private static String dumpAnnotationValue(Object value) {
36363748
}
36373749
}
36383750

3751+
static final class TypeAnnotationDescription {
3752+
AnnotationDescription annotation;
3753+
Map<String, Object> targetInfo;
3754+
List<TypePathComponentDesc> typePath;
3755+
3756+
public TypeAnnotationDescription() {
3757+
}
3758+
3759+
public TypeAnnotationDescription(AnnotationDescription annotation, Map<String, Object> targetInfo, List<TypePathComponentDesc> typePath) {
3760+
this.annotation = annotation;
3761+
this.targetInfo = targetInfo;
3762+
this.typePath = typePath;
3763+
}
3764+
3765+
@Override
3766+
public String toString() {
3767+
return annotation.toString() + "{" + targetInfo.entrySet().stream().map(e -> e.getKey() + "=" + quote(printValue(e.getValue()), false)).collect(Collectors.joining(",")) + "}" +
3768+
(!typePath.isEmpty() ? "[" + typePath.stream().map(desc -> desc.tag + ":" + desc.index).collect(Collectors.joining(",")) + "]" : "");
3769+
}
3770+
3771+
private String printValue(Object obj) {
3772+
if (obj instanceof String s) {
3773+
return "\"" + s + "\"";
3774+
} else if (obj instanceof Integer i) {
3775+
return "I" + String.valueOf(i);
3776+
} else {
3777+
throw new IllegalStateException("Unsupported value: " + obj.getClass());
3778+
}
3779+
}
3780+
3781+
//TODO: path
3782+
record TypePathComponentDesc(String tag, int index) {}
3783+
}
3784+
36393785
static final class EnumConstant {
36403786
String type;
36413787
String constant;
@@ -3975,23 +4121,69 @@ public static List<AnnotationDescription> parseAnnotations(String encoded, int[]
39754121

39764122
private static AnnotationDescription parseAnnotation(String value, int[] valuePointer) {
39774123
String className = className(value, valuePointer);
3978-
Map<String, Object> attribute2Value = new HashMap<>();
4124+
Map<String, Object> attribute2Value = Map.of();
39794125

39804126
if (valuePointer[0] < value.length() && value.charAt(valuePointer[0]) == '(') {
3981-
while (value.charAt(valuePointer[0]) != ')') {
4127+
attribute2Value = parseMap(value, valuePointer, ')');
4128+
}
4129+
4130+
return new AnnotationDescription(className, attribute2Value);
4131+
}
4132+
4133+
private static Map<String, Object> parseMap(String value, int[] valuePointer, char endBracket) {
4134+
Map<String, Object> attribute2Value = new HashMap<>();
4135+
4136+
while (value.charAt(valuePointer[0]) != endBracket) {
4137+
int nameStart = ++valuePointer[0];
4138+
4139+
while (value.charAt(valuePointer[0]++) != '=');
4140+
4141+
String name = value.substring(nameStart, valuePointer[0] - 1);
4142+
4143+
attribute2Value.put(name, parseAnnotationValue(value, valuePointer));
4144+
}
4145+
4146+
valuePointer[0]++;
4147+
4148+
return attribute2Value;
4149+
}
4150+
4151+
public static List<TypeAnnotationDescription> parseTypeAnnotations(String encoded, int[] pointer) {
4152+
List<TypeAnnotationDescription> result = new ArrayList<>();
4153+
4154+
while (pointer[0] < encoded.length() && encoded.charAt(pointer[0]) == '@') {
4155+
pointer[0]++;
4156+
result.add(parseTypeAnnotation(encoded, pointer));
4157+
}
4158+
4159+
return result;
4160+
}
4161+
4162+
private static TypeAnnotationDescription parseTypeAnnotation(String value, int[] valuePointer) {
4163+
AnnotationDescription ann = parseAnnotation(value, valuePointer);
4164+
Map<String, Object> targetInfo = Map.of();
4165+
4166+
if (valuePointer[0] < value.length() && value.charAt(valuePointer[0]) == '{') {
4167+
targetInfo = parseMap(value, valuePointer, '}');
4168+
}
4169+
4170+
List<TypeAnnotationDescription.TypePathComponentDesc> typePath = new ArrayList<>();
4171+
4172+
if (valuePointer[0] < value.length() && value.charAt(valuePointer[0]) == '[') {
4173+
while (value.charAt(valuePointer[0]) != ']') {
39824174
int nameStart = ++valuePointer[0];
39834175

3984-
while (value.charAt(valuePointer[0]++) != '=');
4176+
while (value.charAt(valuePointer[0]++) != ':');
39854177

39864178
String name = value.substring(nameStart, valuePointer[0] - 1);
39874179

3988-
attribute2Value.put(name, parseAnnotationValue(value, valuePointer));
4180+
typePath.add(new TypeAnnotationDescription.TypePathComponentDesc(name, Integer.parseInt(readDigits(value, valuePointer))));
39894181
}
39904182

39914183
valuePointer[0]++;
39924184
}
39934185

3994-
return new AnnotationDescription(className, attribute2Value);
4186+
return new TypeAnnotationDescription(ann, targetInfo, typePath);
39954187
}
39964188
//</editor-fold>
39974189

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,11 @@ public static EnumSet<Flag> asFlagSet(long flags) {
399399
*/
400400
public static final long RESTRICTED = 1L<<62; // MethodSymbols
401401

402+
/**
403+
* Flag to indicate parameters that require identity.
404+
*/
405+
public static final long REQUIRES_IDENTITY = 1L<<62; // VarSymbols (parameters)
406+
402407
/**
403408
* Flag to indicate type annotations have been queued for field initializers.
404409
*/

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -969,7 +969,8 @@ public <A extends Annotation> Attribute.Compound getAttribute(Class<A> annoType)
969969
boolean isCurrentSymbolsAnnotation(Attribute.TypeCompound anno, int index) {
970970
return (anno.position.type == TargetType.CLASS_TYPE_PARAMETER ||
971971
anno.position.type == TargetType.METHOD_TYPE_PARAMETER) &&
972-
anno.position.parameter_index == index;
972+
anno.position.parameter_index == index &&
973+
anno.type.tsym.flatName() != name.table.names.requiresIdentityInternal;
973974
}
974975

975976

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -384,9 +384,15 @@ public boolean isTerminal() {
384384
// Enter a synthetic class that is used to mark classes in ct.sym.
385385
// This class does not have a class file.
386386
private Type enterSyntheticAnnotation(String name) {
387+
return enterSyntheticAnnotation(names.fromString(name));
388+
}
389+
390+
// Enter a synthetic class that is used to mark classes in ct.sym.
391+
// This class does not have a class file.
392+
private Type enterSyntheticAnnotation(Name name) {
387393
// for now, leave the module null, to prevent problems from synthesizing the
388394
// existence of a class in any specific module, including noModule
389-
ClassType type = (ClassType)enterClass(java_base, names.fromString(name)).type;
395+
ClassType type = (ClassType)enterClass(java_base, name).type;
390396
ClassSymbol sym = (ClassSymbol)type.tsym;
391397
sym.completer = Completer.NULL_COMPLETER;
392398
sym.flags_field = PUBLIC|ACYCLIC|ANNOTATION|INTERFACE;
@@ -613,7 +619,7 @@ public <R, P> R accept(ElementVisitor<R, P> v, P p) {
613619
valueBasedType = enterClass("jdk.internal.ValueBased");
614620
valueBasedInternalType = enterSyntheticAnnotation("jdk.internal.ValueBased+Annotation");
615621
requiresIdentityType = enterClass("jdk.internal.RequiresIdentity");
616-
requiresIdentityInternalType = enterSyntheticAnnotation("jdk.internal.RequiresIdentity+Annotation");
622+
requiresIdentityInternalType = enterSyntheticAnnotation(names.requiresIdentityInternal);
617623
classDescType = enterClass("java.lang.constant.ClassDesc");
618624
enumDescType = enterClass("java.lang.Enum$EnumDesc");
619625
// For serialization lint checking

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,12 @@ private <T extends Attribute.Compound> void annotateNow(Symbol toAnnotate,
384384
&& types.isSameType(c.type, syms.restrictedType)) {
385385
toAnnotate.flags_field |= Flags.RESTRICTED;
386386
}
387+
388+
if (!c.type.isErroneous()
389+
&& toAnnotate.kind == VAR
390+
&& types.isSameType(c.type, syms.requiresIdentityType)) {
391+
toAnnotate.flags_field |= Flags.REQUIRES_IDENTITY;
392+
}
387393
}
388394

389395
List<T> buf = List.nil();

0 commit comments

Comments
 (0)