public class NullnessVisitor extends BaseTypeVisitor<NullnessSubchecker>
this
or super
) can always be dereferenced.NullnessSubchecker
BaseTypeVisitor.TypeValidator
checker, options, typeValidator, visitorState
atypeFactory, elements, root, trees, types
Constructor and Description |
---|
NullnessVisitor(NullnessSubchecker checker,
CompilationUnitTree root)
Creates a new visitor for type-checking
NonNull . |
Modifier and Type | Method and Description |
---|---|
protected void |
checkDefaultConstructor(ClassTree node) |
protected void |
checkForRedundantTests(BinaryTree node) |
protected void |
checkMethodInvocability(AnnotatedTypeMirror.AnnotatedExecutableType method,
MethodInvocationTree node)
Special casing NonNull and Raw method calls
|
protected boolean |
checkOverride(MethodTree overriderTree,
AnnotatedTypeMirror.AnnotatedDeclaredType enclosingType,
AnnotatedTypeMirror.AnnotatedExecutableType overridden,
AnnotatedTypeMirror.AnnotatedDeclaredType overriddenType,
Void p)
Ensure that also the method post-condition annotations (like @AssertNonNullAfter) are
overridden consistently: at least the same fields have to be listed in the overriding method.
|
protected void |
commonAssignmentCheck(Tree varTree,
ExpressionTree valueExp,
@CompilerMessageKey String errorKey)
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.
|
protected Pair<Set<VariableElement>,Set<VariableElement>> |
getUninitializedFields(ClassTree classTree,
List<? extends AnnotationMirror> annos) |
static boolean |
isPrimitive(ExpressionTree tree) |
static boolean |
isString(Types types,
TypeMirror stringType,
ExpressionTree tree) |
static boolean |
isUnboxingOperation(Types types,
TypeMirror stringType,
BinaryTree tree) |
boolean |
isValidUse(AnnotatedTypeMirror.AnnotatedDeclaredType declarationType,
AnnotatedTypeMirror.AnnotatedDeclaredType useType)
Tests that the qualifiers present on the useType are valid qualifiers,
given the qualifiers on the declaration of the type, declarationType.
|
boolean |
isValidUse(AnnotatedTypeMirror.AnnotatedPrimitiveType type)
Tests that the qualifiers present on the primitive type are valid.
|
Void |
visitArrayAccess(ArrayAccessTree node,
Void p)
Case 3: Check for array dereferencing
|
Void |
visitAssert(AssertTree node,
Void p) |
Void |
visitAssignment(AssignmentTree node,
Void p)
Performs two checks: subtyping and assignability checks, using
BaseTypeVisitor.commonAssignmentCheck(Tree, ExpressionTree, String) . |
Void |
visitBinary(BinaryTree node,
Void p)
Case 6: Check for redundant nullness tests
Case 7: unboxing case: primitive operations
|
Void |
visitCompoundAssignment(CompoundAssignmentTree node,
Void p)
Case 7: unboxing case: primitive operation
|
Void |
visitConditionalExpression(ConditionalExpressionTree node,
Void p)
If the computation of the type of the ConditionalExpressionTree in
checkers.types.TypeFromTree.TypeFromExpression.visitConditionalExpression(ConditionalExpressionTree, AnnotatedTypeFactory)
is correct, the following checks are redundant.
|
Void |
visitDoWhileLoop(DoWhileLoopTree node,
Void p) |
Void |
visitEnhancedForLoop(EnhancedForLoopTree node,
Void p)
Case 2: Check for implicit
.iterator call |
Void |
visitForLoop(ForLoopTree node,
Void p) |
Void |
visitIf(IfTree node,
Void p) |
Void |
visitMemberSelect(MemberSelectTree node,
Void p)
Case 1: Check for null dereferencing
|
Void |
visitMethod(MethodTree node,
Void p)
Performs pseudo-assignment check: checks that the method obeys override
and subtype rules to all overridden methods.
|
Void |
visitMethodInvocation(MethodInvocationTree node,
Void p)
Performs a method invocation check.
|
Void |
visitNewArray(NewArrayTree node,
Void p) |
Void |
visitNewClass(NewClassTree node,
Void p)
Performs a new class invocation check.
|
Void |
visitSwitch(SwitchTree node,
Void p) |
Void |
visitSynchronized(SynchronizedTree node,
Void p)
Case 5: Check for synchronizing locks
|
Void |
visitThrow(ThrowTree node,
Void p)
Case 4: Check for thrown exception nullness
|
Void |
visitTypeCast(TypeCastTree node,
Void p)
Case 7: unboxing case: casting to a primitive
|
Void |
visitUnary(UnaryTree node,
Void p)
Case 7: unboxing case: primitive operation
|
Void |
visitWhileLoop(WhileLoopTree node,
Void p) |
checkAccess, checkArguments, checkArrayInitialization, checkAssignability, checkConstructorInvocation, checkForAnnotatedJdk, checkTypeArguments, checkTypecastRedundancy, checkTypecastSafety, commonAssignmentCheck, commonAssignmentCheck, createTypeValidator, enclosingMemberSelect, enclosingStatement, isAccessAllowed, isAssignable, isValidUse, isVectorCopyInto, scan, shouldSkipUses, typeCheckVectorCopyIntoArgument, validateTypeOf, visitAnnotation, visitClass, visitCompilationUnit, visitIdentifier, visitInstanceOf, visitParameterizedType, visitReturn, visitTypeParameter, visitVariable
getCurrentPath, scan
reduce, scan, visitAnnotatedType, visitArrayType, visitBlock, visitBreak, visitCase, visitCatch, visitContinue, visitEmptyStatement, visitErroneous, visitExpressionStatement, visitImport, visitIntersectionType, visitLabeledStatement, visitLambdaExpression, visitLiteral, visitMemberReference, visitModifiers, visitOther, visitParenthesized, visitPrimitiveType, visitTry, visitUnionType, visitWildcard
public NullnessVisitor(NullnessSubchecker checker, CompilationUnitTree root)
NonNull
.checker
- the checker to useroot
- the root of the input program's AST to checkpublic Void visitMemberSelect(MemberSelectTree node, Void p)
visitMemberSelect
in interface TreeVisitor<Void,Void>
visitMemberSelect
in class TreeScanner<Void,Void>
public Void visitEnhancedForLoop(EnhancedForLoopTree node, Void p)
.iterator
callvisitEnhancedForLoop
in interface TreeVisitor<Void,Void>
visitEnhancedForLoop
in class BaseTypeVisitor<NullnessSubchecker>
public Void visitArrayAccess(ArrayAccessTree node, Void p)
visitArrayAccess
in interface TreeVisitor<Void,Void>
visitArrayAccess
in class BaseTypeVisitor<NullnessSubchecker>
public Void visitNewArray(NewArrayTree node, Void p)
visitNewArray
in interface TreeVisitor<Void,Void>
visitNewArray
in class BaseTypeVisitor<NullnessSubchecker>
public Void visitThrow(ThrowTree node, Void p)
visitThrow
in interface TreeVisitor<Void,Void>
visitThrow
in class TreeScanner<Void,Void>
public Void visitSynchronized(SynchronizedTree node, Void p)
visitSynchronized
in interface TreeVisitor<Void,Void>
visitSynchronized
in class TreeScanner<Void,Void>
public Void visitAssert(AssertTree node, Void p)
visitAssert
in interface TreeVisitor<Void,Void>
visitAssert
in class TreeScanner<Void,Void>
public Void visitConditionalExpression(ConditionalExpressionTree node, Void p)
BaseTypeVisitor
visitConditionalExpression
in interface TreeVisitor<Void,Void>
visitConditionalExpression
in class BaseTypeVisitor<NullnessSubchecker>
public Void visitIf(IfTree node, Void p)
visitIf
in interface TreeVisitor<Void,Void>
visitIf
in class TreeScanner<Void,Void>
public Void visitDoWhileLoop(DoWhileLoopTree node, Void p)
visitDoWhileLoop
in interface TreeVisitor<Void,Void>
visitDoWhileLoop
in class TreeScanner<Void,Void>
public Void visitWhileLoop(WhileLoopTree node, Void p)
visitWhileLoop
in interface TreeVisitor<Void,Void>
visitWhileLoop
in class TreeScanner<Void,Void>
public Void visitForLoop(ForLoopTree node, Void p)
visitForLoop
in interface TreeVisitor<Void,Void>
visitForLoop
in class TreeScanner<Void,Void>
public Void visitSwitch(SwitchTree node, Void p)
visitSwitch
in interface TreeVisitor<Void,Void>
visitSwitch
in class TreeScanner<Void,Void>
public Void visitNewClass(NewClassTree node, Void p)
BaseTypeVisitor
visitNewClass
in interface TreeVisitor<Void,Void>
visitNewClass
in class BaseTypeVisitor<NullnessSubchecker>
protected void checkForRedundantTests(BinaryTree node)
public Void visitBinary(BinaryTree node, Void p)
visitBinary
in interface TreeVisitor<Void,Void>
visitBinary
in class TreeScanner<Void,Void>
public Void visitUnary(UnaryTree node, Void p)
visitUnary
in interface TreeVisitor<Void,Void>
visitUnary
in class BaseTypeVisitor<NullnessSubchecker>
public Void visitCompoundAssignment(CompoundAssignmentTree node, Void p)
visitCompoundAssignment
in interface TreeVisitor<Void,Void>
visitCompoundAssignment
in class BaseTypeVisitor<NullnessSubchecker>
public Void visitTypeCast(TypeCastTree node, Void p)
visitTypeCast
in interface TreeVisitor<Void,Void>
visitTypeCast
in class BaseTypeVisitor<NullnessSubchecker>
protected void commonAssignmentCheck(Tree varTree, ExpressionTree valueExp, @CompilerMessageKey String errorKey)
BaseTypeVisitor
commonAssignmentCheck
in class BaseTypeVisitor<NullnessSubchecker>
varTree
- the AST node for the variablevalueExp
- the AST node for the valueerrorKey
- the error message to use if the check fails (must be a
compiler message key, see CompilerMessageKey
)public Void visitMethod(MethodTree node, Void p)
BaseTypeVisitor
visitMethod
in interface TreeVisitor<Void,Void>
visitMethod
in class BaseTypeVisitor<NullnessSubchecker>
public Void visitMethodInvocation(MethodInvocationTree node, Void p)
BaseTypeVisitor
visitMethodInvocation
in interface TreeVisitor<Void,Void>
visitMethodInvocation
in class BaseTypeVisitor<NullnessSubchecker>
protected void checkDefaultConstructor(ClassTree node)
checkDefaultConstructor
in class BaseTypeVisitor<NullnessSubchecker>
public Void visitAssignment(AssignmentTree node, Void p)
BaseTypeVisitor
BaseTypeVisitor.commonAssignmentCheck(Tree, ExpressionTree, String)
.
If the subtype check fails, it issues a "assignment.type.incompatible" error.visitAssignment
in interface TreeVisitor<Void,Void>
visitAssignment
in class BaseTypeVisitor<NullnessSubchecker>
protected Pair<Set<VariableElement>,Set<VariableElement>> getUninitializedFields(ClassTree classTree, List<? extends AnnotationMirror> annos)
protected void checkMethodInvocability(AnnotatedTypeMirror.AnnotatedExecutableType method, MethodInvocationTree node)
checkMethodInvocability
in class BaseTypeVisitor<NullnessSubchecker>
method
- the type of the invoked methodnode
- the method invocation nodeprotected boolean checkOverride(MethodTree overriderTree, AnnotatedTypeMirror.AnnotatedDeclaredType enclosingType, AnnotatedTypeMirror.AnnotatedExecutableType overridden, AnnotatedTypeMirror.AnnotatedDeclaredType overriddenType, Void p)
checkOverride
in class BaseTypeVisitor<NullnessSubchecker>
overriderTree
- the AST node of the overriding methodenclosingType
- the declared type enclosing the overrider methodoverridden
- the type of the overridden methodoverriddenType
- the declared type enclosing the overridden methodp
- an optional parameter (as supplied to visitor methods)public static final boolean isUnboxingOperation(Types types, TypeMirror stringType, BinaryTree tree)
public static final boolean isString(Types types, TypeMirror stringType, ExpressionTree tree)
public static final boolean isPrimitive(ExpressionTree tree)
public boolean isValidUse(AnnotatedTypeMirror.AnnotatedDeclaredType declarationType, AnnotatedTypeMirror.AnnotatedDeclaredType useType)
BaseTypeVisitor
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.
For instance, in the IGJ type system, a @Mutable
is an invalid
qualifier for String
, as String
is declared as
@Immutable String
.
In most cases, useType
simply needs to be a subtype of
declarationType
, but there are exceptions. In IGJ, a variable may be
declared @ReadOnly String
, even though String
is
@Immutable String
; ReadOnly
is not a subtype of
Immutable
.
isValidUse
in class BaseTypeVisitor<NullnessSubchecker>
declarationType
- the type of the class (TypeElement)useType
- the use of the class (instance type)public boolean isValidUse(AnnotatedTypeMirror.AnnotatedPrimitiveType type)
BaseTypeVisitor
isValidUse
in class BaseTypeVisitor<NullnessSubchecker>