diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java index 9e957444df2..9c7663ec852 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java @@ -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. * * 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.EnumMap; import java.util.Map; +import java.util.Optional; import java.util.function.Predicate; import javax.lang.model.type.*; 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.UniqueType; 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 * entry of that class. */ - protected final TypeMetadata metadata; - - public TypeMetadata getMetadata() { - return metadata; - } - - public Entry getMetadataOfKind(final Entry.Kind kind) { - return metadata != null ? metadata.get(kind) : null; - } + protected final List metadata; /** Constant type: no type at all. */ 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 */ public Object constValue() { - return null; + return getMetadata(TypeMetadata.ConstantValue.class) + .map(ConstantValue::value).orElse(null); } /** 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 */ - public Type(TypeSymbol tsym, TypeMetadata metadata) { + public Type(TypeSymbol tsym, List metadata) { Assert.checkNonNull(metadata); this.tsym = tsym; this.metadata = metadata; @@ -345,13 +340,53 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons * it should not be used outside this class. */ 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. + * Only to be used internally! */ - public abstract Type cloneWithMetadata(TypeMetadata metadata); + protected Type cloneWithMetadata(List metadata) { + throw new AssertionError("Cannot add metadata to this type: " + getTag()); + } + + /** + * Get all the type metadata associated with this type. + */ + public List getMetadata() { + return metadata; + } + + /** + * Get the type metadata of the given kind associated with this type (if any). + */ + public Optional getMetadata(Class 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 metadataClass) { + List newMetadata = metadata.stream() + .filter(m -> !metadataClass.isAssignableFrom(m.getClass())) + .collect(List.collector()); + return cloneWithMetadata(newMetadata); + } /** * 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 annos) { - final Entry annoMetadata = new TypeMetadata.Annotations(annos); - return cloneWithMetadata(metadata.combine(annoMetadata)); + return addMetadata(new Annotations(annos)); } public boolean isAnnotated() { - final TypeMetadata.Annotations metadata = - (TypeMetadata.Annotations)getMetadataOfKind(Entry.Kind.ANNOTATIONS); - - return null != metadata && !metadata.getAnnotations().isEmpty(); + return getMetadata(TypeMetadata.Annotations.class).isPresent(); } @Override @DefinedBy(Api.LANGUAGE_MODEL) public List getAnnotationMirrors() { - final TypeMetadata.Annotations metadata = - (TypeMetadata.Annotations)getMetadataOfKind(Entry.Kind.ANNOTATIONS); - - return metadata == null ? List.nil() : metadata.getAnnotations(); + return getMetadata(TypeMetadata.Annotations.class) + .map(Annotations::annotations).orElse(List.nil()); } @@ -688,17 +721,17 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons TypeTag tag; 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 metadata) { super(tsym, metadata); this.tag = tag; Assert.check(tag.isPrimitive); } @Override - public JCPrimitiveType cloneWithMetadata(TypeMetadata md) { + protected JCPrimitiveType cloneWithMetadata(List md) { return new JCPrimitiveType(tag, tsym, md) { @Override public Type baseType() { return JCPrimitiveType.this.baseType(); } @@ -744,17 +777,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons */ @Override public Type constType(Object constValue) { - final Object value = constValue; - return new JCPrimitiveType(tag, tsym, metadata) { - @Override - public Object constValue() { - return value; - } - @Override - public Type baseType() { - return tsym.type; - } - }; + return addMetadata(new ConstantValue(constValue)); } /** @@ -829,21 +852,21 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons } 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, - TypeMetadata metadata) { + List metadata) { this(type, kind, tsym, null, metadata); } public WildcardType(Type type, BoundKind kind, TypeSymbol tsym, TypeVar bound) { - this(type, kind, tsym, bound, TypeMetadata.EMPTY); + this(type, kind, tsym, bound, List.nil()); } public WildcardType(Type type, BoundKind kind, TypeSymbol tsym, - TypeVar bound, TypeMetadata metadata) { + TypeVar bound, List metadata) { super(tsym, metadata); this.type = Assert.checkNonNull(type); this.kind = kind; @@ -851,7 +874,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons } @Override - public WildcardType cloneWithMetadata(TypeMetadata md) { + protected WildcardType cloneWithMetadata(List md) { return new WildcardType(type, kind, tsym, bound, md) { @Override public Type baseType() { return WildcardType.this.baseType(); } @@ -978,11 +1001,11 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons public List all_interfaces_field; public ClassType(Type outer, List typarams, TypeSymbol tsym) { - this(outer, typarams, tsym, TypeMetadata.EMPTY); + this(outer, typarams, tsym, List.nil()); } public ClassType(Type outer, List typarams, TypeSymbol tsym, - TypeMetadata metadata) { + List metadata) { super(tsym, metadata); this.outer_field = outer; this.typarams_field = typarams; @@ -996,7 +1019,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons } @Override - public ClassType cloneWithMetadata(TypeMetadata md) { + protected ClassType cloneWithMetadata(List md) { return new ClassType(outer_field, typarams_field, tsym, md) { @Override 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) { - final Object value = constValue; - return new ClassType(getEnclosingType(), typarams_field, tsym, metadata) { - @Override - public Object constValue() { - return value; - } - @Override - public Type baseType() { - return tsym.type; - } - }; + return addMetadata(new ConstantValue(constValue)); } /** 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 ErasedClassType(Type outer, TypeSymbol tsym, - TypeMetadata metadata) { + List metadata) { super(outer, List.nil(), tsym, metadata); } @@ -1215,11 +1228,6 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons alternatives_field = alternatives; } - @Override - public UnionClassType cloneWithMetadata(TypeMetadata md) { - throw new AssertionError("Cannot add metadata to a union type"); - } - public Type getLub() { return tsym.type; } @@ -1271,11 +1279,6 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons !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) public java.util.List getBounds() { return Collections.unmodifiableList(getExplicitComponents()); @@ -1318,11 +1321,11 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons public Type elemtype; public ArrayType(Type elemtype, TypeSymbol arrayClass) { - this(elemtype, arrayClass, TypeMetadata.EMPTY); + this(elemtype, arrayClass, List.nil()); } public ArrayType(Type elemtype, TypeSymbol arrayClass, - TypeMetadata metadata) { + List metadata) { super(arrayClass, metadata); this.elemtype = elemtype; } @@ -1338,7 +1341,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons } @Override - public ArrayType cloneWithMetadata(TypeMetadata md) { + protected ArrayType cloneWithMetadata(List md) { return new ArrayType(elemtype, tsym, md) { @Override public Type baseType() { return ArrayType.this.baseType(); } @@ -1463,17 +1466,12 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons TypeSymbol methodClass) { // Presently no way to refer to a method type directly, so // we cannot put type annotations on it. - super(methodClass, TypeMetadata.EMPTY); + super(methodClass, List.nil()); this.argtypes = argtypes; this.restype = restype; this.thrown = thrown; } - @Override - public MethodType cloneWithMetadata(TypeMetadata md) { - throw new AssertionError("Cannot add metadata to a method type"); - } - @Override public TypeTag getTag() { return METHOD; @@ -1560,12 +1558,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons PackageType(PackageSymbol tsym) { // Package types cannot be annotated - super(tsym, TypeMetadata.EMPTY); - } - - @Override - public PackageType cloneWithMetadata(TypeMetadata md) { - throw new AssertionError("Cannot add metadata to a package type"); + super(tsym, List.nil()); } @Override @@ -1598,12 +1591,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons ModuleType(ModuleSymbol tsym) { // Module types cannot be annotated - super(tsym, TypeMetadata.EMPTY); - } - - @Override - public ModuleType cloneWithMetadata(TypeMetadata md) { - throw new AssertionError("Cannot add metadata to a module type"); + super(tsym, List.nil()); } @Override @@ -1659,7 +1647,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons public Type lower; public TypeVar(Name name, Symbol owner, Type lower) { - super(null, TypeMetadata.EMPTY); + super(null, List.nil()); Assert.checkNonNull(lower); tsym = new TypeVariableSymbol(0, name, this, owner); this.setUpperBound(null); @@ -1667,11 +1655,11 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons } 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, - TypeMetadata metadata) { + List metadata) { super(tsym, metadata); Assert.checkNonNull(lower); this.setUpperBound(bound); @@ -1679,7 +1667,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons } @Override - public TypeVar cloneWithMetadata(TypeMetadata md) { + protected TypeVar cloneWithMetadata(List md) { return new TypeVar(tsym, getUpperBound(), lower, md) { @Override public Type baseType() { return TypeVar.this.baseType(); } @@ -1762,13 +1750,13 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons Type upper, Type lower, WildcardType wildcard, - TypeMetadata metadata) { + List metadata) { super(tsym, bound, lower, metadata); this.wildcard = wildcard; } @Override - public CapturedType cloneWithMetadata(TypeMetadata md) { + protected CapturedType cloneWithMetadata(List md) { return new CapturedType(tsym, getUpperBound(), getUpperBound(), lower, wildcard, md) { @Override public Type baseType() { return CapturedType.this.baseType(); } @@ -1807,11 +1795,11 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons public TypeTag tag; public DelegatedType(TypeTag tag, Type qtype) { - this(tag, qtype, TypeMetadata.EMPTY); + this(tag, qtype, List.nil()); } public DelegatedType(TypeTag tag, Type qtype, - TypeMetadata metadata) { + List metadata) { super(qtype.tsym, metadata); this.tag = tag; this.qtype = qtype; @@ -1844,11 +1832,6 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons this.tvars = tvars; } - @Override - public ForAll cloneWithMetadata(TypeMetadata md) { - throw new AssertionError("Cannot add metadata to a forall type"); - } - @Override public R accept(Type.Visitor v, S s) { return v.visitForAll(this, s); @@ -2077,11 +2060,6 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons uv2.kind = kind; } - @Override - public UndetVar cloneWithMetadata(TypeMetadata md) { - throw new AssertionError("Cannot add metadata to an UndetVar type"); - } - @Override public boolean isPartial() { return true; @@ -2224,12 +2202,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons // Need to use List.nil(), because JCNoType constructor // gets called in static initializers in Type, where // noAnnotations is also defined. - super(null, TypeMetadata.EMPTY); - } - - @Override - public JCNoType cloneWithMetadata(TypeMetadata md) { - throw new AssertionError("Cannot add metadata to a JCNoType"); + super(null, List.nil()); } @Override @@ -2257,12 +2230,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons public JCVoidType() { // Void cannot be annotated - super(null, TypeMetadata.EMPTY); - } - - @Override - public JCVoidType cloneWithMetadata(TypeMetadata md) { - throw new AssertionError("Cannot add metadata to a void type"); + super(null, List.nil()); } @Override @@ -2292,12 +2260,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons static class BottomType extends Type implements NullType { public BottomType() { // Bottom is a synthesized internal type, so it cannot be annotated - super(null, TypeMetadata.EMPTY); - } - - @Override - public BottomType cloneWithMetadata(TypeMetadata md) { - throw new AssertionError("Cannot add metadata to a bottom type"); + super(null, List.nil()); } @Override @@ -2354,14 +2317,14 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons } private ErrorType(Type originalType, TypeSymbol tsym, - TypeMetadata metadata) { + List metadata) { super(noType, List.nil(), null, metadata); this.tsym = tsym; this.originalType = (originalType == null ? noType : originalType); } @Override - public ErrorType cloneWithMetadata(TypeMetadata md) { + protected ErrorType cloneWithMetadata(List md) { return new ErrorType(originalType, tsym, md) { @Override public Type baseType() { return ErrorType.this.baseType(); } @@ -2432,12 +2395,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons public UnknownType() { // Unknown is a synthesized internal type, so it cannot be // annotated. - super(null, TypeMetadata.EMPTY); - } - - @Override - public UnknownType cloneWithMetadata(TypeMetadata md) { - throw new AssertionError("Cannot add metadata to an unknown type"); + super(null, List.nil()); } @Override diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeMetadata.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeMetadata.java index bb47d82b99f..499b232fed9 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeMetadata.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeMetadata.java @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -25,181 +25,55 @@ package com.sun.tools.javac.code; -import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.List; -import java.util.EnumMap; -import java.util.HashSet; -import java.util.Set; +import com.sun.tools.javac.util.ListBuffer; /** - * TypeMetadata is essentially an immutable {@code EnumMap>} - * - * A metadata class represented by a subtype of Entry can express a property on a Type instance. - * There should be at most one instance of an Entry per Entry.Kind on any given Type instance. - * - * Metadata classes of a specific kind are responsible for how they combine themselves. - * - * @implNote {@code Entry:combine} need not be commutative. + * 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, + * typically using {@link Type#dropMetadata(Class)}. To drop all metadata from a given type, + * 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)}). + *

+ * There are no constraints on how a type metadata should be defined. Typically, a type + * 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}). + *

+ * The only invariant the implementation requires is that there must be one 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 static final TypeMetadata EMPTY = new TypeMetadata(); - - private final EnumMap contents; +public sealed interface TypeMetadata { /** - * 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() { - contents = new EnumMap<>(Entry.Kind.class); - } + record Annotations(ListBuffer annotationBuffer) implements TypeMetadata { - /** - * Create a new TypeMetadata map containing the Entry {@code elem}. - * - * @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 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() { + this(new ListBuffer<>()); } - /** - * Get the kind of metadata this object represents - */ - public Kind kind(); + Annotations(List annotations) { + this(); + annotationBuffer.appendList(annotations); + } - /** - * Combine this type metadata with another metadata of the - * same kind. - * - * @param other The metadata with which to combine this one. - * @return The combined metadata. - */ - public Entry combine(Entry other); + List annotations() { + return annotationBuffer.toList(); + } } /** - * 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 { - private List annos; - - public static final List TO_BE_SET = List.nil(); - - public Annotations(List annos) { - this.annos = annos; - } - - /** - * Get the type annotations contained in this metadata. - * - * @return The annotations. - */ - public List 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 + " ]"; } - } + record ConstantValue(Object value) implements TypeMetadata { } } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java index db7ddacf793..8be952f26af 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java @@ -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.Source.Feature; 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.Check; import com.sun.tools.javac.comp.Enter; @@ -2399,7 +2399,7 @@ public class Types { private TypeMapping erasure = new StructuralTypeMapping() { private Type combineMetadata(final Type s, final Type t) { - if (t.getMetadata() != TypeMetadata.EMPTY) { + if (t.getMetadata().nonEmpty()) { switch (s.getKind()) { case OTHER: case UNION: @@ -2410,7 +2410,7 @@ public class Types { case VOID: case ERROR: return s; - default: return s.cloneWithMetadata(s.getMetadata().without(Kind.ANNOTATIONS)); + default: return s.dropMetadata(Annotations.class); } } else { return s; @@ -2437,7 +2437,7 @@ public class Types { Type erased = t.tsym.erasure(Types.this); if (recurse) { erased = new ErasedClassType(erased.getEnclosingType(),erased.tsym, - t.getMetadata().without(Kind.ANNOTATIONS)); + t.dropMetadata(Annotations.class).getMetadata()); return erased; } else { return combineMetadata(erased, t); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java index 2158b241c94..b45500b7c5a 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java @@ -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.Source.Feature; 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.resources.CompilerProperties.Errors; import com.sun.tools.javac.resources.CompilerProperties.Fragments; @@ -1049,7 +1049,10 @@ public class Annotate { typeAnnotation(() -> { List compounds = fromAnnotations(annotations); 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); }); } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java index 9d2328d393a..aba09e28590 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java @@ -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.Symbol.*; 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.comp.ArgumentAttr.LocalCacheContext; import com.sun.tools.javac.comp.Check.CheckContext; @@ -5210,7 +5209,7 @@ public class Attr extends JCTree.Visitor { public void visitAnnotatedType(JCAnnotatedType tree) { attribAnnotationTypes(tree.annotations, env); Type underlyingType = attribType(tree.underlyingType, env); - Type annotatedType = underlyingType.annotatedType(Annotations.TO_BE_SET); + Type annotatedType = underlyingType.preannotatedType(); if (!env.info.isNewClass) annotate.annotateTypeSecondStage(tree, tree.annotations, annotatedType); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java index 1ae84301274..965e677a931 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java @@ -221,17 +221,12 @@ public class DeferredAttr extends JCTree.Visitor { SpeculativeCache speculativeCache; DeferredType(JCExpression tree, Env env) { - super(null, TypeMetadata.EMPTY); + super(null, List.nil()); this.tree = tree; this.env = attr.copyEnv(env); this.speculativeCache = new SpeculativeCache(); } - @Override - public DeferredType cloneWithMetadata(TypeMetadata md) { - throw new AssertionError("Cannot add metadata to a deferred type"); - } - @Override public TypeTag getTag() { return DEFERRED; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java index 259773c64c4..e8c47137d0c 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java @@ -2925,7 +2925,7 @@ public class ClassReader { private final Name name; public ProxyType(int index) { - super(syms.noSymbol, TypeMetadata.EMPTY); + super(syms.noSymbol, List.nil()); this.name = poolReader.getName(index); } @@ -2934,11 +2934,6 @@ public class ClassReader { return TypeTag.NONE; } - @Override - public Type cloneWithMetadata(TypeMetadata metadata) { - throw new UnsupportedOperationException(); - } - public Type resolve() { return name.map(ClassReader.this::sigToType); } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/UninitializedType.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/UninitializedType.java index 5b40f6419fa..aa489b581b1 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/UninitializedType.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/UninitializedType.java @@ -53,13 +53,13 @@ class UninitializedType extends Type.DelegatedType { public final int offset; // PC where allocation took place private UninitializedType(TypeTag tag, Type qtype, int offset, - TypeMetadata metadata) { + List metadata) { super(tag, qtype, metadata); this.offset = offset; } @Override - public UninitializedType cloneWithMetadata(final TypeMetadata md) { + protected UninitializedType cloneWithMetadata(final List md) { return new UninitializedType(tag, qtype, offset, md); }