Class MustCallVisitor

java.lang.Object
com.sun.source.util.TreeScanner<R,P>
com.sun.source.util.TreePathScanner<R,P>
All Implemented Interfaces:
com.sun.source.tree.TreeVisitor<Void,Void>

public class MustCallVisitor extends BaseTypeVisitor<MustCallAnnotatedTypeFactory>
The visitor for the Must Call Checker. This visitor is similar to BaseTypeVisitor, but overrides methods that don't work well with the MustCall type hierarchy because it doesn't use the top type as the default type.
  • Constructor Details

    • MustCallVisitor

      public MustCallVisitor(BaseTypeChecker checker)
      Creates a new MustCallVisitor.
      Parameters:
      checker - the type-checker associated with this visitor
  • Method Details

    • visitReturn

      public Void visitReturn(com.sun.source.tree.ReturnTree node, Void p)
      Description copied from class: BaseTypeVisitor
      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 BaseTypeVisitor<MustCallAnnotatedTypeFactory>
    • validateType

      protected boolean validateType(com.sun.source.tree.Tree tree, AnnotatedTypeMirror type)
      Description copied from class: BaseTypeVisitor
      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.
      Overrides:
      validateType in class BaseTypeVisitor<MustCallAnnotatedTypeFactory>
      Parameters:
      tree - the type tree supplied by the user
      type - the type corresponding to tree
      Returns:
      true if the type is valid
    • isValidUse

      public boolean isValidUse(AnnotatedTypeMirror.AnnotatedDeclaredType declarationType, AnnotatedTypeMirror.AnnotatedDeclaredType useType, com.sun.source.tree.Tree tree)
      Description copied from class: BaseTypeVisitor
      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). BaseTypeVisitor.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.

      Overrides:
      isValidUse in class BaseTypeVisitor<MustCallAnnotatedTypeFactory>
      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
    • skipReceiverSubtypeCheck

      protected boolean skipReceiverSubtypeCheck(com.sun.source.tree.MethodInvocationTree node, AnnotatedTypeMirror methodDefinitionReceiver, AnnotatedTypeMirror methodCallReceiver)
      Description copied from class: BaseTypeVisitor
      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.
      Overrides:
      skipReceiverSubtypeCheck in class BaseTypeVisitor<MustCallAnnotatedTypeFactory>
      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
    • commonAssignmentCheck

      protected void commonAssignmentCheck(com.sun.source.tree.Tree varTree, com.sun.source.tree.ExpressionTree valueExp, @CompilerMessageKey String errorKey, Object... extraArgs)
      Mark (using the #commonAssignmentCheckOnResourceVariable field of this class) any assignments where the LHS is a resource variable, so that close doesn't need to be considered. See commonAssignmentCheck(AnnotatedTypeMirror, AnnotatedTypeMirror, Tree, String, Object...) for the code that uses and removes the mark.
      Overrides:
      commonAssignmentCheck in class BaseTypeVisitor<MustCallAnnotatedTypeFactory>
      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, AnnotatedTypeMirror valueType, com.sun.source.tree.Tree valueTree, @CompilerMessageKey String errorKey, Object... extraArgs)
      Iff the LHS is a resource variable, then #commonAssignmentCheckOnResourceVariable will be true. This method guarantees that #commonAssignmentCheckOnResourceVariable will be false when it returns.
      Overrides:
      commonAssignmentCheck in class BaseTypeVisitor<MustCallAnnotatedTypeFactory>
      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
    • checkConstructorResult

      protected void checkConstructorResult(AnnotatedTypeMirror.AnnotatedExecutableType constructorType, ExecutableElement constructorElement)
      This method typically issues a warning if the result type of the constructor is not top, because in top-default type systems that indicates a potential problem. The Must Call Checker does not need this warning, because it expects the type of all constructors to be MustCall({}) (by default) or some other MustCall type, not the top type.

      Instead, this method checks that the result type of a constructor is a supertype of the declared type on the class, if one exists.

      Overrides:
      checkConstructorResult in class BaseTypeVisitor<MustCallAnnotatedTypeFactory>
      Parameters:
      constructorType - AnnotatedExecutableType for the constructor
      constructorElement - element that declares the constructor
    • getExceptionParameterLowerBoundAnnotations

      protected Set<? extends AnnotationMirror> getExceptionParameterLowerBoundAnnotations()
      Change the default for exception parameter lower bounds to bottom (the default), to prevent false positives. This is unsound; see the discussion on https://github.com/typetools/checker-framework/issues/3839.

      TODO: change checking of throws clauses to require that the thrown exception is @MustCall({}). This would probably eliminate most of the same false positives, without adding undue false positives.

      Overrides:
      getExceptionParameterLowerBoundAnnotations in class BaseTypeVisitor<MustCallAnnotatedTypeFactory>
      Returns:
      a set containing only the @MustCall({}) annotation
    • visitAnnotation

      public Void visitAnnotation(com.sun.source.tree.AnnotationTree node, Void p)
      Does not issue any warnings.

      This implementation prevents recursing into annotation arguments. Annotation arguments are literals, which don't have must-call obligations.

      Annotation arguments are treated as return locations for the purposes of defaulting, rather than parameter locations. This causes them to default incorrectly when the annotation is defined in bytecode. See https://github.com/typetools/checker-framework/issues/3178 for an explanation of why this is necessary to avoid false positives.

      Specified by:
      visitAnnotation in interface com.sun.source.tree.TreeVisitor<Void,Void>
      Overrides:
      visitAnnotation in class BaseTypeVisitor<MustCallAnnotatedTypeFactory>
    • isTypeCastSafe

      protected boolean isTypeCastSafe(AnnotatedTypeMirror castType, AnnotatedTypeMirror exprType)
      Description copied from class: BaseTypeVisitor
      Returns true if the cast is safe.

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

      Overrides:
      isTypeCastSafe in class BaseTypeVisitor<MustCallAnnotatedTypeFactory>
      Parameters:
      castType - annotated type of the cast
      exprType - annotated type of the casted expression
      Returns:
      true if the type cast is safe, false otherwise