Class BaseTypeValidator

java.lang.Object
org.checkerframework.framework.type.visitor.AnnotatedTypeScanner<Void,com.sun.source.tree.Tree>
org.checkerframework.common.basetype.BaseTypeValidator
All Implemented Interfaces:
TypeValidator, AnnotatedTypeVisitor<Void,com.sun.source.tree.Tree>
Direct Known Subclasses:
ReportVisitor.ReportTypeValidator

public class BaseTypeValidator extends AnnotatedTypeScanner<Void,com.sun.source.tree.Tree> implements TypeValidator
A visitor to validate the types in a tree.

Note: A TypeValidator (this class and its subclasses) cannot tell whether an annotation was written by a programmer or defaulted/inferred/computed by the Checker Framework, because the AnnotatedTypeMirror does not make distinctions about which annotations in an AnnotatedTypeMirror were explicitly written and which were added by a checker. To issue a warning/error only when a programmer writes an annotation, override BaseTypeVisitor.visitAnnotatedType(com.sun.source.tree.AnnotatedTypeTree, java.lang.Void) and BaseTypeVisitor.visitVariable(com.sun.source.tree.VariableTree, java.lang.Void).

  • Field Details

    • isValid

      protected boolean isValid
      Is the type valid? This is side-effected by the visitor, and read at the end of visiting.
    • checkTopLevelDeclaredOrPrimitiveType

      protected boolean checkTopLevelDeclaredOrPrimitiveType
      Should the primary annotation on the top level type be checked?
    • checker

      protected final BaseTypeChecker checker
      BaseTypeChecker.
    • visitor

      protected final BaseTypeVisitor<?> visitor
      BaseTypeVisitor.
    • atypeFactory

      protected final AnnotatedTypeFactory atypeFactory
      AnnotatedTypeFactory.
  • Constructor Details

  • Method Details

    • isValid

      public boolean isValid(AnnotatedTypeMirror type, com.sun.source.tree.Tree tree)
      Validate the type against the given tree. This method both issues error messages and also returns a boolean value.

      This is the entry point to the type validator. Neither this method nor visit should be called directly by a visitor, only use BaseTypeVisitor.validateTypeOf(Tree).

      This method is only called on top-level types, but it validates the entire type including components of a compound type. Subclasses should override this only if there is special-case behavior that should be performed only on top-level types.

      Specified by:
      isValid in interface TypeValidator
      Parameters:
      type - the type to validate
      tree - the tree from which the type originated. If the tree is a method tree, type is its return type. If the tree is a variable tree, type is the variable's type.
      Returns:
      true if the type is valid
    • shouldCheckTopLevelDeclaredOrPrimitiveType

      protected boolean shouldCheckTopLevelDeclaredOrPrimitiveType(AnnotatedTypeMirror type, com.sun.source.tree.Tree tree)
      Should the top-level declared or primitive type be checked?

      If type is not a declared or primitive type, then this method returns true.

      Top-level type is not checked if tree is a local variable or an expression tree.

      Parameters:
      type - AnnotatedTypeMirror being validated
      tree - a Tree whose type is type
      Returns:
      whether or not the top-level type should be checked, if type is a declared or primitive type.
    • isValidStructurally

      protected List<DiagMessage> isValidStructurally(QualifierHierarchy qualifierHierarchy, AnnotatedTypeMirror type)
      Performs some well-formedness checks on the given AnnotatedTypeMirror. Returns a list of failures. If successful, returns an empty list. The method will never return failures for a valid type, but might not catch all invalid types.

      This method ensures that the type is structurally or lexically well-formed, but it does not check whether the annotations are semantically sensible. Subclasses should generally override visit methods such as visitDeclared(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType, com.sun.source.tree.Tree) rather than this method.

      Currently, this implementation checks the following (subclasses can extend this behavior):

      1. There should not be multiple annotations from the same qualifier hierarchy.
      2. There should not be more annotations than the width of the QualifierHierarchy.
      3. If the type is not a type variable, then the number of annotations should be the same as the width of the QualifierHierarchy.
      4. These properties should also hold recursively for component types of arrays and for bounds of type variables and wildcards.
      Parameters:
      qualifierHierarchy - the QualifierHierarchy
      type - the type to test
      Returns:
      list of reasons the type is invalid, or empty list if the type is valid
    • isTopLevelValidType

      protected List<DiagMessage> isTopLevelValidType(QualifierHierarchy qualifierHierarchy, AnnotatedTypeMirror type)
      Checks every property listed in isValidStructurally(org.checkerframework.framework.type.QualifierHierarchy, org.checkerframework.framework.type.AnnotatedTypeMirror), but only for the top level type. If successful, returns an empty list. If not successful, returns diagnostics.
      Parameters:
      qualifierHierarchy - the QualifierHierarchy
      type - the type to be checked
      Returns:
      the diagnostics indicating failure, or an empty list if successful
    • reportValidityResult

      protected void reportValidityResult(@CompilerMessageKey String errorType, AnnotatedTypeMirror type, com.sun.source.tree.Tree p)
    • reportValidityResultOnUnannotatedType

      protected void reportValidityResultOnUnannotatedType(@CompilerMessageKey String errorType, AnnotatedTypeMirror type, com.sun.source.tree.Tree p)
      Like reportValidityResult(java.lang.String, org.checkerframework.framework.type.AnnotatedTypeMirror, com.sun.source.tree.Tree), but the type is printed in the error message without annotations. This method would print "annotation @NonNull is not permitted on type int", whereas reportValidityResult(java.lang.String, org.checkerframework.framework.type.AnnotatedTypeMirror, com.sun.source.tree.Tree) would print "annotation @NonNull is not permitted on type @NonNull int". In addition, when the underlying type is a compound type such as @Bad List<String>, the erased type will be used, i.e., "List" will print instead of "@Bad List<String>".
    • reportInvalidBounds

      protected void reportInvalidBounds(AnnotatedTypeMirror type, com.sun.source.tree.Tree tree)
      Most errors reported by this class are of the form type.invalid. This method reports when the bounds of a wildcard or type variable don't make sense. Bounds make sense when the effective annotations on the upper bound are supertypes of those on the lower bounds for all hierarchies. To ensure that this subtlety is not lost on users, we report "bound" and print the bounds along with the invalid type rather than a "type.invalid".
      Parameters:
      type - the type with invalid bounds
      tree - where to report the error
    • reportInvalidType

      protected void reportInvalidType(AnnotatedTypeMirror type, com.sun.source.tree.Tree p)
    • reportInvalidAnnotationsOnUse

      protected void reportInvalidAnnotationsOnUse(AnnotatedTypeMirror type, com.sun.source.tree.Tree p)
      Report an "annotations.on.use" error for the given type and tree.
      Parameters:
      type - the type with invalid annotations
      p - the tree where to report the error
    • visitDeclared

      public Void visitDeclared(AnnotatedTypeMirror.AnnotatedDeclaredType type, com.sun.source.tree.Tree tree)
      Description copied from interface: AnnotatedTypeVisitor
      Visits a declared type.
      Specified by:
      visitDeclared in interface AnnotatedTypeVisitor<Void,com.sun.source.tree.Tree>
      Overrides:
      visitDeclared in class AnnotatedTypeScanner<Void,com.sun.source.tree.Tree>
      Parameters:
      type - the type to visit
      tree - a visitor-specified parameter
      Returns:
      a visitor-specified result
    • visitClassTypeParameters

      protected void visitClassTypeParameters(AnnotatedTypeMirror.AnnotatedDeclaredType type, com.sun.source.tree.ClassTree tree)
      Visits the type parameters of a class tree.
      Parameters:
      type - type of tree
      tree - a class tree
    • visitTypeParameterBounds

      protected void visitTypeParameterBounds(AnnotatedTypeMirror.AnnotatedTypeVariable typeParameter, com.sun.source.tree.TypeParameterTree typeParameterTree)
      Visits type parameter bounds.
      Parameters:
      typeParameter - type of typeParameterTree
      typeParameterTree - a type parameter tree
    • visitPrimitive

      public Void visitPrimitive(AnnotatedTypeMirror.AnnotatedPrimitiveType type, com.sun.source.tree.Tree tree)
      Description copied from interface: AnnotatedTypeVisitor
      Visits a primitive type.
      Specified by:
      visitPrimitive in interface AnnotatedTypeVisitor<Void,com.sun.source.tree.Tree>
      Overrides:
      visitPrimitive in class AnnotatedTypeScanner<Void,com.sun.source.tree.Tree>
      Parameters:
      type - the type to visit
      tree - a visitor-specified parameter
      Returns:
      a visitor-specified result
    • visitArray

      public Void visitArray(AnnotatedTypeMirror.AnnotatedArrayType type, com.sun.source.tree.Tree tree)
      Description copied from interface: AnnotatedTypeVisitor
      Visits an array type.
      Specified by:
      visitArray in interface AnnotatedTypeVisitor<Void,com.sun.source.tree.Tree>
      Overrides:
      visitArray in class AnnotatedTypeScanner<Void,com.sun.source.tree.Tree>
      Parameters:
      type - the type to visit
      tree - a visitor-specified parameter
      Returns:
      a visitor-specified result
    • visitParameterizedType

      protected Void visitParameterizedType(AnnotatedTypeMirror.AnnotatedDeclaredType type, com.sun.source.tree.ParameterizedTypeTree tree)
      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:
      type - the type to check
      tree - the type's tree
    • visitTypeVariable

      public Void visitTypeVariable(AnnotatedTypeMirror.AnnotatedTypeVariable type, com.sun.source.tree.Tree tree)
      Description copied from interface: AnnotatedTypeVisitor
      Visits a type variable.
      Specified by:
      visitTypeVariable in interface AnnotatedTypeVisitor<Void,com.sun.source.tree.Tree>
      Overrides:
      visitTypeVariable in class AnnotatedTypeScanner<Void,com.sun.source.tree.Tree>
      Parameters:
      type - the type to visit
      tree - a visitor-specified parameter
      Returns:
      a visitor-specified result
    • visitWildcard

      public Void visitWildcard(AnnotatedTypeMirror.AnnotatedWildcardType type, com.sun.source.tree.Tree tree)
      Description copied from interface: AnnotatedTypeVisitor
      Visits a wildcard type.
      Specified by:
      visitWildcard in interface AnnotatedTypeVisitor<Void,com.sun.source.tree.Tree>
      Overrides:
      visitWildcard in class AnnotatedTypeScanner<Void,com.sun.source.tree.Tree>
      Parameters:
      type - the type to visit
      tree - a visitor-specified parameter
      Returns:
      a visitor-specified result
    • areBoundsValid

      public boolean areBoundsValid(AnnotatedTypeMirror upperBound, AnnotatedTypeMirror lowerBound)
      Returns true if the effective annotations on the upperBound are above those on the lowerBound.
      Returns:
      true if the effective annotations on the upperBound are above those on the lowerBound