Class GenericAnnotatedTypeFactory<Value extends CFAbstractValue<Value>,​Store extends CFAbstractStore<Value,​Store>,​TransferFunction extends CFAbstractTransfer<Value,​Store,​TransferFunction>,​FlowAnalysis extends CFAbstractAnalysis<Value,​Store,​TransferFunction>>

    • Constructor Detail

      • GenericAnnotatedTypeFactory

        protected GenericAnnotatedTypeFactory​(BaseTypeChecker checker,
                                              boolean useFlow)
        Creates a type factory. Its compilation unit is not yet set.
        Parameters:
        checker - the checker to which this type factory belongs
        useFlow - whether flow analysis should be performed
      • GenericAnnotatedTypeFactory

        protected GenericAnnotatedTypeFactory​(BaseTypeChecker checker)
        Creates a type factory. Its compilation unit is not yet set. This constructor might get reflectively called by BaseTypeVisitor.createTypeFactory and uses flowByDefault to determine whether flow refinement should be enabled. Subclasses should instead use the two-parameter constructor and explicitly set whether to use flow refinement.
        Parameters:
        checker - the checker to which this type factory belongs
    • Method Detail

      • preProcessClassTree

        public void preProcessClassTree​(com.sun.source.tree.ClassTree classTree)
        Performs flow-sensitive type refinement on classTree if this type factory is configured to do so.
        Overrides:
        preProcessClassTree in class AnnotatedTypeFactory
        Parameters:
        classTree - tree on which to perform flow-sensitive type refinement
      • setRoot

        public void setRoot​(@Nullable com.sun.source.tree.CompilationUnitTree root)
        Description copied from class: AnnotatedTypeFactory
        Set the CompilationUnitTree that should be used.
        Overrides:
        setRoot in class AnnotatedTypeFactory
        Parameters:
        root - the new compilation unit to use
      • getSupportedMonotonicTypeQualifiers

        public final java.util.Set<java.lang.Class<? extends java.lang.annotation.Annotation>> getSupportedMonotonicTypeQualifiers()
        Returns an immutable set of the monotonic type qualifiers supported by this checker.
        Returns:
        the monotonic type qualifiers supported this processor, or an empty set if none
        See Also:
        MonotonicQualifier
      • annotationsForIrrelevantJavaType

        public AnnotationMirrorSet annotationsForIrrelevantJavaType​(javax.lang.model.type.TypeMirror tm)
        Returns the annotations that should appear on the given irrelevant Java type. If the type is relevant, this method's behavior is undefined.
        Parameters:
        tm - an irrelevant Java type
        Returns:
        the annotations that should appear on the given irrelevant Java type
      • createFlowAnalysis

        protected FlowAnalysis createFlowAnalysis()
        Returns the appropriate flow analysis class that is used for the org.checkerframework.dataflow analysis.

        This implementation uses the checker naming convention to create the appropriate analysis. If no transfer function is found, it returns an instance of CFAnalysis.

        Subclasses have to override this method to create the appropriate analysis if they do not follow the checker naming convention.

        Returns:
        the appropriate flow analysis class that is used for the org.checkerframework.dataflow analysis
      • createFlowTransferFunction

        public TransferFunction createFlowTransferFunction​(CFAbstractAnalysis<Value,​Store,​TransferFunction> analysis)
        Returns the appropriate transfer function that is used for the given org.checkerframework.dataflow analysis.

        This implementation uses the checker naming convention to create the appropriate transfer function. If no transfer function is found, it returns an instance of CFTransfer.

        Subclasses have to override this method to create the appropriate transfer function if they do not follow the checker naming convention.

        Parameters:
        analysis - a dataflow analysis
        Returns:
        a new transfer function
      • getDependentTypesHelper

        public DependentTypesHelper getDependentTypesHelper()
        Returns the DependentTypesHelper.
        Returns:
        the DependentTypesHelper
      • getContractsFromMethod

        public ContractsFromMethod getContractsFromMethod()
        Returns the helper for method pre- and postconditions.
        Returns:
        the helper for method pre- and postconditions
      • getExplicitNewClassClassTypeArgs

        protected java.util.List<AnnotatedTypeMirror> getExplicitNewClassClassTypeArgs​(com.sun.source.tree.NewClassTree newClassTree)
        Description copied from class: AnnotatedTypeFactory
        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.
        Overrides:
        getExplicitNewClassClassTypeArgs in class AnnotatedTypeFactory
        Parameters:
        newClassTree - a new class tree
        Returns:
        the partially annotated AnnotatedTypeMirrors for the (explicit) class type arguments of the new class tree
      • getExplicitNewClassAnnos

        public AnnotationMirrorSet getExplicitNewClassAnnos​(com.sun.source.tree.NewClassTree newClassTree)
        Description copied from class: AnnotatedTypeFactory
        Returns the annotations explicitly written on a NewClassTree.

        new @HERE Class()

        Overrides:
        getExplicitNewClassAnnos in class AnnotatedTypeFactory
        Parameters:
        newClassTree - a constructor invocation
        Returns:
        the annotations explicitly written on a NewClassTree
      • createQualifierDefaults

        protected QualifierDefaults createQualifierDefaults()
        Create QualifierDefaults which handles checker specified defaults. Sub-classes override this method to provide a different QualifierDefault implementation.
      • getSortedQualifierNames

        protected final java.lang.String getSortedQualifierNames()
        Creates and returns a string containing the number of qualifiers and the canonical class names of each qualifier that has been added to this checker's supported qualifier set. The names are alphabetically sorted.
        Returns:
        a string containing the number of qualifiers and canonical names of each qualifier
      • addCheckedStandardDefaults

        protected void addCheckedStandardDefaults​(QualifierDefaults defs)
        Adds the standard CLIMB defaults that do not conflict with previously added defaults.
        Parameters:
        defs - QualifierDefaults object to which defaults are added
      • addUncheckedStandardDefaults

        protected void addUncheckedStandardDefaults​(QualifierDefaults defs)
        Adds standard unchecked defaults that do not conflict with previously added defaults.
        Parameters:
        defs - QualifierDefaults object to which defaults are added
      • checkForDefaultQualifierInHierarchy

        protected void checkForDefaultQualifierInHierarchy​(QualifierDefaults defs)
        Check that a default qualifier (in at least one hierarchy) has been set and issue an error if not.
        Parameters:
        defs - QualifierDefaults object to which defaults are added
      • createQualifierPolymorphism

        protected QualifierPolymorphism createQualifierPolymorphism()
        Creates the QualifierPolymorphism instance which supports the QualifierPolymorphism mechanism.
        Returns:
        the QualifierPolymorphism instance to use
      • getQualifierPolymorphism

        public QualifierPolymorphism getQualifierPolymorphism()
        Gives the current QualifierPolymorphism instance which supports the QualifierPolymorphism mechanism.
        Returns:
        the QualifierPolymorphism instance to use
      • postDirectSuperTypes

        protected void postDirectSuperTypes​(AnnotatedTypeMirror type,
                                            java.util.List<? extends AnnotatedTypeMirror> supertypes)
        Description copied from class: AnnotatedTypeFactory
        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.

        Overrides:
        postDirectSuperTypes in class AnnotatedTypeFactory
        Parameters:
        type - the type whose supertypes are desired
        supertypes - the supertypes as specified by the base AnnotatedTypeFactory
      • getResultingTypeOfConstructorMemberReference

        public AnnotatedTypeMirror getResultingTypeOfConstructorMemberReference​(com.sun.source.tree.MemberReferenceTree memberReferenceTree,
                                                                                AnnotatedTypeMirror.AnnotatedExecutableType constructorType)
        Gets the type of the resulting constructor call of a MemberReferenceTree.
        Parameters:
        memberReferenceTree - MemberReferenceTree where the member is a constructor
        constructorType - AnnotatedExecutableType of the declaration of the constructor
        Returns:
        AnnotatedTypeMirror of the resulting type of the constructor
      • getAnnotationFromJavaExpressionString

        public @Nullable javax.lang.model.element.AnnotationMirror getAnnotationFromJavaExpressionString​(java.lang.String expression,
                                                                                                         com.sun.source.tree.Tree tree,
                                                                                                         com.sun.source.util.TreePath path,
                                                                                                         java.lang.Class<? extends java.lang.annotation.Annotation> clazz)
                                                                                                  throws JavaExpressionParseUtil.JavaExpressionParseException
        Returns the primary annotation on expression if it were evaluated at path.
        Parameters:
        expression - a Java expression
        tree - current tree
        path - location at which expression is evaluated
        clazz - class of the annotation
        Returns:
        the annotation on expression or null if one does not exist
        Throws:
        JavaExpressionParseUtil.JavaExpressionParseException - thrown if the expression cannot be parsed
      • getAnnotationFromJavaExpression

        public @Nullable javax.lang.model.element.AnnotationMirror getAnnotationFromJavaExpression​(JavaExpression expr,
                                                                                                   com.sun.source.tree.Tree tree,
                                                                                                   java.lang.Class<? extends java.lang.annotation.Annotation> clazz)
        Returns the primary annotation on an expression, at a particular location.
        Parameters:
        expr - the expression for which the annotation is returned
        tree - current tree
        clazz - the Class of the annotation
        Returns:
        the annotation on expression or null if one does not exist
      • getAnnotationsFromJavaExpression

        public @Nullable AnnotationMirrorSet getAnnotationsFromJavaExpression​(JavaExpression expr,
                                                                              com.sun.source.tree.Tree tree)
        Returns the primary annotations on an expression, at a particular location.
        Parameters:
        expr - the expression for which the annotation is returned
        tree - current tree
        Returns:
        the annotation on expression or null if one does not exist
      • getExpressionAndOffsetFromJavaExpressionString

        public org.plumelib.util.IPair<JavaExpression,​java.lang.String> getExpressionAndOffsetFromJavaExpressionString​(java.lang.String expression,
                                                                                                                             com.sun.source.util.TreePath currentPath)
                                                                                                                      throws JavaExpressionParseUtil.JavaExpressionParseException
        Produces the JavaExpression and offset associated with an expression. For instance, "n+1" has no associated JavaExpression, but this method produces a pair of a JavaExpression (for "n") and an offset ("1").
        Parameters:
        expression - a Java expression, possibly with a constant offset
        currentPath - location at which expression is evaluated
        Returns:
        the JavaExpression and offset for the given expression
        Throws:
        JavaExpressionParseUtil.JavaExpressionParseException - thrown if the expression cannot be parsed
      • getAnnotationMirrorFromJavaExpressionString

        public @Nullable javax.lang.model.element.AnnotationMirror getAnnotationMirrorFromJavaExpressionString​(java.lang.String expression,
                                                                                                               com.sun.source.tree.Tree tree,
                                                                                                               com.sun.source.util.TreePath currentPath)
                                                                                                        throws JavaExpressionParseUtil.JavaExpressionParseException
        Returns the annotation mirror from dataflow for expression.

        This will output a different annotation than getAnnotationFromJavaExpressionString(String, Tree, TreePath, Class), because if the specified annotation isn't found in the store, the type from the factory is used.

        Parameters:
        expression - a Java expression
        tree - the tree at the location to parse the expression
        currentPath - location at which expression is evaluated
        Returns:
        an AnnotationMirror representing the type in the store at the given location from this type factory's type system, or null if one is not available
        Throws:
        JavaExpressionParseUtil.JavaExpressionParseException - thrown if the expression cannot be parsed
      • getRegularExitStore

        public @Nullable Store getRegularExitStore​(com.sun.source.tree.Tree tree)
        Returns the regular exit store for a method or another code block (such as static initializers). Returns null if there is no such store. This can happen because the method cannot exit through the regular exit block, or it is abstract or in an interface.
        Parameters:
        tree - a MethodTree or other code block, such as a static initializer
        Returns:
        the regular exit store, or null
      • getExceptionalExitStore

        public @Nullable Store getExceptionalExitStore​(com.sun.source.tree.Tree tree)
        Returns the exceptional exit store for a method or another code block (such as static initializers).
        Parameters:
        tree - a MethodTree or other code block, such as a static initializer
        Returns:
        the exceptional exit store, or null, if there is no such store
      • getReturnStatementStores

        public java.util.List<org.plumelib.util.IPair<ReturnNode,​TransferResult<Value,​Store>>> getReturnStatementStores​(com.sun.source.tree.MethodTree methodTree)
        Returns a list of all return statements of method paired with their corresponding TransferResult. If method has no return statement, then the empty list is returned.
        Parameters:
        methodTree - method whose return statements should be returned
        Returns:
        a list of all return statements of method paired with their corresponding TransferResult or an empty list if method has no return statements
      • getStoreBefore

        public Store getStoreBefore​(com.sun.source.tree.Tree tree)
        Returns the store immediately before a given Tree.
        Returns:
        the store immediately before a given Tree
      • getStoreBefore

        public Store getStoreBefore​(java.util.Set<Node> nodes)
        Returns the store immediately before a given Set of Nodes.
        Returns:
        the store immediately before a given Set of Nodes
      • getStoreBefore

        public @Nullable Store getStoreBefore​(Node node)
        Returns the store immediately before a given node.
        Parameters:
        node - a node whose pre-store to return
        Returns:
        the store immediately before node
      • getStoreAfter

        public @Nullable Store getStoreAfter​(com.sun.source.tree.Tree tree)
        Returns the store immediately after a given tree.

        May return null; for example, after a return statement.

        Parameters:
        tree - the tree whose post-store to return
        Returns:
        the store immediately after a given tree
      • getStoreAfter

        public Store getStoreAfter​(java.util.Set<Node> nodes)
        Returns the store immediately after a given set of nodes.
        Parameters:
        nodes - the nodes whose post-stores to LUB
        Returns:
        the LUB of the stores store immediately after nodes
      • getStoreAfter

        public Store getStoreAfter​(Node node)
        Returns the store immediately after a given Node.
        Parameters:
        node - node after which the store is returned
        Returns:
        the store immediately after a given Node
      • getFirstNodeOfKindForTree

        public <T extends Node@Nullable T getFirstNodeOfKindForTree​(com.sun.source.tree.Tree tree,
                                                                      java.lang.Class<T> kind)
        Return the first Node for a given Tree that has class kind.

        You probably don't want to use this function: iterate over the result of getNodesForTree(Tree) yourself or ask for a conservative approximation of the store using getStoreBefore(Tree) or getStoreAfter(Tree). This method is for code that uses a Node in a rather unusual way. Callers should probably be rewritten to not use a Node at all.

        Type Parameters:
        T - the class of the node to return
        Parameters:
        tree - a tree in which to search for a node of class kind
        kind - the class of the node to return
        Returns:
        the first Node for a given Tree that has class kind
        See Also:
        getNodesForTree(Tree), getStoreBefore(Tree), getStoreAfter(Tree)
      • getFinalLocalValues

        public java.util.Map<javax.lang.model.element.VariableElement,​Value> getFinalLocalValues()
        Returns the value of effectively final local variables.
        Returns:
        the value of effectively final local variables
      • isNotFullyInitializedReceiver

        @Pure
        public boolean isNotFullyInitializedReceiver​(com.sun.source.tree.MethodTree methodDeclTree)
        Returns true if the receiver of a method or constructor might not be fully initialized.
        Parameters:
        methodDeclTree - the declaration of the method or constructor
        Returns:
        true if the receiver of a method or constructor might not be fully initialized
      • performFlowAnalysis

        protected void performFlowAnalysis​(com.sun.source.tree.ClassTree classTree)
        Perform a org.checkerframework.dataflow analysis over a single class tree and its nested classes.
        Parameters:
        classTree - the class to analyze
      • analyze

        protected void analyze​(java.util.Queue<org.plumelib.util.IPair<com.sun.source.tree.ClassTree,​Store>> classQueue,
                               java.util.Queue<org.plumelib.util.IPair<com.sun.source.tree.LambdaExpressionTree,​Store>> lambdaQueue,
                               UnderlyingAST ast,
                               java.util.List<CFAbstractAnalysis.FieldInitialValue<Value>> fieldValues,
                               com.sun.source.tree.ClassTree currentClass,
                               boolean isInitializationCode,
                               boolean updateInitializationStore,
                               boolean isStatic,
                               @Nullable Store capturedStore)
        Analyze the AST ast and store the result. Additional operations that should be performed after analysis should be implemented in postAnalyze(ControlFlowGraph).
        Parameters:
        classQueue - the queue for encountered class trees and their initial stores
        lambdaQueue - the queue for encountered lambda expression trees and their initial stores
        ast - the AST to analyze
        fieldValues - the abstract values for all fields of the same class
        currentClass - the class we are currently looking at
        isInitializationCode - are we analyzing a (static/non-static) initializer block of a class
        updateInitializationStore - should the initialization store be updated
        isStatic - are we analyzing a static construct
        capturedStore - the input Store to use for captured variables, e.g. in a lambda
        See Also:
        postAnalyze(org.checkerframework.dataflow.cfg.ControlFlowGraph)
      • handleCFGViz

        protected void handleCFGViz​(ControlFlowGraph cfg)
        Handle the visualization of the CFG, if necessary.
        Parameters:
        cfg - the CFG
      • getAnnotatedTypeLhsNoTypeVarDefault

        public AnnotatedTypeMirror getAnnotatedTypeLhsNoTypeVarDefault​(com.sun.source.tree.Tree lhsTree)
        Returns the type of the left-hand side of an assignment without applying local variable defaults to type variables.

        The type variables that are types of local variables are defaulted to top so that they can be refined by dataflow. When these types are used as context during type argument inference, this default is too conservative. So this method is used instead of getAnnotatedTypeLhs(Tree).

        TypeArgInferenceUtil.assignedToVariable(AnnotatedTypeFactory, VariableTree) explains why a different type is used.

        Parameters:
        lhsTree - left-hand side of an assignment
        Returns:
        AnnotatedTypeMirror of lhsTree
      • isComputingAnnotatedTypeMirrorOfLhs

        public boolean isComputingAnnotatedTypeMirrorOfLhs()
        Returns whether getAnnotatedTypeLhs(Tree) is running right now. This controls which hierarchies' qualifiers are changed based on the receiver type and the declared annotations for a field.
        Returns:
        whether getAnnotatedTypeLhs(Tree) is running right now
        See Also:
        getAnnotatedTypeLhs(Tree)
      • getAnnotatedTypeLhs

        public AnnotatedTypeMirror getAnnotatedTypeLhs​(com.sun.source.tree.Tree lhsTree)
        Returns the type of a left-hand side of an assignment.

        The default implementation returns the type without considering dataflow type refinement. Subclass can override this method and add additional logic for computing the type of a LHS.

        Parameters:
        lhsTree - left-hand side of an assignment
        Returns:
        AnnotatedTypeMirror of lhsTree
      • getAnnotatedTypeVarargsArray

        public @Nullable AnnotatedTypeMirror getAnnotatedTypeVarargsArray​(com.sun.source.tree.Tree tree)
        Returns the type of a varargs array of a method invocation or a constructor invocation. Returns null only if private field useFlow is false.
        Parameters:
        tree - a method invocation or a constructor invocation
        Returns:
        AnnotatedTypeMirror of varargs array for a method or constructor invocation tree; returns null if private field useFlow is false
      • getAnnotatedTypeRhsUnaryAssign

        public AnnotatedTypeMirror getAnnotatedTypeRhsUnaryAssign​(com.sun.source.tree.UnaryTree tree)
        Returns the type of v + 1 or v - 1 where v is the expression in the postfixed increment or decrement expression.
        Parameters:
        tree - a postfixed increment or decrement tree
        Returns:
        AnnotatedTypeMirror of a right-hand side of an assignment for unary operation
      • constructorFromUsePreSubstitution

        protected void constructorFromUsePreSubstitution​(com.sun.source.tree.NewClassTree tree,
                                                         AnnotatedTypeMirror.AnnotatedExecutableType type)
        Description copied from class: AnnotatedTypeFactory
        A callback method for the AnnotatedTypeFactory subtypes to customize the handling of the declared constructor type before type variable substitution.
        Overrides:
        constructorFromUsePreSubstitution in class AnnotatedTypeFactory
        Parameters:
        tree - a NewClassTree from constructorFromUse()
        type - declared method type before type variable substitution
      • getDefaultAnnotations

        public AnnotatedTypeMirror getDefaultAnnotations​(com.sun.source.tree.Tree tree,
                                                         AnnotatedTypeMirror type)
        Removes all primary annotations on a copy of the type and calculates the default annotations that apply to the copied type, without type refinements.
        Parameters:
        tree - tree where the type is used
        type - type to determine the defaulted version for
        Returns:
        the annotated type mirror with default annotations
      • addComputedTypeAnnotations

        protected void addComputedTypeAnnotations​(com.sun.source.tree.Tree tree,
                                                  AnnotatedTypeMirror type,
                                                  boolean iUseFlow)
        Like addComputedTypeAnnotations(Tree, AnnotatedTypeMirror). Overriding implementations typically simply pass the boolean to calls to super.
        Parameters:
        tree - an AST node
        type - the type obtained from tree
        iUseFlow - whether to use information from dataflow analysis
      • checkAndPerformFlowAnalysis

        protected void checkAndPerformFlowAnalysis​(com.sun.source.tree.Tree tree)
        Flow analysis will be performed if all of the following are true.
        • tree is a ClassTree
        • Flow analysis has not already been performed on tree
        Parameters:
        tree - the tree to check and possibly perform flow analysis on
      • getInferredValueFor

        public @Nullable Value getInferredValueFor​(com.sun.source.tree.Tree tree)
        Returns the inferred value (by the org.checkerframework.dataflow analysis) for a given tree.
        Parameters:
        tree - the tree
        Returns:
        the value for the tree, if one has been computed by dataflow. If no value has been computed, null is returned (this does not mean that no value will ever be computed for the given tree).
      • applyInferredAnnotations

        protected void applyInferredAnnotations​(AnnotatedTypeMirror type,
                                                Value inferred)
        Applies the annotations inferred by the org.checkerframework.dataflow analysis to the type type.
        Parameters:
        type - the type to modify
        inferred - the inferred annotations to apply
      • applyQualifierParameterDefaults

        protected void applyQualifierParameterDefaults​(com.sun.source.tree.Tree tree,
                                                       AnnotatedTypeMirror type)
        Applies defaults for types in a class with an qualifier parameter.

        Within a class with @HasQualifierParameter, types with that class default to the polymorphic qualifier rather than the typical default. Local variables with a type that has a qualifier parameter are initialized to the type of their initializer, rather than the default for local variables.

        Parameters:
        tree - a Tree whose type is type
        type - where the defaults are applied
      • applyQualifierParameterDefaults

        protected void applyQualifierParameterDefaults​(@Nullable javax.lang.model.element.Element elt,
                                                       AnnotatedTypeMirror type)
        Applies defaults for types in a class with an qualifier parameter.

        Within a class with @HasQualifierParameter, types with that class default to the polymorphic qualifier rather than the typical default. Local variables with a type that has a qualifier parameter are initialized to the type of their initializer, rather than the default for local variables.

        Parameters:
        elt - an Element whose type is type
        type - where the defaults are applied
      • methodFromUsePreSubstitution

        public void methodFromUsePreSubstitution​(com.sun.source.tree.ExpressionTree tree,
                                                 AnnotatedTypeMirror.AnnotatedExecutableType type)
        Description copied from class: AnnotatedTypeFactory
        A callback method for the AnnotatedTypeFactory subtypes to customize the handling of the declared method type before type variable substitution.
        Overrides:
        methodFromUsePreSubstitution in class AnnotatedTypeFactory
        Parameters:
        tree - either a method invocation or a member reference tree
        type - declared method type before type variable substitution
      • typeVariablesFromUse

        public java.util.List<AnnotatedTypeParameterBounds> typeVariablesFromUse​(AnnotatedTypeMirror.AnnotatedDeclaredType type,
                                                                                 javax.lang.model.element.TypeElement element)
        Description copied from class: AnnotatedTypeFactory
        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.

        Overrides:
        typeVariablesFromUse in class AnnotatedTypeFactory
        Parameters:
        type - the use of the type
        element - the corresponding element
        Returns:
        the adapted bounds of the type parameters
      • getEmptyStore

        public Store getEmptyStore()
        Returns the empty store.
        Returns:
        the empty store
      • getShouldDefaultTypeVarLocals

        public boolean getShouldDefaultTypeVarLocals()
        Should the local variable default annotation be applied to type variables?

        It is initialized to true if data flow is used by the checker. It is set to false when getting the assignment context for type argument inference.

        Returns:
        shouldDefaultTypeVarLocals
        See Also:
        getAnnotatedTypeLhsNoTypeVarDefault(com.sun.source.tree.Tree)
      • postAsMemberOf

        public void postAsMemberOf​(AnnotatedTypeMirror type,
                                   AnnotatedTypeMirror owner,
                                   javax.lang.model.element.Element element)
        Description copied from class: AnnotatedTypeFactory
        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.
        Overrides:
        postAsMemberOf in class AnnotatedTypeFactory
        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
      • addAnnotationsFromDefaultForType

        protected void addAnnotationsFromDefaultForType​(@Nullable javax.lang.model.element.Element element,
                                                        AnnotatedTypeMirror type)
        Adds default qualifiers based on the underlying type of type to type. If element is a local variable, or if the type already has an annotation from the relevant type hierarchy, then the defaults are not added.

        (This uses both the DefaultQualifierForUseTypeAnnotator and DefaultForTypeAnnotator.)

        Parameters:
        element - possibly null element whose type is type
        type - the type to which defaults are added
      • isRelevant

        public final boolean isRelevant​(javax.lang.model.type.TypeMirror tm)
        Returns true if users can write type annotations from this type system directly on the given Java type.

        May return false for a compound type (for which it is possible to write type qualifiers on elements of the type).

        Subclasses should override #isRelevantImpl instead of this method.

        Parameters:
        tm - a type
        Returns:
        true if users can write type annotations from this type system directly on the given Java type
      • isRelevant

        public final boolean isRelevant​(AnnotatedTypeMirror tm)
        Returns true if users can write type annotations from this type system directly on the given Java type.

        May return false for a compound type (for which it is possible to write type qualifiers on elements of the type).

        Subclasses should override #isRelevantImpl instead of this method.

        Parameters:
        tm - a type
        Returns:
        true if users can write type annotations from this type system directly on the given Java type
      • isRelevantImpl

        protected boolean isRelevantImpl​(javax.lang.model.type.TypeMirror tm)
        Returns true if users can write type annotations from this type system on the given Java type. Does not use a cache.

        Clients should never call this. Call isRelevant(javax.lang.model.type.TypeMirror) instead. This is a helper method for isRelevant(javax.lang.model.type.TypeMirror).

        Parameters:
        tm - a type
        Returns:
        true if users can write type annotations from this type system on the given Java type
      • irrelevantExtraMessage

        public java.lang.String irrelevantExtraMessage()
        Returns a string that can be passed to the "anno.on.irrelevant" error, giving information about which types are relevant.
        Returns:
        a string that can be passed to the "anno.on.irrelevant" error, possibly the empty string
      • getDefaultValueAnnotatedType

        public AnnotatedTypeMirror getDefaultValueAnnotatedType​(javax.lang.model.type.TypeMirror typeMirror)
        Return the type of the default value of the given type. The default value is 0, false, or null.
        Parameters:
        typeMirror - a type
        Returns:
        the annotated type of type's default value
      • createRequiresOrEnsuresQualifier

        protected @Nullable javax.lang.model.element.AnnotationMirror createRequiresOrEnsuresQualifier​(java.lang.String expression,
                                                                                                       javax.lang.model.element.AnnotationMirror qualifier,
                                                                                                       AnnotatedTypeMirror declaredType,
                                                                                                       Analysis.BeforeOrAfter preOrPost,
                                                                                                       @Nullable java.util.List<javax.lang.model.element.AnnotationMirror> preconds)
        Creates a RequiresQualifier("...") or EnsuresQualifier("...") annotation for the given expression.

        This is of the form @RequiresQualifier(expression="expression", qualifier=MyQual.class) or @EnsuresQualifier(expression="expression", qualifier=MyQual.class), where "expression" is exactly the string expression and MyQual is the annotation represented by qualifier.

        Returns null if the expression is invalid when combined with the kind of annotation: for example, precondition annotations on "this" and parameters ("#1", etc.) are not supported, because receiver/parameter annotations should be inferred instead.

        This implementation returns null if no annotation can be created, because the qualifier has elements/arguments, which @RequiresQualifier and @EnsuresQualifier do not support. Subclasses may override this method to return qualifiers that do have arguments instead of returning null.

        Parameters:
        expression - the expression to which the qualifier applies
        qualifier - the qualifier that must be present
        declaredType - the declared type of the expression, which is used to avoid inferring redundant pre- or postcondition annotations
        preOrPost - whether to return a precondition or postcondition annotation
        preconds - the list of precondition annotations; used to suppress redundant postconditions; non-null exactly when preOrPost is BeforeOrAfter.BEFORE
        Returns:
        a RequiresQualifier("...") or EnsuresQualifier("...") annotation for the given expression, or null
      • addSharedCFGForTree

        public boolean addSharedCFGForTree​(com.sun.source.tree.Tree tree,
                                           ControlFlowGraph cfg)
        Add a new entry to the shared CFG. If this is a subchecker, this method delegates to the superchecker's GenericAnnotatedTypeFactory, if it exists. Duplicate keys must map to the same CFG.

        Calls to this method should be guarded by checking hasOrIsSubchecker; it is nonsensical to have a shared CFG when a checker is running alone.

        Parameters:
        tree - the source code corresponding to cfg
        cfg - the control flow graph to use for tree
        Returns:
        whether a shared CFG was found to actually add to (duplicate keys also return true)
      • getSharedCFGForTree

        public @Nullable ControlFlowGraph getSharedCFGForTree​(com.sun.source.tree.Tree tree)
        Get the shared control flow graph used for tree by this checker's topmost superchecker. Returns null if no information is available about the given tree, or if this checker has a parent checker that does not have a GenericAnnotatedTypeFactory.

        Calls to this method should be guarded by checking hasOrIsSubchecker; it is nonsensical to have a shared CFG when a checker is running alone.

        Parameters:
        tree - the tree whose CFG should be looked up
        Returns:
        the CFG stored by this checker's uppermost superchecker for tree, or null if it is not available
      • getEnsuresQualifierIfResult

        public @Nullable java.lang.Boolean getEnsuresQualifierIfResult​(Contract.Kind kind,
                                                                       javax.lang.model.element.AnnotationMirror contractAnnotation)
        If kind = CONDITIONALPOSTCONDITION, return the result element, e.g. EnsuresQualifierIf.result(). Otherwise, return null.
        Parameters:
        kind - the kind of contractAnnotation
        contractAnnotation - a RequiresQualifier, EnsuresQualifier, or EnsuresQualifierIf
        Returns:
        the result element of contractAnnotation, or null if it doesn't have a result element
      • getContractExpressions

        public @Nullable java.util.List<java.lang.String> getContractExpressions​(Contract.Kind kind,
                                                                                 javax.lang.model.element.AnnotationMirror contractAnnotation)
        If contractAnnotation is a framework annotation, return its expression element. Otherwise, contractAnnotation is defined in a checker. If kind = CONDITIONALPOSTCONDITION, return its expression element, else return its value element.
        Parameters:
        kind - the kind of contractAnnotation
        contractAnnotation - a RequiresQualifier, EnsuresQualifier, or EnsuresQualifierIf
        Returns:
        the result element of contractAnnotation, or null if it doesn't have a result element