8303820: Simplify type metadata
Reviewed-by: vromero
This commit is contained in:
parent
75d630621c
commit
b9951dd639
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -30,12 +30,14 @@ import java.util.ArrayDeque;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
import javax.lang.model.type.*;
|
import javax.lang.model.type.*;
|
||||||
|
|
||||||
import com.sun.tools.javac.code.Symbol.*;
|
import com.sun.tools.javac.code.Symbol.*;
|
||||||
import com.sun.tools.javac.code.TypeMetadata.Entry;
|
import com.sun.tools.javac.code.TypeMetadata.Annotations;
|
||||||
|
import com.sun.tools.javac.code.TypeMetadata.ConstantValue;
|
||||||
import com.sun.tools.javac.code.Types.TypeMapping;
|
import com.sun.tools.javac.code.Types.TypeMapping;
|
||||||
import com.sun.tools.javac.code.Types.UniqueType;
|
import com.sun.tools.javac.code.Types.UniqueType;
|
||||||
import com.sun.tools.javac.comp.Infer.IncorporationAction;
|
import com.sun.tools.javac.comp.Infer.IncorporationAction;
|
||||||
@ -86,15 +88,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
|||||||
* class, a given {@code Type} may have at most one metadata array
|
* class, a given {@code Type} may have at most one metadata array
|
||||||
* entry of that class.
|
* entry of that class.
|
||||||
*/
|
*/
|
||||||
protected final TypeMetadata metadata;
|
protected final List<TypeMetadata> metadata;
|
||||||
|
|
||||||
public TypeMetadata getMetadata() {
|
|
||||||
return metadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Entry getMetadataOfKind(final Entry.Kind kind) {
|
|
||||||
return metadata != null ? metadata.get(kind) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Constant type: no type at all. */
|
/** Constant type: no type at all. */
|
||||||
public static final JCNoType noType = new JCNoType() {
|
public static final JCNoType noType = new JCNoType() {
|
||||||
@ -188,7 +182,8 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
|||||||
* @return the constant value attribute of this type
|
* @return the constant value attribute of this type
|
||||||
*/
|
*/
|
||||||
public Object constValue() {
|
public Object constValue() {
|
||||||
return null;
|
return getMetadata(TypeMetadata.ConstantValue.class)
|
||||||
|
.map(ConstantValue::value).orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Is this a constant type whose value is false?
|
/** Is this a constant type whose value is false?
|
||||||
@ -230,7 +225,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
|||||||
/** Define a type given its tag, type symbol, and type annotations
|
/** Define a type given its tag, type symbol, and type annotations
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public Type(TypeSymbol tsym, TypeMetadata metadata) {
|
public Type(TypeSymbol tsym, List<TypeMetadata> metadata) {
|
||||||
Assert.checkNonNull(metadata);
|
Assert.checkNonNull(metadata);
|
||||||
this.tsym = tsym;
|
this.tsym = tsym;
|
||||||
this.metadata = metadata;
|
this.metadata = metadata;
|
||||||
@ -345,13 +340,53 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
|||||||
* it should not be used outside this class.
|
* it should not be used outside this class.
|
||||||
*/
|
*/
|
||||||
protected Type typeNoMetadata() {
|
protected Type typeNoMetadata() {
|
||||||
return metadata == TypeMetadata.EMPTY ? this : baseType();
|
return metadata.isEmpty() ? this : baseType();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new copy of this type but with the specified TypeMetadata.
|
* Create a new copy of this type but with the specified TypeMetadata.
|
||||||
|
* Only to be used internally!
|
||||||
*/
|
*/
|
||||||
public abstract Type cloneWithMetadata(TypeMetadata metadata);
|
protected Type cloneWithMetadata(List<TypeMetadata> metadata) {
|
||||||
|
throw new AssertionError("Cannot add metadata to this type: " + getTag());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all the type metadata associated with this type.
|
||||||
|
*/
|
||||||
|
public List<TypeMetadata> getMetadata() {
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the type metadata of the given kind associated with this type (if any).
|
||||||
|
*/
|
||||||
|
public <M extends TypeMetadata> Optional<M> getMetadata(Class<M> metadataClass) {
|
||||||
|
return metadata.stream()
|
||||||
|
.filter(m -> metadataClass.isAssignableFrom(m.getClass()))
|
||||||
|
.map(metadataClass::cast)
|
||||||
|
.findFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new copy of this type but with the specified type metadata.
|
||||||
|
* If this type is already associated with a type metadata of the same class,
|
||||||
|
* an exception is thrown.
|
||||||
|
*/
|
||||||
|
public Type addMetadata(TypeMetadata md) {
|
||||||
|
Assert.check(getMetadata(md.getClass()).isEmpty());
|
||||||
|
return cloneWithMetadata(metadata.append(md));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new copy of this type but without the specified type metadata.
|
||||||
|
*/
|
||||||
|
public Type dropMetadata(Class<? extends TypeMetadata> metadataClass) {
|
||||||
|
List<TypeMetadata> newMetadata = metadata.stream()
|
||||||
|
.filter(m -> !metadataClass.isAssignableFrom(m.getClass()))
|
||||||
|
.collect(List.collector());
|
||||||
|
return cloneWithMetadata(newMetadata);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does this type require annotation stripping for API clients?
|
* Does this type require annotation stripping for API clients?
|
||||||
@ -398,24 +433,22 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public Type preannotatedType() {
|
||||||
|
return addMetadata(new Annotations());
|
||||||
|
}
|
||||||
|
|
||||||
public Type annotatedType(final List<Attribute.TypeCompound> annos) {
|
public Type annotatedType(final List<Attribute.TypeCompound> annos) {
|
||||||
final Entry annoMetadata = new TypeMetadata.Annotations(annos);
|
return addMetadata(new Annotations(annos));
|
||||||
return cloneWithMetadata(metadata.combine(annoMetadata));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAnnotated() {
|
public boolean isAnnotated() {
|
||||||
final TypeMetadata.Annotations metadata =
|
return getMetadata(TypeMetadata.Annotations.class).isPresent();
|
||||||
(TypeMetadata.Annotations)getMetadataOfKind(Entry.Kind.ANNOTATIONS);
|
|
||||||
|
|
||||||
return null != metadata && !metadata.getAnnotations().isEmpty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override @DefinedBy(Api.LANGUAGE_MODEL)
|
@Override @DefinedBy(Api.LANGUAGE_MODEL)
|
||||||
public List<Attribute.TypeCompound> getAnnotationMirrors() {
|
public List<Attribute.TypeCompound> getAnnotationMirrors() {
|
||||||
final TypeMetadata.Annotations metadata =
|
return getMetadata(TypeMetadata.Annotations.class)
|
||||||
(TypeMetadata.Annotations)getMetadataOfKind(Entry.Kind.ANNOTATIONS);
|
.map(Annotations::annotations).orElse(List.nil());
|
||||||
|
|
||||||
return metadata == null ? List.nil() : metadata.getAnnotations();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -688,17 +721,17 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
|||||||
TypeTag tag;
|
TypeTag tag;
|
||||||
|
|
||||||
public JCPrimitiveType(TypeTag tag, TypeSymbol tsym) {
|
public JCPrimitiveType(TypeTag tag, TypeSymbol tsym) {
|
||||||
this(tag, tsym, TypeMetadata.EMPTY);
|
this(tag, tsym, List.nil());
|
||||||
}
|
}
|
||||||
|
|
||||||
private JCPrimitiveType(TypeTag tag, TypeSymbol tsym, TypeMetadata metadata) {
|
private JCPrimitiveType(TypeTag tag, TypeSymbol tsym, List<TypeMetadata> metadata) {
|
||||||
super(tsym, metadata);
|
super(tsym, metadata);
|
||||||
this.tag = tag;
|
this.tag = tag;
|
||||||
Assert.check(tag.isPrimitive);
|
Assert.check(tag.isPrimitive);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JCPrimitiveType cloneWithMetadata(TypeMetadata md) {
|
protected JCPrimitiveType cloneWithMetadata(List<TypeMetadata> md) {
|
||||||
return new JCPrimitiveType(tag, tsym, md) {
|
return new JCPrimitiveType(tag, tsym, md) {
|
||||||
@Override
|
@Override
|
||||||
public Type baseType() { return JCPrimitiveType.this.baseType(); }
|
public Type baseType() { return JCPrimitiveType.this.baseType(); }
|
||||||
@ -744,17 +777,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Type constType(Object constValue) {
|
public Type constType(Object constValue) {
|
||||||
final Object value = constValue;
|
return addMetadata(new ConstantValue(constValue));
|
||||||
return new JCPrimitiveType(tag, tsym, metadata) {
|
|
||||||
@Override
|
|
||||||
public Object constValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public Type baseType() {
|
|
||||||
return tsym.type;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -829,21 +852,21 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
|||||||
}
|
}
|
||||||
|
|
||||||
public WildcardType(Type type, BoundKind kind, TypeSymbol tsym) {
|
public WildcardType(Type type, BoundKind kind, TypeSymbol tsym) {
|
||||||
this(type, kind, tsym, null, TypeMetadata.EMPTY);
|
this(type, kind, tsym, null, List.nil());
|
||||||
}
|
}
|
||||||
|
|
||||||
public WildcardType(Type type, BoundKind kind, TypeSymbol tsym,
|
public WildcardType(Type type, BoundKind kind, TypeSymbol tsym,
|
||||||
TypeMetadata metadata) {
|
List<TypeMetadata> metadata) {
|
||||||
this(type, kind, tsym, null, metadata);
|
this(type, kind, tsym, null, metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
public WildcardType(Type type, BoundKind kind, TypeSymbol tsym,
|
public WildcardType(Type type, BoundKind kind, TypeSymbol tsym,
|
||||||
TypeVar bound) {
|
TypeVar bound) {
|
||||||
this(type, kind, tsym, bound, TypeMetadata.EMPTY);
|
this(type, kind, tsym, bound, List.nil());
|
||||||
}
|
}
|
||||||
|
|
||||||
public WildcardType(Type type, BoundKind kind, TypeSymbol tsym,
|
public WildcardType(Type type, BoundKind kind, TypeSymbol tsym,
|
||||||
TypeVar bound, TypeMetadata metadata) {
|
TypeVar bound, List<TypeMetadata> metadata) {
|
||||||
super(tsym, metadata);
|
super(tsym, metadata);
|
||||||
this.type = Assert.checkNonNull(type);
|
this.type = Assert.checkNonNull(type);
|
||||||
this.kind = kind;
|
this.kind = kind;
|
||||||
@ -851,7 +874,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WildcardType cloneWithMetadata(TypeMetadata md) {
|
protected WildcardType cloneWithMetadata(List<TypeMetadata> md) {
|
||||||
return new WildcardType(type, kind, tsym, bound, md) {
|
return new WildcardType(type, kind, tsym, bound, md) {
|
||||||
@Override
|
@Override
|
||||||
public Type baseType() { return WildcardType.this.baseType(); }
|
public Type baseType() { return WildcardType.this.baseType(); }
|
||||||
@ -978,11 +1001,11 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
|||||||
public List<Type> all_interfaces_field;
|
public List<Type> all_interfaces_field;
|
||||||
|
|
||||||
public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym) {
|
public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym) {
|
||||||
this(outer, typarams, tsym, TypeMetadata.EMPTY);
|
this(outer, typarams, tsym, List.nil());
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym,
|
public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym,
|
||||||
TypeMetadata metadata) {
|
List<TypeMetadata> metadata) {
|
||||||
super(tsym, metadata);
|
super(tsym, metadata);
|
||||||
this.outer_field = outer;
|
this.outer_field = outer;
|
||||||
this.typarams_field = typarams;
|
this.typarams_field = typarams;
|
||||||
@ -996,7 +1019,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassType cloneWithMetadata(TypeMetadata md) {
|
protected ClassType cloneWithMetadata(List<TypeMetadata> md) {
|
||||||
return new ClassType(outer_field, typarams_field, tsym, md) {
|
return new ClassType(outer_field, typarams_field, tsym, md) {
|
||||||
@Override
|
@Override
|
||||||
public Type baseType() { return ClassType.this.baseType(); }
|
public Type baseType() { return ClassType.this.baseType(); }
|
||||||
@ -1014,17 +1037,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Type constType(Object constValue) {
|
public Type constType(Object constValue) {
|
||||||
final Object value = constValue;
|
return addMetadata(new ConstantValue(constValue));
|
||||||
return new ClassType(getEnclosingType(), typarams_field, tsym, metadata) {
|
|
||||||
@Override
|
|
||||||
public Object constValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public Type baseType() {
|
|
||||||
return tsym.type;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The Java source which this type represents.
|
/** The Java source which this type represents.
|
||||||
@ -1190,7 +1203,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
|||||||
|
|
||||||
public static class ErasedClassType extends ClassType {
|
public static class ErasedClassType extends ClassType {
|
||||||
public ErasedClassType(Type outer, TypeSymbol tsym,
|
public ErasedClassType(Type outer, TypeSymbol tsym,
|
||||||
TypeMetadata metadata) {
|
List<TypeMetadata> metadata) {
|
||||||
super(outer, List.nil(), tsym, metadata);
|
super(outer, List.nil(), tsym, metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1215,11 +1228,6 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
|||||||
alternatives_field = alternatives;
|
alternatives_field = alternatives;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public UnionClassType cloneWithMetadata(TypeMetadata md) {
|
|
||||||
throw new AssertionError("Cannot add metadata to a union type");
|
|
||||||
}
|
|
||||||
|
|
||||||
public Type getLub() {
|
public Type getLub() {
|
||||||
return tsym.type;
|
return tsym.type;
|
||||||
}
|
}
|
||||||
@ -1271,11 +1279,6 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
|||||||
!supertype_field.isInterface(), supertype_field);
|
!supertype_field.isInterface(), supertype_field);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public IntersectionClassType cloneWithMetadata(TypeMetadata md) {
|
|
||||||
throw new AssertionError("Cannot add metadata to an intersection type");
|
|
||||||
}
|
|
||||||
|
|
||||||
@DefinedBy(Api.LANGUAGE_MODEL)
|
@DefinedBy(Api.LANGUAGE_MODEL)
|
||||||
public java.util.List<? extends TypeMirror> getBounds() {
|
public java.util.List<? extends TypeMirror> getBounds() {
|
||||||
return Collections.unmodifiableList(getExplicitComponents());
|
return Collections.unmodifiableList(getExplicitComponents());
|
||||||
@ -1318,11 +1321,11 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
|||||||
public Type elemtype;
|
public Type elemtype;
|
||||||
|
|
||||||
public ArrayType(Type elemtype, TypeSymbol arrayClass) {
|
public ArrayType(Type elemtype, TypeSymbol arrayClass) {
|
||||||
this(elemtype, arrayClass, TypeMetadata.EMPTY);
|
this(elemtype, arrayClass, List.nil());
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayType(Type elemtype, TypeSymbol arrayClass,
|
public ArrayType(Type elemtype, TypeSymbol arrayClass,
|
||||||
TypeMetadata metadata) {
|
List<TypeMetadata> metadata) {
|
||||||
super(arrayClass, metadata);
|
super(arrayClass, metadata);
|
||||||
this.elemtype = elemtype;
|
this.elemtype = elemtype;
|
||||||
}
|
}
|
||||||
@ -1338,7 +1341,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayType cloneWithMetadata(TypeMetadata md) {
|
protected ArrayType cloneWithMetadata(List<TypeMetadata> md) {
|
||||||
return new ArrayType(elemtype, tsym, md) {
|
return new ArrayType(elemtype, tsym, md) {
|
||||||
@Override
|
@Override
|
||||||
public Type baseType() { return ArrayType.this.baseType(); }
|
public Type baseType() { return ArrayType.this.baseType(); }
|
||||||
@ -1463,17 +1466,12 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
|||||||
TypeSymbol methodClass) {
|
TypeSymbol methodClass) {
|
||||||
// Presently no way to refer to a method type directly, so
|
// Presently no way to refer to a method type directly, so
|
||||||
// we cannot put type annotations on it.
|
// we cannot put type annotations on it.
|
||||||
super(methodClass, TypeMetadata.EMPTY);
|
super(methodClass, List.nil());
|
||||||
this.argtypes = argtypes;
|
this.argtypes = argtypes;
|
||||||
this.restype = restype;
|
this.restype = restype;
|
||||||
this.thrown = thrown;
|
this.thrown = thrown;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public MethodType cloneWithMetadata(TypeMetadata md) {
|
|
||||||
throw new AssertionError("Cannot add metadata to a method type");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeTag getTag() {
|
public TypeTag getTag() {
|
||||||
return METHOD;
|
return METHOD;
|
||||||
@ -1560,12 +1558,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
|||||||
|
|
||||||
PackageType(PackageSymbol tsym) {
|
PackageType(PackageSymbol tsym) {
|
||||||
// Package types cannot be annotated
|
// Package types cannot be annotated
|
||||||
super(tsym, TypeMetadata.EMPTY);
|
super(tsym, List.nil());
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PackageType cloneWithMetadata(TypeMetadata md) {
|
|
||||||
throw new AssertionError("Cannot add metadata to a package type");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1598,12 +1591,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
|||||||
|
|
||||||
ModuleType(ModuleSymbol tsym) {
|
ModuleType(ModuleSymbol tsym) {
|
||||||
// Module types cannot be annotated
|
// Module types cannot be annotated
|
||||||
super(tsym, TypeMetadata.EMPTY);
|
super(tsym, List.nil());
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ModuleType cloneWithMetadata(TypeMetadata md) {
|
|
||||||
throw new AssertionError("Cannot add metadata to a module type");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1659,7 +1647,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
|||||||
public Type lower;
|
public Type lower;
|
||||||
|
|
||||||
public TypeVar(Name name, Symbol owner, Type lower) {
|
public TypeVar(Name name, Symbol owner, Type lower) {
|
||||||
super(null, TypeMetadata.EMPTY);
|
super(null, List.nil());
|
||||||
Assert.checkNonNull(lower);
|
Assert.checkNonNull(lower);
|
||||||
tsym = new TypeVariableSymbol(0, name, this, owner);
|
tsym = new TypeVariableSymbol(0, name, this, owner);
|
||||||
this.setUpperBound(null);
|
this.setUpperBound(null);
|
||||||
@ -1667,11 +1655,11 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
|||||||
}
|
}
|
||||||
|
|
||||||
public TypeVar(TypeSymbol tsym, Type bound, Type lower) {
|
public TypeVar(TypeSymbol tsym, Type bound, Type lower) {
|
||||||
this(tsym, bound, lower, TypeMetadata.EMPTY);
|
this(tsym, bound, lower, List.nil());
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeVar(TypeSymbol tsym, Type bound, Type lower,
|
public TypeVar(TypeSymbol tsym, Type bound, Type lower,
|
||||||
TypeMetadata metadata) {
|
List<TypeMetadata> metadata) {
|
||||||
super(tsym, metadata);
|
super(tsym, metadata);
|
||||||
Assert.checkNonNull(lower);
|
Assert.checkNonNull(lower);
|
||||||
this.setUpperBound(bound);
|
this.setUpperBound(bound);
|
||||||
@ -1679,7 +1667,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeVar cloneWithMetadata(TypeMetadata md) {
|
protected TypeVar cloneWithMetadata(List<TypeMetadata> md) {
|
||||||
return new TypeVar(tsym, getUpperBound(), lower, md) {
|
return new TypeVar(tsym, getUpperBound(), lower, md) {
|
||||||
@Override
|
@Override
|
||||||
public Type baseType() { return TypeVar.this.baseType(); }
|
public Type baseType() { return TypeVar.this.baseType(); }
|
||||||
@ -1762,13 +1750,13 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
|||||||
Type upper,
|
Type upper,
|
||||||
Type lower,
|
Type lower,
|
||||||
WildcardType wildcard,
|
WildcardType wildcard,
|
||||||
TypeMetadata metadata) {
|
List<TypeMetadata> metadata) {
|
||||||
super(tsym, bound, lower, metadata);
|
super(tsym, bound, lower, metadata);
|
||||||
this.wildcard = wildcard;
|
this.wildcard = wildcard;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CapturedType cloneWithMetadata(TypeMetadata md) {
|
protected CapturedType cloneWithMetadata(List<TypeMetadata> md) {
|
||||||
return new CapturedType(tsym, getUpperBound(), getUpperBound(), lower, wildcard, md) {
|
return new CapturedType(tsym, getUpperBound(), getUpperBound(), lower, wildcard, md) {
|
||||||
@Override
|
@Override
|
||||||
public Type baseType() { return CapturedType.this.baseType(); }
|
public Type baseType() { return CapturedType.this.baseType(); }
|
||||||
@ -1807,11 +1795,11 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
|||||||
public TypeTag tag;
|
public TypeTag tag;
|
||||||
|
|
||||||
public DelegatedType(TypeTag tag, Type qtype) {
|
public DelegatedType(TypeTag tag, Type qtype) {
|
||||||
this(tag, qtype, TypeMetadata.EMPTY);
|
this(tag, qtype, List.nil());
|
||||||
}
|
}
|
||||||
|
|
||||||
public DelegatedType(TypeTag tag, Type qtype,
|
public DelegatedType(TypeTag tag, Type qtype,
|
||||||
TypeMetadata metadata) {
|
List<TypeMetadata> metadata) {
|
||||||
super(qtype.tsym, metadata);
|
super(qtype.tsym, metadata);
|
||||||
this.tag = tag;
|
this.tag = tag;
|
||||||
this.qtype = qtype;
|
this.qtype = qtype;
|
||||||
@ -1844,11 +1832,6 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
|||||||
this.tvars = tvars;
|
this.tvars = tvars;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ForAll cloneWithMetadata(TypeMetadata md) {
|
|
||||||
throw new AssertionError("Cannot add metadata to a forall type");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <R,S> R accept(Type.Visitor<R,S> v, S s) {
|
public <R,S> R accept(Type.Visitor<R,S> v, S s) {
|
||||||
return v.visitForAll(this, s);
|
return v.visitForAll(this, s);
|
||||||
@ -2077,11 +2060,6 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
|||||||
uv2.kind = kind;
|
uv2.kind = kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public UndetVar cloneWithMetadata(TypeMetadata md) {
|
|
||||||
throw new AssertionError("Cannot add metadata to an UndetVar type");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPartial() {
|
public boolean isPartial() {
|
||||||
return true;
|
return true;
|
||||||
@ -2224,12 +2202,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
|||||||
// Need to use List.nil(), because JCNoType constructor
|
// Need to use List.nil(), because JCNoType constructor
|
||||||
// gets called in static initializers in Type, where
|
// gets called in static initializers in Type, where
|
||||||
// noAnnotations is also defined.
|
// noAnnotations is also defined.
|
||||||
super(null, TypeMetadata.EMPTY);
|
super(null, List.nil());
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JCNoType cloneWithMetadata(TypeMetadata md) {
|
|
||||||
throw new AssertionError("Cannot add metadata to a JCNoType");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -2257,12 +2230,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
|||||||
|
|
||||||
public JCVoidType() {
|
public JCVoidType() {
|
||||||
// Void cannot be annotated
|
// Void cannot be annotated
|
||||||
super(null, TypeMetadata.EMPTY);
|
super(null, List.nil());
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JCVoidType cloneWithMetadata(TypeMetadata md) {
|
|
||||||
throw new AssertionError("Cannot add metadata to a void type");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -2292,12 +2260,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
|||||||
static class BottomType extends Type implements NullType {
|
static class BottomType extends Type implements NullType {
|
||||||
public BottomType() {
|
public BottomType() {
|
||||||
// Bottom is a synthesized internal type, so it cannot be annotated
|
// Bottom is a synthesized internal type, so it cannot be annotated
|
||||||
super(null, TypeMetadata.EMPTY);
|
super(null, List.nil());
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BottomType cloneWithMetadata(TypeMetadata md) {
|
|
||||||
throw new AssertionError("Cannot add metadata to a bottom type");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -2354,14 +2317,14 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
|||||||
}
|
}
|
||||||
|
|
||||||
private ErrorType(Type originalType, TypeSymbol tsym,
|
private ErrorType(Type originalType, TypeSymbol tsym,
|
||||||
TypeMetadata metadata) {
|
List<TypeMetadata> metadata) {
|
||||||
super(noType, List.nil(), null, metadata);
|
super(noType, List.nil(), null, metadata);
|
||||||
this.tsym = tsym;
|
this.tsym = tsym;
|
||||||
this.originalType = (originalType == null ? noType : originalType);
|
this.originalType = (originalType == null ? noType : originalType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ErrorType cloneWithMetadata(TypeMetadata md) {
|
protected ErrorType cloneWithMetadata(List<TypeMetadata> md) {
|
||||||
return new ErrorType(originalType, tsym, md) {
|
return new ErrorType(originalType, tsym, md) {
|
||||||
@Override
|
@Override
|
||||||
public Type baseType() { return ErrorType.this.baseType(); }
|
public Type baseType() { return ErrorType.this.baseType(); }
|
||||||
@ -2432,12 +2395,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
|||||||
public UnknownType() {
|
public UnknownType() {
|
||||||
// Unknown is a synthesized internal type, so it cannot be
|
// Unknown is a synthesized internal type, so it cannot be
|
||||||
// annotated.
|
// annotated.
|
||||||
super(null, TypeMetadata.EMPTY);
|
super(null, List.nil());
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UnknownType cloneWithMetadata(TypeMetadata md) {
|
|
||||||
throw new AssertionError("Cannot add metadata to an unknown type");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -25,181 +25,55 @@
|
|||||||
|
|
||||||
package com.sun.tools.javac.code;
|
package com.sun.tools.javac.code;
|
||||||
|
|
||||||
import com.sun.tools.javac.util.Assert;
|
|
||||||
import com.sun.tools.javac.util.List;
|
import com.sun.tools.javac.util.List;
|
||||||
import java.util.EnumMap;
|
import com.sun.tools.javac.util.ListBuffer;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TypeMetadata is essentially an immutable {@code EnumMap<Entry.Kind, <? extends Entry>>}
|
* A type metadata is an object that can be stapled on a type. This is typically done using
|
||||||
*
|
* {@link Type#addMetadata(TypeMetadata)}. Metadata associated to a type can also be removed,
|
||||||
* A metadata class represented by a subtype of Entry can express a property on a Type instance.
|
* typically using {@link Type#dropMetadata(Class)}. To drop <em>all</em> metadata from a given type,
|
||||||
* There should be at most one instance of an Entry per Entry.Kind on any given Type instance.
|
* the {@link Type#baseType()} method can also be used. This can be useful when comparing two
|
||||||
*
|
* using reference equality (see also {@link Type#equalsIgnoreMetadata(Type)}).
|
||||||
* Metadata classes of a specific kind are responsible for how they combine themselves.
|
* <p>
|
||||||
*
|
* There are no constraints on how a type metadata should be defined. Typically, a type
|
||||||
* @implNote {@code Entry:combine} need not be commutative.
|
* metadata will be defined as a small record, storing additional information (see {@link ConstantValue}).
|
||||||
|
* In other cases, type metadata can be mutable and support complex state transitions
|
||||||
|
* (see {@link Annotations}).
|
||||||
|
* <p>
|
||||||
|
* The only invariant the implementation requires is that there must be <em>one</em> metadata
|
||||||
|
* of a given kind attached to a type, as this makes accessing and dropping metadata simpler.
|
||||||
|
* If clients wish to store multiple metadata values that are logically related, they should
|
||||||
|
* define a metadata type that collects such values in e.g. a list.
|
||||||
*/
|
*/
|
||||||
public class TypeMetadata {
|
public sealed interface TypeMetadata {
|
||||||
public static final TypeMetadata EMPTY = new TypeMetadata();
|
|
||||||
|
|
||||||
private final EnumMap<Entry.Kind, Entry> contents;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new empty TypeMetadata map.
|
* A type metadata object holding type annotations. This metadata needs to be mutable,
|
||||||
|
* because type annotations are sometimes set in two steps. That is, a type can be created with
|
||||||
|
* an empty set of annotations (e.g. during member enter). At some point later, the type
|
||||||
|
* is then updated to contain the correct annotations. At this point we need to augment
|
||||||
|
* the existing type (rather than creating a new one), as the type might already have been
|
||||||
|
* saved inside other symbols.
|
||||||
*/
|
*/
|
||||||
private TypeMetadata() {
|
record Annotations(ListBuffer<Attribute.TypeCompound> annotationBuffer) implements TypeMetadata {
|
||||||
contents = new EnumMap<>(Entry.Kind.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
Annotations() {
|
||||||
* Create a new TypeMetadata map containing the Entry {@code elem}.
|
this(new ListBuffer<>());
|
||||||
*
|
|
||||||
* @param elem the sole contents of this map
|
|
||||||
*/
|
|
||||||
public TypeMetadata(Entry elem) {
|
|
||||||
this();
|
|
||||||
Assert.checkNonNull(elem);
|
|
||||||
contents.put(elem.kind(), elem);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a copy of TypeMetadata {@code other} with a shallow copy the other's metadata contents.
|
|
||||||
*
|
|
||||||
* @param other the TypeMetadata to copy contents from.
|
|
||||||
*/
|
|
||||||
public TypeMetadata(TypeMetadata other) {
|
|
||||||
Assert.checkNonNull(other);
|
|
||||||
contents = other.contents.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a copy of this TypeMetadata with the metadata entry for {@code elem.kind()} combined
|
|
||||||
* with {@code elem}.
|
|
||||||
*
|
|
||||||
* @param elem the new value
|
|
||||||
* @return a new TypeMetadata updated with {@code Entry elem}
|
|
||||||
*/
|
|
||||||
public TypeMetadata combine(Entry elem) {
|
|
||||||
Assert.checkNonNull(elem);
|
|
||||||
|
|
||||||
TypeMetadata out = new TypeMetadata(this);
|
|
||||||
Entry.Kind key = elem.kind();
|
|
||||||
if (contents.containsKey(key)) {
|
|
||||||
out.add(key, this.contents.get(key).combine(elem));
|
|
||||||
} else {
|
|
||||||
out.add(key, elem);
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a copy of this TypeMetadata with the metadata entry for all kinds from {@code other}
|
|
||||||
* combined with the same kind from this.
|
|
||||||
*
|
|
||||||
* @param other the TypeMetadata to combine with this
|
|
||||||
* @return a new TypeMetadata updated with all entries from {@code other}
|
|
||||||
*/
|
|
||||||
public TypeMetadata combineAll(TypeMetadata other) {
|
|
||||||
Assert.checkNonNull(other);
|
|
||||||
|
|
||||||
TypeMetadata out = new TypeMetadata();
|
|
||||||
Set<Entry.Kind> keys = new HashSet<>(contents.keySet());
|
|
||||||
keys.addAll(other.contents.keySet());
|
|
||||||
|
|
||||||
for(Entry.Kind key : keys) {
|
|
||||||
if (contents.containsKey(key)) {
|
|
||||||
if (other.contents.containsKey(key)) {
|
|
||||||
out.add(key, contents.get(key).combine(other.contents.get(key)));
|
|
||||||
} else {
|
|
||||||
out.add(key, contents.get(key));
|
|
||||||
}
|
|
||||||
} else if (other.contents.containsKey(key)) {
|
|
||||||
out.add(key, other.contents.get(key));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a TypeMetadata with the metadata entry for {@code kind} removed.
|
|
||||||
*
|
|
||||||
* This may be the same instance or a new TypeMetadata.
|
|
||||||
*
|
|
||||||
* @param kind the {@code Kind} to remove metadata for
|
|
||||||
* @return a new TypeMetadata without {@code Kind kind}
|
|
||||||
*/
|
|
||||||
public TypeMetadata without(Entry.Kind kind) {
|
|
||||||
if (this == EMPTY || contents.get(kind) == null)
|
|
||||||
return this;
|
|
||||||
|
|
||||||
TypeMetadata out = new TypeMetadata(this);
|
|
||||||
out.contents.remove(kind);
|
|
||||||
return out.contents.isEmpty() ? EMPTY : out;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Entry get(Entry.Kind kind) {
|
|
||||||
return contents.get(kind);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void add(Entry.Kind kind, Entry elem) {
|
|
||||||
contents.put(kind, elem);
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface Entry {
|
|
||||||
|
|
||||||
public enum Kind {
|
|
||||||
ANNOTATIONS
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
Annotations(List<Attribute.TypeCompound> annotations) {
|
||||||
* Get the kind of metadata this object represents
|
this();
|
||||||
*/
|
annotationBuffer.appendList(annotations);
|
||||||
public Kind kind();
|
}
|
||||||
|
|
||||||
/**
|
List<Attribute.TypeCompound> annotations() {
|
||||||
* Combine this type metadata with another metadata of the
|
return annotationBuffer.toList();
|
||||||
* same kind.
|
}
|
||||||
*
|
|
||||||
* @param other The metadata with which to combine this one.
|
|
||||||
* @return The combined metadata.
|
|
||||||
*/
|
|
||||||
public Entry combine(Entry other);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A type metadata object holding type annotations.
|
* A type metadata holding a constant value. This can be used to describe constant types,
|
||||||
|
* such as the type of a string literal, or that of a numeric constant.
|
||||||
*/
|
*/
|
||||||
public static class Annotations implements Entry {
|
record ConstantValue(Object value) implements TypeMetadata { }
|
||||||
private List<Attribute.TypeCompound> annos;
|
|
||||||
|
|
||||||
public static final List<Attribute.TypeCompound> TO_BE_SET = List.nil();
|
|
||||||
|
|
||||||
public Annotations(List<Attribute.TypeCompound> annos) {
|
|
||||||
this.annos = annos;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the type annotations contained in this metadata.
|
|
||||||
*
|
|
||||||
* @return The annotations.
|
|
||||||
*/
|
|
||||||
public List<Attribute.TypeCompound> getAnnotations() {
|
|
||||||
return annos;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Annotations combine(Entry other) {
|
|
||||||
Assert.check(annos == TO_BE_SET);
|
|
||||||
annos = ((Annotations)other).annos;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Kind kind() { return Kind.ANNOTATIONS; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() { return "ANNOTATIONS [ " + annos + " ]"; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ import com.sun.tools.javac.code.Attribute.RetentionPolicy;
|
|||||||
import com.sun.tools.javac.code.Lint.LintCategory;
|
import com.sun.tools.javac.code.Lint.LintCategory;
|
||||||
import com.sun.tools.javac.code.Source.Feature;
|
import com.sun.tools.javac.code.Source.Feature;
|
||||||
import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
|
import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
|
||||||
import com.sun.tools.javac.code.TypeMetadata.Entry.Kind;
|
import com.sun.tools.javac.code.TypeMetadata.Annotations;
|
||||||
import com.sun.tools.javac.comp.AttrContext;
|
import com.sun.tools.javac.comp.AttrContext;
|
||||||
import com.sun.tools.javac.comp.Check;
|
import com.sun.tools.javac.comp.Check;
|
||||||
import com.sun.tools.javac.comp.Enter;
|
import com.sun.tools.javac.comp.Enter;
|
||||||
@ -2399,7 +2399,7 @@ public class Types {
|
|||||||
private TypeMapping<Boolean> erasure = new StructuralTypeMapping<Boolean>() {
|
private TypeMapping<Boolean> erasure = new StructuralTypeMapping<Boolean>() {
|
||||||
private Type combineMetadata(final Type s,
|
private Type combineMetadata(final Type s,
|
||||||
final Type t) {
|
final Type t) {
|
||||||
if (t.getMetadata() != TypeMetadata.EMPTY) {
|
if (t.getMetadata().nonEmpty()) {
|
||||||
switch (s.getKind()) {
|
switch (s.getKind()) {
|
||||||
case OTHER:
|
case OTHER:
|
||||||
case UNION:
|
case UNION:
|
||||||
@ -2410,7 +2410,7 @@ public class Types {
|
|||||||
case VOID:
|
case VOID:
|
||||||
case ERROR:
|
case ERROR:
|
||||||
return s;
|
return s;
|
||||||
default: return s.cloneWithMetadata(s.getMetadata().without(Kind.ANNOTATIONS));
|
default: return s.dropMetadata(Annotations.class);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return s;
|
return s;
|
||||||
@ -2437,7 +2437,7 @@ public class Types {
|
|||||||
Type erased = t.tsym.erasure(Types.this);
|
Type erased = t.tsym.erasure(Types.this);
|
||||||
if (recurse) {
|
if (recurse) {
|
||||||
erased = new ErasedClassType(erased.getEnclosingType(),erased.tsym,
|
erased = new ErasedClassType(erased.getEnclosingType(),erased.tsym,
|
||||||
t.getMetadata().without(Kind.ANNOTATIONS));
|
t.dropMetadata(Annotations.class).getMetadata());
|
||||||
return erased;
|
return erased;
|
||||||
} else {
|
} else {
|
||||||
return combineMetadata(erased, t);
|
return combineMetadata(erased, t);
|
||||||
|
@ -32,7 +32,7 @@ import com.sun.tools.javac.code.Kinds.KindSelector;
|
|||||||
import com.sun.tools.javac.code.Scope.WriteableScope;
|
import com.sun.tools.javac.code.Scope.WriteableScope;
|
||||||
import com.sun.tools.javac.code.Source.Feature;
|
import com.sun.tools.javac.code.Source.Feature;
|
||||||
import com.sun.tools.javac.code.Symbol.*;
|
import com.sun.tools.javac.code.Symbol.*;
|
||||||
import com.sun.tools.javac.code.TypeMetadata.Entry.Kind;
|
import com.sun.tools.javac.code.TypeMetadata.Annotations;
|
||||||
import com.sun.tools.javac.comp.Check.CheckContext;
|
import com.sun.tools.javac.comp.Check.CheckContext;
|
||||||
import com.sun.tools.javac.resources.CompilerProperties.Errors;
|
import com.sun.tools.javac.resources.CompilerProperties.Errors;
|
||||||
import com.sun.tools.javac.resources.CompilerProperties.Fragments;
|
import com.sun.tools.javac.resources.CompilerProperties.Fragments;
|
||||||
@ -1049,7 +1049,10 @@ public class Annotate {
|
|||||||
typeAnnotation(() -> {
|
typeAnnotation(() -> {
|
||||||
List<Attribute.TypeCompound> compounds = fromAnnotations(annotations);
|
List<Attribute.TypeCompound> compounds = fromAnnotations(annotations);
|
||||||
Assert.check(annotations.size() == compounds.size());
|
Assert.check(annotations.size() == compounds.size());
|
||||||
storeAt.getMetadataOfKind(Kind.ANNOTATIONS).combine(new TypeMetadata.Annotations(compounds));
|
// the type already has annotation metadata, but it's empty
|
||||||
|
Annotations metadata = storeAt.getMetadata(Annotations.class).orElseThrow(AssertionError::new);
|
||||||
|
Assert.check(metadata.annotationBuffer().isEmpty());
|
||||||
|
metadata.annotationBuffer().appendList(compounds);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,6 @@ import com.sun.tools.javac.code.Scope.WriteableScope;
|
|||||||
import com.sun.tools.javac.code.Source.Feature;
|
import com.sun.tools.javac.code.Source.Feature;
|
||||||
import com.sun.tools.javac.code.Symbol.*;
|
import com.sun.tools.javac.code.Symbol.*;
|
||||||
import com.sun.tools.javac.code.Type.*;
|
import com.sun.tools.javac.code.Type.*;
|
||||||
import com.sun.tools.javac.code.TypeMetadata.Annotations;
|
|
||||||
import com.sun.tools.javac.code.Types.FunctionDescriptorLookupError;
|
import com.sun.tools.javac.code.Types.FunctionDescriptorLookupError;
|
||||||
import com.sun.tools.javac.comp.ArgumentAttr.LocalCacheContext;
|
import com.sun.tools.javac.comp.ArgumentAttr.LocalCacheContext;
|
||||||
import com.sun.tools.javac.comp.Check.CheckContext;
|
import com.sun.tools.javac.comp.Check.CheckContext;
|
||||||
@ -5210,7 +5209,7 @@ public class Attr extends JCTree.Visitor {
|
|||||||
public void visitAnnotatedType(JCAnnotatedType tree) {
|
public void visitAnnotatedType(JCAnnotatedType tree) {
|
||||||
attribAnnotationTypes(tree.annotations, env);
|
attribAnnotationTypes(tree.annotations, env);
|
||||||
Type underlyingType = attribType(tree.underlyingType, env);
|
Type underlyingType = attribType(tree.underlyingType, env);
|
||||||
Type annotatedType = underlyingType.annotatedType(Annotations.TO_BE_SET);
|
Type annotatedType = underlyingType.preannotatedType();
|
||||||
|
|
||||||
if (!env.info.isNewClass)
|
if (!env.info.isNewClass)
|
||||||
annotate.annotateTypeSecondStage(tree, tree.annotations, annotatedType);
|
annotate.annotateTypeSecondStage(tree, tree.annotations, annotatedType);
|
||||||
|
@ -221,17 +221,12 @@ public class DeferredAttr extends JCTree.Visitor {
|
|||||||
SpeculativeCache speculativeCache;
|
SpeculativeCache speculativeCache;
|
||||||
|
|
||||||
DeferredType(JCExpression tree, Env<AttrContext> env) {
|
DeferredType(JCExpression tree, Env<AttrContext> env) {
|
||||||
super(null, TypeMetadata.EMPTY);
|
super(null, List.nil());
|
||||||
this.tree = tree;
|
this.tree = tree;
|
||||||
this.env = attr.copyEnv(env);
|
this.env = attr.copyEnv(env);
|
||||||
this.speculativeCache = new SpeculativeCache();
|
this.speculativeCache = new SpeculativeCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public DeferredType cloneWithMetadata(TypeMetadata md) {
|
|
||||||
throw new AssertionError("Cannot add metadata to a deferred type");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeTag getTag() {
|
public TypeTag getTag() {
|
||||||
return DEFERRED;
|
return DEFERRED;
|
||||||
|
@ -2925,7 +2925,7 @@ public class ClassReader {
|
|||||||
private final Name name;
|
private final Name name;
|
||||||
|
|
||||||
public ProxyType(int index) {
|
public ProxyType(int index) {
|
||||||
super(syms.noSymbol, TypeMetadata.EMPTY);
|
super(syms.noSymbol, List.nil());
|
||||||
this.name = poolReader.getName(index);
|
this.name = poolReader.getName(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2934,11 +2934,6 @@ public class ClassReader {
|
|||||||
return TypeTag.NONE;
|
return TypeTag.NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type cloneWithMetadata(TypeMetadata metadata) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Type resolve() {
|
public Type resolve() {
|
||||||
return name.map(ClassReader.this::sigToType);
|
return name.map(ClassReader.this::sigToType);
|
||||||
}
|
}
|
||||||
|
@ -53,13 +53,13 @@ class UninitializedType extends Type.DelegatedType {
|
|||||||
|
|
||||||
public final int offset; // PC where allocation took place
|
public final int offset; // PC where allocation took place
|
||||||
private UninitializedType(TypeTag tag, Type qtype, int offset,
|
private UninitializedType(TypeTag tag, Type qtype, int offset,
|
||||||
TypeMetadata metadata) {
|
List<TypeMetadata> metadata) {
|
||||||
super(tag, qtype, metadata);
|
super(tag, qtype, metadata);
|
||||||
this.offset = offset;
|
this.offset = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UninitializedType cloneWithMetadata(final TypeMetadata md) {
|
protected UninitializedType cloneWithMetadata(final List<TypeMetadata> md) {
|
||||||
return new UninitializedType(tag, qtype, offset, md);
|
return new UninitializedType(tag, qtype, offset, md);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user