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

java.lang.Object
com.sun.source.util.TreeScanner<R,P>
com.sun.source.util.TreePathScanner<R,P>
org.checkerframework.framework.source.SourceVisitor<Void,Void>
org.checkerframework.common.basetype.BaseTypeVisitor<Factory>
All Implemented Interfaces:
com.sun.source.tree.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.

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 TypeHierarchy.isSubtype 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.
    • positions

      protected final com.sun.source.util.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.
    • 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.
    • methodTree

      protected @Nullable com.sun.source.tree.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(com.sun.source.tree.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 com.sun.source.tree.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(com.sun.source.tree.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 com.sun.source.tree.TreeVisitor<Void,Void>
      Overrides:
      visitClass in class SourceVisitor<Void,Void>
      Parameters:
      classTree - class to check
      p - null
      Returns:
      null
    • processClassTree

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

      protected void checkForPolymorphicQualifiers(com.sun.source.tree.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 com.sun.source.tree.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(com.sun.source.tree.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
    • checkExtendsImplements

      protected void checkExtendsImplements(com.sun.source.tree.ClassTree classTree)
      If "@B class Y extends @A X {}", then enforce that @B must be a subtype of @A.

      Also validate the types of the extends and implements clauses.

      Parameters:
      classTree - class tree to check
    • checkFieldInvariantDeclarations

      protected void checkFieldInvariantDeclarations(com.sun.source.tree.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(com.sun.source.tree.ClassTree node)
    • visitMethod

      public Void visitMethod(com.sun.source.tree.MethodTree node, Void p)
      Checks that the method 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 com.sun.source.tree.TreeVisitor<Void,Void>
      Overrides:
      visitMethod in class SourceVisitor<Void,Void>
    • checkPurity

      protected void checkPurity(com.sun.source.tree.MethodTree node)
      Parameters:
      node - the method tree to check
    • checkConstructorResult

      protected void checkConstructorResult(AnnotatedTypeMirror.AnnotatedExecutableType constructorType, ExecutableElement constructorElement)
      Issue a warning if the result type of the constructor 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 - AnnotatedExecutableType for the constructor
      constructorElement - element that declares the constructor
    • reportPurityErrors

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

      protected void checkPostcondition(com.sun.source.tree.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
    • checkConditionalPostcondition

      protected void checkConditionalPostcondition(com.sun.source.tree.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(com.sun.source.tree.TypeParameterTree node, Void p)
      Specified by:
      visitTypeParameter in interface com.sun.source.tree.TreeVisitor<Void,Void>
      Overrides:
      visitTypeParameter in class com.sun.source.util.TreeScanner<Void,Void>
    • checkExplicitAnnotationsOnIntersectionBounds

      protected void checkExplicitAnnotationsOnIntersectionBounds(AnnotatedTypeMirror.AnnotatedIntersectionType intersection, List<? extends com.sun.source.tree.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(com.sun.source.tree.VariableTree node, Void p)
      Specified by:
      visitVariable in interface com.sun.source.tree.TreeVisitor<Void,Void>
      Overrides:
      visitVariable in class SourceVisitor<Void,Void>
    • visitAssignment

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

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

      Specified by:
      visitAssignment in interface com.sun.source.tree.TreeVisitor<Void,Void>
      Overrides:
      visitAssignment in class com.sun.source.util.TreeScanner<Void,Void>
    • visitEnhancedForLoop

      public Void visitEnhancedForLoop(com.sun.source.tree.EnhancedForLoopTree node, Void p)
      Performs a subtype check, to test whether the node 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 com.sun.source.tree.TreeVisitor<Void,Void>
      Overrides:
      visitEnhancedForLoop in class com.sun.source.util.TreeScanner<Void,Void>
    • visitMethodInvocation

      public Void visitMethodInvocation(com.sun.source.tree.MethodInvocationTree node, 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 com.sun.source.tree.TreeVisitor<Void,Void>
      Overrides:
      visitMethodInvocation in class com.sun.source.util.TreeScanner<Void,Void>
    • checkThisConstructorCall

      protected void checkThisConstructorCall(com.sun.source.tree.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(com.sun.source.tree.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(com.sun.source.tree.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, com.sun.source.tree.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(com.sun.source.tree.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(com.sun.source.tree.MethodInvocationTree node, 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:
      node - a method invocation of Vector.copyInto()
      params - the types of the parameters of Vectory.copyInto()
    • visitNewClass

      public Void visitNewClass(com.sun.source.tree.NewClassTree node, 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 com.sun.source.tree.TreeVisitor<Void,Void>
      Overrides:
      visitNewClass in class com.sun.source.util.TreeScanner<Void,Void>
    • visitLambdaExpression

      public Void visitLambdaExpression(com.sun.source.tree.LambdaExpressionTree node, Void p)
      Specified by:
      visitLambdaExpression in interface com.sun.source.tree.TreeVisitor<Void,Void>
      Overrides:
      visitLambdaExpression in class com.sun.source.util.TreeScanner<Void,Void>
    • visitMemberReference

      public Void visitMemberReference(com.sun.source.tree.MemberReferenceTree node, Void p)
      Specified by:
      visitMemberReference in interface com.sun.source.tree.TreeVisitor<Void,Void>
      Overrides:
      visitMemberReference in class com.sun.source.util.TreeScanner<Void,Void>
    • visitReturn

      public Void visitReturn(com.sun.source.tree.ReturnTree node, 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 com.sun.source.tree.TreeVisitor<Void,Void>
      Overrides:
      visitReturn in class com.sun.source.util.TreeScanner<Void,Void>
    • visitAnnotation

      public Void visitAnnotation(com.sun.source.tree.AnnotationTree node, 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 com.sun.source.tree.TreeVisitor<Void,Void>
      Overrides:
      visitAnnotation in class com.sun.source.util.TreeScanner<Void,Void>
    • visitConditionalExpression

      public Void visitConditionalExpression(com.sun.source.tree.ConditionalExpressionTree node, 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 com.sun.source.tree.TreeVisitor<Void,Void>
      Overrides:
      visitConditionalExpression in class com.sun.source.util.TreeScanner<Void,Void>
    • visitSwitchExpression17

      public void visitSwitchExpression17(com.sun.source.tree.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(com.sun.source.tree.UnaryTree tree, Void p)
      Performs assignability check.
      Specified by:
      visitUnary in interface com.sun.source.tree.TreeVisitor<Void,Void>
      Overrides:
      visitUnary in class com.sun.source.util.TreeScanner<Void,Void>
    • visitCompoundAssignment

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

      public Void visitNewArray(com.sun.source.tree.NewArrayTree node, Void p)
      Specified by:
      visitNewArray in interface com.sun.source.tree.TreeVisitor<Void,Void>
      Overrides:
      visitNewArray in class com.sun.source.util.TreeScanner<Void,Void>
    • checkTypecastRedundancy

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

      protected void checkTypecastSafety(com.sun.source.tree.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(com.sun.source.tree.TypeCastTree node, Void p)
      Specified by:
      visitTypeCast in interface com.sun.source.tree.TreeVisitor<Void,Void>
      Overrides:
      visitTypeCast in class com.sun.source.util.TreeScanner<Void,Void>
    • visitInstanceOf

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

      public Void visitCatch(com.sun.source.tree.CatchTree node, 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 com.sun.source.tree.TreeVisitor<Void,Void>
      Overrides:
      visitCatch in class com.sun.source.util.TreeScanner<Void,Void>
    • visitThrow

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

      public Void visitAnnotatedType(com.sun.source.tree.AnnotatedTypeTree node, 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 com.sun.source.tree.TreeVisitor<Void,Void>
      Overrides:
      visitAnnotatedType in class com.sun.source.util.TreeScanner<Void,Void>
    • visitAnnotatedType

      public void visitAnnotatedType(@Nullable List<? extends com.sun.source.tree.AnnotationTree> annoTrees, com.sun.source.tree.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 com.sun.source.tree.AnnotationTree> annoTrees, com.sun.source.tree.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(com.sun.source.tree.CatchTree node)
      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:
      node - CatchTree to check
    • getExceptionParameterLowerBoundAnnotations

      protected Set<? extends AnnotationMirror> 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(com.sun.source.tree.ThrowTree node)
      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:
      node - ThrowTree to check
    • getThrowUpperBoundAnnotations

      protected Set<? extends AnnotationMirror> 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 void commonAssignmentCheck(com.sun.source.tree.Tree varTree, com.sun.source.tree.ExpressionTree valueExp, @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)
      valueExp - 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
    • commonAssignmentCheck

      protected void commonAssignmentCheck(AnnotatedTypeMirror varType, com.sun.source.tree.ExpressionTree valueExp, @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)
      valueExp - 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
    • commonAssignmentCheck

      protected void commonAssignmentCheck(AnnotatedTypeMirror varType, AnnotatedTypeMirror valueType, com.sun.source.tree.Tree valueTree, @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
      valueTree - 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
    • commonAssignmentCheckStartDiagnostic

      protected final void commonAssignmentCheckStartDiagnostic(AnnotatedTypeMirror varType, AnnotatedTypeMirror valueType, com.sun.source.tree.Tree valueTree)
      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
      valueTree - the location to use when reporting the error message
    • commonAssignmentCheckEndDiagnostic

      protected final void commonAssignmentCheckEndDiagnostic(boolean success, String extraMessage, AnnotatedTypeMirror varType, AnnotatedTypeMirror valueType, com.sun.source.tree.Tree valueTree)
      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
      valueTree - the location to use when reporting the error message
    • commonAssignmentCheckEndDiagnostic

      protected final void commonAssignmentCheckEndDiagnostic(String message, AnnotatedTypeMirror varType, AnnotatedTypeMirror valueType, com.sun.source.tree.Tree valueTree)
      Prints 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; may be null
      varType - the annotated type of the variable
      valueType - the annotated type of the value
      valueTree - the location to use when reporting the error message
    • checkArrayInitialization

      protected void checkArrayInitialization(AnnotatedTypeMirror type, List<? extends com.sun.source.tree.ExpressionTree> initializers)
    • checkTypeArguments

      protected void checkTypeArguments(com.sun.source.tree.Tree toptree, List<? extends AnnotatedTypeParameterBounds> paramBounds, List<? extends AnnotatedTypeMirror> typeargs, List<? extends com.sun.source.tree.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(com.sun.source.tree.MethodInvocationTree node, 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:
      node - the method invocation node
      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, com.sun.source.tree.MethodInvocationTree node)
      Tests whether the method can be invoked using the receiver of the 'node' 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
      node - the method invocation node
    • reportMethodInvocabilityError

      protected void reportMethodInvocabilityError(com.sun.source.tree.MethodInvocationTree node, AnnotatedTypeMirror found, AnnotatedTypeMirror expected)
      Report a method invocability error. Allows checkers to change how the message is output.
      Parameters:
      node - 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, com.sun.source.tree.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 com.sun.source.tree.ExpressionTree> passedArgs, CharSequence executableName, List<?> paramNames)
      A helper method to check that each passed argument is a subtype of the corresponding required argument, and issues "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(com.sun.source.tree.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(com.sun.source.tree.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(com.sun.source.tree.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(com.sun.source.tree.MemberReferenceTree memberReferenceTree, Void p)
      Check that a method reference is allowed. Using the OverrideChecker class.
      Parameters:
      memberReferenceTree - the tree for the method reference
      Returns:
      true if the method reference is allowed
    • enclosingMemberSelect

      protected com.sun.source.tree.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 com.sun.source.tree.Tree enclosingStatement(@FindDistinct com.sun.source.tree.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(com.sun.source.tree.IdentifierTree node, Void p)
      Specified by:
      visitIdentifier in interface com.sun.source.tree.TreeVisitor<Void,Void>
      Overrides:
      visitIdentifier in class com.sun.source.util.TreeScanner<Void,Void>
    • checkAccess

      protected void checkAccess(com.sun.source.tree.IdentifierTree node, Void p)
    • checkAccessAllowed

      protected void checkAccessAllowed(Element field, AnnotatedTypeMirror receiverType, @FindDistinct com.sun.source.tree.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, com.sun.source.tree.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, com.sun.source.tree.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, com.sun.source.tree.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(com.sun.source.tree.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
    • validateType

      protected boolean validateType(com.sun.source.tree.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(com.sun.source.tree.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(com.sun.source.tree.CompilationUnitTree node, Void p)
      Override Compilation Unit so we won't visit package names or imports.
      Specified by:
      visitCompilationUnit in interface com.sun.source.tree.TreeVisitor<Void,Void>
      Overrides:
      visitCompilationUnit in class com.sun.source.util.TreeScanner<Void,Void>