Class AnnotatedTypes


  • public class AnnotatedTypes
    extends java.lang.Object
    Utility methods for operating on AnnotatedTypeMirror. This class mimics the class Types.
    • Method Detail

      • asSuper

        public static <T extends AnnotatedTypeMirror> T asSuper​(AnnotatedTypeFactory atypeFactory,
                                                                AnnotatedTypeMirror type,
                                                                T superType)
        Copies annotations from type to a copy of superType where the type variables of superType have been substituted. How the annotations are copied depends on the kinds of AnnotatedTypeMirrors given. Generally, if type and superType are both declared types, asSuper is called recursively on the direct super types, see AnnotatedTypeMirror.directSupertypes(), of type until type's erased Java type is the same as superType's erased super type. Then type is returned. For compound types, asSuper is called recursively on components.

        Preconditions:
        superType may have annotations, but they are ignored.
        type may not be an instanceof AnnotatedNullType, because if superType is a compound type, the annotations on the component types are undefined.
        The underlying type (ie the Java type) of type should be a subtype (or the same type) of the underlying type of superType. Except for these cases:

        • If type is a primitive, then the boxed type of type must be subtype of superType.
        • If superType is a primitive, then type must be convertible to superType.
        • If superType is a type variable or wildcard without a lower bound, then type must be a subtype of the upper bound of superType. (This relaxed rule is used during type argument inference where the type variable or wildcard is the type argument that was inferred.)
        • If superType is a wildcard with a lower bound, then type must be a subtype of the lower bound of superType.

        Postconditions: type and superType are not modified.

        Parameters:
        atypeFactory - AnnotatedTypeFactory
        type - type from which to copy annotations
        superType - a type whose erased Java type is a supertype of type's erased Java type.
        Returns:
        superType with annotations copied from type and type variables substituted from type.
      • castedAsSuper

        public static <T extends AnnotatedTypeMirror> T castedAsSuper​(AnnotatedTypeFactory atypeFactory,
                                                                      AnnotatedTypeMirror subtype,
                                                                      T supertype)
        Calls asSuper and casts the result to the same type as the input supertype.
        Type Parameters:
        T - the type of supertype and return type
        Parameters:
        atypeFactory - the type factory
        subtype - subtype to be transformed to supertype
        supertype - supertype that subtype is transformed to
        Returns:
        subtype as an instance of supertype
      • asMemberOf

        public static AnnotatedTypeMirror asMemberOf​(javax.lang.model.util.Types types,
                                                     AnnotatedTypeFactory atypeFactory,
                                                     AnnotatedTypeMirror t,
                                                     javax.lang.model.element.Element elem)
        Returns the type of an element when that element is viewed as a member of, or otherwise directly contained by, a given type.

        For example, when viewed as a member of the parameterized type Set<@NonNull String>, the Set.add method is an ExecutableType whose parameter is of type @NonNull String.

        Before returning the result, this method adjusts it by calling AnnotatedTypeFactory.postAsMemberOf(AnnotatedTypeMirror, AnnotatedTypeMirror, Element).

        Parameters:
        types - the Types instance to use
        atypeFactory - the type factory to use
        t - the receiver type
        elem - the element that should be viewed as member of t
        Returns:
        the type of elem as member of t
      • asMemberOf

        public static AnnotatedTypeMirror asMemberOf​(javax.lang.model.util.Types types,
                                                     AnnotatedTypeFactory atypeFactory,
                                                     @Nullable AnnotatedTypeMirror t,
                                                     javax.lang.model.element.Element elem,
                                                     AnnotatedTypeMirror elemType)
        Returns the type of an element when that element is viewed as a member of, or otherwise directly contained by, a given type. An initial type for the member is provided, to allow for earlier changes to the declared type of elem. For example, polymorphic qualifiers must be substituted before type variables are substituted.
        Parameters:
        types - the Types instance to use
        atypeFactory - the type factory to use
        t - the receiver type
        elem - the element that should be viewed as member of t
        elemType - unsubstituted type of elem
        Returns:
        the type of elem as member of t
        See Also:
        asMemberOf(Types, AnnotatedTypeFactory, AnnotatedTypeMirror, Element)
      • overriddenMethods

        public static java.util.Map<AnnotatedTypeMirror.AnnotatedDeclaredType,​javax.lang.model.element.ExecutableElement> overriddenMethods​(javax.lang.model.util.Elements elements,
                                                                                                                                                  AnnotatedTypeFactory atypeFactory,
                                                                                                                                                  javax.lang.model.element.ExecutableElement method)
        Given a method, return the methods that it overrides.
        Parameters:
        method - the overriding method
        Returns:
        a map from types to methods that method overrides
      • overriddenMethods

        public static java.util.Map<AnnotatedTypeMirror.AnnotatedDeclaredType,​javax.lang.model.element.ExecutableElement> overriddenMethods​(javax.lang.model.util.Elements elements,
                                                                                                                                                  javax.lang.model.element.ExecutableElement method,
                                                                                                                                                  java.util.Collection<AnnotatedTypeMirror.AnnotatedDeclaredType> supertypes)
        Given a method and all supertypes (recursively) of the method's containing class, returns the methods that the method overrides.
        Parameters:
        method - the overriding method
        supertypes - the set of supertypes to check for methods that are overridden by method
        Returns:
        a map from types to methods that method overrides
      • findTypeArguments

        public static java.util.Map<javax.lang.model.type.TypeVariable,​AnnotatedTypeMirror> findTypeArguments​(javax.annotation.processing.ProcessingEnvironment processingEnv,
                                                                                                                    AnnotatedTypeFactory atypeFactory,
                                                                                                                    com.sun.source.tree.ExpressionTree expr,
                                                                                                                    javax.lang.model.element.ExecutableElement elt,
                                                                                                                    AnnotatedTypeMirror.AnnotatedExecutableType preType)
        Given a method or constructor invocation, return a mapping of the type variables to their type arguments, if any exist.

        It uses the method or constructor invocation type arguments if they were specified and otherwise it infers them based on the passed arguments or the return type context, according to JLS 15.12.2.

        Parameters:
        atypeFactory - the annotated type factory
        expr - the method or constructor invocation tree; the passed argument has to be a subtype of MethodInvocationTree or NewClassTree
        elt - the element corresponding to the tree
        preType - the (partially annotated) type corresponding to the tree - the result of AnnotatedTypes.asMemberOf with the receiver and elt
        Returns:
        the mapping of the type variables to type arguments for this method or constructor invocation
      • leastUpperBound

        public static AnnotatedTypeMirror leastUpperBound​(AnnotatedTypeFactory atypeFactory,
                                                          AnnotatedTypeMirror type1,
                                                          AnnotatedTypeMirror type2,
                                                          javax.lang.model.type.TypeMirror lubTypeMirror)
        Returns the lub, whose underlying type is lubTypeMirror of two annotated types.
        Parameters:
        atypeFactory - a type factory
        type1 - annotated type whose underlying type must be a subtype or convertible to lubTypeMirror
        type2 - annotated type whose underlying type must be a subtype or convertible to lubTypeMirror
        lubTypeMirror - underlying type of the returned lub
        Returns:
        the lub of type1 and type2 with underlying type lubTypeMirror
      • annotatedGLB

        public static AnnotatedTypeMirror annotatedGLB​(AnnotatedTypeFactory atypeFactory,
                                                       AnnotatedTypeMirror type1,
                                                       AnnotatedTypeMirror type2)
        Returns the "annotated greatest lower bound" of type1 and type2.

        Suppose that there is an expression e with annotated type T. The underlying type of T must be the same as javac's type for e. (This is a requirement of the Checker Framework.) As a corollary, when computing a glb of atype1 and atype2, it is required that underlyingType(cfGLB(atype1, atype2) == glb(javacGLB(underlyingType(atype1), underlyingType(atype2)). Because of this requirement, the return value of this method (the "annotated GLB") may not be a subtype of one of the types.

        The "annotated greatest lower bound" is defined as follows:

        1. If the underlying type of type1 and type2 are the same, then return a copy of type1 whose primary annotations are the greatest lower bound of the primary annotations on type1 and type2.
        2. If the underlying type of type1 is a subtype of the underlying type of type2, then return a copy of type1 whose primary annotations are the greatest lower bound of the primary annotations on type1 and type2.
        3. If the underlying type of type1 is a supertype of the underlying type of type2, then return a copy of type2 whose primary annotations are the greatest lower bound of the primary annotations on type1 and type2.
        4. If the underlying type of type1 and type2 are not in a subtyping relationship, then return an annotated intersection type whose bounds are type1 and type2.
        Parameters:
        atypeFactory - the AnnotatedTypeFactory
        type1 - annotated type
        type2 - annotated type
        Returns:
        the annotated glb of type1 and type2
      • expandVarArgsParameters

        @Deprecated
        public static java.util.List<AnnotatedTypeMirror> expandVarArgsParameters​(AnnotatedTypeFactory atypeFactory,
                                                                                  AnnotatedTypeMirror.AnnotatedExecutableType method,
                                                                                  java.util.List<? extends com.sun.source.tree.ExpressionTree> args)
        Returns the method parameters for the invoked method, with the same number of arguments passed in the methodInvocation tree.

        If the invoked method is not a vararg method or it is a vararg method but the invocation passes an array to the vararg parameter, it would simply return the method parameters.

        Otherwise, it would return the list of parameters as if the vararg is expanded to match the size of the passed arguments.

        Parameters:
        atypeFactory - the type factory to use for fetching annotated types
        method - the method's type
        args - the arguments to the method invocation
        Returns:
        the types that the method invocation arguments need to be subtype of
      • adaptParameters

        public static java.util.List<AnnotatedTypeMirror> adaptParameters​(AnnotatedTypeFactory atypeFactory,
                                                                          AnnotatedTypeMirror.AnnotatedExecutableType method,
                                                                          java.util.List<? extends com.sun.source.tree.ExpressionTree> args,
                                                                          @Nullable com.sun.source.tree.NewClassTree tree)
        Returns the method parameters for the invoked method (or constructor), with the same number of arguments as passed to the invocation tree.

        This expands the parameters if the call uses varargs or contracts the parameters if the call is to an anonymous class that extends a class with an enclosing type. If the call is neither of these, then the parameters are returned unchanged.

        Parameters:
        atypeFactory - the type factory to use for fetching annotated types
        method - the method or constructor's type
        args - the arguments to the method or constructor invocation
        tree - the NewClassTree if method is a constructor
        Returns:
        a list of the types that the invocation arguments need to be subtype of; has the same length as args
      • expandVarArgsParametersFromTypes

        public static java.util.List<AnnotatedTypeMirror> expandVarArgsParametersFromTypes​(AnnotatedTypeMirror.AnnotatedExecutableType method,
                                                                                           java.util.List<AnnotatedTypeMirror> args)
        Returns the method parameters for the invoked method, with the same number of formal parameters as the arguments in the given list.
        Parameters:
        method - the method's type
        args - the types of the arguments at the call site
        Returns:
        the method parameters, with varargs replaced by instances of its component type
      • getAnnotatedTypeMirrorOfParameter

        public static AnnotatedTypeMirror getAnnotatedTypeMirrorOfParameter​(AnnotatedTypeMirror.AnnotatedExecutableType methodType,
                                                                            int index)
        Given an AnnotatedExecutableType of a method or constructor declaration, get the parameter type expected at the indexth position (unwrapping varargs if necessary).
        Parameters:
        methodType - the type of a method or constructor containing the parameter to return
        index - position of the parameter type to return
        Returns:
        the type of the parameter in the index position. If that parameter is a varArgs, return the component type of the varargs and NOT the array type.
      • getAnnotatedTypes

        @Deprecated
        public static java.util.List<AnnotatedTypeMirror> getAnnotatedTypes​(AnnotatedTypeFactory atypeFactory,
                                                                            java.util.List<AnnotatedTypeMirror> paramTypes,
                                                                            java.util.List<? extends com.sun.source.tree.ExpressionTree> trees)
        Deprecated.
        use CollectionsPlume.mapList(atypeFactory::getAnnotatedType, trees) instead.
        Return a list of the AnnotatedTypeMirror of the passed expression trees, in the same order as the trees.
        Parameters:
        atypeFactory - a type factory
        paramTypes - the parameter types to use as assignment context
        trees - the AST nodes
        Returns:
        a list with the AnnotatedTypeMirror of each tree in trees
      • getArrayDepth

        public static int getArrayDepth​(AnnotatedTypeMirror.AnnotatedArrayType array)
        Returns the depth of the array type of the provided array.
        Parameters:
        array - the type of the array
        Returns:
        the depth of the provided array
      • containsModifier

        public static boolean containsModifier​(AnnotatedTypeMirror type,
                                               javax.lang.model.element.AnnotationMirror modifier)
        Checks whether type contains the given modifier, also recursively in type arguments and arrays. This method might be easier to implement directly as instance method in AnnotatedTypeMirror; it corresponds to a "deep" version of AnnotatedTypeMirror.hasAnnotation(AnnotationMirror).
        Parameters:
        type - the type to search
        modifier - the modifier to search for
        Returns:
        whether the type contains the modifier
      • isJavaLangAnnotation

        public static boolean isJavaLangAnnotation​(AnnotatedTypeMirror atm)
        Returns true if the underlying type of this atm is a java.lang.annotation.Annotation.
        Returns:
        true if the underlying type of this atm is a java.lang.annotation.Annotation
      • implementsAnnotation

        public static boolean implementsAnnotation​(AnnotatedTypeMirror atm)
        Returns true if atm is an Annotation interface, i.e., an implementation of java.lang.annotation.Annotation. Given @interface MyAnno, a call to implementsAnnotation returns true when called on an AnnotatedDeclaredType representing a use of MyAnno.
        Returns:
        true if atm is an Annotation interface
      • isDeclarationOfJavaLangEnum

        public static boolean isDeclarationOfJavaLangEnum​(javax.lang.model.util.Types types,
                                                          javax.lang.model.util.Elements elements,
                                                          AnnotatedTypeMirror typeMirror)
      • haveSameDeclaration

        public static boolean haveSameDeclaration​(javax.lang.model.util.Types types,
                                                  AnnotatedTypeMirror.AnnotatedTypeVariable typeVar1,
                                                  AnnotatedTypeMirror.AnnotatedTypeVariable typeVar2)
        Returns true if the typeVar1 and typeVar2 are two uses of the same type variable.
        Parameters:
        types - type utils
        typeVar1 - a type variable
        typeVar2 - a type variable
        Returns:
        true if the typeVar1 and typeVar2 are two uses of the same type variable
      • areCorrespondingTypeVariables

        public static boolean areCorrespondingTypeVariables​(javax.lang.model.util.Elements elements,
                                                            AnnotatedTypeMirror.AnnotatedTypeVariable type1,
                                                            AnnotatedTypeMirror.AnnotatedTypeVariable type2)
        When overriding a method, you must include the same number of type parameters as the base method. By index, these parameters are considered equivalent to the type parameters of the overridden method.

        Necessary conditions:

        • Both type variables are defined in methods.
        • One of the two methods overrides the other.
        • Within their method declaration, both types have the same type parameter index.
        Returns:
        true if type1 and type2 are corresponding type variables (that is, either one "overrides" the other)
      • findEffectiveAnnotationInHierarchy

        public static javax.lang.model.element.AnnotationMirror findEffectiveAnnotationInHierarchy​(QualifierHierarchy qualHierarchy,
                                                                                                   AnnotatedTypeMirror toSearch,
                                                                                                   javax.lang.model.element.AnnotationMirror top)
        When comparing types against the bounds of a type variable, we may encounter other type variables, wildcards, and intersections in those bounds. This method traverses the bounds until it finds a concrete type from which it can pull an annotation.
        Parameters:
        top - the top of the hierarchy for which you are searching
        Returns:
        the AnnotationMirror that represents the type of toSearch in the hierarchy of top
      • findEffectiveAnnotationInHierarchy

        public static @Nullable javax.lang.model.element.AnnotationMirror findEffectiveAnnotationInHierarchy​(QualifierHierarchy qualHierarchy,
                                                                                                             AnnotatedTypeMirror toSearch,
                                                                                                             javax.lang.model.element.AnnotationMirror top,
                                                                                                             boolean canBeEmpty)
        When comparing types against the bounds of a type variable, we may encounter other type variables, wildcards, and intersections in those bounds. This method traverses the bounds until it finds a concrete type from which it can pull an annotation.
        Parameters:
        top - the top of the hierarchy for which you are searching
        canBeEmpty - whether or not the effective type can have NO annotation in the hierarchy specified by top. If this param is false, an exception will be thrown if no annotation is found. Otherwise the result is null.
        Returns:
        the AnnotationMirror that represents the type of toSearch in the hierarchy of top
      • findEffectiveLowerBoundAnnotations

        public static AnnotationMirrorSet findEffectiveLowerBoundAnnotations​(QualifierHierarchy qualHierarchy,
                                                                             AnnotatedTypeMirror toSearch)
        This method returns the effective annotation on the lower bound of a type, or on the type itself if the type has no lower bound (it is not a type variable, wildcard, or intersection).
        Parameters:
        qualHierarchy - the qualifier hierarchy
        toSearch - the type whose lower bound to examine
        Returns:
        the set of effective annotation mirrors in all hierarchies
      • findEffectiveAnnotations

        public static AnnotationMirrorSet findEffectiveAnnotations​(QualifierHierarchy qualHierarchy,
                                                                   AnnotatedTypeMirror toSearch)
        When comparing types against the bounds of a type variable, we may encounter other type variables, wildcards, and intersections in those bounds. This method traverses the bounds until it finds a concrete type from which it can pull an annotation. This occurs for every hierarchy in QualifierHierarchy.
        Parameters:
        qualHierarchy - the qualifier hierarchy
        toSearch - the type whose effective annotations to determine
        Returns:
        the set of effective annotation mirrors in all hierarchies
      • glbOfBounds

        public static AnnotationMirrorSet glbOfBounds​(AnnotatedTypeMirror.AnnotatedIntersectionType isect,
                                                      QualifierHierarchy qualHierarchy)
        Gets the lowest primary annotation of all bounds in the intersection.
        Parameters:
        isect - the intersection for which we are glbing bounds
        qualHierarchy - the qualifier used to get the hierarchies in which to glb
        Returns:
        a set of annotations representing the glb of the intersection's bounds
      • hasNoExplicitBound

        public static boolean hasNoExplicitBound​(AnnotatedTypeMirror wildcardType)
        This method identifies wildcard types that are unbound.
        Parameters:
        wildcardType - the type to check
        Returns:
        true if the given card is an unbounded wildcard
      • hasExplicitSuperBound

        public static boolean hasExplicitSuperBound​(AnnotatedTypeMirror wildcardType)
        Returns true if wildcard type has an explicit super bound.
        Parameters:
        wildcardType - the wildcard type to test
        Returns:
        true if wildcard type is explicitly super bounded
      • hasExplicitExtendsBound

        public static boolean hasExplicitExtendsBound​(AnnotatedTypeMirror wildcardType)
        Returns true if wildcard type has an explicit extends bound.
        Parameters:
        wildcardType - the wildcard type to test
        Returns:
        true if wildcard type is explicitly extends bounded
      • isUnboundedOrSuperBounded

        public static boolean isUnboundedOrSuperBounded​(AnnotatedTypeMirror.AnnotatedWildcardType wildcardType)
        Returns true if this type is super bounded or unbounded.
        Parameters:
        wildcardType - the wildcard type to test
        Returns:
        true if this type is super bounded or unbounded
      • isUnboundedOrExtendsBounded

        public static boolean isUnboundedOrExtendsBounded​(AnnotatedTypeMirror.AnnotatedWildcardType wildcardType)
        Returns true if this type is extends bounded or unbounded.
        Parameters:
        wildcardType - the wildcard type to test
        Returns:
        true if this type is extends bounded or unbounded
      • copyOnlyExplicitConstructorAnnotations

        public static void copyOnlyExplicitConstructorAnnotations​(AnnotatedTypeFactory atypeFactory,
                                                                  AnnotatedTypeMirror.AnnotatedDeclaredType returnType,
                                                                  AnnotatedTypeMirror.AnnotatedExecutableType constructorType)
        Copies explicit annotations and annotations resulting from resolution of polymorphic qualifiers from constructor to returnType. If returnType has an annotation in the same hierarchy of an annotation to be copied, that annotation is not copied.
        Parameters:
        atypeFactory - type factory
        returnType - return type to copy annotations to
        constructorType - the ATM for the constructor
      • applyAnnotationsFromDeclaredType

        public static void applyAnnotationsFromDeclaredType​(AnnotatedTypeMirror.AnnotatedDeclaredType annotatedDeclaredType,
                                                            javax.lang.model.type.DeclaredType declaredType)
        Add all the annotations in declaredType to annotatedDeclaredType.

        (The TypeMirror returned by annotatedDeclaredType#getUnderlyingType may not have all the annotations on the type, so allow the user to specify a different one.)

        Parameters:
        annotatedDeclaredType - annotated type to which annotations are added
        declaredType - a type that may have annotations