Class AnnotatedTypes

java.lang.Object
org.checkerframework.framework.util.AnnotatedTypes

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

    • 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

      Specialization of asMemberOf(Types, AnnotatedTypeFactory, AnnotatedTypeMirror, Element) with more precise return type.
      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
      See Also:
    • asMemberOf

      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
      type - unsubstituted type of member
      Returns:
      the type of member as member of t, with initial type memberType; can be an alias to memberType
      See Also:
    • asMemberOf

      public static AnnotatedTypeMirror asMemberOf(Types types, AnnotatedTypeFactory atypeFactory, AnnotatedTypeMirror t, 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(Types types, AnnotatedTypeFactory atypeFactory, @Nullable AnnotatedTypeMirror t, 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:
    • getSuperTypes

      Returns all the supertypes (direct or indirect) of the given declared type.
      Parameters:
      type - a declared type
      Returns:
      all the supertypes of the given type
    • overriddenMethods

      public static Map<AnnotatedTypeMirror.AnnotatedDeclaredType,ExecutableElement> overriddenMethods(Elements elements, AnnotatedTypeFactory atypeFactory, 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

      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

      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)
      Returns the lub of two annotated types.
      Parameters:
      atypeFactory - the type factory
      type1 - a type
      type2 - another type
      Returns:
      the lub of type1 and type2
    • leastUpperBound

      public static AnnotatedTypeMirror leastUpperBound(AnnotatedTypeFactory atypeFactory, AnnotatedTypeMirror type1, AnnotatedTypeMirror type2, 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 List<AnnotatedTypeMirror> expandVarArgsParameters(AnnotatedTypeFactory atypeFactory, AnnotatedTypeMirror.AnnotatedExecutableType method, List<? extends 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 List<AnnotatedTypeMirror> adaptParameters(AnnotatedTypeFactory atypeFactory, AnnotatedTypeMirror.AnnotatedExecutableType method, List<? extends ExpressionTree> args)
      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
      Returns:
      a list of the types that the invocation arguments need to be subtype of; has the same length as args
    • expandVarArgsParametersFromTypes

      public static List<AnnotatedTypeMirror> expandVarArgsParametersFromTypes(AnnotatedTypeMirror.AnnotatedExecutableType method, 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 List<AnnotatedTypeMirror> getAnnotatedTypes(AnnotatedTypeFactory atypeFactory, List<AnnotatedTypeMirror> paramTypes, List<? extends 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
    • innerMostType

      public static AnnotatedTypeMirror innerMostType(AnnotatedTypeMirror t)
    • containsModifier

      public static boolean containsModifier(AnnotatedTypeMirror type, 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.hasPrimaryAnnotation(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
    • isEnum

      public static boolean isEnum(AnnotatedTypeMirror typeMirror)
    • isDeclarationOfJavaLangEnum

      public static boolean isDeclarationOfJavaLangEnum(Types types, Elements elements, AnnotatedTypeMirror typeMirror)
    • haveSameDeclaration

      public static boolean haveSameDeclaration(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(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 AnnotationMirror findEffectiveAnnotationInHierarchy(QualifierHierarchy qualHierarchy, AnnotatedTypeMirror toSearch, 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 AnnotationMirror findEffectiveAnnotationInHierarchy(QualifierHierarchy qualHierarchy, AnnotatedTypeMirror toSearch, 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

      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 wildcard)
      This method identifies wildcard types that are unbound.
      Parameters:
      wildcard - the type to check
      Returns:
      true if the given card is an unbounded wildcard
    • isExplicitlySuperBounded

      @Deprecated public static boolean isExplicitlySuperBounded(AnnotatedTypeMirror.AnnotatedWildcardType wildcardType)
      Returns true if wildcard type is explicitly super bounded.
      Parameters:
      wildcardType - the wildcard type to test
      Returns:
      true if wildcard type is explicitly super bounded
    • hasExplicitSuperBound

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

      @Deprecated public static boolean isExplicitlyExtendsBounded(AnnotatedTypeMirror.AnnotatedWildcardType wildcardType)
      Returns true if wildcard type is explicitly extends bounded.
      Parameters:
      wildcardType - the wildcard type to test
      Returns:
      true if wildcard type is explicitly extends bounded
    • hasExplicitExtendsBound

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

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

      public static boolean isUnboundedOrExtendsBounded(AnnotatedTypeMirror.AnnotatedWildcardType wildcard)
      Returns true if this type is extends bounded or unbounded.
      Parameters:
      wildcard - 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 constructor)
      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
      constructor - the ATM for the constructor
    • applyAnnotationsFromDeclaredType

      public static void applyAnnotationsFromDeclaredType(AnnotatedTypeMirror.AnnotatedDeclaredType annotatedDeclaredType, 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