Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8336794

Remodel TypeAnnotation to "have" instead of "be" an Annotation

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P4 P4
    • 24
    • core-libs
    • None
    • source
    • minimal
    • Changes to preview APIs entail minimal compatibility risk.
    • Java API
    • SE

      Summary

      java.lang.classfile.TypeAnnotation now models a type_annotation structure; it no longer inherits java.lang.classfile.Annotation, and now has a new method Annotation annotation(). The specification of other Annotation model classes are updated.

      Problem

      1. TypeAnnotation is not substitutable as Annotation anywhere; for example, in AnnotationValue.ofAnnotation, TypeAnnotation can be passed, but type information will be lost, which is undesirable.

      2. Annotation models more than just the declaration annotations that it claims to model. In addition, default values and repeatable annotations need special attention.

      3. Annotation and TypeAnnotation don't clearly indicate which class file structures they correspond to.

      4. AnnotationElement is element-value pair instead of key-value pair, and there are many other misusage of terms.

      5. The conventional element name "value" should be noted for single-element annotations.

      Solution

      1. Remodel TypeAnnotation to no longer extend Annotation and instead contain an Annotation. Remove the factory methods that take annotation components, and add one that takes a complete Annotation as the type annotation.

      2. TypeAnnotation is specified to model the type_annotation structure. It's noted to be able to reconstruct a type annotation with contextual information.

      3. Annotation is specified to model the annotation structure or part of type_annotation structure; It's noted to be able to reconstruct an annotation with contextual information. There's added notes about representation of default values and occurrences of multiple repeatable annotations, that they derive from the contextual annotation interface definition. Changed references to "annotation class" to "annotation interface".

      4. Change improper terminologies, such as "annotation class" to "annotation interface", "key-value" to "element-value pair", distinguish "annotation" and "annotation interface“, bad usages of "elements" to "values", etc. See the specification.

      5. Added links to JVMS, names in JVMS, and specification for comparing with equals in annotation structure model classes. (Uses JVMS {@jvms} correct format)

      6. Added notes for AnnotationElement::name, noting about the conventional value name.

      Specification

      --- a/src/java.base/share/classes/java/lang/classfile/Annotation.java
      +++ b/src/java.base/share/classes/java/lang/classfile/Annotation.java
      @@ -37,43 +37,60 @@
       import jdk.internal.javac.PreviewFeature;
      
       /**
      - * Models an annotation on a declaration.
      + * Models an {@code annotation} structure (JVMS {@jvms 4.7.16}) or part of a {@code
      + * type_annotation} structure (JVMS {@jvms 4.7.20}). This model indicates the
      + * interface of the annotation and a set of element-value pairs.
      + * <p>
      + * This model can reconstruct an annotation, given the location of the modeled structure
      + * in the class file and the definition of the annotation interface.
      + * <p>
      + * Two {@code Annotation} objects should be compared using the {@link
      + * Object#equals(Object) equals} method.
      + *
      + * @apiNote
      + * For Java programs, the location of the modeled structure indicates the source code
      + * element or type (JLS {@jls 9.7.4}) on which the reconstructed annotation appears,
      + * and the annotation interface definition determines whether the reconstructed annotation has
      + * elements with default values (JLS {@jls 9.6.2}), and whether the reconstructed annotation
      + * is a container annotation for multiple annotations (JLS {@jls 9.7.5}).
        *
        * @see AnnotationElement
        * @see AnnotationValue
      + * @see TypeAnnotation
        * @see RuntimeVisibleAnnotationsAttribute
        * @see RuntimeInvisibleAnnotationsAttribute
        * @see RuntimeVisibleParameterAnnotationsAttribute
        * @see RuntimeInvisibleParameterAnnotationsAttribute
        *
      - * @sealedGraph
        * @since 22
        */
       @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
       public sealed interface Annotation
      -        permits TypeAnnotation, AnnotationImpl {
      +        permits AnnotationImpl {
      
           /**
      -     * {@return the class of the annotation}
      +     * {@return the constant pool entry holding the {@linkplain Class#descriptorString
      +     * descriptor string} of the annotation interface}
            */
           Utf8Entry className();
      
           /**
      -     * {@return the class of the annotation, as a symbolic descriptor}
      +     * {@return the annotation interface, as a symbolic descriptor}
            */
           default ClassDesc classSymbol() {
               return ClassDesc.ofDescriptor(className().stringValue());
           }
      
           /**
      -     * {@return the elements of the annotation}
      +     * {@return the element-value pairs of the annotation}
            */
           List<AnnotationElement> elements();
      
           /**
            * {@return an annotation}
      -     * @param annotationClass the class of the annotation
      -     * @param elements the elements of the annotation
      +     * @param annotationClass the constant pool entry holding the descriptor string
      +     *                        of the annotation interface
      +     * @param elements the element-value pairs of the annotation
            */
           static Annotation of(Utf8Entry annotationClass,
                                List<AnnotationElement> elements) {
      @@ -82,8 +99,9 @@ static Annotation of(Utf8Entry annotationClass,
      
           /**
            * {@return an annotation}
      -     * @param annotationClass the class of the annotation
      -     * @param elements the elements of the annotation
      +     * @param annotationClass the constant pool entry holding the descriptor string
      +     *                        of the annotation interface
      +     * @param elements the element-value pairs of the annotation
            */
           static Annotation of(Utf8Entry annotationClass,
                                AnnotationElement... elements) {
      @@ -92,8 +110,8 @@ static Annotation of(Utf8Entry annotationClass,
      
           /**
            * {@return an annotation}
      -     * @param annotationClass the class of the annotation
      -     * @param elements the elements of the annotation
      +     * @param annotationClass the descriptor of the annotation interface
      +     * @param elements the element-value pairs of the annotation
            */
           static Annotation of(ClassDesc annotationClass,
                                List<AnnotationElement> elements) {
      @@ -102,8 +120,8 @@ static Annotation of(ClassDesc annotationClass,
      
           /**
            * {@return an annotation}
      -     * @param annotationClass the class of the annotation
      -     * @param elements the elements of the annotation
      +     * @param annotationClass the descriptor of the annotation interface
      +     * @param elements the element-value pairs of the annotation
            */
           static Annotation of(ClassDesc annotationClass,
                                AnnotationElement... elements) {
      --- a/src/java.base/share/classes/java/lang/classfile/AnnotationElement.java
      +++ b/src/java.base/share/classes/java/lang/classfile/AnnotationElement.java
      @@ -32,7 +32,13 @@
       import jdk.internal.javac.PreviewFeature;
      
       /**
      - * Models a key-value pair of an annotation.
      + * Models an element-value pair in the {@code element_value_pairs}
      + * table in the {@code annotation} structure defined in JVMS
      + * {@jvms 4.7.16} or the {@code type_annotation} structure defined
      + * in JVMS {@jvms 4.7.20}.
      + * <p>
      + * Two {@code AnnotationElement} objects should be compared using the
      + * {@link Object#equals(Object) equals} method.
        *
        * @see Annotation
        * @see AnnotationValue
      @@ -45,6 +51,12 @@ public sealed interface AnnotationElement
      
           /**
            * {@return the element name}
      +     *
      +     * @apiNote
      +     * In Java source code, by convention, the name of the sole element in a
      +     * single-element annotation interface is {@code value}. (JLS {@jls 9.6.1})
      +     * This is the case for single-element annotations (JLS {@jls 9.7.3}) and
      +     * container annotations for multiple annotations (JLS {@jls 9.6.3}).
            */
           Utf8Entry name();
      
      @@ -54,7 +66,7 @@ public sealed interface AnnotationElement
           AnnotationValue value();
      
           /**
      -     * {@return an annotation key-value pair}
      +     * {@return an element-value pair}
            * @param name the name of the key
            * @param value the associated value
            */
      @@ -64,7 +76,7 @@ static AnnotationElement of(Utf8Entry name,
           }
      
           /**
      -     * {@return an annotation key-value pair}
      +     * {@return an element-value pair}
            * @param name the name of the key
            * @param value the associated value
            */
      @@ -74,9 +86,10 @@ static AnnotationElement of(String name,
           }
      
           /**
      -     * {@return an annotation key-value pair for a class-valued annotation}
      +     * {@return an element-value pair for a class-valued element}
            * @param name the name of the key
            * @param value the associated value
      +     * @see AnnotationValue#ofClass(ClassDesc) AnnotationValue::ofClass
            */
           static AnnotationElement ofClass(String name,
                                            ClassDesc value) {
      @@ -84,9 +97,10 @@ static AnnotationElement ofClass(String name,
           }
      
           /**
      -     * {@return an annotation key-value pair for a string-valued annotation}
      +     * {@return an element-value pair for a string-valued element}
            * @param name the name of the key
            * @param value the associated value
      +     * @see AnnotationValue#ofString(String) AnnotationValue::ofString
            */
           static AnnotationElement ofString(String name,
                                             String value) {
      @@ -94,9 +108,10 @@ static AnnotationElement ofString(String name,
           }
      
           /**
      -     * {@return an annotation key-value pair for a long-valued annotation}
      +     * {@return an element-value pair for a long-valued element}
            * @param name the name of the key
            * @param value the associated value
      +     * @see AnnotationValue#ofLong(long) AnnotationValue::ofLong
            */
           static AnnotationElement ofLong(String name,
                                           long value) {
      @@ -104,9 +119,10 @@ static AnnotationElement ofLong(String name,
           }
      
           /**
      -     * {@return an annotation key-value pair for an int-valued annotation}
      +     * {@return an element-value pair for an int-valued element}
            * @param name the name of the key
            * @param value the associated value
      +     * @see AnnotationValue#ofInt(int) AnnotationValue::ofInt
            */
           static AnnotationElement ofInt(String name,
                                          int value) {
      @@ -114,9 +130,10 @@ static AnnotationElement ofInt(String name,
           }
      
           /**
      -     * {@return an annotation key-value pair for a char-valued annotation}
      +     * {@return an element-value pair for a char-valued element}
            * @param name the name of the key
            * @param value the associated value
      +     * @see AnnotationValue#ofChar(char) AnnotationValue::ofChar
            */
           static AnnotationElement ofChar(String name,
                                           char value) {
      @@ -124,9 +141,10 @@ static AnnotationElement ofChar(String name,
           }
      
           /**
      -     * {@return an annotation key-value pair for a short-valued annotation}
      +     * {@return an element-value pair for a short-valued element}
            * @param name the name of the key
            * @param value the associated value
      +     * @see AnnotationValue#ofShort(short) AnnotationValue::ofShort
            */
           static AnnotationElement ofShort(String name,
                                            short value) {
      @@ -134,29 +152,32 @@ static AnnotationElement ofShort(String name,
           }
      
           /**
      -     * {@return an annotation key-value pair for a byte-valued annotation}
      +     * {@return an element-value pair for a byte-valued element}
            * @param name the name of the key
            * @param value the associated value
      +     * @see AnnotationValue#ofByte(byte) AnnotationValue::ofByte
            */
           static AnnotationElement ofByte(String name,
      -                                      byte value) {
      +                                    byte value) {
               return of(name, AnnotationValue.ofByte(value));
           }
      
           /**
      -     * {@return an annotation key-value pair for a boolean-valued annotation}
      +     * {@return an element-value pair for a boolean-valued element}
            * @param name the name of the key
            * @param value the associated value
      +     * @see AnnotationValue#ofBoolean(boolean) AnnotationValue::ofBoolean
            */
           static AnnotationElement ofBoolean(String name,
      -                                      boolean value) {
      +                                       boolean value) {
               return of(name, AnnotationValue.ofBoolean(value));
           }
      
           /**
      -     * {@return an annotation key-value pair for a double-valued annotation}
      +     * {@return an element-value pair for a double-valued element}
            * @param name the name of the key
            * @param value the associated value
      +     * @see AnnotationValue#ofDouble(double) AnnotationValue::ofDouble
            */
           static AnnotationElement ofDouble(String name,
                                             double value) {
      @@ -164,9 +185,10 @@ static AnnotationElement ofDouble(String name,
           }
      
           /**
      -     * {@return an annotation key-value pair for a float-valued annotation}
      +     * {@return an element-value pair for a float-valued element}
            * @param name the name of the key
            * @param value the associated value
      +     * @see AnnotationValue#ofFloat(float) AnnotationValue::ofFloat
            */
           static AnnotationElement ofFloat(String name,
                                            float value) {
      @@ -174,9 +196,10 @@ static AnnotationElement ofFloat(String name,
           }
      
           /**
      -     * {@return an annotation key-value pair for an annotation-valued annotation}
      +     * {@return an element-value pair for an annotation-valued element}
            * @param name the name of the key
            * @param value the associated value
      +     * @see AnnotationValue#ofAnnotation AnnotationValue::ofAnnotation
            */
           static AnnotationElement ofAnnotation(String name,
                                                 Annotation value) {
      @@ -184,9 +207,10 @@ static AnnotationElement ofAnnotation(String name,
           }
      
           /**
      -     * {@return an annotation key-value pair for an array-valued annotation}
      +     * {@return an element-value pair for an array-valued element}
            * @param name the name of the key
            * @param values the associated values
      +     * @see AnnotationValue#ofArray(AnnotationValue...) AnnotationValue::ofArray
            */
           static AnnotationElement ofArray(String name,
                                            AnnotationValue... values) {
      --- a/src/java.base/share/classes/java/lang/classfile/AnnotationValue.java
      +++ b/src/java.base/share/classes/java/lang/classfile/AnnotationValue.java
      @@ -41,7 +41,11 @@
       import jdk.internal.javac.PreviewFeature;
      
       /**
      - * Models the value of a key-value pair of an annotation.
      + * Models an {@code element_value} structure, or a value of an element-value
      + * pair of an annotation, as defined in JVMS {@jvms 4.7.16.1}.
      + * <p>
      + * Two {@code AnnotationValue} objects should be compared using the {@link
      + * Object#equals(Object) equals} method.
        *
        * @see Annotation
        * @see AnnotationElement
      @@ -53,8 +57,8 @@
       public sealed interface AnnotationValue {
      
           /**
      -     * Models an annotation-valued element.
      -     * The {@linkplain #tag tag} of this element is {@value ClassFile#AEV_ANNOTATION}.
      +     * Models an annotation value of an element-value pair.
      +     * The {@linkplain #tag tag} of this value is {@value ClassFile#AEV_ANNOTATION}.
            *
            * @since 22
            */
      @@ -66,8 +70,8 @@ sealed interface OfAnnotation extends AnnotationValue
           }
      
           /**
      -     * Models an array-valued element.
      -     * The {@linkplain #tag tag} of this element is {@value ClassFile#AEV_ARRAY}.
      +     * Models an array value of an element-value pair.
      +     * The {@linkplain #tag tag} of this value is {@value ClassFile#AEV_ARRAY}.
            *
            * @since 22
            */
      @@ -79,13 +83,15 @@ sealed interface OfArray extends AnnotationValue
                *
                * @apiNote
                * All array elements derived from Java source code have the same type,
      -         * which must not be an array type. ({@jls 9.6.1})
      +         * which must not be an array type. ({@jls 9.6.1}) If such elements are
      +         * annotations, they have the same annotation interface; if such elements
      +         * are enum, they belong to the same enum class.
                */
               List<AnnotationValue> values();
           }
      
           /**
      -     * Models a constant-valued element.
      +     * Models a constant value of an element-value pair.
            *
            * @sealedGraph
            * @since 22
      @@ -123,8 +129,8 @@ sealed interface OfConstant
           }
      
           /**
      -     * Models a string-valued element.
      -     * The {@linkplain #tag tag} of this element is {@value ClassFile#AEV_STRING}.
      +     * Models a string value of an element-value pair.
      +     * The {@linkplain #tag tag} of this value is {@value ClassFile#AEV_STRING}.
            *
            * @since 22
            */
      @@ -151,8 +157,8 @@ default String resolvedValue() {
           }
      
           /**
      -     * Models a double-valued element.
      -     * The {@linkplain #tag tag} of this element is {@value ClassFile#AEV_DOUBLE}.
      +     * Models a double value of an element-value pair.
      +     * The {@linkplain #tag tag} of this value is {@value ClassFile#AEV_DOUBLE}.
            *
            * @since 22
            */
      @@ -179,8 +185,8 @@ default Double resolvedValue() {
           }
      
           /**
      -     * Models a float-valued element.
      -     * The {@linkplain #tag tag} of this element is {@value ClassFile#AEV_FLOAT}.
      +     * Models a float value of an element-value pair.
      +     * The {@linkplain #tag tag} of this value is {@value ClassFile#AEV_FLOAT}.
            *
            * @since 22
            */
      @@ -207,8 +213,8 @@ default Float resolvedValue() {
           }
      
           /**
      -     * Models a long-valued element.
      -     * The {@linkplain #tag tag} of this element is {@value ClassFile#AEV_LONG}.
      +     * Models a long value of an element-value pair.
      +     * The {@linkplain #tag tag} of this value is {@value ClassFile#AEV_LONG}.
            *
            * @since 22
            */
      @@ -235,8 +241,8 @@ default Long resolvedValue() {
           }
      
           /**
      -     * Models an int-valued element.
      -     * The {@linkplain #tag tag} of this element is {@value ClassFile#AEV_INT}.
      +     * Models an int value of an element-value pair.
      +     * The {@linkplain #tag tag} of this value is {@value ClassFile#AEV_INT}.
            *
            * @since 22
            */
      @@ -263,8 +269,8 @@ default Integer resolvedValue() {
           }
      
           /**
      -     * Models a short-valued element.
      -     * The {@linkplain #tag tag} of this element is {@value ClassFile#AEV_SHORT}.
      +     * Models a short value of an element-value pair.
      +     * The {@linkplain #tag tag} of this value is {@value ClassFile#AEV_SHORT}.
            *
            * @since 22
            */
      @@ -294,8 +300,8 @@ default Short resolvedValue() {
           }
      
           /**
      -     * Models a char-valued element.
      -     * The {@linkplain #tag tag} of this element is {@value ClassFile#AEV_CHAR}.
      +     * Models a char value of an element-value pair.
      +     * The {@linkplain #tag tag} of this value is {@value ClassFile#AEV_CHAR}.
            *
            * @since 22
            */
      @@ -325,8 +331,8 @@ default Character resolvedValue() {
           }
      
           /**
      -     * Models a byte-valued element.
      -     * The {@linkplain #tag tag} of this element is {@value ClassFile#AEV_BYTE}.
      +     * Models a byte value of an element-value pair.
      +     * The {@linkplain #tag tag} of this value is {@value ClassFile#AEV_BYTE}.
            *
            * @since 22
            */
      @@ -356,8 +362,8 @@ default Byte resolvedValue() {
           }
      
           /**
      -     * Models a boolean-valued element.
      -     * The {@linkplain #tag tag} of this element is {@value ClassFile#AEV_BOOLEAN}.
      +     * Models a boolean value of an element-value pair.
      +     * The {@linkplain #tag tag} of this value is {@value ClassFile#AEV_BOOLEAN}.
            *
            * @since 22
            */
      @@ -387,8 +393,8 @@ default Boolean resolvedValue() {
           }
      
           /**
      -     * Models a class-valued element.
      -     * The {@linkplain #tag tag} of this element is {@value ClassFile#AEV_CLASS}.
      +     * Models a class value of an element-value pair.
      +     * The {@linkplain #tag tag} of this value is {@value ClassFile#AEV_CLASS}.
            *
            * @since 22
            */
      @@ -405,8 +411,8 @@ default ClassDesc classSymbol() {
           }
      
           /**
      -     * Models an enum-valued element.
      -     * The {@linkplain #tag tag} of this element is {@value ClassFile#AEV_ENUM}.
      +     * Models an enum value of an element-value pair.
      +     * The {@linkplain #tag tag} of this value is {@value ClassFile#AEV_ENUM}.
            *
            * @since 22
            */
      @@ -426,12 +432,13 @@ default ClassDesc classSymbol() {
           }
      
           /**
      -     * {@return the tag character for this type as per {@jvms 4.7.16.1}}
      +     * {@return the tag character for this value as per JVMS {@jvms 4.7.16.1}}
      +     * The tag characters have a one-to-one mapping to the types of annotation element values.
            */
           char tag();
      
           /**
      -     * {@return an annotation element for a enum-valued element}
      +     * {@return an enum value for an element-value pair}
            * @param className the descriptor string of the enum class
            * @param constantName the name of the enum constant
            */
      @@ -441,7 +448,7 @@ static OfEnum ofEnum(Utf8Entry className,
           }
      
           /**
      -     * {@return an annotation element for a enum-valued element}
      +     * {@return an enum value for an element-value pair}
            * @param className the descriptor of the enum class
            * @param constantName the name of the enum constant
            */
      @@ -451,7 +458,7 @@ static OfEnum ofEnum(ClassDesc className, String constantName) {
           }
      
           /**
      -     * {@return an annotation element for a class-valued element}
      +     * {@return a class value for an element-value pair}
            * @param className the descriptor string of the class
            */
           static OfClass ofClass(Utf8Entry className) {
      @@ -459,7 +466,7 @@ static OfClass ofClass(Utf8Entry className) {
           }
      
           /**
      -     * {@return an annotation element for a class-valued element}
      +     * {@return a class value for an element-value pair}
            * @param className the descriptor of the class
            */
           static OfClass ofClass(ClassDesc className) {
      @@ -467,7 +474,7 @@ static OfClass ofClass(ClassDesc className) {
           }
      
           /**
      -     * {@return an annotation element for a string-valued element}
      +     * {@return a string value for an element-value pair}
            * @param value the string
            */
           static OfString ofString(Utf8Entry value) {
      @@ -475,7 +482,7 @@ static OfString ofString(Utf8Entry value) {
           }
      
           /**
      -     * {@return an annotation element for a string-valued element}
      +     * {@return a string value for an element-value pair}
            * @param value the string
            */
           static OfString ofString(String value) {
      @@ -483,7 +490,7 @@ static OfString ofString(String value) {
           }
      
           /**
      -     * {@return an annotation element for a double-valued element}
      +     * {@return a double value for an element-value pair}
            * @param value the double value
            */
           static OfDouble ofDouble(DoubleEntry value) {
      @@ -491,7 +498,7 @@ static OfDouble ofDouble(DoubleEntry value) {
           }
      
           /**
      -     * {@return an annotation element for a double-valued element}
      +     * {@return a double value for an element-value pair}
            * @param value the double value
            */
           static OfDouble ofDouble(double value) {
      @@ -499,7 +506,7 @@ static OfDouble ofDouble(double value) {
           }
      
           /**
      -     * {@return an annotation element for a float-valued element}
      +     * {@return a float value for an element-value pair}
            * @param value the float value
            */
           static OfFloat ofFloat(FloatEntry value) {
      @@ -507,7 +514,7 @@ static OfFloat ofFloat(FloatEntry value) {
           }
      
           /**
      -     * {@return an annotation element for a float-valued element}
      +     * {@return a float value for an element-value pair}
            * @param value the float value
            */
           static OfFloat ofFloat(float value) {
      @@ -515,7 +522,7 @@ static OfFloat ofFloat(float value) {
           }
      
           /**
      -     * {@return an annotation element for a long-valued element}
      +     * {@return a long value for an element-value pair}
            * @param value the long value
            */
           static OfLong ofLong(LongEntry value) {
      @@ -523,7 +530,7 @@ static OfLong ofLong(LongEntry value) {
           }
      
           /**
      -     * {@return an annotation element for a long-valued element}
      +     * {@return a long value for an element-value pair}
            * @param value the long value
            */
           static OfLong ofLong(long value) {
      @@ -531,7 +538,7 @@ static OfLong ofLong(long value) {
           }
      
           /**
      -     * {@return an annotation element for an int-valued element}
      +     * {@return an int value for an element-value pair}
            * @param value the int value
            */
           static OfInt ofInt(IntegerEntry value) {
      @@ -539,7 +546,7 @@ static OfInt ofInt(IntegerEntry value) {
           }
      
           /**
      -     * {@return an annotation element for an int-valued element}
      +     * {@return an int value for an element-value pair}
            * @param value the int value
            */
           static OfInt ofInt(int value) {
      @@ -547,7 +554,7 @@ static OfInt ofInt(int value) {
           }
      
           /**
      -     * {@return an annotation element for a short-valued element}
      +     * {@return a short value for an element-value pair}
            * @param value the short value
            */
           static OfShort ofShort(IntegerEntry value) {
      @@ -555,7 +562,7 @@ static OfShort ofShort(IntegerEntry value) {
           }
      
           /**
      -     * {@return an annotation element for a short-valued element}
      +     * {@return a short value for an element-value pair}
            * @param value the short value
            */
           static OfShort ofShort(short value) {
      @@ -563,7 +570,7 @@ static OfShort ofShort(short value) {
           }
      
           /**
      -     * {@return an annotation element for a char-valued element}
      +     * {@return a char value for an element-value pair}
            * @param value the char value
            */
           static OfChar ofChar(IntegerEntry value) {
      @@ -571,7 +578,7 @@ static OfChar ofChar(IntegerEntry value) {
           }
      
           /**
      -     * {@return an annotation element for a char-valued element}
      +     * {@return a char value for an element-value pair}
            * @param value the char value
            */
           static OfChar ofChar(char value) {
      @@ -579,7 +586,7 @@ static OfChar ofChar(char value) {
           }
      
           /**
      -     * {@return an annotation element for a byte-valued element}
      +     * {@return a byte value for an element-value pair}
            * @param value the byte value
            */
           static OfByte ofByte(IntegerEntry value) {
      @@ -587,7 +594,7 @@ static OfByte ofByte(IntegerEntry value) {
           }
      
           /**
      -     * {@return an annotation element for a byte-valued element}
      +     * {@return a byte value for an element-value pair}
            * @param value the byte value
            */
           static OfByte ofByte(byte value) {
      @@ -595,7 +602,7 @@ static OfByte ofByte(byte value) {
           }
      
           /**
      -     * {@return an annotation element for a boolean-valued element}
      +     * {@return a boolean value for an element-value pair}
            * @param value the boolean value
            */
           static OfBoolean ofBoolean(IntegerEntry value) {
      @@ -603,7 +610,7 @@ static OfBoolean ofBoolean(IntegerEntry value) {
           }
      
           /**
      -     * {@return an annotation element for a boolean-valued element}
      +     * {@return a boolean value for an element-value pair}
            * @param value the boolean value
            */
           static OfBoolean ofBoolean(boolean value) {
      @@ -612,7 +619,7 @@ static OfBoolean ofBoolean(boolean value) {
           }
      
           /**
      -     * {@return an annotation element for an annotation-valued element}
      +     * {@return an annotation value for an element-value pair}
            * @param value the annotation
            */
           static OfAnnotation ofAnnotation(Annotation value) {
      @@ -620,7 +627,12 @@ static OfAnnotation ofAnnotation(Annotation value) {
           }
      
           /**
      -     * {@return an annotation element for an array-valued element}
      +     * {@return an array value for an element-value pair}
      +     *
      +     * @apiNote
      +     * See {@link AnnotationValue.OfArray#values() values()} for conventions
      +     * on array values derived from Java source code.
      +     *
            * @param values the array elements
            */
           static OfArray ofArray(List<AnnotationValue> values) {
      @@ -628,7 +640,12 @@ static OfArray ofArray(List<AnnotationValue> values) {
           }
      
           /**
      -     * {@return an annotation element for an array-valued element}
      +     * {@return an array value for an element-value pair}
      +     *
      +     * @apiNote
      +     * See {@link AnnotationValue.OfArray#values() values()} for conventions
      +     * on array values derived from Java source code.
      +     *
            * @param values the array elements
            */
           static OfArray ofArray(AnnotationValue... values) {
      --- a/src/java.base/share/classes/java/lang/classfile/TypeAnnotation.java
      +++ b/src/java.base/share/classes/java/lang/classfile/TypeAnnotation.java
      
       /**
      - * Models an annotation on a type use, as defined in {@jvms 4.7.19} and {@jvms 4.7.20}.
      + * Models a {@code type_annotation} structure (JVMS {@jvms 4.7.20}). This model
      + * indicates the annotated type within a declaration or expression and the part
      + * of the indicated type that is annotated, in addition to what is {@linkplain
      + * #annotation() available} in an {@code Annotation}.
      + * <p>
      + * This model can reconstruct an annotation on a type or a part of a type, given
      + * the location of the {@code type_annotation} structure in the class file and
      + * the definition of the annotation interface.
      + * <p>
      + * Two {@code TypeAnnotation} objects should be compared using the {@link
      + * Object#equals(Object) equals} method.
        *
      + * @see Annotation
        * @see RuntimeVisibleTypeAnnotationsAttribute
        * @see RuntimeInvisibleTypeAnnotationsAttribute
        *
      @@ -69,7 +77,6 @@
        */
       @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
       public sealed interface TypeAnnotation
      -        extends Annotation
               permits UnboundAttribute.UnboundTypeAnnotation {
      
           /**
      @@ -170,7 +177,7 @@ public int sizeIfFixed() {
      
           /**
            * {@return information describing precisely which type in a declaration or expression
      -     * is annotated}
      +     * is annotated} This models the {@code target_type} and {@code target_info} items.
            */
           TargetInfo targetInfo();
      
      @@ -180,57 +187,22 @@ public int sizeIfFixed() {
           List<TypePathComponent> targetPath();
      
           /**
      -     * {@return a type annotation}
      -     * @param targetInfo which type in a declaration or expression is annotated
      -     * @param targetPath which part of the type is annotated
      -     * @param annotationClassUtf8Entry the annotation class
      -     * @param annotationElements the annotation elements
      -     */
      -    static TypeAnnotation of(TargetInfo targetInfo, List<TypePathComponent> targetPath,
      -                             Utf8Entry annotationClassUtf8Entry,
      -                             List<AnnotationElement> annotationElements) {
      -        return new UnboundAttribute.UnboundTypeAnnotation(targetInfo, targetPath,
      -                annotationClassUtf8Entry, annotationElements);
      -    }
      -
      -    /**
      -     * {@return a type annotation}
      -     * @param targetInfo which type in a declaration or expression is annotated
      -     * @param targetPath which part of the type is annotated
      -     * @param annotationClass the annotation class
      -     * @param annotationElements the annotation elements
      -     */
      -    static TypeAnnotation of(TargetInfo targetInfo, List<TypePathComponent> targetPath,
      -                             ClassDesc annotationClass,
      -                             AnnotationElement... annotationElements) {
      -        return of(targetInfo, targetPath, annotationClass, List.of(annotationElements));
      -    }
      -
      -    /**
      -     * {@return a type annotation}
      -     * @param targetInfo which type in a declaration or expression is annotated
      -     * @param targetPath which part of the type is annotated
      -     * @param annotationClass the annotation class
      -     * @param annotationElements the annotation elements
      -     */
      -    static TypeAnnotation of(TargetInfo targetInfo, List<TypePathComponent> targetPath,
      -                             ClassDesc annotationClass,
      -                             List<AnnotationElement> annotationElements) {
      -        return of(targetInfo, targetPath,
      -                TemporaryConstantPool.INSTANCE.utf8Entry(annotationClass.descriptorString()), annotationElements);
      -    }
      +     * {@return the annotation applied to the part indicated by {@link #targetPath()}}
      +     * This models the interface of the annotation and the set of element-value pairs,
      +     * the subset of the {@code type_annotation} structure that is identical to the
      +     * {@code annotation} structure.
      +     */
      +    Annotation annotation();
      
           /**
      -     * {@return a type annotation}
      +     * {@return a {@code type_annotation} structure}
            * @param targetInfo which type in a declaration or expression is annotated
            * @param targetPath which part of the type is annotated
      -     * @param annotationClassUtf8Entry the annotation class
      -     * @param annotationElements the annotation elements
      +     * @param annotation the annotation
            */
           static TypeAnnotation of(TargetInfo targetInfo, List<TypePathComponent> targetPath,
      -                             Utf8Entry annotationClassUtf8Entry,
      -                             AnnotationElement... annotationElements) {
      -        return of(targetInfo, targetPath, annotationClassUtf8Entry, List.of(annotationElements));
      +                             Annotation annotation) {
      +        return new UnboundAttribute.UnboundTypeAnnotation(targetInfo, targetPath, annotation);
           }
      
           /**

            liach Chen Liang
            liach Chen Liang
            Adam Sotona, Alex Buckley
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: