Skip to content

Commit 5d7ceac

Browse files
committed
Backport 8d0831478338e9b084b2c47f46eba9faae3a5eb6
1 parent cdbbf45 commit 5d7ceac

File tree

2 files changed

+81
-84
lines changed

2 files changed

+81
-84
lines changed

src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java

Lines changed: 61 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@
3636
import java.util.HashSet;
3737
import java.util.Map;
3838
import java.util.Set;
39-
import java.util.function.BiFunction;
4039
import java.util.function.IntFunction;
4140
import java.util.function.Predicate;
41+
import java.util.stream.IntStream;
4242

4343
import javax.lang.model.element.Modifier;
4444
import javax.lang.model.element.NestingKind;
@@ -2342,13 +2342,8 @@ private Type addTypeAnnotations(Type type, Predicate<TypeAnnotationPosition> fil
23422342
.add(attribute);
23432343
}
23442344

2345-
// Search the structure of the type to find the contained types at each type path
2346-
Map<Type, List<Attribute.TypeCompound>> attributesByType = new HashMap<>();
2347-
new TypeAnnotationLocator(attributesByPath, attributesByType).visit(type, List.nil());
2348-
23492345
// Rewrite the type and add the annotations
2350-
type = new TypeAnnotationTypeMapping(attributesByType).visit(type, null);
2351-
Assert.check(attributesByType.isEmpty(), "Failed to apply annotations to types");
2346+
type = new TypeAnnotationStructuralTypeMapping(attributesByPath).visit(type, List.nil());
23522347

23532348
return type;
23542349
}
@@ -2376,124 +2371,106 @@ private static Predicate<TypeAnnotationPosition> classExtends(int index) {
23762371
}
23772372

23782373
/**
2379-
* Visit all contained types, assembling a type path to represent the current location, and
2380-
* record the types at each type path that need to be annotated.
2374+
* A type mapping that rewrites the type to include type annotations.
2375+
*
2376+
* <p>This logic is similar to {@link Type.StructuralTypeMapping}, but also tracks the path to
2377+
* the contained types being rewritten, and so cannot easily share the existing logic.
23812378
*/
2382-
private static class TypeAnnotationLocator
2383-
extends Types.DefaultTypeVisitor<Void, List<TypeAnnotationPosition.TypePathEntry>> {
2379+
private static final class TypeAnnotationStructuralTypeMapping
2380+
extends Types.TypeMapping<List<TypeAnnotationPosition.TypePathEntry>> {
2381+
23842382
private final Map<List<TypeAnnotationPosition.TypePathEntry>,
2385-
ListBuffer<Attribute.TypeCompound>> attributesByPath;
2386-
private final Map<Type, List<Attribute.TypeCompound>> attributesByType;
2383+
ListBuffer<Attribute.TypeCompound>> attributesByPath;
23872384

2388-
private TypeAnnotationLocator(
2385+
private TypeAnnotationStructuralTypeMapping(
23892386
Map<List<TypeAnnotationPosition.TypePathEntry>, ListBuffer<Attribute.TypeCompound>>
2390-
attributesByPath,
2391-
Map<Type, List<Attribute.TypeCompound>> attributesByType) {
2387+
attributesByPath) {
23922388
this.attributesByPath = attributesByPath;
2393-
this.attributesByType = attributesByType;
23942389
}
23952390

2391+
23962392
@Override
2397-
public Void visitClassType(ClassType t, List<TypeAnnotationPosition.TypePathEntry> path) {
2393+
public Type visitClassType(ClassType t, List<TypeAnnotationPosition.TypePathEntry> path) {
23982394
// As described in JVMS 4.7.20.2, type annotations on nested types are located with
23992395
// 'left-to-right' steps starting on 'the outermost part of the type for which a type
24002396
// annotation is admissible'. So the current path represents the outermost containing
24012397
// type of the type being visited, and we add type path steps for every contained nested
24022398
// type.
2403-
List<ClassType> enclosing = List.nil();
2404-
for (Type curr = t;
2405-
curr != null && curr != Type.noType;
2399+
Type outer = t.getEnclosingType();
2400+
Type outer1 = outer != Type.noType ? visit(outer, path) : outer;
2401+
for (Type curr = t.getEnclosingType();
2402+
curr != Type.noType;
24062403
curr = curr.getEnclosingType()) {
2407-
enclosing = enclosing.prepend((ClassType) curr);
2408-
}
2409-
for (ClassType te : enclosing) {
2410-
if (te.typarams_field != null) {
2411-
int i = 0;
2412-
for (Type typaram : te.typarams_field) {
2413-
visit(typaram, path.append(new TypeAnnotationPosition.TypePathEntry(
2414-
TypeAnnotationPosition.TypePathEntryKind.TYPE_ARGUMENT, i++)));
2415-
}
2416-
}
2417-
visitType(te, path);
24182404
path = path.append(TypeAnnotationPosition.TypePathEntry.INNER_TYPE);
24192405
}
2420-
return null;
2406+
List<Type> typarams = t.getTypeArguments();
2407+
List<Type> typarams1 = rewriteTypeParams(path, typarams);
2408+
if (outer1 != outer || typarams != typarams1) {
2409+
t = new ClassType(outer1, typarams1, t.tsym, t.getMetadata());
2410+
}
2411+
return reannotate(t, path);
24212412
}
24222413

2423-
@Override
2424-
public Void visitWildcardType(
2425-
WildcardType t, List<TypeAnnotationPosition.TypePathEntry> path) {
2426-
visit(t.type, path.append(TypeAnnotationPosition.TypePathEntry.WILDCARD));
2427-
return super.visitWildcardType(t, path);
2414+
private List<Type> rewriteTypeParams(
2415+
List<TypeAnnotationPosition.TypePathEntry> path, List<Type> typarams) {
2416+
var i = IntStream.iterate(0, x -> x + 1).iterator();
2417+
return typarams.map(typaram -> visit(typaram,
2418+
path.append(new TypeAnnotationPosition.TypePathEntry(
2419+
TypeAnnotationPosition.TypePathEntryKind.TYPE_ARGUMENT, i.nextInt()))));
24282420
}
24292421

24302422
@Override
2431-
public Void visitArrayType(ArrayType t, List<TypeAnnotationPosition.TypePathEntry> path) {
2432-
visit(t.elemtype, path.append(TypeAnnotationPosition.TypePathEntry.ARRAY));
2433-
return super.visitArrayType(t, path);
2423+
public Type visitWildcardType(
2424+
WildcardType wt, List<TypeAnnotationPosition.TypePathEntry> path) {
2425+
Type t = wt.type;
2426+
if (t != null) {
2427+
t = visit(t, path.append(TypeAnnotationPosition.TypePathEntry.WILDCARD));
2428+
}
2429+
if (t != wt.type) {
2430+
wt = new WildcardType(t, wt.kind, wt.tsym, wt.bound, wt.getMetadata());
2431+
}
2432+
return reannotate(wt, path);
24342433
}
24352434

24362435
@Override
2437-
public Void visitType(Type t, List<TypeAnnotationPosition.TypePathEntry> path) {
2438-
ListBuffer<Attribute.TypeCompound> attributes = attributesByPath.remove(path);
2439-
if (attributes != null) {
2440-
attributesByType.put(t, attributes.toList());
2436+
public Type visitArrayType(ArrayType t, List<TypeAnnotationPosition.TypePathEntry> path) {
2437+
Type elemtype = t.elemtype;
2438+
Type elemtype1 =
2439+
visit(elemtype, path.append(TypeAnnotationPosition.TypePathEntry.ARRAY));
2440+
if (elemtype1 != elemtype) {
2441+
t = new ArrayType(elemtype1, t.tsym, t.getMetadata());
24412442
}
2442-
return null;
2443+
return reannotate(t, path);
24432444
}
2444-
}
2445-
2446-
/** A type mapping that rewrites the type to include type annotations. */
2447-
private static class TypeAnnotationTypeMapping extends Type.StructuralTypeMapping<Void> {
24482445

2449-
private final Map<Type, List<Attribute.TypeCompound>> attributesByType;
2450-
2451-
private TypeAnnotationTypeMapping(
2452-
Map<Type, List<Attribute.TypeCompound>> attributesByType) {
2453-
this.attributesByType = attributesByType;
2446+
@Override
2447+
public Type visitType(Type t, List<TypeAnnotationPosition.TypePathEntry> path) {
2448+
return reannotate(t, path);
24542449
}
24552450

2456-
private <T extends Type> Type reannotate(T t, BiFunction<T, Void, Type> f) {
2457-
// We're relying on object identify of Type instances to record where the annotations
2458-
// need to be added, so we have to retrieve the annotations for each type before
2459-
// rewriting it, and then add them after its contained types have been rewritten.
2460-
List<Attribute.TypeCompound> attributes = attributesByType.remove(t);
2461-
Type mapped = f.apply(t, null);
2462-
if (attributes == null) {
2463-
return mapped;
2451+
Type reannotate(Type type, List<TypeAnnotationPosition.TypePathEntry> path) {
2452+
List<Attribute.TypeCompound> attributes = attributesForPath(path);
2453+
if (attributes.isEmpty()) {
2454+
return type;
24642455
}
24652456
// Runtime-visible and -invisible annotations are completed separately, so if the same
24662457
// type has annotations from both it will get annotated twice.
2467-
TypeMetadata metadata = mapped.getMetadata();
2458+
TypeMetadata metadata = type.getMetadata();
24682459
TypeMetadata.Annotations existing =
24692460
(TypeMetadata.Annotations) metadata.get(TypeMetadata.Entry.Kind.ANNOTATIONS);
24702461
if (existing != null) {
24712462
TypeMetadata.Annotations combined = new TypeMetadata.Annotations(
24722463
existing.getAnnotations().appendList(attributes));
2473-
return mapped.cloneWithMetadata(
2464+
return type.cloneWithMetadata(
24742465
metadata.without(TypeMetadata.Entry.Kind.ANNOTATIONS).combine(combined));
24752466
}
2476-
return mapped.annotatedType(attributes);
2477-
}
2478-
2479-
@Override
2480-
public Type visitClassType(ClassType t, Void unused) {
2481-
return reannotate(t, super::visitClassType);
2482-
}
2483-
2484-
@Override
2485-
public Type visitWildcardType(WildcardType t, Void unused) {
2486-
return reannotate(t, super::visitWildcardType);
2467+
return type.annotatedType(attributes);
24872468
}
24882469

2489-
@Override
2490-
public Type visitArrayType(ArrayType t, Void unused) {
2491-
return reannotate(t, super::visitArrayType);
2492-
}
2493-
2494-
@Override
2495-
public Type visitType(Type t, Void unused) {
2496-
return reannotate(t, (x, u) -> x);
2470+
List<Attribute.TypeCompound> attributesForPath(
2471+
List<TypeAnnotationPosition.TypePathEntry> path) {
2472+
ListBuffer<Attribute.TypeCompound> attributes = attributesByPath.remove(path);
2473+
return attributes != null ? attributes.toList() : List.nil();
24972474
}
24982475
}
24992476

test/langtools/tools/javac/processing/model/type/BasicAnnoTests.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,4 +585,24 @@ class Inner90<@TA(90) T> {
585585
@Test(posn=4, annoType = TB.class, expect = "100")
586586
class Inner100<T extends Inner100<@TB(100) T>> {
587587
}
588+
589+
// receiver parameters
590+
class Inner110 {
591+
@Test(posn=2, annoType = TA.class, expect = "110")
592+
void f(@TA(110) Inner110 this) {}
593+
594+
@Test(posn=2, annoType = TA.class, expect = "111")
595+
Inner110(@TA(111) BasicAnnoTests BasicAnnoTests.this) {}
596+
}
597+
598+
static class GenericInner120<X> {
599+
private class GenericNested<Y> {
600+
@Test(posn=2, annoType = TA.class, expect = "120")
601+
GenericNested(@TA(120) GenericInner120<X> GenericInner120.this) {}
602+
}
603+
}
604+
605+
@Test(posn=1, annoType=TA.class, expect="130")
606+
@Test(posn=23, annoType=TA.class, expect="131")
607+
public Map<@TA(130) String, @TA(131) String> f130;
588608
}

0 commit comments

Comments
 (0)