Class AnnotatedTypeFactory

java.lang.Object
org.checkerframework.framework.type.AnnotatedTypeFactory
All Implemented Interfaces:
AnnotationProvider
Direct Known Subclasses:
GenericAnnotatedTypeFactory, TypeOutputtingChecker.GeneralAnnotatedTypeFactory

public class AnnotatedTypeFactory extends Object implements AnnotationProvider
The methods of this class take an element or AST node, and return the annotated type as an AnnotatedTypeMirror. The methods are: This implementation only adds qualifiers explicitly specified by the programmer. Subclasses override addComputedTypeAnnotations(com.sun.source.tree.Tree, org.checkerframework.framework.type.AnnotatedTypeMirror) to add defaults, flow-sensitive refinement, and type-system-specific rules.

Unless otherwise indicated, each public method in this class returns a "fully annotated" type, which is one that has an annotation in all positions.

Type system checker writers may need to subclass this class, to add default qualifiers according to the type system semantics. Subclasses should especially override addComputedTypeAnnotations(Element, AnnotatedTypeMirror) and addComputedTypeAnnotations(Tree, AnnotatedTypeMirror) to handle default annotations. (Also, addDefaultAnnotations(AnnotatedTypeMirror) adds annotations, but that method is a workaround for Issue 979.)

See the Checker Framework Manual:
How to write a checker plug-in
  • Field Details

    • trees

      protected final Trees trees
      The Trees instance to use for tree node path finding.
    • root

      Optional! The AST of the source file being operated on.
    • processingEnv

      protected final ProcessingEnvironment processingEnv
      The processing environment to use for accessing compiler internals.
    • elements

      protected final Elements elements
      Utility class for working with Elements.
    • types

      public final Types types
      Utility class for working with TypeMirrors.
    • annotatedForValueElement

      protected final ExecutableElement annotatedForValueElement
      The AnnotatedFor.value argument/element.
    • ensuresQualifierExpressionElement

      protected final ExecutableElement ensuresQualifierExpressionElement
      The EnsuresQualifier.expression field/element.
    • ensuresQualifierListValueElement

      protected final ExecutableElement ensuresQualifierListValueElement
      The EnsuresQualifier.List.value field/element.
    • ensuresQualifierIfExpressionElement

      protected final ExecutableElement ensuresQualifierIfExpressionElement
      The EnsuresQualifierIf.expression field/element.
    • ensuresQualifierIfResultElement

      protected final ExecutableElement ensuresQualifierIfResultElement
      The EnsuresQualifierIf.result argument/element.
    • ensuresQualifierIfListValueElement

      protected final ExecutableElement ensuresQualifierIfListValueElement
      The EnsuresQualifierIf.List.value field/element.
    • fieldInvariantFieldElement

      protected final ExecutableElement fieldInvariantFieldElement
      The FieldInvariant.field argument/element.
    • fieldInvariantQualifierElement

      protected final ExecutableElement fieldInvariantQualifierElement
      The FieldInvariant.qualifier argument/element.
    • hasQualifierParameterValueElement

      protected final ExecutableElement hasQualifierParameterValueElement
      The HasQualifierParameter.value field/element.
    • methodValClassNameElement

      public final ExecutableElement methodValClassNameElement
      The MethodVal.className argument/element.
    • methodValMethodNameElement

      public final ExecutableElement methodValMethodNameElement
      The MethodVal.methodName argument/element.
    • methodValParamsElement

      public final ExecutableElement methodValParamsElement
      The MethodVal.params argument/element.
    • noQualifierParameterValueElement

      protected final ExecutableElement noQualifierParameterValueElement
      The NoQualifierParameter.value field/element.
    • requiresQualifierExpressionElement

      protected final ExecutableElement requiresQualifierExpressionElement
      The RequiresQualifier.expression field/element.
    • requiresQualifierListValueElement

      protected final ExecutableElement requiresQualifierListValueElement
      The RequiresQualifier.List.value field/element.
    • requiresQualifierTM

      protected final TypeMirror requiresQualifierTM
      The RequiresQualifier type.
    • requiresQualifierListTM

      protected final TypeMirror requiresQualifierListTM
      The RequiresQualifier.List type.
    • ensuresQualifierTM

      protected final TypeMirror ensuresQualifierTM
      The EnsuresQualifier type.
    • ensuresQualifierListTM

      protected final TypeMirror ensuresQualifierListTM
      The EnsuresQualifier.List type.
    • ensuresQualifierIfTM

      protected final TypeMirror ensuresQualifierIfTM
      The EnsuresQualifierIf type.
    • ensuresQualifierIfListTM

      protected final TypeMirror ensuresQualifierIfListTM
      The EnsuresQualifierIf.List type.
    • qualHierarchy

      protected QualifierHierarchy qualHierarchy
      Represent the annotation relations.
    • typeHierarchy

      protected TypeHierarchy typeHierarchy
      Represent the type relations.
    • typeFormatter

      protected final AnnotatedTypeFormatter typeFormatter
      This formatter is used for converting AnnotatedTypeMirrors to Strings. This formatter will be used by all AnnotatedTypeMirrors created by this factory in their toString methods.
    • qualifierUpperBounds

      protected QualifierUpperBounds qualifierUpperBounds
      Holds the qualifier upper bounds for type uses.
    • typeVarSubstitutor

      protected TypeVariableSubstitutor typeVarSubstitutor
      Provides utility method to substitute arguments for their type variables. Field should be final, but can only be set in postInit, because subtypes might need other state to be initialized first.
    • typeArgumentInference

      protected TypeArgumentInference typeArgumentInference
      Provides utility method to infer type arguments.
    • stubTypes

      public final AnnotationFileElementTypes stubTypes
      Parses stub files and stores annotations on public elements from stub files.
    • ajavaTypes

      public final AnnotationFileElementTypes ajavaTypes
      Parses ajava files and stores annotations on public elements from ajava files.
    • currentFileAjavaTypes

      protected @Nullable AnnotationFileElementTypes currentFileAjavaTypes
      If type checking a Java file, stores annotations read from an ajava file for that class if one exists. Unlike ajavaTypes, which only stores annotations on public elements, this stores annotations on all element locations such as in anonymous class bodies.
    • checker

      protected final BaseTypeChecker checker
      The checker to use for option handling and resource management.
    • uid

      public final int uid
      Unique ID of the current object; for debugging purposes.
    • reflectionResolver

      protected ReflectionResolver reflectionResolver
      Object that is used to resolve reflective method calls, if reflection resolution is turned on.
    • loader

      protected AnnotationClassLoader loader
      This loads type annotation classes via reflective lookup.
    • wpiOutputFormat

      public WholeProgramInference.OutputFormat wpiOutputFormat
      Which whole-program inference output format to use, if doing whole-program inference. This variable would be final, but it is not set unless WPI is enabled.
    • shouldCache

      public boolean shouldCache
      Should results be cached? This means that ATM.deepCopy() will be called. ATM.deepCopy() used to (and perhaps still does) side effect the ATM being copied. So setting this to false is not equivalent to setting shouldReadCache to false.
    • fromExpressionTreeCache

      protected final Map<Tree,AnnotatedTypeMirror> fromExpressionTreeCache
      Mapping from an expression tree to its annotated type; before defaults are applied, just what the programmer wrote.
    • fromMemberTreeCache

      protected final Map<Tree,AnnotatedTypeMirror> fromMemberTreeCache
      Mapping from a member tree to its annotated type; before defaults are applied, just what the programmer wrote.
    • fromTypeTreeCache

      protected final Map<Tree,AnnotatedTypeMirror> fromTypeTreeCache
      Mapping from a type tree to its annotated type; before defaults are applied, just what the programmer wrote.
    • artificialTreeToEnclosingElementMap

      protected final Map<Tree,Element> artificialTreeToEnclosingElementMap
      Mapping from CFG-generated trees to their enclosing elements.
    • ignoreUninferredTypeArguments

      public final boolean ignoreUninferredTypeArguments
      Whether to ignore uninferred type arguments. This is a temporary flag to work around Issue 979.
    • objectGetClass

      protected final ExecutableElement objectGetClass
      The Object.getClass method.
  • Constructor Details

    • AnnotatedTypeFactory

      public AnnotatedTypeFactory(BaseTypeChecker checker)
      Constructs a factory from the given checker.

      A subclass must call postInit at the end of its constructor. postInit must be the last call in the constructor or else types from stub files may not be created as expected.

      Parameters:
      checker - the SourceChecker to which this factory belongs
  • Method Details

    • checkInvalidOptionsInferSignatures

      protected void checkInvalidOptionsInferSignatures()
      This method is called only when -Ainfer is passed as an option. It checks if another option that should not occur simultaneously with the whole-program inference is also passed as argument, and aborts the process if that is the case. For example, the whole-program inference process was not designed to work with conservative defaults.

      Subclasses may override this method to add more options.

    • postInit

      protected void postInit(@UnderInitialization(AnnotatedTypeFactory.class) AnnotatedTypeFactory this)
      Actions that logically belong in the constructor, but need to run after the subclass constructor has completed. In particular, AnnotationFileElementTypes.parseStubFiles() may try to do type resolution with this AnnotatedTypeFactory.
    • getChecker

      public BaseTypeChecker getChecker()
      Returns the checker associated with this factory.
      Returns:
      the checker associated with this factory
    • getCheckerNames

      public List<String> getCheckerNames()
      Returns the names of the annotation processors that are being run.
      Returns:
      the names of the annotation processors that are being run
    • createQualifierUpperBounds

      protected QualifierUpperBounds createQualifierUpperBounds()
      Creates QualifierUpperBounds for this type factory.
      Returns:
      a new QualifierUpperBounds for this type factory
    • getQualifierUpperBounds

      public QualifierUpperBounds getQualifierUpperBounds()
      Return QualifierUpperBounds for this type factory.
      Returns:
      QualifierUpperBounds for this type factory
    • getWholeProgramInference

      public @Nullable WholeProgramInference getWholeProgramInference()
      Returns the WholeProgramInference instance (may be null).
      Returns:
      the WholeProgramInference instance, or null
    • initializeReflectionResolution

      protected void initializeReflectionResolution()
      Initialize reflection resolution.
    • setRoot

      public void setRoot(@Nullable CompilationUnitTree root)
      Set the CompilationUnitTree that should be used.
      Parameters:
      root - the new compilation unit to use
    • toString

      @SideEffectFree public String toString()
      Overrides:
      toString in class Object
    • createQualifierHierarchy

      protected QualifierHierarchy createQualifierHierarchy()
      Returns the QualifierHierarchy to be used by this checker.

      The implementation builds the type qualifier hierarchy for the getSupportedTypeQualifiers() using the meta-annotations found in them. The current implementation returns an instance of NoElementQualifierHierarchy.

      Subclasses must override this method if their qualifiers have elements; the method must return an implementation of QualifierHierarchy, such as ElementQualifierHierarchy.

      Returns:
      a QualifierHierarchy for this type system
    • getQualifierHierarchy

      public final QualifierHierarchy getQualifierHierarchy()
      Returns the type qualifier hierarchy graph to be used by this processor.
      Returns:
      the QualifierHierarchy for this checker
      See Also:
    • createTypeHierarchy

      protected TypeHierarchy createTypeHierarchy()
      Creates the type hierarchy to be used by this factory.

      Subclasses may override this method to specify new type-checking rules beyond the typical Java subtyping rules.

      Returns:
      the type relations class to check type subtyping
    • getTypeHierarchy

      public final TypeHierarchy getTypeHierarchy()
    • createTypeVariableSubstitutor

      protected TypeVariableSubstitutor createTypeVariableSubstitutor()
      TypeVariableSubstitutor provides a method to replace type parameters with their arguments.
    • getTypeVarSubstitutor

      public TypeVariableSubstitutor getTypeVarSubstitutor()
    • createTypeArgumentInference

      protected TypeArgumentInference createTypeArgumentInference()
      TypeArgumentInference infers the method type arguments when they are not explicitly written.
    • getTypeArgumentInference

      public TypeArgumentInference getTypeArgumentInference()
    • createAnnotationClassLoader

      protected AnnotationClassLoader createAnnotationClassLoader()
      Factory method to easily change what AnnotationClassLoader is created to load type annotation classes. Subclasses can override this method and return a custom AnnotationClassLoader subclass to customize loading logic.
    • createSupportedTypeQualifiers

      protected Set<Class<? extends Annotation>> createSupportedTypeQualifiers()
      Returns a mutable set of annotation classes that are supported by a checker.

      Subclasses may override this method to return a mutable set of their supported type qualifiers through one of the 5 approaches shown below.

      Subclasses should not call this method; they should call getSupportedTypeQualifiers() instead.

      By default, a checker supports all annotations located in a subdirectory called qual that's located in the same directory as the checker. Note that only annotations defined with the @Target({ElementType.TYPE_USE}) meta-annotation (and optionally with the additional value of ElementType.TYPE_PARAMETER, but no other ElementType values) are automatically considered as supported annotations.

      To support a different set of annotations than those in the qual subdirectory, or that have other ElementType values, see examples below.

      In total, there are 5 ways to indicate annotations that are supported by a checker:

      1. Only support annotations located in a checker's qual directory:

        This is the default behavior. Simply place those annotations within the qual directory.

      2. Support annotations located in a checker's qual directory and a list of other annotations:

        Place those annotations within the qual directory, and override createSupportedTypeQualifiers() by calling getBundledTypeQualifiers(Class...) with a varargs parameter list of the other annotations. Code example:

         @Override protected Set<Class<? extends Annotation>> createSupportedTypeQualifiers() {
              return getBundledTypeQualifiers(Regex.class, PartialRegex.class, RegexBottom.class, UnknownRegex.class);
          } 
         
      3. Supporting only annotations that are explicitly listed: Override createSupportedTypeQualifiers() and return a mutable set of the supported annotations. Code example:
         @Override protected Set<Class<? extends Annotation>> createSupportedTypeQualifiers() {
              return new HashSet<Class<? extends Annotation>>(
                      Arrays.asList(A.class, B.class));
          } 
         
        The set of qualifiers returned by createSupportedTypeQualifiers() must be a fresh, mutable set. The methods getBundledTypeQualifiers(Class...) must return a fresh, mutable set
      Returns:
      the type qualifiers supported this processor, or an empty set if none
    • getBundledTypeQualifiers

      @SafeVarargs protected final Set<Class<? extends Annotation>> getBundledTypeQualifiers(Class<? extends Annotation>... explicitlyListedAnnotations)
      Loads all annotations contained in the qual directory of a checker via reflection; if a polymorphic type qualifier exists, and an explicit array of annotations to the set of annotation classes.

      This method can be called in the overridden versions of createSupportedTypeQualifiers() in each checker.

      Parameters:
      explicitlyListedAnnotations - a varargs array of explicitly listed annotation classes to be added to the returned set. For example, it is used frequently to add Bottom qualifiers.
      Returns:
      a mutable set of the loaded and listed annotation classes
    • createAnnotatedTypeFormatter

      protected AnnotatedTypeFormatter createAnnotatedTypeFormatter()
      Creates the AnnotatedTypeFormatter used by this type factory and all AnnotatedTypeMirrors it creates. The AnnotatedTypeFormatter is used in AnnotatedTypeMirror.toString and will affect the error messages printed for checkers that use this type factory.
      Returns:
      the AnnotatedTypeFormatter to pass to all instantiated AnnotatedTypeMirrors
    • getAnnotatedTypeFormatter

      public AnnotatedTypeFormatter getAnnotatedTypeFormatter()
    • createAnnotationFormatter

      protected AnnotationFormatter createAnnotationFormatter()
    • getAnnotationFormatter

      public AnnotationFormatter getAnnotationFormatter()
    • getSupportedTypeQualifiers

      public final Set<Class<? extends Annotation>> getSupportedTypeQualifiers()
      Returns an immutable set of the classes corresponding to the type qualifiers supported by this checker.

      Subclasses cannot override this method; they should override createSupportedTypeQualifiers instead.

      Returns:
      an immutable set of the supported type qualifiers, or an empty set if no qualifiers are supported
      See Also:
    • getSupportedTypeQualifierNames

      public final Set<@CanonicalName String> getSupportedTypeQualifierNames()
      Returns an immutable set of the fully qualified names of the type qualifiers supported by this checker.

      Subclasses cannot override this method; they should override createSupportedTypeQualifiers instead.

      Returns:
      an immutable set of the supported type qualifiers, or an empty set if no qualifiers are supported
      See Also:
    • getCacheSize

      protected int getCacheSize()
      Returns the size for LRU caches. It is either the value supplied via the -AatfCacheSize option or the default cache size.
      Returns:
      cache size passed as argument to checker or DEFAULT_CACHE_SIZE
    • getAnnotatedType

      public AnnotatedTypeMirror getAnnotatedType(Element elt)
      Returns an AnnotatedTypeMirror representing the annotated type of elt.
      Parameters:
      elt - the element
      Returns:
      the annotated type of elt
    • getAnnotatedType

      public AnnotatedTypeMirror getAnnotatedType(Class<?> clazz)
      Returns an AnnotatedTypeMirror representing the annotated type of clazz.
      Parameters:
      clazz - a class
      Returns:
      the annotated type of clazz
    • getAnnotationMirror

      public @Nullable AnnotationMirror getAnnotationMirror(Tree tree, Class<? extends Annotation> target)
      Description copied from interface: AnnotationProvider
      Return the annotation on tree that is in the hierarchy that contains the qualifier target. Returns null if none exists.
      Specified by:
      getAnnotationMirror in interface AnnotationProvider
      Parameters:
      tree - the tree of which the annotation is returned
      target - the class of the annotation
      Returns:
      the annotation on tree that has the class target, or null
    • getAnnotatedType

      public AnnotatedTypeMirror getAnnotatedType(Tree tree)
      Returns an AnnotatedTypeMirror representing the annotated type of tree.
      Parameters:
      tree - the AST node
      Returns:
      the annotated type of tree
    • preProcessClassTree

      public void preProcessClassTree(ClassTree classTree)
      Called by BaseTypeVisitor.visitClass(ClassTree, Void) before the classTree is type checked.
      Parameters:
      classTree - the class on which to perform preprocessing
    • postProcessClassTree

      public void postProcessClassTree(ClassTree tree)
      Called by BaseTypeVisitor.visitClass(ClassTree, Void) after the ClassTree has been type checked.

      The default implementation uses this to store the defaulted AnnotatedTypeMirrors and inherited declaration annotations back into the corresponding Elements. Subclasses might want to override this method if storing defaulted types is not desirable.

    • getAnnotatedTypeFromTypeTree

      public AnnotatedTypeMirror getAnnotatedTypeFromTypeTree(Tree tree)
      Determines the annotated type from a type in tree form.

      Note that we cannot decide from a Tree whether it is a type use or an expression. TreeUtils.isTypeTree is only an under-approximation. For example, an identifier can be either a type or an expression.

      Parameters:
      tree - the type tree
      Returns:
      the annotated type of the type in the AST
    • getTypeDeclarationBounds

      public AnnotationMirrorSet getTypeDeclarationBounds(TypeMirror type)
      Returns the set of qualifiers that are the upper bounds for a use of the type.
      Parameters:
      type - a type whose upper bounds to obtain
      Returns:
      the set of qualifiers that are the upper bounds for a use of the type
    • getDefaultTypeDeclarationBounds

      protected AnnotationMirrorSet getDefaultTypeDeclarationBounds()
      Returns the set of qualifiers that are the upper bound for a type use if no other bound is specified for the type.

      This implementation returns the top qualifiers by default. Subclass may override to return different qualifiers.

      Returns:
      the set of qualifiers that are the upper bound for a type use if no other bound is specified for the type
    • getTypeOfExtendsImplements

      public AnnotatedTypeMirror getTypeOfExtendsImplements(Tree clause)
      Returns the type of the extends or implements clause.

      The primary qualifier is either an explicit annotation on clause, or it is the qualifier upper bounds for uses of the type of the clause.

      Parameters:
      clause - tree that represents an extends or implements clause
      Returns:
      the type of the extends or implements clause
    • fromElement

      public AnnotatedTypeMirror fromElement(Element elt)
      Creates an AnnotatedTypeMirror for elt that includes: annotations explicitly written on the element and annotations from stub files.

      Does not include default qualifiers. To obtain them, use getAnnotatedType(Element).

      Does not include fake overrides from the stub file.

      Parameters:
      elt - the element
      Returns:
      AnnotatedTypeMirror of the element with explicitly-written and stub file annotations
    • mergeAnnotationFileAnnosIntoType

      protected AnnotatedTypeMirror mergeAnnotationFileAnnosIntoType(@Nullable AnnotatedTypeMirror type, Element elt, AnnotationFileElementTypes source)
      Merges types from annotation files for elt into type by taking the greatest lower bound of the annotations in both.
      Parameters:
      type - the type to apply annotation file types to
      elt - the element from which to read annotation file types
      source - storage for current annotation file annotations
      Returns:
      the type, side-effected to add the annotation file types
    • addComputedTypeAnnotations

      protected void addComputedTypeAnnotations(Tree tree, AnnotatedTypeMirror type)
      Changes annotations on a type obtained from a Tree. By default, this method does nothing. GenericAnnotatedTypeFactory uses this method to implement defaulting and inference (flow-sensitive type refinement). Its subclasses usually override it only to customize default annotations.

      Subclasses that override this method should also override addComputedTypeAnnotations(Element, AnnotatedTypeMirror).

      In classes that extend GenericAnnotatedTypeFactory, override GenericAnnotatedTypeFactory.addComputedTypeAnnotations(Tree, AnnotatedTypeMirror, boolean) instead of this method.

      Parameters:
      tree - an AST node
      type - the type obtained from tree
    • addComputedTypeAnnotations

      protected void addComputedTypeAnnotations(Element elt, AnnotatedTypeMirror type)
      Changes annotations on a type obtained from an Element. By default, this method does nothing. GenericAnnotatedTypeFactory uses this method to implement defaulting.

      Subclasses that override this method should also override addComputedTypeAnnotations(Tree, AnnotatedTypeMirror).

      Parameters:
      elt - an element
      type - the type obtained from elt
    • addDefaultAnnotations

      public void addDefaultAnnotations(AnnotatedTypeMirror type)
      Adds default annotations to type. This method should only be used in places where the correct annotations cannot be computed because of uninferred type arguments. (See AnnotatedTypeMirror.AnnotatedWildcardType.isUninferredTypeArgument().)
      Parameters:
      type - annotated type to which default annotations are added
    • postDirectSuperTypes

      protected void postDirectSuperTypes(AnnotatedTypeMirror type, List<? extends AnnotatedTypeMirror> supertypes)
      A callback method for the AnnotatedTypeFactory subtypes to customize directSupertypes(). Overriding methods should merely change the annotations on the supertypes, without adding or removing new types.

      The default provided implementation adds type annotations to supertypes. This allows the type and its supertypes to have the qualifiers.

      Parameters:
      type - the type whose supertypes are desired
      supertypes - the supertypes as specified by the base AnnotatedTypeFactory
    • postAsMemberOf

      public void postAsMemberOf(AnnotatedTypeMirror type, AnnotatedTypeMirror owner, Element element)
      A callback method for the AnnotatedTypeFactory subtypes to customize AnnotatedTypes.asMemberOf(). Overriding methods should merely change the annotations on the subtypes, without changing the types.
      Parameters:
      type - the annotated type of the element
      owner - the annotated type of the receiver of the accessing tree
      element - the element of the field or method
    • addAnnotationFromFieldInvariant

      protected void addAnnotationFromFieldInvariant(AnnotatedTypeMirror type, AnnotatedTypeMirror accessedVia, VariableElement field)
      Adds the qualifier specified by a field invariant for field to type.
      Parameters:
      type - annotated type to which the annotation is added
      accessedVia - the annotated type of the receiver of the accessing tree. (Only used to get the type element of the underling type.)
      field - element representing the field
    • getFieldInvariants

      public @Nullable FieldInvariants getFieldInvariants(TypeElement element)
      Returns the field invariants for the given class, as expressed by the user in @FieldInvariant method annotations.

      Subclasses may implement their own field invariant annotations if @FieldInvariant is not expressive enough. They must override this method to properly create AnnotationMirror and also override getFieldInvariantDeclarationAnnotations() to return their field invariants.

      Parameters:
      element - class for which to get invariants
      Returns:
      field invariants for element
    • getFieldInvariantAnnotationTree

      public @Nullable AnnotationTree getFieldInvariantAnnotationTree(@Nullable List<? extends AnnotationTree> annoTrees)
      Returns the element of annoTrees that is a use of one of the field invariant annotations (as specified via getFieldInvariantDeclarationAnnotations(). If one isn't found, null is returned.
      Parameters:
      annoTrees - list of trees to search; the result is one of the list elements, or null
      Returns:
      the AnnotationTree that is a use of one of the field invariant annotations, or null if one isn't found
    • getFieldInvariantDeclarationAnnotations

      protected Set<Class<? extends Annotation>> getFieldInvariantDeclarationAnnotations()
      Returns the set of classes of field invariant annotations.
      Returns:
      the set of classes of field invariant annotations
    • typeVariablesFromUse

      Adapt the upper bounds of the type variables of a class relative to the type instantiation. In some type systems, the upper bounds depend on the instantiation of the class. For example, in the Generic Universe Type system, consider a class declaration
        class C<X extends @Peer Object> 
      then the instantiation
        @Rep C<@Rep Object> 
      is legal. The upper bounds of class C have to be adapted by the main modifier.

      An example of an adaptation follows. Suppose, I have a declaration:

       class MyClass<E extends List<E>>
      And an instantiation:
       new MyClass<@NonNull String>()

      The upper bound of E adapted to the argument String, would be List<@NonNull String> and the lower bound would be an AnnotatedNullType.

      TODO: ensure that this method is consistently used instead of directly querying the type variables.

      Parameters:
      type - the use of the type
      element - the corresponding element
      Returns:
      the adapted bounds of the type parameters
    • getAnnotatedNullType

      public AnnotatedTypeMirror.AnnotatedNullType getAnnotatedNullType(Set<? extends AnnotationMirror> annotations)
      Creates and returns an AnnotatedNullType qualified with annotations.
      Parameters:
      annotations - set of AnnotationMirrors to qualify the returned type with
      Returns:
      AnnotatedNullType qualified with annotations
    • getImplicitReceiverType

      protected @Nullable AnnotatedTypeMirror.AnnotatedDeclaredType getImplicitReceiverType(ExpressionTree tree)
      Return the implicit receiver type of an expression tree.

      The result is null for expressions that don't have a receiver, e.g. for a local variable or method parameter access. The result is also null for expressions that have an explicit receiver.

      Clients should generally call getReceiverType(com.sun.source.tree.ExpressionTree).

      Parameters:
      tree - the expression that might have an implicit receiver
      Returns:
      the type of the implicit receiver. Returns null if the expression has an explicit receiver or doesn't have a receiver.
    • getSelfType

      Returns the type of this at the location of tree. Returns null if tree is in a location where this has no meaning, such as the body of a static method.

      The parameter is an arbitrary tree and does not have to mention "this", neither explicitly nor implicitly. This method can be overridden for type-system specific behavior.

      Parameters:
      tree - location used to decide the type of this
      Returns:
      the type of this at the location of tree
    • getEnclosingClassOrMethod

      public @Nullable Tree getEnclosingClassOrMethod(Tree tree)
      Returns the innermost enclosing method or class tree of tree. If tree is artificial (that is, created by dataflow), then artificialTreeToEnclosingElementMap is used to find the enclosing tree.

      If the tree is inside an annotation, then null is returned.

      Parameters:
      tree - tree to whose innermost enclosing method or class to return
      Returns:
      the innermost enclosing method or class tree of tree, or null if tree is inside an annotation
    • getEnclosingType

      public AnnotatedTypeMirror.AnnotatedDeclaredType getEnclosingType(TypeElement typeElement, Tree tree)
      Returns the AnnotatedTypeMirror of the enclosing type at the location of tree that is the same type as typeElement.
      Parameters:
      typeElement - type of the enclosing type to return
      tree - location to use
      Returns:
      the enclosing type at the location of tree that is the same type as typeElement
    • getEnclosingSubType

      public AnnotatedTypeMirror.AnnotatedDeclaredType getEnclosingSubType(TypeElement typeElement, Tree tree)
      Returns the AnnotatedTypeMirror of the enclosing type at the location of tree that is a subtype of typeElement.
      Parameters:
      typeElement - super type of the enclosing type to return
      tree - location to use
      Returns:
      the enclosing type at the location of tree that is a subtype of typeElement
    • getReceiverType

      public final @Nullable AnnotatedTypeMirror getReceiverType(ExpressionTree expression)
      Returns the receiver type of the expression tree, which might be the type of an implicit this. Returns null if the expression has no explicit or implicit receiver.
      Parameters:
      expression - the expression for which to determine the receiver type
      Returns:
      the type of the receiver of expression
    • methodFromUse

      Determines the type of the invoked method based on the passed method invocation tree.

      The returned method type has all type variables resolved, whether based on receiver type, passed type parameters if any, and method invocation parameter.

      Subclasses may override this method to customize inference of types or qualifiers based on method invocation parameters.

      As an implementation detail, this method depends on AnnotatedTypes.asMemberOf(Types, AnnotatedTypeFactory, AnnotatedTypeMirror, Element), and customization based on receiver type should be in accordance to its specification.

      The return type is a pair of the type of the invoked method and the (inferred) type arguments. Note that neither the explicitly passed nor the inferred type arguments are guaranteed to be subtypes of the corresponding upper bounds. See method BaseTypeVisitor.checkTypeArguments(com.sun.source.tree.Tree, java.util.List<? extends org.checkerframework.framework.type.AnnotatedTypeParameterBounds>, java.util.List<? extends org.checkerframework.framework.type.AnnotatedTypeMirror>, java.util.List<? extends com.sun.source.tree.Tree>, java.lang.CharSequence, java.util.List<?>) for the checks of type argument well-formedness.

      Note that "this" and "super" constructor invocations are also handled by this method (explicit or implicit ones, at the beginning of a constructor). Method constructorFromUse(NewClassTree) is only used for a constructor invocation in a "new" expression.

      Parameters:
      tree - the method invocation tree
      Returns:
      the method type being invoked with tree and the (inferred) type arguments
    • methodFromUse

      Determines the type of the invoked method based on the passed expression tree, executable element, and receiver type.
      Parameters:
      tree - either a MethodInvocationTree or a MemberReferenceTree
      methodElt - the element of the referenced method
      receiverType - the type of the receiver
      Returns:
      the method type being invoked with tree and the (inferred) type arguments
      See Also:
    • methodFromUsePreSubstitution

      protected void methodFromUsePreSubstitution(ExpressionTree tree, AnnotatedTypeMirror.AnnotatedExecutableType type)
      A callback method for the AnnotatedTypeFactory subtypes to customize the handling of the declared method type before type variable substitution.
      Parameters:
      tree - either a method invocation or a member reference tree
      type - declared method type before type variable substitution
    • adaptGetClassReturnTypeToReceiver

      protected void adaptGetClassReturnTypeToReceiver(AnnotatedTypeMirror.AnnotatedExecutableType getClassType, AnnotatedTypeMirror receiverType, ExpressionTree tree)
      Java special-cases the return type of getClass(). Though the method has a return type of Class<?>, the compiler special cases this return-type and changes the bound of the type argument to the erasure of the receiver type. For example:
      • x.getClass() has the type Class< ? extends erasure_of_x >
      • someInteger.getClass() has the type Class< ? extends Integer >
      Parameters:
      getClassType - this must be a type representing a call to Object.getClass otherwise a runtime exception will be thrown. It is modified by side effect.
      receiverType - the receiver type of the method invocation (not the declared receiver type)
      tree - getClass method invocation tree
    • getIterableElementType

      public AnnotatedTypeMirror getIterableElementType(ExpressionTree expression)
      Return the element type of expression. This is usually the type of expression.itertor().next(). If expression is an array, it is the component type of the array.
      Parameters:
      expression - an expression whose type is an array or implements Iterable
      Returns:
      the type of expression.itertor().next() or if expression is an array, the component type of the array.
    • getIterableElementType

      protected AnnotatedTypeMirror getIterableElementType(ExpressionTree expression, AnnotatedTypeMirror iterableType)
      Return the element type of iterableType. This is usually the type of expression.itertor().next(). If expression is an array, it is the component type of the array.
      Parameters:
      expression - an expression whose type is an array or implements Iterable
      iterableType - the type of the expression
      Returns:
      the type of expression.itertor().next() or if expression is an array, the component type of the array.
    • constructorFromUse

      Determines the type of the invoked constructor based on the passed new class tree.

      The returned method type has all type variables resolved, whether based on receiver type, passed type parameters if any, and constructor invocation parameter.

      Subclasses may override this method to customize inference of types or qualifiers based on constructor invocation parameters.

      As an implementation detail, this method depends on AnnotatedTypes.asMemberOf(Types, AnnotatedTypeFactory, AnnotatedTypeMirror, Element), and customization based on receiver type should be in accordance with its specification.

      The return type is a pair of the type of the invoked constructor and the (inferred) type arguments. Note that neither the explicitly passed nor the inferred type arguments are guaranteed to be subtypes of the corresponding upper bounds. See method BaseTypeVisitor.checkTypeArguments(com.sun.source.tree.Tree, java.util.List<? extends org.checkerframework.framework.type.AnnotatedTypeParameterBounds>, java.util.List<? extends org.checkerframework.framework.type.AnnotatedTypeMirror>, java.util.List<? extends com.sun.source.tree.Tree>, java.lang.CharSequence, java.util.List<?>) for the checks of type argument well-formedness.

      Note that "this" and "super" constructor invocations are handled by method methodFromUse(com.sun.source.tree.MethodInvocationTree). This method only handles constructor invocations in a "new" expression.

      Parameters:
      tree - the constructor invocation tree
      Returns:
      the annotated type of the invoked constructor (as an executable type) and the (inferred) type arguments
    • getEnumConstructorQualifiers

      protected Set<AnnotationMirror> getEnumConstructorQualifiers()
      Returns the annotations that should be applied to enum constructors. This implementation returns an empty set. Subclasses can override to return a different set.
      Returns:
      the annotations that should be applied to enum constructors
    • fromNewClass

      Creates an AnnotatedDeclaredType for a NewClassTree. Only adds explicit annotations, unless newClassTree has a diamond operator. In that case, the annotations on the type arguments are inferred using the assignment context and contain defaults.

      (Subclass beside GenericAnnotatedTypeFactory should not override this method.)

      Parameters:
      newClassTree - a NewClassTree
      Returns:
      the AnnotatedDeclaredType
    • getExplicitNewClassAnnos

      public AnnotationMirrorSet getExplicitNewClassAnnos(NewClassTree newClassTree)
      Returns the annotations explicitly written on a NewClassTree.

      new @HERE Class()

      Parameters:
      newClassTree - a constructor invocation
      Returns:
      the annotations explicitly written on a NewClassTree
    • getExplicitNewClassClassTypeArgs

      protected List<AnnotatedTypeMirror> getExplicitNewClassClassTypeArgs(NewClassTree newClass)
      Returns the partially-annotated explicit class type arguments of the new class tree. The AnnotatedTypeMirror only include the annotations explicitly written on the explict type arguments. (If newClass use a diamond operator, this method returns the empty list.) For example, when called with new MyClass<@HERE String>() this method would return a list containing @HERE String.
      Parameters:
      newClass - a new class tree
      Returns:
      the partially annotated AnnotatedTypeMirrors for the (explicit) class type arguments of the new class tree
    • constructorFromUsePreSubstitution

      protected void constructorFromUsePreSubstitution(NewClassTree tree, AnnotatedTypeMirror.AnnotatedExecutableType type)
      A callback method for the AnnotatedTypeFactory subtypes to customize the handling of the declared constructor type before type variable substitution.
      Parameters:
      tree - a NewClassTree from constructorFromUse()
      type - declared method type before type variable substitution
    • getMethodReturnType

      public AnnotatedTypeMirror getMethodReturnType(MethodTree m)
      Returns the return type of the method m.
      Parameters:
      m - tree of a method declaration
      Returns:
      the return type of the method
    • getMethodReturnType

      public AnnotatedTypeMirror getMethodReturnType(MethodTree m, ReturnTree r)
      Returns the return type of the method m at the return statement r. This implementation just calls getMethodReturnType(MethodTree), but subclasses may override this method to change the type based on the return statement.
      Parameters:
      m - tree of a method declaration
      r - a return statement within method m
      Returns:
      the return type of the method m at the return statement r
    • getBoxedType

      Returns the annotated boxed type of the given primitive type. The returned type would only have the annotations on the given type.

      Subclasses may override this method safely to override this behavior.

      Parameters:
      type - the primitive type
      Returns:
      the boxed declared type of the passed primitive type
    • applyUnboxing

      Return a primitive type: either the argument, or the result of unboxing it (which might affect its annotations).

      Subclasses should override getUnboxedType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) rather than this method.

      Parameters:
      type - a type: a primitive or boxed primitive
      Returns:
      the unboxed variant of the type
    • getUnboxedType

      Returns the annotated primitive type of the given declared type if it is a boxed declared type. Otherwise, it throws IllegalArgumentException exception.

      In the AnnotatedTypeFactory implementation, the returned type has the same primary annotations as the given type. Subclasses may override this behavior.

      Parameters:
      type - the declared type
      Returns:
      the unboxed primitive type
      Throws:
      IllegalArgumentException - if the type given has no unbox conversion
    • getStringType

      Returns AnnotatedDeclaredType with underlying type String and annotations copied from type. Subclasses may change the annotations.
      Parameters:
      type - type to convert to String
      Returns:
      AnnotatedTypeMirror that results from converting type to a String type
    • getWidenedType

      public final AnnotatedTypeMirror getWidenedType(AnnotatedTypeMirror exprType, AnnotatedTypeMirror widenedType)
      Returns a widened type if applicable, otherwise returns its first argument.

      Subclasses should override getWidenedAnnotations(org.checkerframework.javacutil.AnnotationMirrorSet, javax.lang.model.type.TypeKind, javax.lang.model.type.TypeKind) rather than this method.

      Parameters:
      exprType - type to possibly widen
      widenedType - type to possibly widen to; its annotations are ignored
      Returns:
      if widening is applicable, the result of converting type to the underlying type of widenedType; otherwise type
    • getWidenedType

      public final AnnotatedTypeMirror getWidenedType(AnnotationMirrorSet exprAnnos, TypeMirror exprTypeMirror, AnnotatedTypeMirror widenedType)
      Applies widening if applicable, otherwise returns its first argument.

      Subclasses should override getWidenedAnnotations(org.checkerframework.javacutil.AnnotationMirrorSet, javax.lang.model.type.TypeKind, javax.lang.model.type.TypeKind) rather than this method.

      Parameters:
      exprAnnos - annotations to possibly widen
      exprTypeMirror - type to possibly widen
      widenedType - type to possibly widen to; its annotations are ignored
      Returns:
      if widening is applicable, the result of converting type to the underlying type of widenedType; otherwise type
    • getNarrowedAnnotations

      public AnnotationMirrorSet getNarrowedAnnotations(AnnotationMirrorSet annos, TypeKind typeKind, TypeKind narrowedTypeKind)
      Returns annotations applicable to type narrowedTypeKind, that are copied or adapted from annos.
      Parameters:
      annos - annotations to narrow, from a primitive or boxed primitive
      typeKind - primitive type to narrow
      narrowedTypeKind - target for the returned annotations; a primitive type that is narrower than typeKind (in the sense of JLS 5.1.3).
      Returns:
      result of converting annos from typeKind to narrowedTypeKind
    • getWidenedAnnotations

      public AnnotationMirrorSet getWidenedAnnotations(AnnotationMirrorSet annos, TypeKind typeKind, TypeKind widenedTypeKind)
      Returns annotations applicable to type widenedTypeKind, that are copied or adapted from annos.
      Parameters:
      annos - annotations to widen, from a primitive or boxed primitive
      typeKind - primitive type to widen
      widenedTypeKind - target for the returned annotations; a primitive type that is wider than typeKind (in the sense of JLS 5.1.2)
      Returns:
      result of converting annos from typeKind to widenedTypeKind
    • binaryTreeArgTypes

      public org.plumelib.util.IPair<AnnotatedTypeMirror,AnnotatedTypeMirror> binaryTreeArgTypes(BinaryTree tree)
      Returns the types of the two arguments to the BinaryTree, accounting for widening and unboxing if applicable.
      Parameters:
      tree - a binary tree
      Returns:
      the types of the two arguments
    • compoundAssignmentTreeArgTypes

      public org.plumelib.util.IPair<AnnotatedTypeMirror,AnnotatedTypeMirror> compoundAssignmentTreeArgTypes(CompoundAssignmentTree tree)
      Returns the types of the two arguments to the CompoundAssignmentTree, accounting for widening and unboxing if applicable.
      Parameters:
      tree - a compound assignment tree
      Returns:
      the types of the two arguments
    • binaryTreeArgTypes

      public org.plumelib.util.IPair<AnnotatedTypeMirror,AnnotatedTypeMirror> binaryTreeArgTypes(AnnotatedTypeMirror left, AnnotatedTypeMirror right)
      Returns the types of the two arguments to a binary operation, accounting for widening and unboxing if applicable.
      Parameters:
      left - the type of the left argument of a binary operation
      right - the type of the right argument of a binary operation
      Returns:
      the types of the two arguments
    • getNarrowedPrimitive

      Returns AnnotatedPrimitiveType with underlying type narrowedTypeMirror and with annotations copied or adapted from type.

      Currently this method is called only for primitives that are narrowed at assignments from literal ints, for example, byte b = 1;. All other narrowing conversions happen at typecasts.

      Parameters:
      type - type to narrow
      narrowedTypeMirror - underlying type for the returned type mirror
      Returns:
      result of converting type to narrowedTypeMirror
    • getAnnotatedType

      public final AnnotatedTypeMirror.AnnotatedDeclaredType getAnnotatedType(ClassTree tree)
      See Also:
    • getAnnotatedType

      public final AnnotatedTypeMirror.AnnotatedDeclaredType getAnnotatedType(NewClassTree tree)
      See Also:
    • getAnnotatedType

      public final AnnotatedTypeMirror.AnnotatedArrayType getAnnotatedType(NewArrayTree tree)
      See Also:
    • getAnnotatedType

      public final AnnotatedTypeMirror.AnnotatedExecutableType getAnnotatedType(MethodTree tree)
      See Also:
    • getAnnotatedType

      public final AnnotatedTypeMirror.AnnotatedDeclaredType getAnnotatedType(TypeElement elt)
      See Also:
    • getAnnotatedType

      See Also:
    • fromElement

      See Also:
    • fromElement

      See Also:
    • isSupportedQualifier

      @EnsuresNonNullIf(expression="#1", result=true) public boolean isSupportedQualifier(@Nullable AnnotationMirror a)
      Returns true if the given annotation is a part of the type system under which this type factory operates. Null is never a supported qualifier; the parameter is nullable to allow the result of canonicalAnnotation to be passed in directly.
      Parameters:
      a - any annotation
      Returns:
      true if that annotation is part of the type system under which this type factory operates, false otherwise
    • isSupportedQualifier

      public boolean isSupportedQualifier(Class<? extends Annotation> clazz)
      Returns true if the given class is a part of the type system under which this type factory operates.
      Parameters:
      clazz - annotation class
      Returns:
      true if that class is a type qualifier in the type system under which this type factory operates, false otherwise
    • isSupportedQualifier

      public boolean isSupportedQualifier(String className)
      Returns true if the given class name is a part of the type system under which this type factory operates.
      Parameters:
      className - fully-qualified annotation class name
      Returns:
      true if that class name is a type qualifier in the type system under which this type factory operates, false otherwise
    • addAliasedTypeAnnotation

      protected void addAliasedTypeAnnotation(Class<?> aliasClass, AnnotationMirror canonicalAnno)
      Adds the annotation aliasClass as an alias for the canonical annotation canonicalAnno that will be used by the Checker Framework in the alias's place.

      By specifying the alias/canonical relationship using this method, the elements of the alias are not preserved when the canonical annotation to use is constructed from the alias. If you want the elements to be copied over as well, use addAliasedTypeAnnotation(Class, Class, boolean, String...).

      Parameters:
      aliasClass - the class of the aliased annotation
      canonicalAnno - the canonical annotation
    • addAliasedTypeAnnotation

      protected void addAliasedTypeAnnotation(@FullyQualifiedName String aliasName, AnnotationMirror canonicalAnno)
      Adds the annotation, whose fully-qualified name is given by aliasName, as an alias for the canonical annotation canonicalAnno that will be used by the Checker Framework in the alias's place.

      Use this method if the alias class is not necessarily on the classpath at Checker Framework compile and run time. Otherwise, use addAliasedTypeAnnotation(Class, AnnotationMirror) which prevents the possibility of a typo in the class name.

      Parameters:
      aliasName - the canonical name of the aliased annotation
      canonicalAnno - the canonical annotation
    • addAliasedTypeAnnotation

      protected void addAliasedTypeAnnotation(Class<?> aliasClass, Class<?> canonicalClass, boolean copyElements, String... ignorableElements)
      Adds the annotation aliasClass as an alias for the canonical annotation canonicalClass that will be used by the Checker Framework in the alias's place.

      You may specify the copyElements flag to indicate whether you want the elements of the alias to be copied over when the canonical annotation is constructed as a copy of canonicalClass. Be careful that the framework will try to copy the elements by name matching, so make sure that names and types of the elements to be copied over are exactly the same as the ones in the canonical annotation. Otherwise, an 'Couldn't find element in annotation' error is raised.

      To facilitate the cases where some of the elements are ignored on purpose when constructing the canonical annotation, this method also provides a varargs ignorableElements for you to explicitly specify the ignoring rules. For example, org.checkerframework.checker.index.qual.IndexFor is an alias of org.checkerframework.checker.index.qual.NonNegative, but the element "value" of @IndexFor should be ignored when constructing @NonNegative. In the cases where all elements are ignored, we can simply use addAliasedTypeAnnotation(Class, AnnotationMirror) instead.

      Parameters:
      aliasClass - the class of the aliased annotation
      canonicalClass - the class of the canonical annotation
      copyElements - a flag that indicates whether you want to copy the elements over when getting the alias from the canonical annotation
      ignorableElements - a list of elements that can be safely dropped when the elements are being copied over
    • addAliasedTypeAnnotation

      protected void addAliasedTypeAnnotation(@FullyQualifiedName String aliasName, Class<?> canonicalAnno, boolean copyElements, String... ignorableElements)
      Adds the annotation, whose fully-qualified name is given by aliasName, as an alias for the canonical annotation canonicalAnno that will be used by the Checker Framework in the alias's place.

      Use this method if the alias class is not necessarily on the classpath at Checker Framework compile and run time. Otherwise, use addAliasedTypeAnnotation(Class, Class, boolean, String[]) which prevents the possibility of a typo in the class name.

      Parameters:
      aliasName - the canonical name of the aliased class
      canonicalAnno - the canonical annotation
      copyElements - a flag that indicates whether we want to copy the elements over when getting the alias from the canonical annotation
      ignorableElements - a list of elements that can be safely dropped when the elements are being copied over
    • canonicalAnnotation

      public @Nullable AnnotationMirror canonicalAnnotation(AnnotationMirror a)
      Returns the canonical annotation for the passed annotation. Returns null if the passed annotation is not an alias of a canonical one in the framework.

      A canonical annotation is the internal annotation that will be used by the Checker Framework in the aliased annotation's place.

      Parameters:
      a - the qualifier to check for an alias
      Returns:
      the canonical annotation, or null if none exists
    • addAliasedDeclAnnotation

      protected void addAliasedDeclAnnotation(Class<? extends Annotation> alias, Class<? extends Annotation> annotation, AnnotationMirror annotationToUse)
      Add the annotation alias as an alias for the declaration annotation annotation, where the annotation mirror annotationToUse will be used instead. If multiple calls are made with the same annotation, then the annotationToUse must be the same.

      The point of annotationToUse is that it may include elements/fields.

      Parameters:
      alias - the class of the alias annotation
      annotation - the class of the canonical annotation
      annotationToUse - the annotation mirror to use
    • addInheritedAnnotation

      protected void addInheritedAnnotation(AnnotationMirror annotation)
      Adds the annotation annotation in the set of declaration annotations that should be inherited. A declaration annotation will be inherited if it is in this list, or if it has the meta-annotation @InheritedAnnotation. The meta-annotation @InheritedAnnotation should be used instead of this method, if possible.
    • toAnnotatedType

      protected final AnnotatedTypeMirror toAnnotatedType(TypeMirror t, boolean declaration)
      Parameters:
      t - the TypeMirror
      declaration - true if the result should be marked as a type declaration
      Returns:
      an AnnotatedTypeMirror that has t as its underlying type
    • type

      protected final AnnotatedTypeMirror type(Tree tree)
      Determines an empty annotated type of the given tree. In other words, finds the TypeMirror for the tree and converts that into an AnnotatedTypeMirror, but does not add any annotations to the result.

      Most users will want to use getAnnotatedType(Tree) instead; this method is mostly for internal use.

      Parameters:
      tree - the tree to analyze
      Returns:
      the type of tree, without any annotations
    • declarationFromElement

      public final @Nullable Tree declarationFromElement(Element elt)
      Gets the declaration tree for the element, if the source is available.

      TODO: would be nice to move this to InternalUtils/TreeUtils.

      Parameters:
      elt - an element
      Returns:
      the tree declaration of the element if found
    • getCurrentClassTree

      @Deprecated protected final ClassTree getCurrentClassTree(Tree tree)
      Deprecated.
      Use TreePathUtil.enclosingClass(getPath(tree)) instead.
      Returns the class tree enclosing tree.
      Parameters:
      tree - the tree whose enclosing class is returned
      Returns:
      the class tree enclosing tree
    • getCurrentMethodReceiver

      @Deprecated protected final @Nullable AnnotatedTypeMirror.AnnotatedDeclaredType getCurrentMethodReceiver(Tree tree)
      Deprecated.
      Use getSelfType(Tree) instead
      Returns the receiver type of the method enclosing tree.

      The method uses the parameter only if the most enclosing method cannot be found directly.

      Parameters:
      tree - the tree used to find the enclosing method
      Returns:
      receiver type of the most enclosing method being visited
    • isWithinConstructor

      protected final boolean isWithinConstructor(Tree tree)
      Returns true if tree is within a constructor.
      Parameters:
      tree - the tree that might be within a constructor
      Returns:
      true if tree is within a constructor
    • setVisitorTreePath

      public void setVisitorTreePath(@Nullable TreePath visitorTreePath)
      Sets the path to the tree that an external "visitor" is visiting. The visitor is either a subclass of BaseTypeVisitor or CFAbstractTransfer.
      Parameters:
      visitorTreePath - path to the current tree that an external "visitor" is visiting
    • getVisitorTreePath

      public @Nullable TreePath getVisitorTreePath()
      Returns the path to the tree that an external "visitor" is visiting. The type factory does not update this value as it computes the types of any tree or element needed compute the type of the tree being visited. Therefore this path may not be the path to the tree whose type is being computed. This method should not be used directly. Use getPath(Tree) instead.

      This method is used to save the previous tree path and to give a hint to getPath(Tree) on where to look for a tree rather than searching starting at the root.

      Returns:
      the path to the tree that an external "visitor" is visiting
    • getPath

      public final @Nullable TreePath getPath(@FindDistinct Tree tree)
      Gets the path for the given Tree under the current root by checking from the visitor's current path, and using Trees.getPath(CompilationUnitTree, Tree) (which is much slower) only if tree is not found on the current path.

      Note that the given Tree has to be within the current compilation unit, otherwise null will be returned.

      Within a subclass of BaseTypeVisitor, use getCurrentPath() rather than this method.

      Parameters:
      tree - the Tree to get the path for
      Returns:
      the path for tree under the current root. Returns null if tree is not within the current compilation unit.
    • getEnclosingElementForArtificialTree

      public final @Nullable Element getEnclosingElementForArtificialTree(Tree tree)
      Gets the Element representing the declaration of the method enclosing a tree AST node. This feature is used to record the enclosing methods of Trees that are created internally by the checker.

      TODO: Find a better way to store information about enclosing Trees.

      Parameters:
      tree - the Tree to get the enclosing method for
      Returns:
      the method Element enclosing the argument, or null if none has been recorded
    • setEnclosingElementForArtificialTree

      public final void setEnclosingElementForArtificialTree(Tree tree, Element enclosing)
      Adds the given mapping from a synthetic (generated) tree to its enclosing element.

      See org.checkerframework.framework.flow.CFCFGBuilder.CFCFGTranslationPhaseOne.handleArtificialTree(Tree).

      Parameters:
      tree - artifical tree
      enclosing - element that encloses tree
    • parseAnnotationFiles

      protected void parseAnnotationFiles()
      Parses all annotation files in the following order:
      1. jdk.astub in the same directory as the checker, if it exists and ignorejdkastub option is not supplied
      2. jdkN.astub (where N is the Java version or any higher value) in the same directory as the checker, if it exists and ignorejdkastub option is not supplied
      3. Stub files listed in @StubFiles annotation on the checker; must be in same directory as the checker
      4. Stub files provided via -Astubs compiler option
      5. Ajava files provided via -Aajava compiler option

      If a type is annotated with a qualifier from the same hierarchy in more than one stub file, the qualifier in the last stub file is applied.

      The annotations are stored by side-effecting stubTypes and ajavaTypes.

    • getDeclAnnotation

      public final AnnotationMirror getDeclAnnotation(Element elt, Class<? extends Annotation> anno)
      Returns all of the declaration annotations whose name equals the passed annotation class (or is an alias for it) including annotations:
      • on the element
      • written in stubfiles
      • inherited from overridden methods, (see InheritedAnnotation)
      • inherited from superclasses or super interfaces (see Inherited)
      Specified by:
      getDeclAnnotation in interface AnnotationProvider
      Parameters:
      elt - the element to retrieve the declaration annotation from
      anno - annotation class
      Returns:
      the annotation mirror for anno
      See Also:
    • getDeclAnnotationNoAliases

      public final @Nullable AnnotationMirror getDeclAnnotationNoAliases(Element elt, Class<? extends Annotation> anno)
      Returns the annotation mirror used to annotate this element, whose name equals the passed annotation class. Looks in the same places specified by getDeclAnnotation(Element, Class). Returns null if none exists. Does not check for aliases of the annotation class.

      Call this method from a checker that needs to alias annotations for one purpose and not for another. For example, in the Lock Checker, @LockingFree and @ReleasesNoLocks are both aliases of @SideEffectFree since they are all considered side-effect-free with regard to the set of locks held before and after the method call. However, a synchronized block is permitted inside a @ReleasesNoLocks method but not inside a @LockingFree or @SideEffectFree method.

      Parameters:
      elt - the element to retrieve the declaration annotation from
      anno - annotation class
      Returns:
      the annotation mirror for anno
      See Also:
    • isFromStubFile

      public boolean isFromStubFile(Element element)
      Returns true if the element appears in a stub file (Currently only works for methods, constructors, and fields).
    • isFromByteCode

      public boolean isFromByteCode(Element element)
      Returns true if the element is from bytecode and the if the element did not appear in a stub file. Currently only works for methods, constructors, and fields.
    • shouldWarnIfStubRedundantWithBytecode

      public boolean shouldWarnIfStubRedundantWithBytecode()
      Returns true if redundancy between a stub file and bytecode should be reported.

      For most type systems the default behavior of returning true is correct. For subcheckers, redundancy in one of the type hierarchies can be ok. Such implementations should return false.

      Returns:
      whether to warn about redundancy between a stub file and bytecode
    • getDeclAnnotations

      public AnnotationMirrorSet getDeclAnnotations(Element elt)
      Returns all of the declaration annotations on this element including annotations:
      • on the element
      • written in stubfiles
      • inherited from overridden methods, (see InheritedAnnotation)
      • inherited from superclasses or super interfaces (see Inherited)

      This method returns the actual annotations not their aliases. getDeclAnnotation(Element, Class) returns aliases.

      Parameters:
      elt - the element for which to determine annotations
      Returns:
      all of the declaration annotations on this element, written in stub files, or inherited
    • getDeclAnnotationWithMetaAnnotation

      public List<org.plumelib.util.IPair<AnnotationMirror,AnnotationMirror>> getDeclAnnotationWithMetaAnnotation(Element element, Class<? extends Annotation> metaAnnotationClass)
      Returns a list of all declaration annotations used to annotate the element, which have a meta-annotation (i.e., an annotation on that annotation) with class metaAnnotationClass.
      Parameters:
      element - the element for which to determine annotations
      metaAnnotationClass - the class of the meta-annotation that needs to be present
      Returns:
      a list of pairs (anno, metaAnno) where anno is the annotation mirror at element, and metaAnno is the annotation mirror (of type metaAnnotationClass) used to meta-annotate the declaration of anno
    • getAnnotationWithMetaAnnotation

      public List<org.plumelib.util.IPair<AnnotationMirror,AnnotationMirror>> getAnnotationWithMetaAnnotation(Element element, Class<? extends Annotation> metaAnnotationClass)
      Returns a list of all annotations used to annotate this element, which have a meta-annotation (i.e., an annotation on that annotation) with class metaAnnotationClass.
      Parameters:
      element - the element at which to look for annotations
      metaAnnotationClass - the class of the meta-annotation that needs to be present
      Returns:
      a list of pairs (anno, metaAnno) where anno is the annotation mirror at element, and metaAnno is the annotation mirror used to annotate anno.
    • hasQualifierParameterInHierarchy

      public boolean hasQualifierParameterInHierarchy(AnnotatedTypeMirror annotatedTypeMirror, AnnotationMirror top)
      Whether or not the annotatedTypeMirror has a qualifier parameter.
      Parameters:
      annotatedTypeMirror - the type to check
      top - the top of the hierarchy to check
      Returns:
      true if the type has a qualifier parameter
    • hasQualifierParameterInHierarchy

      public boolean hasQualifierParameterInHierarchy(@Nullable Element element, AnnotationMirror top)
      Whether or not the element has a qualifier parameter.
      Parameters:
      element - element to check
      top - the top of the hierarchy to check
      Returns:
      true if the type has a qualifier parameter
    • hasExplicitQualifierParameterInHierarchy

      public boolean hasExplicitQualifierParameterInHierarchy(Element element, AnnotationMirror top)
      Returns whether the HasQualifierParameter annotation was explicitly written on element for the hierarchy given by top.
      Parameters:
      element - the Element to check
      top - the top qualifier for the hierarchy to check
      Returns:
      whether the class given by element has been explicitly annotated with HasQualifierParameter for the given hierarchy
    • hasExplicitNoQualifierParameterInHierarchy

      public boolean hasExplicitNoQualifierParameterInHierarchy(Element element, AnnotationMirror top)
      Returns whether the NoQualifierParameter annotation was explicitly written on element for the hierarchy given by top.
      Parameters:
      element - the Element to check
      top - the top qualifier for the hierarchy to check
      Returns:
      whether the class given by element has been explicitly annotated with NoQualifierParameter for the given hierarchy
    • getQualifierParameterHierarchies

      public AnnotationMirrorSet getQualifierParameterHierarchies(AnnotatedTypeMirror annotatedType)
      Returns the set of top annotations representing all the hierarchies for which this type has a qualifier parameter.
      Parameters:
      annotatedType - the type to check
      Returns:
      the set of top annotations representing all the hierarchies for which this type has a qualifier parameter
    • getQualifierParameterHierarchies

      public AnnotationMirrorSet getQualifierParameterHierarchies(Element element)
      Returns the set of top annotations representing all the hierarchies for which this element has a qualifier parameter.
      Parameters:
      element - the Element to check
      Returns:
      the set of top annotations representing all the hierarchies for which this element has a qualifier parameter
    • replaceAnnotations

      public void replaceAnnotations(AnnotatedTypeMirror from, AnnotatedTypeMirror to)
      Replaces or adds all annotations from from to to. Annotations from from will be used everywhere they exist, but annotations in to will be kept anywhere that from is unannotated.
      Parameters:
      from - the annotated type mirror from which to take new annotations
      to - the annotated type mirror to which the annotations will be added
    • replaceAnnotations

      public void replaceAnnotations(AnnotatedTypeMirror from, AnnotatedTypeMirror to, AnnotationMirror top)
      Replaces or adds annotations in top's hierarchy from from to to. Annotations from from will be used everywhere they exist, but annotations in to will be kept anywhere that from is unannotated.
      Parameters:
      from - the annotated type mirror from which to take new annotations
      to - the annotated type mirror to which the annotations will be added
      top - the top type of the hierarchy whose annotations will be added
    • containsUninferredTypeArguments

      public boolean containsUninferredTypeArguments(AnnotatedTypeMirror type)
      Returns whether this type or any component type is a wildcard type for which Java 7 type inference is insufficient. See issue 979, or the documentation on AnnotatedWildcardType.
      Parameters:
      type - type to check
      Returns:
      whether this type or any component type is a wildcard type for which Java 7 type inference is insufficient
    • getUninferredWildcardType

      Returns a wildcard type to be used as a type argument when the correct type could not be inferred. The wildcard will be marked as an uninferred wildcard so that AnnotatedTypeMirror.AnnotatedWildcardType.isUninferredTypeArgument() returns true.

      This method should only be used by type argument inference. org.checkerframework.framework.util.AnnotatedTypes.inferTypeArguments(ProcessingEnvironment, AnnotatedTypeFactory, ExpressionTree, ExecutableElement)

      Parameters:
      typeVar - the TypeVariable that could not be inferred
      Returns:
      a wildcard that is marked as an uninferred type argument
    • getFunctionTypeFromTree

      Returns the function type that this member reference targets.

      The function type is the type of the single method declared in the functional interface adapted as if it were invoked using the functional interface as the receiver expression.

      The target type of a member reference is the type to which it is assigned or casted.

      Parameters:
      tree - member reference tree
      Returns:
      the function type that this method reference targets
    • getFunctionTypeFromTree

      Returns the function type that this lambda targets.

      The function type is the type of the single method declared in the functional interface adapted as if it were invoked using the functional interface as the receiver expression.

      The target type of a lambda is the type to which it is assigned or casted.

      Parameters:
      tree - lambda expression tree
      Returns:
      the function type that this lambda targets
    • getFnInterfaceFromTree

      public org.plumelib.util.IPair<AnnotatedTypeMirror,AnnotatedTypeMirror.AnnotatedExecutableType> getFnInterfaceFromTree(Tree tree)
      Returns the functional interface and the function type that this lambda or member references targets.

      The function type is the type of the single method declared in the functional interface adapted as if it were invoked using the functional interface as the receiver expression.

      The target type of a lambda or a method reference is the type to which it is assigned or casted.

      Parameters:
      tree - lambda expression tree or member reference tree
      Returns:
      the functional interface and the function type that this method reference or lambda targets
    • applyCaptureConversion

      public AnnotatedTypeMirror applyCaptureConversion(AnnotatedTypeMirror typeToCapture)
      Apply capture conversion to typeToCapture.

      Capture conversion is the process of converting wildcards in a parameterized type to fresh type variables. See JLS 5.1.10 for details.

      If type is not a declared type or if it does not have any wildcard type arguments, this method returns type.

      Parameters:
      typeToCapture - type to capture
      Returns:
      the result of applying capture conversion to typeToCapture
    • applyCaptureConversion

      public AnnotatedTypeMirror applyCaptureConversion(AnnotatedTypeMirror type, TypeMirror typeMirror)
      Apply capture conversion to type.

      Capture conversion is the process of converting wildcards in a parameterized type to fresh type variables. See JLS 5.1.10 for details.

      If type is not a declared type or if it does not have any wildcard type arguments, this method returns type.

      Parameters:
      type - type to capture
      typeMirror - the result of applying capture conversion to the underlying type of type; it is used as the underlying type of the returned type
      Returns:
      the result of applying capture conversion to type
    • order

      Returns the list of type variables such that a type variable in the list only references type variables at a lower index than itself.
      Parameters:
      collection - a collection of type variables
      Returns:
      the type variables ordered so that each type variable only references earlier type variables
    • getElementUtils

      public final Elements getElementUtils()
      Returns the utility class for working with Elements.
      Returns:
      the utility class for working with Elements
    • getTreeUtils

      public Trees getTreeUtils()
      Accessor for the tree utilities.
    • getProcessingEnv

      public ProcessingEnvironment getProcessingEnv()
      Accessor for the processing environment.
      Returns:
      the processing environment
    • getExpressionAndOffset

      public static org.plumelib.util.IPair<String,String> getExpressionAndOffset(String expression)
      Given an expression, split it into a subexpression and a constant offset. For example:
      
       "a" => <"a", "0">
       "a + 5" => <"a", "5">
       "a + -5" => <"a", "-5">
       "a - 5" => <"a", "-5">
       
      There are methods that can only take as input an expression that represents a JavaExpression. The purpose of this is to pre-process expressions to make those methods more likely to succeed.
      Parameters:
      expression - an expression to remove a constant offset from
      Returns:
      a sub-expression and a constant offset. The offset is "0" if this routine is unable to splite the given expression
    • negateConstant

      public static String negateConstant(String constantExpression)
      Given an expression string, returns its negation.
      Parameters:
      constantExpression - a string representing an integer constant
      Returns:
      the negation of constantExpression
    • getDummyAssignedTo

      public @Nullable AnnotatedTypeMirror getDummyAssignedTo(ExpressionTree expressionTree)
      Returns null or an annotated type mirror that type argument inference should assume expressionTree is assigned to.

      If null is returned, inference proceeds normally.

      If a type is returned, then inference assumes that expressionTree was asigned to it. This biases the inference algorithm toward the annotations in the returned type. In particular, if the annotations on type variables in invariant positions are a super type of the annotations inferred, the super type annotations are chosen.

      This implementation returns null, but subclasses may override this method to return a type.

      Parameters:
      expressionTree - an expression which has no assignment context and for which type arguments need to be inferred
      Returns:
      null or an annotated type mirror that inferrence should pretend expressionTree is assigned to
    • areSameByClass

      public boolean areSameByClass(AnnotationMirror am, Class<? extends Annotation> annoClass)
      Checks that the annotation am has the name of annoClass. Values are ignored.

      This method is faster than AnnotationUtils.areSameByClass(AnnotationMirror, Class) because it caches the name of the class rather than computing it each time.

      Parameters:
      am - the AnnotationMirror whose class to compare
      annoClass - the class to compare
      Returns:
      true if annoclass is the class of am
    • containsSameByClass

      public boolean containsSameByClass(Collection<? extends AnnotationMirror> c, Class<? extends Annotation> anno)
      Checks that the collection contains the annotation. Using Collection.contains does not always work, because it does not use areSame() for comparison.

      This method is faster than AnnotationUtils.containsSameByClass(Collection, Class) because is caches the name of the class rather than computing it each time.

      Parameters:
      c - a collection of AnnotationMirrors
      anno - the annotation class to search for in c
      Returns:
      true iff c contains anno, according to areSameByClass
    • getAnnotationByClass

      public @Nullable AnnotationMirror getAnnotationByClass(Collection<? extends AnnotationMirror> c, Class<? extends Annotation> anno)
      Returns the AnnotationMirror in c that has the same class as anno.

      This method is faster than AnnotationUtils.getAnnotationByClass(Collection, Class) because is caches the name of the class rather than computing it each time.

      Parameters:
      c - a collection of AnnotationMirrors
      anno - the class to search for in c
      Returns:
      AnnotationMirror with the same class as anno iff c contains anno, according to areSameByClass; otherwise, null
    • wpiAdjustForUpdateField

      public void wpiAdjustForUpdateField(Tree lhsTree, Element element, String fieldName, AnnotatedTypeMirror rhsATM)
      Changes the type of rhsATM when being assigned to a field, for use by whole-program inference. The default implementation does nothing.
      Parameters:
      lhsTree - the tree for the field whose type will be changed
      element - the element for the field whose type will be changed
      fieldName - the name of the field whose type will be changed
      rhsATM - the type of the expression being assigned to the field, which is side-effected by this method
    • wpiAdjustForUpdateNonField

      public void wpiAdjustForUpdateNonField(AnnotatedTypeMirror rhsATM)
      Changes the type of rhsATM when being assigned to anything other than a field, for use by whole-program inference. The default implementation does nothing.
      Parameters:
      rhsATM - the type of the rhs of the pseudo-assignment, which is side-effected by this method
    • wpiShouldInferTypesForReceivers

      public boolean wpiShouldInferTypesForReceivers()
      Returns whether whole-program inference should infer types for receiver expressions. For some type systems, such as nullness, it doesn't make sense for WPI to do inference on receivers.
      Returns:
      true if WPI should infer types for method receiver parameters, false otherwise
    • wpiPrepareMethodForWriting

      public void wpiPrepareMethodForWriting(org.checkerframework.afu.scenelib.el.AMethod methodAnnos)
      Side-effects the method or constructor annotations to make any desired changes before writing to an annotation file.
      Parameters:
      methodAnnos - the method or constructor annotations to modify
    • wpiPrepareMethodForWriting

      Side-effects the method or constructor annotations to make any desired changes before writing to an ajava file.

      Overriding implementations should call super.wpiPrepareMethodForWriting().

      Parameters:
      methodAnnos - the method or constructor annotations to modify
      inSupertypes - the method or constructor annotations for all overridden methods; not side-effected
      inSubtypes - the method or constructor annotations for all overriding methods; not side-effected
    • makeConditionConsistentWithOtherMethod

      protected void makeConditionConsistentWithOtherMethod(Map<String,org.plumelib.util.IPair<AnnotatedTypeMirror,AnnotatedTypeMirror>> conditionMap, WholeProgramInferenceJavaParserStorage.CallableDeclarationAnnos otherDeclAnnos, boolean isPrecondition, boolean otherIsSupertype)
      Performs side effects to make conditionMap obey behavioral subtyping constraints with otherDeclAnnos, that is, postconditions must be at least as strong as the postcondition on the superclass, and preconditions must be at most as strong as the condition on the superclass.

      Overriding implementations should call super.makeConditionConsistentWithOtherMethod().

      Parameters:
      conditionMap - pre- or post-condition annotations on a method M; may be side-effected
      otherDeclAnnos - annotations on a method that M overrides or that overrides M; that is, on a method in the same "method family" as M; may be side-effected
      isPrecondition - true if the annotations are pre-condition annotations, false if they are post-condition annotations
      otherIsSupertype - true if otherDeclAnnos are on a supertype; false if they are on a subtype
    • doesAnnotatedForApplyToThisChecker

      public boolean doesAnnotatedForApplyToThisChecker(AnnotationMirror annotatedForAnno)
      Does anno, which is an AnnotatedFor annotation, apply to this checker?
      Parameters:
      annotatedForAnno - an AnnotatedFor annotation
      Returns:
      whether anno applies to this checker
    • getContractExpressions

      public List<String> getContractExpressions(AnnotationMirror contractAnno)
      Get the expression field/element of the given contract annotation.
      Parameters:
      contractAnno - a RequiresQualifier, EnsuresQualifier, or EnsuresQualifier
      Returns:
      the expression field/element of the given annotation
    • getContractListValues

      public List<AnnotationMirror> getContractListValues(AnnotationMirror contractListAnno)
      Get the value field/element of the given contract list annotation.
      Parameters:
      contractListAnno - a RequiresQualifier.List, EnsuresQualifier.List, or EnsuresQualifierIf.List
      Returns:
      the value field/element of the given annotation
    • isImmutable

      public boolean isImmutable(TypeMirror type)
      Returns true if the type is immutable. Subclasses can override this method to add types that are mutable, but the annotated type of an object is immutable.
      Parameters:
      type - type to test
      Returns:
      true if the type is immutable
    • isSideEffectFree

      public boolean isSideEffectFree(ExecutableElement methodElement)
      Description copied from interface: AnnotationProvider
      Returns true if the given method is side-effect-free according to this AnnotationProvider — that is, if a call to the given method does not undo flow-sensitive type refinement.

      Note that this method takes account of this AnnotationProvider's semantics, whereas org.checkerframework.dataflow.util.PurityUtils#isSideEffectFree does not.

      Specified by:
      isSideEffectFree in interface AnnotationProvider
      Parameters:
      methodElement - a method
      Returns:
      true if a call to the method does not undo flow-sensitive type refinement
    • isDeterministic

      public boolean isDeterministic(ExecutableElement methodElement)
      Description copied from interface: AnnotationProvider
      Returns true if the given method is deterministic according to this AnnotationProvider — that is, if multiple calls to the given method (with the same arguments) return the same value.

      Note that this method takes account of this AnnotationProvider's semantics, whereas org.checkerframework.dataflow.util.PurityUtils#isDeterministic does not.

      Specified by:
      isDeterministic in interface AnnotationProvider
      Parameters:
      methodElement - a method
      Returns:
      true if multiple calls to the method (with the same arguments) return the same value
    • logGat

      @FormatMethod public void logGat(String format, Object... args)
      Output a message about getAnnotatedType(javax.lang.model.element.Element), if logging is on.
      Parameters:
      format - a format string
      args - arguments to the format string