Uploaded image for project: 'CCC Migration Project'
  1. CCC Migration Project
  2. CCC-8057804

AnnotatedType interfaces provide no way to get annotations on owner type

    XMLWordPrintable

    Details

    • Subcomponent:
    • Compatibility Kind:
      source
    • Compatibility Risk:
      minimal
    • Compatibility Risk Description:
      There are likely zero implementations of the interface outside of the platform. Notably Guava seem to lack one. With a default method the compatibility is minimal.
    • Interface Kind:
      Java API
    • Scope:
      SE

      Description

      Summary

      Add getAnnotatedOwnerType() to AnnotatedType along with type-specific overrides in subtypes.

      Problem

      When adding the interface java.lang.reflect.AnnotatedParameterizedType to be the counterpart with annotations to the interface j.l.r.ParameterizedType the method getAnnotatedOwner() was forgotten. The result is that for non-top-level classes, there is no way to get the potentially annotated owner type with annotations intact.

      Further investigation showed that there also is no way to navigate to the enclosing type in an AnnotatedType representing a non-parameterized type e.g. @Foo Outer. @Bar Inner . These types are not instances of AnnotatedParameterizedType but plain AnnotatedTypes.

      AnnotatedType is an interface. It is unfortunately not possible to add a default method that fully computes the correct result, it depends on the concrete implementation of the interface.

      Solution

      Add java.lang.reflect.AnnotatedType.getAnnotatedOwner() with a default implementation returning null. For clarity, subinterfaces override the new method to restate the particular requirements and to reduce the number of exceptions thrown.

      This method should return null for top-level types and instances of AnnotatedType that can not be nested, like AnnotatedWildcardType, AnnotatedArrayType, and AnnotatedTypeVariable.

      Specification

      --- old/src/java.base/share/classes/java/lang/reflect/AnnotatedType.java    2015-12-13 21:16:22.000000000 +0100
      +++ new/src/java.base/share/classes/java/lang/reflect/AnnotatedType.java    2015-12-13 21:16:22.000000000 +0100
      @@ -36,9 +36,40 @@
       public interface AnnotatedType extends AnnotatedElement {
      
           /**
      +     * Returns the potentially annotated type that this type is a member of, if
      +     * this type represents a nested type. For example, if this type is
      +     * {@code @TA O<T>.I<S>}, return a representation of {@code @TA O<T>}.
      +     *
      +     * <p>Returns {@code null} if this {@code AnnotatedType} represents a
      +     *     top-level type, or a local or anonymous class, or a primitive type, or
      +     *     void.
      +     *
      +     * <p>Returns {@code null} if this {@code AnnotatedType} is an instance of
      +     *     {@code AnnotatedArrayType}, {@code AnnotatedTypeVariable}, or
      +     *     {@code AnnotatedWildcardType}.
      +     * 
      +     * @implSpec
      +     * This default implementation returns {@code null} and performs no other
      +     * action.
      +     *
      +     * @return an {@code AnnotatedType} object representing the potentially
      +     *     annotated type that this type is a member of, or {@code null}
      +     * @throws TypeNotPresentException if the owner type
      +     *     refers to a non-existent type declaration
      +     * @throws MalformedParameterizedTypeException if the owner type
      +     *     refers to a parameterized type that cannot be instantiated
      +     *     for any reason
      +     *
      +     * @since 1.9
      +     */
      +    default AnnotatedType getAnnotatedOwnerType() {
      +        return null;
      +    }
      +
      +    /**
            * Returns the underlying type that this annotated type represents.
            *
            * @return the type this annotated type represents
            */
           public Type getType();
      -}
      +}
      
      
      --- old/src/java.base/share/classes/java/lang/reflect/AnnotatedArrayType.java   2015-12-13 21:16:21.000000000 +0100
      +++ new/src/java.base/share/classes/java/lang/reflect/AnnotatedArrayType.java   2015-12-13 21:16:21.000000000 +0100
      @@ -42,4 +42,19 @@
            * @see GenericArrayType#getGenericComponentType()
            */
           AnnotatedType  getAnnotatedGenericComponentType();
      +
      +    /**
      +     * Returns the potentially annotated type that this type is a member of, if
      +     * this type represents a nested type. For example, if this type is
      +     * {@code @TA O<T>.I<S>}, return a representation of {@code @TA O<T>}.
      +     *
      +     * <p>Returns {@code null} for an {@code AnnotatedType} that is an instance
      +     *     of {@code AnnotatedArrayType}.
      +     *
      +     * @return {@code null}
      +     *
      +     * @since 1.9
      +     */
      +    @Override
      +    AnnotatedType getAnnotatedOwnerType();
       }
      
      --- old/src/java.base/share/classes/java/lang/reflect/AnnotatedParameterizedType.java   2015-12-13 21:16:21.000000000 +0100
      +++ new/src/java.base/share/classes/java/lang/reflect/AnnotatedParameterizedType.java   2015-12-13 21:16:21.000000000 +0100
      @@ -41,4 +41,26 @@
            * @see ParameterizedType#getActualTypeArguments()
            */
           AnnotatedType[] getAnnotatedActualTypeArguments();
      +
      +    /**
      +     * Returns the potentially annotated type that this type is a member of, if
      +     * this type represents a nested type. For example, if this type is
      +     * {@code @TA O<T>.I<S>}, return a representation of {@code @TA O<T>}.
      +     *
      +     * <p>Returns {@code null} if this {@code AnnotatedType} represents a
      +     *     top-level type, or a local or anonymous class, or a primitive type, or
      +     *     void.
      +     *
      +     * @return an {@code AnnotatedType} object representing the potentially
      +     *     annotated type that this type is a member of, or {@code null}
      +     * @throws TypeNotPresentException if the owner type
      +     *     refers to a non-existent type declaration
      +     * @throws MalformedParameterizedTypeException if the owner type
      +     *     refers to a parameterized type that cannot be instantiated
      +     *     for any reason
      +     *
      +     * @since 1.9
      +     */
      +    @Override
      +    AnnotatedType getAnnotatedOwnerType();
       }
      
      --- old/src/java.base/share/classes/java/lang/reflect/AnnotatedTypeVariable.java    2015-12-13 21:16:23.000000000 +0100
      +++ new/src/java.base/share/classes/java/lang/reflect/AnnotatedTypeVariable.java    2015-12-13 21:16:23.000000000 +0100
      @@ -43,4 +43,19 @@
            * @see TypeVariable#getBounds()
            */
           AnnotatedType[] getAnnotatedBounds();
      +
      +    /**
      +     * Returns the potentially annotated type that this type is a member of, if
      +     * this type represents a nested type. For example, if this type is
      +     * {@code @TA O<T>.I<S>}, return a representation of {@code @TA O<T>}.
      +     *
      +     * <p>Returns {@code null} for an {@code AnnotatedType} that is an instance
      +     *     of {@code AnnotatedTypeVariable}.
      +     *
      +     * @return {@code null}
      +     *
      +     * @since 1.9
      +     */
      +    @Override
      +    AnnotatedType getAnnotatedOwnerType();
       }
      
      --- old/src/java.base/share/classes/java/lang/reflect/AnnotatedWildcardType.java    2015-12-13 21:16:23.000000000 +0100
      +++ new/src/java.base/share/classes/java/lang/reflect/AnnotatedWildcardType.java    2015-12-13 21:16:23.000000000 +0100
      @@ -54,4 +54,19 @@
            * @see WildcardType#getUpperBounds()
            */
           AnnotatedType[] getAnnotatedUpperBounds();
      +
      +    /**
      +     * Returns the potentially annotated type that this type is a member of, if
      +     * this type represents a nested type. For example, if this type is
      +     * {@code @TA O<T>.I<S>}, return a representation of {@code @TA O<T>}.
      +     *
      +     * <p>Returns {@code null} for an {@code AnnotatedType} that is an instance
      +     *     of {@code AnnotatedWildcardType}.
      +     *
      +     * @return {@code null}
      +     *
      +     * @since 1.9
      +     */
      +    @Override
      +    AnnotatedType getAnnotatedOwnerType();
       }

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              darcy Joe Darcy
              Reporter:
              darcy Joe Darcy
              Reviewed By:
              Alex Buckley
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: