Class BaseTypeVisitor<Factory extends GenericAnnotatedTypeFactory<?,?,?,?>>

All Implemented Interfaces:
TreeVisitor<Void,Void>
Direct Known Subclasses:
AccumulationVisitor, AliasingVisitor, ClassValVisitor, FenumVisitor, FormatterVisitor, GuiEffectVisitor, I18nFormatterVisitor, InitializationVisitor, InterningVisitor, LessThanVisitor, LockVisitor, LowerBoundVisitor, MethodValVisitor, MustCallVisitor, OptionalVisitor, RegexVisitor, ReportVisitor, ReturnsReceiverVisitor, SameLenVisitor, SignednessVisitor, TaintingVisitor, TypeOutputtingChecker.Visitor, UnitsVisitor, UpperBoundVisitor, ValueVisitor

public class BaseTypeVisitor<Factory extends GenericAnnotatedTypeFactory<?,?,?,?>> extends SourceVisitor<Void,Void>
A SourceVisitor that performs assignment and pseudo-assignment checking, method invocation checking, and assignability checking. The visitor visits every construct in a program, not just types.

This implementation uses the AnnotatedTypeFactory implementation provided by an associated BaseTypeChecker; its visitor methods will invoke this factory on parts of the AST to determine the "annotated type" of an expression. Then, the visitor methods will check the types in assignments and pseudo-assignments using commonAssignmentCheck(com.sun.source.tree.Tree, com.sun.source.tree.ExpressionTree, java.lang.String, java.lang.Object...), which ultimately calls the TypeHierarchy.isSubtype(org.checkerframework.framework.type.AnnotatedTypeMirror, org.checkerframework.framework.type.AnnotatedTypeMirror) method and reports errors that violate Java's rules of assignment.

Note that since this implementation only performs assignment and pseudo-assignment checking, other rules for custom type systems must be added in subclasses (e.g., dereference checking in the NullnessChecker is implemented in the NullnessChecker's TreeScanner.visitMemberSelect(com.sun.source.tree.MemberSelectTree, P) method).

This implementation does the following checks:

  1. Assignment and Pseudo-Assignment Check: It verifies that any assignment type-checks, using the TypeHierarchy.isSubtype(org.checkerframework.framework.type.AnnotatedTypeMirror, org.checkerframework.framework.type.AnnotatedTypeMirror) method. This includes method invocation and method overriding checks.
  2. Type Validity Check: It verifies that any user-supplied type is a valid type, using one of the isValidUse methods.
  3. (Re-)Assignability Check: It verifies that any assignment is valid, using Checker.isAssignable method.
See Also:
  • Field Details

    • checker

      protected final BaseTypeChecker checker
      The BaseTypeChecker for error reporting.
    • atypeFactory

      protected final Factory extends GenericAnnotatedTypeFactory<?,?,?,?> atypeFactory
      The factory to use for obtaining "parsed" version of annotations.
    • qualHierarchy

      protected final QualifierHierarchy qualHierarchy
      The qualifier hierarchy.
    • typeHierarchy

      protected final TypeHierarchy typeHierarchy
      The Annotated Type Hierarchy.
    • positions

      protected final SourcePositions positions
      For obtaining line numbers in -Ashowchecks debugging output.
    • TARGET

      protected final AnnotationMirror TARGET
      The @java.lang.annotation.Target annotation.
    • DETERMINISTIC

      protected final AnnotationMirror DETERMINISTIC
      The @Deterministic annotation.
    • SIDE_EFFECT_FREE

      protected final AnnotationMirror SIDE_EFFECT_FREE
      The @SideEffectFree annotation.
    • PURE

      protected final AnnotationMirror PURE
      The @Pure annotation.
    • IMPURE

      protected final AnnotationMirror IMPURE
      The @Impure annotation.
    • targetValueElement

      protected final ExecutableElement targetValueElement
      The value element/field of the @java.lang.annotation.Target annotation.
    • unusedWhenElement

      protected final ExecutableElement unusedWhenElement
      The when element/field of the @Unused annotation.
    • showchecks

      protected final boolean showchecks
      True if "-Ashowchecks" was passed on the command line.
    • assumePureGetters

      public final boolean assumePureGetters
      True if "-AassumePureGetters" was passed on the command line.
    • methodTree

      protected @Nullable MethodTree methodTree
      The tree of the enclosing method that is currently being visited.
    • typeValidator

      protected final TypeValidator typeValidator
  • Constructor Details

  • Method Details

    • createTypeFactory

      protected Factory createTypeFactory()
      Constructs an instance of the appropriate type factory for the implemented type system.

      The default implementation uses the checker naming convention to create the appropriate type factory. If no factory is found, it returns BaseAnnotatedTypeFactory. It reflectively invokes the constructor that accepts this checker and compilation unit tree (in that order) as arguments.

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

      Returns:
      the appropriate type factory
    • getTypeFactory

      public final Factory getTypeFactory()
    • createTypeFactoryPublic

      public Factory createTypeFactoryPublic()
      A public variant of createTypeFactory(). Only use this if you know what you are doing.
      Returns:
      the appropriate type factory
    • setRoot

      public void setRoot(CompilationUnitTree root)
      Description copied from class: SourceVisitor
      Set the CompilationUnitTree to be used during any visits. For any later calls of com.sun.source.util.TreePathScanner.scan(TreePath, P), the CompilationUnitTree of the TreePath has to be equal to root.
      Overrides:
      setRoot in class SourceVisitor<Void,Void>
    • scan

      public Void scan(@Nullable Tree tree, Void p)
      Overrides:
      scan in class SourceVisitor<Void,Void>
    • testJointJavacJavaParserVisitor

      protected void testJointJavacJavaParserVisitor()
      Test JointJavacJavaParserVisitor if the checker has the "ajavaChecks" option.

      Parse the current source file with JavaParser and check that the AST can be matched with the Tree produced by javac. Crash if not.

      Subclasses may override this method to disable the test if even the option is provided.

    • testAnnotationInsertion

      protected void testAnnotationInsertion()
      Tests InsertAjavaAnnotations if the checker has the "ajavaChecks" option.
      1. Parses the current file with JavaParser.
      2. Removes all annotations.
      3. Reinserts the annotations.
      4. Throws an exception if the ASTs are not the same.

      Subclasses may override this method to disable the test even if the option is provided.

    • visitClass

      public final Void visitClass(ClassTree classTree, Void p)
      Type-check classTree and skips classes specified by the skipDef option. Subclasses should override processClassTree(ClassTree) instead of this method.
      Specified by:
      visitClass in interface TreeVisitor<Void,Void>
      Overrides:
      visitClass in class SourceVisitor<Void,Void>
      Parameters:
      classTree - class to check
      p - null
      Returns:
      null
    • processClassTree

      public void processClassTree(ClassTree classTree)
      Type-check classTree. Subclasses should override this method instead of visitClass(ClassTree, Void).
      Parameters:
      classTree - class to check
    • checkForPolymorphicQualifiers

      protected void checkForPolymorphicQualifiers(ClassTree classTree)
      Issues an "invalid.polymorphic.qualifier" error for all polymorphic annotations written on the class declaration.
      Parameters:
      classTree - the class to check
    • checkForPolymorphicQualifiers

      protected void checkForPolymorphicQualifiers(List<? extends TypeParameterTree> typeParameterTrees)
      Issues an "invalid.polymorphic.qualifier" error for all polymorphic annotations written on the type parameters declaration.
      Parameters:
      typeParameterTrees - the type parameters to check
    • checkQualifierParameter

      protected void checkQualifierParameter(ClassTree classTree)
      Issues an error if classTree has polymorphic fields but is not annotated with @HasQualifierParameter. Always issue a warning if the type of a static field is annotated with a polymorphic qualifier.

      Issues an error if classTree extends or implements a class/interface that has a qualifier parameter, but this class does not.

      Parameters:
      classTree - the ClassTree to check for polymorphic fields
    • checkExtendsAndImplements

      protected void checkExtendsAndImplements(ClassTree classTree)
      In @A class X extends @B Y implements @C Z {}, enforce that @A must be a subtype of @B and @C.

      Also validate the types of the extends and implements clauses.

      Parameters:
      classTree - class tree to check
    • checkExtendsOrImplements

      protected void checkExtendsOrImplements(Tree superClause, AnnotationMirrorSet classBounds, TypeMirror classType, boolean isExtends)
      Helper for checkExtendsAndImplements(com.sun.source.tree.ClassTree) that checks one extends or implements clause.
      Parameters:
      superClause - an extends or implements clause
      classBounds - the type declarations bounds to check for consistency with superClause
      classType - the type being declared
      isExtends - true for an extends clause, false for an implements clause
    • checkFieldInvariantDeclarations

      protected void checkFieldInvariantDeclarations(ClassTree classTree)
      Check that the field invariant declaration annotations meet the following requirements:
      1. If the superclass of classTree has a field invariant, then the field invariant for classTree must include all the fields in the superclass invariant and those fields' annotations must be a subtype (or equal) to the annotations for those fields in the superclass.
      2. The fields in the invariant must be a.) final and b.) declared in a superclass of classTree.
      3. The qualifier for each field must be a subtype of the annotation on the declaration of that field.
      4. The field invariant has an equal number of fields and qualifiers, or it has one qualifier and at least one field.
      Parameters:
      classTree - class that might have a field invariant
      See the Checker Framework Manual:
      Field invariants
    • checkDefaultConstructor

      protected void checkDefaultConstructor(ClassTree tree)
      Check the default constructor.
      Parameters:
      tree - a class declaration
    • visitMethod

      public Void visitMethod(MethodTree tree, Void p)
      Checks that the method or constructor obeys override and subtype rules to all overridden methods. (Uses the pseudo-assignment logic to do so.)

      The override rule specifies that a method, m1, may override a method m2 only if:

      • m1 return type is a subtype of m2
      • m1 receiver type is a supertype of m2
      • m1 parameters are supertypes of corresponding m2 parameters
      Also, it issues a "missing.this" error for static method annotated receivers.
      Specified by:
      visitMethod in interface TreeVisitor<Void,Void>
      Overrides:
      visitMethod in class SourceVisitor<Void,Void>
    • shouldPerformContractInference

      protected boolean shouldPerformContractInference()
      Should Whole Program Inference attempt to infer contract annotations? Typically, the answer is "yes" whenever WPI is enabled, but this method exists to allow subclasses to customize that behavior.
      Returns:
      true if contract inference should be performed, false if it should be disabled (even when WPI is enabled)
    • checkPurity

      protected void checkPurity(MethodTree tree)
      Parameters:
      tree - the method tree to check
    • checkConstructorResult

      protected void checkConstructorResult(AnnotatedTypeMirror.AnnotatedExecutableType constructorType, ExecutableElement constructorElement)
      Issue a warning if the result type of the constructor declaration is not top. If it is a supertype of the class, then a conflicting.annos error will also be issued by isValidUse(AnnotatedTypeMirror.AnnotatedDeclaredType,AnnotatedTypeMirror.AnnotatedDeclaredType,Tree).
      Parameters:
      constructorType - the AnnotatedExecutableType for the constructor
      constructorElement - the element that declares the constructor
    • reportPurityErrors

      protected void reportPurityErrors(PurityChecker.PurityResult result, MethodTree tree, EnumSet<Pure.Kind> expectedKinds)
      Reports errors found during purity checking.
      Parameters:
      result - whether the method is deterministic and/or side-effect-free
      tree - the method
      expectedKinds - the expected purity for the method
    • checkPostcondition

      protected void checkPostcondition(MethodTree methodTree, AnnotationMirror annotation, JavaExpression expression)
      Check that the expression's type is annotated with annotation at the regular exit store.
      Parameters:
      methodTree - declaration of the method
      annotation - expression's type must have this annotation
      expression - the expression that must have an annotation
    • contractExpressionAndType

      protected String contractExpressionAndType(String expression, @Nullable AnnotationMirror qualifier)
      Returns a string representation of an expression and type qualifier.
      Parameters:
      expression - a Java expression
      qualifier - the expression's type, or null if no information is available
      Returns:
      a string representation of the expression and type qualifier
    • checkConditionalPostcondition

      protected void checkConditionalPostcondition(MethodTree methodTree, AnnotationMirror annotation, JavaExpression expression, boolean result)
      Check that the expression's type is annotated with annotation at every regular exit that returns result.
      Parameters:
      methodTree - tree of method with the postcondition
      annotation - expression's type must have this annotation
      expression - the expression that the postcondition concerns
      result - result for which the postcondition is valid
    • visitTypeParameter

      public Void visitTypeParameter(TypeParameterTree tree, Void p)
      Specified by:
      visitTypeParameter in interface TreeVisitor<Void,Void>
      Overrides:
      visitTypeParameter in class TreeScanner<Void,Void>
    • checkExplicitAnnotationsOnIntersectionBounds

      protected void checkExplicitAnnotationsOnIntersectionBounds(AnnotatedTypeMirror.AnnotatedIntersectionType intersection, List<? extends Tree> boundTrees)
      Issues "explicit.annotation.ignored" warning if any explicit annotation on an intersection bound is not the same as the primary annotation of the given intersection type.
      Parameters:
      intersection - type to use
      boundTrees - trees of intersection bounds
    • visitVariable

      public Void visitVariable(VariableTree tree, Void p)
      Specified by:
      visitVariable in interface TreeVisitor<Void,Void>
      Overrides:
      visitVariable in class SourceVisitor<Void,Void>
    • warnRedundantAnnotations

      protected void warnRedundantAnnotations(Tree tree, AnnotatedTypeMirror type)
      Issues a "redundant.anno" warning if the annotation written on the type is the same as the default annotation for this type and location.
      Parameters:
      tree - an AST node
      type - get the explicit annotation on this type and compare it with the default one for this type and location.
    • visitAssignment

      public Void visitAssignment(AssignmentTree tree, Void p)
      Performs two checks: subtyping and assignability checks, using commonAssignmentCheck(Tree, ExpressionTree, String, Object[]).

      If the subtype check fails, it issues an "assignment" error.

      Specified by:
      visitAssignment in interface TreeVisitor<Void,Void>
      Overrides:
      visitAssignment in class TreeScanner<Void,Void>
    • visitEnhancedForLoop

      public Void visitEnhancedForLoop(EnhancedForLoopTree tree, Void p)
      Performs a subtype check, to test whether the tree expression iterable type is a subtype of the variable type in the enhanced for loop.

      If the subtype check fails, it issues a "enhancedfor" error.

      Specified by:
      visitEnhancedForLoop in interface TreeVisitor<Void,Void>
      Overrides:
      visitEnhancedForLoop in class TreeScanner<Void,Void>
    • visitMethodInvocation

      public Void visitMethodInvocation(MethodInvocationTree tree, Void p)
      Performs a method invocation check.

      An invocation of a method, m, on the receiver, r is valid only if:

      • passed arguments are subtypes of corresponding m parameters
      • r is a subtype of m receiver type
      • if m is generic, passed type arguments are subtypes of m type variables
      Specified by:
      visitMethodInvocation in interface TreeVisitor<Void,Void>
      Overrides:
      visitMethodInvocation in class TreeScanner<Void,Void>
    • checkThisConstructorCall

      protected void checkThisConstructorCall(MethodInvocationTree thisCall)
      Checks that the following rule is satisfied: The type on a constructor declaration must be a supertype of the return type of "this()" invocation within that constructor.

      Subclasses can override this method to change the behavior for just "this" constructor class. Or override checkThisOrSuperConstructorCall(MethodInvocationTree, String) to change the behavior for "this" and "super" constructor calls.

      Parameters:
      thisCall - the AST node for the constructor call
    • checkSuperConstructorCall

      protected void checkSuperConstructorCall(MethodInvocationTree superCall)
      Checks that the following rule is satisfied: The type on a constructor declaration must be a supertype of the return type of "super()" invocation within that constructor.

      Subclasses can override this method to change the behavior for just "super" constructor class. Or override checkThisOrSuperConstructorCall(MethodInvocationTree, String) to change the behavior for "this" and "super" constructor calls.

      Parameters:
      superCall - the AST node for the super constructor call
    • checkThisOrSuperConstructorCall

      protected void checkThisOrSuperConstructorCall(MethodInvocationTree call, @CompilerMessageKey String errorKey)
      Checks that the following rule is satisfied: The type on a constructor declaration must be a supertype of the return type of "this()" or "super()" invocation within that constructor.
      Parameters:
      call - the AST node for the constructor call
      errorKey - the error message key to use if the check fails
    • checkVarargs

      protected void checkVarargs(AnnotatedTypeMirror.AnnotatedExecutableType invokedMethod, Tree tree)
      If the given invocation is a varargs invocation, check that the array type of actual varargs is a subtype of the corresponding formal parameter; issues "argument" error if not.

      The caller must type-check for each element in varargs before or after calling this method.

      Parameters:
      invokedMethod - the method type to be invoked
      tree - method or constructor invocation tree
      See Also:
    • checkPreconditions

      protected void checkPreconditions(MethodInvocationTree tree, Set<Contract.Precondition> preconditions)
      Checks that all the given preconditions hold true immediately prior to the method invocation or variable access at tree.
      Parameters:
      tree - the method invocation; immediately prior to it, the preconditions must hold true
      preconditions - the preconditions to be checked
    • checkContract

      protected boolean checkContract(JavaExpression expr, AnnotationMirror necessaryAnnotation, AnnotationMirror inferredAnnotation, CFAbstractStore<?,?> store)
      Returns true if and only if inferredAnnotation is valid for a given expression to match the necessaryAnnotation.

      By default, inferredAnnotation must be a subtype of necessaryAnnotation, but subclasses might override this behavior.

    • typeCheckVectorCopyIntoArgument

      protected void typeCheckVectorCopyIntoArgument(MethodInvocationTree tree, List<? extends AnnotatedTypeMirror> params)
      Type checks the method arguments of Vector.copyInto().

      The Checker Framework special-cases the method invocation, as its type safety cannot be expressed by Java's type system.

      For a Vector v of type Vector<E>, the method invocation v.copyInto(arr) is type-safe iff arr is an array of type T[], where T is a subtype of E.

      In other words, this method checks that the type argument of the receiver method is a subtype of the component type of the passed array argument.

      Parameters:
      tree - a method invocation of Vector.copyInto()
      params - the types of the parameters of Vectory.copyInto()
    • visitNewClass

      public Void visitNewClass(NewClassTree tree, Void p)
      Performs a new class invocation check.

      An invocation of a constructor, c, is valid only if:

      • passed arguments are subtypes of corresponding c parameters
      • if c is generic, passed type arguments are subtypes of c type variables
      Specified by:
      visitNewClass in interface TreeVisitor<Void,Void>
      Overrides:
      visitNewClass in class TreeScanner<Void,Void>
    • visitLambdaExpression

      public Void visitLambdaExpression(LambdaExpressionTree tree, Void p)
      Specified by:
      visitLambdaExpression in interface TreeVisitor<Void,Void>
      Overrides:
      visitLambdaExpression in class TreeScanner<Void,Void>
    • visitMemberReference

      public Void visitMemberReference(MemberReferenceTree tree, Void p)
      Specified by:
      visitMemberReference in interface TreeVisitor<Void,Void>
      Overrides:
      visitMemberReference in class TreeScanner<Void,Void>
    • visitReturn

      public Void visitReturn(ReturnTree tree, Void p)
      Checks that the type of the return expression is a subtype of the enclosing method required return type. If not, it issues a "return" error.
      Specified by:
      visitReturn in interface TreeVisitor<Void,Void>
      Overrides:
      visitReturn in class TreeScanner<Void,Void>
    • visitAnnotation

      public Void visitAnnotation(AnnotationTree tree, Void p)
      Ensure that the annotation arguments comply to their declarations. This needs some special casing, as annotation arguments form special trees.
      Specified by:
      visitAnnotation in interface TreeVisitor<Void,Void>
      Overrides:
      visitAnnotation in class TreeScanner<Void,Void>
    • visitConditionalExpression

      public Void visitConditionalExpression(ConditionalExpressionTree tree, Void p)
      If the computation of the type of the ConditionalExpressionTree in org.checkerframework.framework.type.TypeFromTree.TypeFromExpression.visitConditionalExpression(ConditionalExpressionTree, AnnotatedTypeFactory) is correct, the following checks are redundant. However, let's add another failsafe guard and do the checks.
      Specified by:
      visitConditionalExpression in interface TreeVisitor<Void,Void>
      Overrides:
      visitConditionalExpression in class TreeScanner<Void,Void>
    • visitSwitchExpression17

      public void visitSwitchExpression17(Tree switchExpressionTree)
      This method validates the type of the switch expression. It issues an error if the type of a value that the switch expression can result is not a subtype of the switch type.

      If a subclass overrides this method, it must call super.scan(switchExpressionTree, null) so that the blocks and statements in the cases are checked.

      Parameters:
      switchExpressionTree - a SwitchExpressionTree
    • visitUnary

      public Void visitUnary(UnaryTree tree, Void p)
      Performs assignability check.
      Specified by:
      visitUnary in interface TreeVisitor<Void,Void>
      Overrides:
      visitUnary in class TreeScanner<Void,Void>
    • visitCompoundAssignment

      public Void visitCompoundAssignment(CompoundAssignmentTree tree, Void p)
      Performs assignability check.
      Specified by:
      visitCompoundAssignment in interface TreeVisitor<Void,Void>
      Overrides:
      visitCompoundAssignment in class TreeScanner<Void,Void>
    • visitNewArray

      public Void visitNewArray(NewArrayTree tree, Void p)
      Specified by:
      visitNewArray in interface TreeVisitor<Void,Void>
      Overrides:
      visitNewArray in class TreeScanner<Void,Void>
    • checkTypecastRedundancy

      protected void checkTypecastRedundancy(TypeCastTree typeCastTree)
      If the lint option "cast:redundant" is set, this method issues a warning if the cast is redundant.
    • checkTypecastSafety

      protected void checkTypecastSafety(TypeCastTree typeCastTree)
      Issues a warning if the given explicitly-written typecast is unsafe. Does nothing if the lint option "cast:unsafe" is not set. Only primary qualifiers are checked unless the command line option "checkCastElementType" is supplied.
      Parameters:
      typeCastTree - an explicitly-written typecast
    • isTypeCastSafe

      protected boolean isTypeCastSafe(AnnotatedTypeMirror castType, AnnotatedTypeMirror exprType)
      Returns true if the cast is safe.

      Only primary qualifiers are checked unless the command line option "checkCastElementType" is supplied.

      Parameters:
      castType - annotated type of the cast
      exprType - annotated type of the casted expression
      Returns:
      true if the type cast is safe, false otherwise
    • visitTypeCast

      public Void visitTypeCast(TypeCastTree tree, Void p)
      Specified by:
      visitTypeCast in interface TreeVisitor<Void,Void>
      Overrides:
      visitTypeCast in class TreeScanner<Void,Void>
    • visitInstanceOf

      public Void visitInstanceOf(InstanceOfTree tree, Void p)
      Specified by:
      visitInstanceOf in interface TreeVisitor<Void,Void>
      Overrides:
      visitInstanceOf in class TreeScanner<Void,Void>
    • visitCatch

      public Void visitCatch(CatchTree tree, Void p)
      Checks the type of the exception parameter. Subclasses should override checkExceptionParameter(com.sun.source.tree.CatchTree) rather than this method to change the behavior of this check.
      Specified by:
      visitCatch in interface TreeVisitor<Void,Void>
      Overrides:
      visitCatch in class TreeScanner<Void,Void>
    • visitThrow

      public Void visitThrow(ThrowTree tree, Void p)
      Checks the type of a thrown exception. Subclasses should override checkThrownExpression(ThrowTree tree) rather than this method to change the behavior of this check.
      Specified by:
      visitThrow in interface TreeVisitor<Void,Void>
      Overrides:
      visitThrow in class TreeScanner<Void,Void>
    • visitAnnotatedType

      public Void visitAnnotatedType(AnnotatedTypeTree tree, Void p)
      Rather than overriding this method, clients should often override visitAnnotatedType(List,Tree). That method also handles the case of annotations at the beginning of a variable or method declaration. javac parses all those annotations as being on the variable or method declaration, even though the ones that are type annotations logically belong to the variable type or method return type.
      Specified by:
      visitAnnotatedType in interface TreeVisitor<Void,Void>
      Overrides:
      visitAnnotatedType in class TreeScanner<Void,Void>
    • visitAnnotatedType

      public void visitAnnotatedType(@Nullable List<? extends AnnotationTree> annoTrees, Tree typeTree)
      Checks an annotated type. Invoked by visitAnnotatedType(AnnotatedTypeTree, Void), visitVariable(com.sun.source.tree.VariableTree, java.lang.Void), and visitMethod(com.sun.source.tree.MethodTree, java.lang.Void). Exists to prevent code duplication among the three. Checking in visitVariable and visitMethod is needed because there isn't an AnnotatedTypeTree within a variable declaration or for a method return type -- all the annotations are attached to the VariableTree or MethodTree, respectively.
      Parameters:
      annoTrees - annotations written before a variable/method declaration, if this type is from one; null otherwise. This might contain type annotations that the Java parser attached to the declaration rather than to the type.
      typeTree - the type that any type annotations in annoTrees apply to
    • warnAboutIrrelevantJavaTypes

      public void warnAboutIrrelevantJavaTypes(@Nullable List<? extends AnnotationTree> annoTrees, Tree typeTree)
      Warns if a type annotation is written on a Java type that is not listed in the @RelevantJavaTypes annotation.
      Parameters:
      annoTrees - annotations written before a variable/method declaration, if this type is from one; null otherwise. This might contain type annotations that the Java parser attached to the declaration rather than to the type.
      typeTree - the type that any type annotations in annoTrees apply to
    • shouldWarnAboutIrrelevantJavaTypes

      protected boolean shouldWarnAboutIrrelevantJavaTypes()
      Returns true if the checker should issue warnings about irrelevant java types.
      Returns:
      true if the checker should issue warnings about irrelevant java types
    • checkExceptionParameter

      protected void checkExceptionParameter(CatchTree tree)
      Issue error if the exception parameter is not a supertype of the annotation specified by getExceptionParameterLowerBoundAnnotations(), which is top by default.

      Subclasses may override this method to change the behavior of this check. Subclasses wishing to enforce that exception parameter be annotated with other annotations can just override getExceptionParameterLowerBoundAnnotations().

      Parameters:
      tree - a CatchTree to check
    • getExceptionParameterLowerBoundAnnotations

      protected AnnotationMirrorSet getExceptionParameterLowerBoundAnnotations()
      Returns a set of AnnotationMirrors that is a lower bound for exception parameters.

      This implementation returns top; subclasses can change this behavior.

      Note: by default this method is called by getThrowUpperBoundAnnotations(), so that this annotation is enforced.

      Returns:
      set of annotation mirrors, one per hierarchy, that form a lower bound of annotations that can be written on an exception parameter
    • checkThrownExpression

      protected void checkThrownExpression(ThrowTree tree)
      Checks the type of the thrown expression.

      By default, this method checks that the thrown expression is a subtype of top.

      Issue error if the thrown expression is not a sub type of the annotation given by getThrowUpperBoundAnnotations(), the same as getExceptionParameterLowerBoundAnnotations() by default.

      Subclasses may override this method to change the behavior of this check. Subclasses wishing to enforce that the thrown expression be a subtype of a type besides getExceptionParameterLowerBoundAnnotations(), should override getThrowUpperBoundAnnotations().

      Parameters:
      tree - a ThrowTree to check
    • getThrowUpperBoundAnnotations

      protected AnnotationMirrorSet getThrowUpperBoundAnnotations()
      Returns a set of AnnotationMirrors that is a upper bound for thrown exceptions.

      Note: by default this method is returns by getExceptionParameterLowerBoundAnnotations(), so that this annotation is enforced.

      (Default is top)

      Returns:
      set of annotation mirrors, one per hierarchy, that form an upper bound of thrown expressions
    • commonAssignmentCheck

      protected boolean commonAssignmentCheck(Tree varTree, ExpressionTree valueExpTree, @CompilerMessageKey String errorKey, Object... extraArgs)
      Checks the validity of an assignment (or pseudo-assignment) from a value to a variable and emits an error message (through the compiler's messaging interface) if it is not valid.
      Parameters:
      varTree - the AST node for the lvalue (usually a variable)
      valueExpTree - the AST node for the rvalue (the new value)
      errorKey - the error message key to use if the check fails
      extraArgs - arguments to the error message key, before "found" and "expected" types
      Returns:
      true if the check succeeds, false if an error message was issued
    • commonAssignmentCheck

      protected boolean commonAssignmentCheck(AnnotatedTypeMirror varType, ExpressionTree valueExpTree, @CompilerMessageKey String errorKey, Object... extraArgs)
      Checks the validity of an assignment (or pseudo-assignment) from a value to a variable and emits an error message (through the compiler's messaging interface) if it is not valid.
      Parameters:
      varType - the annotated type for the lvalue (usually a variable)
      valueExpTree - the AST node for the rvalue (the new value)
      errorKey - the error message key to use if the check fails
      extraArgs - arguments to the error message key, before "found" and "expected" types
      Returns:
      true if the check succeeds, false if an error message was issued
    • commonAssignmentCheck

      protected boolean commonAssignmentCheck(AnnotatedTypeMirror varType, AnnotatedTypeMirror valueType, Tree valueExpTree, @CompilerMessageKey String errorKey, Object... extraArgs)
      Checks the validity of an assignment (or pseudo-assignment) from a value to a variable and emits an error message (through the compiler's messaging interface) if it is not valid.
      Parameters:
      varType - the annotated type of the variable
      valueType - the annotated type of the value
      valueExpTree - the location to use when reporting the error message
      errorKey - the error message key to use if the check fails
      extraArgs - arguments to the error message key, before "found" and "expected" types
      Returns:
      true if the check succeeds, false if an error message was issued
    • commonAssignmentCheckStartDiagnostic

      protected final void commonAssignmentCheckStartDiagnostic(AnnotatedTypeMirror varType, AnnotatedTypeMirror valueType, Tree valueExpTree)
      Prints a diagnostic about entering commonAssignmentCheck(), if the showchecks option was set.
      Parameters:
      varType - the annotated type of the variable
      valueType - the annotated type of the value
      valueExpTree - the location to use when reporting the error message
    • commonAssignmentCheckEndDiagnostic

      protected final void commonAssignmentCheckEndDiagnostic(boolean success, @Nullable String extraMessage, AnnotatedTypeMirror varType, AnnotatedTypeMirror valueType, Tree valueExpTree)
      Prints a diagnostic about exiting commonAssignmentCheck(), if the showchecks option was set.
      Parameters:
      success - whether the check succeeded or failed
      extraMessage - information about why the result is what it is; may be null
      varType - the annotated type of the variable
      valueType - the annotated type of the value
      valueExpTree - the location to use when reporting the error message
    • commonAssignmentCheckEndDiagnostic

      protected final void commonAssignmentCheckEndDiagnostic(String message, AnnotatedTypeMirror varType, AnnotatedTypeMirror valueType, Tree valueExpTree)
      Helper method for printing a diagnostic about exiting commonAssignmentCheck(), if the showchecks option was set.

      Most clients should call commonAssignmentCheckEndDiagnostic(boolean, String, AnnotatedTypeMirror, AnnotatedTypeMirror, Tree). The purpose of this method is to permit customizing the message that is printed.

      Parameters:
      message - the result, plus information about why the result is what it is
      varType - the annotated type of the variable
      valueType - the annotated type of the value
      valueExpTree - the location to use when reporting the error message
    • checkArrayInitialization

      protected boolean checkArrayInitialization(AnnotatedTypeMirror type, List<? extends ExpressionTree> initializers)
      Checks that the array initializers are consistent with the array type.
      Parameters:
      type - the array elemen type
      initializers - the initializers
      Returns:
      true if the check succeeds, false if an error message was issued
    • checkTypeArguments

      protected void checkTypeArguments(Tree toptree, List<? extends AnnotatedTypeParameterBounds> paramBounds, List<? extends AnnotatedTypeMirror> typeargs, List<? extends Tree> typeargTrees, CharSequence typeOrMethodName, List<?> paramNames)
      Checks that the annotations on the type arguments supplied to a type or a method invocation are within the bounds of the type variables as declared, and issues the "type.argument" error if they are not.
      Parameters:
      toptree - the tree for error reporting, only used for inferred type arguments
      paramBounds - the bounds of the type parameters from a class or method declaration
      typeargs - the type arguments from the type or method invocation
      typeargTrees - the type arguments as trees, used for error reporting
    • skipReceiverSubtypeCheck

      protected boolean skipReceiverSubtypeCheck(MethodInvocationTree tree, AnnotatedTypeMirror methodDefinitionReceiver, AnnotatedTypeMirror methodCallReceiver)
      Indicates whether to skip subtype checks on the receiver when checking method invocability. A visitor may, for example, allow a method to be invoked even if the receivers are siblings in a hierarchy, provided that some other condition (implemented by the visitor) is satisfied.
      Parameters:
      tree - the method invocation tree
      methodDefinitionReceiver - the ATM of the receiver of the method definition
      methodCallReceiver - the ATM of the receiver of the method call
      Returns:
      whether to skip subtype checks on the receiver
    • checkMethodInvocability

      protected void checkMethodInvocability(AnnotatedTypeMirror.AnnotatedExecutableType method, MethodInvocationTree tree)
      Tests whether the method can be invoked using the receiver of the 'tree' method invocation, and issues a "method.invocation" if the invocation is invalid.

      This implementation tests whether the receiver in the method invocation is a subtype of the method receiver type. This behavior can be specialized by overriding skipReceiverSubtypeCheck.

      Parameters:
      method - the type of the invoked method
      tree - the method invocation tree
    • reportMethodInvocabilityError

      protected void reportMethodInvocabilityError(MethodInvocationTree tree, AnnotatedTypeMirror found, AnnotatedTypeMirror expected)
      Report a method invocability error. Allows checkers to change how the message is output.
      Parameters:
      tree - the AST node at which to report the error
      found - the actual type of the receiver
      expected - the expected type of the receiver
    • checkConstructorInvocation

      protected void checkConstructorInvocation(AnnotatedTypeMirror.AnnotatedDeclaredType invocation, AnnotatedTypeMirror.AnnotatedExecutableType constructor, NewClassTree newClassTree)
      Check that the (explicit) annotations on a new class tree are comparable to the result type of the constructor. Issue an error if not.

      Issue a warning if the annotations on the constructor invocation is a subtype of the constructor result type. This is equivalent to down-casting.

    • checkArguments

      protected void checkArguments(List<? extends AnnotatedTypeMirror> requiredArgs, List<? extends ExpressionTree> passedArgs, CharSequence executableName, List<?> paramNames)
      A helper method to check that each passed argument is a subtype of the corresponding required argument. Issues an "argument" error for each passed argument that not a subtype of the required one.

      Note this method requires the lists to have the same length, as it does not handle cases like var args.

      Parameters:
      requiredArgs - the required types. This may differ from the formal parameter types, because it replaces a varargs parameter by multiple parameters with the vararg's element type.
      passedArgs - the expressions passed to the corresponding types
      executableName - the name of the method or constructor being called
      paramNames - the names of the callee's formal parameters
      See Also:
    • testTypevarContainment

      protected boolean testTypevarContainment(AnnotatedTypeMirror inner, AnnotatedTypeMirror outer)
      Returns true if both types are type variables and outer contains inner. Outer contains inner implies: inner.upperBound <: outer.upperBound outer.lowerBound <: inner.lowerBound.
      Returns:
      true if both types are type variables and outer contains inner
    • createOverrideChecker

      protected BaseTypeVisitor<Factory>.OverrideChecker createOverrideChecker(Tree overriderTree, AnnotatedTypeMirror.AnnotatedExecutableType overriderMethodType, AnnotatedTypeMirror overriderType, AnnotatedTypeMirror overriderReturnType, AnnotatedTypeMirror.AnnotatedExecutableType overriddenMethodType, AnnotatedTypeMirror.AnnotatedDeclaredType overriddenType, AnnotatedTypeMirror overriddenReturnType)
      Create an OverrideChecker.

      This exists so that subclasses can subclass OverrideChecker and use their subclass instead of using OverrideChecker itself.

      Parameters:
      overriderTree - the AST node of the overriding method or method reference
      overriderMethodType - the type of the overriding method
      overriderType - the type enclosing the overrider method, usually an AnnotatedDeclaredType; for Method References may be something else
      overriderReturnType - the return type of the overriding method
      overriddenMethodType - the type of the overridden method
      overriddenType - the declared type enclosing the overridden method
      overriddenReturnType - the return type of the overridden method
      Returns:
      an OverrideChecker
    • checkOverride

      protected boolean checkOverride(MethodTree overriderTree, AnnotatedTypeMirror.AnnotatedDeclaredType overriderType, AnnotatedTypeMirror.AnnotatedExecutableType overriddenMethodType, AnnotatedTypeMirror.AnnotatedDeclaredType overriddenType)
      Parameters:
      overriderTree - declaration tree of overriding method
      overriderType - type of overriding class
      overriddenMethodType - type of overridden method
      overriddenType - type of overridden class
      Returns:
      true if the override is allowed
      See Also:
    • checkOverride

      protected boolean checkOverride(MethodTree overriderTree, AnnotatedTypeMirror.AnnotatedExecutableType overriderMethodType, AnnotatedTypeMirror.AnnotatedDeclaredType overriderType, AnnotatedTypeMirror.AnnotatedExecutableType overriddenMethodType, AnnotatedTypeMirror.AnnotatedDeclaredType overriddenType)
      Parameters:
      overriderTree - declaration tree of overriding method
      overriderMethodType - type of the overriding method
      overriderType - type of overriding class
      overriddenMethodType - type of overridden method
      overriddenType - type of overridden class
      Returns:
      true if the override is allowed
      See Also:
    • checkMethodReferenceAsOverride

      protected boolean checkMethodReferenceAsOverride(MemberReferenceTree memberReferenceTree, Void p)
      Check that a method reference is allowed. Uses the OverrideChecker class.
      Parameters:
      memberReferenceTree - the tree for the method reference
      Returns:
      true if the method reference is allowed
    • enclosingMemberSelect

      protected @Nullable MemberSelectTree enclosingMemberSelect()
      Call this only when the current path is an identifier.
      Returns:
      the enclosing member select, or null if the identifier is not the field in a member selection
    • enclosingStatement

      protected @Nullable Tree enclosingStatement(@FindDistinct Tree tree)
      Returns the statement that encloses the given one.
      Parameters:
      tree - an AST node that is on the current path
      Returns:
      the statement that encloses the given one
    • visitIdentifier

      public Void visitIdentifier(IdentifierTree tree, Void p)
      Specified by:
      visitIdentifier in interface TreeVisitor<Void,Void>
      Overrides:
      visitIdentifier in class TreeScanner<Void,Void>
    • checkAccess

      protected void checkAccess(IdentifierTree identifierTree, Void p)
      Issues an error if access not allowed, based on an @Unused annotation.
      Parameters:
      identifierTree - the identifier being accessed; the method does nothing if it is not a field
      p - ignored
    • checkAccessAllowed

      protected void checkAccessAllowed(Element field, @Nullable AnnotatedTypeMirror receiverType, @FindDistinct ExpressionTree accessTree)
      Issues an error if access not allowed, based on an @Unused annotation.
      Parameters:
      field - the field to be accessed, whose declaration might be annotated by @Unused. It can also be (for example) this, in which case receiverType is null.
      receiverType - the type of the expression whose field is accessed; null if the field is static
      accessTree - the access expression
    • isValidUse

      public boolean isValidUse(AnnotatedTypeMirror.AnnotatedDeclaredType declarationType, AnnotatedTypeMirror.AnnotatedDeclaredType useType, Tree tree)
      Tests that the qualifiers present on useType are valid qualifiers, given the qualifiers on the declaration of the type, declarationType.

      The check is shallow, as it does not descend into generic or array types (i.e. only performing the validity check on the raw type or outermost array dimension). validateTypeOf(Tree) would call this for each type argument or array dimension separately.

      In most cases, useType simply needs to be a subtype of declarationType. If a type system makes exceptions to this rule, its implementation should override this method.

      This method is not called if BaseTypeValidator.shouldCheckTopLevelDeclaredOrPrimitiveType(AnnotatedTypeMirror, Tree) returns false -- by default, it is not called on the top level for locals and expressions. To enforce a type validity property everywhere, override methods such as BaseTypeValidator.visitDeclared(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType, com.sun.source.tree.Tree) rather than this method.

      Parameters:
      declarationType - the type of the class (TypeElement)
      useType - the use of the class (instance type)
      tree - the tree where the type is used
      Returns:
      true if the useType is a valid use of elemType
    • isValidUse

      public boolean isValidUse(AnnotatedTypeMirror.AnnotatedPrimitiveType type, Tree tree)
      Tests that the qualifiers present on the primitive type are valid.
      Parameters:
      type - the use of the primitive type
      tree - the tree where the type is used
      Returns:
      true if the type is a valid use of the primitive type
    • isValidUse

      public boolean isValidUse(AnnotatedTypeMirror.AnnotatedArrayType type, Tree tree)
      Tests that the qualifiers present on the array type are valid. This method will be invoked for each array level independently, i.e. this method only needs to check the top-level qualifiers of an array.
      Parameters:
      type - the array type use
      tree - the tree where the type is used
      Returns:
      true if the type is a valid array type
    • validateTypeOf

      public boolean validateTypeOf(Tree tree)
      Tests whether the tree expressed by the passed type tree is a valid type, and emits an error if that is not the case (e.g. '@Mutable String'). If the tree is a method or constructor, check the return type.
      Parameters:
      tree - the AST type supplied by the user
      Returns:
      true if the tree is a valid type
    • validateType

      protected boolean validateType(Tree tree, AnnotatedTypeMirror type)
      Tests whether the type and corresponding type tree is a valid type, and emits an error if that is not the case (e.g. '@Mutable String'). If the tree is a method or constructor, tests the return type.
      Parameters:
      tree - the type tree supplied by the user
      type - the type corresponding to tree
      Returns:
      true if the type is valid
    • createTypeValidator

      protected TypeValidator createTypeValidator()
    • shouldSkipUses

      protected final boolean shouldSkipUses(ExpressionTree exprTree)
      Tests whether the expression should not be checked because of the tree referring to unannotated classes, as specified in the checker.skipUses property.

      It returns true if exprTree is a method invocation or a field access to a class whose qualified name matches the checker.skipUses property.

      Parameters:
      exprTree - any expression tree
      Returns:
      true if checker should not test exprTree
    • visitCompilationUnit

      public Void visitCompilationUnit(CompilationUnitTree identifierTree, Void p)
      Override Compilation Unit so we won't visit package names or imports.
      Specified by:
      visitCompilationUnit in interface TreeVisitor<Void,Void>
      Overrides:
      visitCompilationUnit in class TreeScanner<Void,Void>