public class NullnessVisitor extends BaseTypeVisitor<NullnessSubchecker>
this
or super
) can always be dereferenced.NullnessSubchecker
BaseTypeVisitor.TypeValidator
annoFactory, annoTypes, checker, options, typeValidator, visitorState
atypeFactory, elements, root, trees, types
Constructor and Description |
---|
NullnessVisitor(NullnessSubchecker checker,
@Nullable CompilationUnitTree root)
Creates a new visitor for type-checking
NonNull . |
Modifier and Type | Method and Description |
---|---|
protected void |
checkDefaultConstructor(@Nullable ClassTree node) |
protected void |
checkForRedundantTests(BinaryTree node) |
protected boolean |
checkMethodInvocability(AnnotatedTypeMirror.AnnotatedExecutableType method,
MethodInvocationTree node)
Special casing NonNull and Raw method calls
|
protected boolean |
checkOverride(@Nullable MethodTree overriderTree,
AnnotatedTypeMirror.AnnotatedDeclaredType enclosingType,
AnnotatedTypeMirror.AnnotatedExecutableType overridden,
AnnotatedTypeMirror.AnnotatedDeclaredType overriddenType,
@Nullable 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(@Nullable Tree varTree,
ExpressionTree valueExp,
@ReadOnly 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(@Nullable ClassTree classTree,
List<? extends @Nullable 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.
|
@Nullable Void |
visitArrayAccess(ArrayAccessTree node,
@Nullable Void p)
Case 3: Check for array dereferencing
|
@Nullable Void |
visitAssert(AssertTree node,
@Nullable Void p) |
@Nullable Void |
visitAssignment(AssignmentTree node,
@Nullable Void p)
Performs two checks: subtyping and assignability checks, using
BaseTypeVisitor.commonAssignmentCheck(Tree, ExpressionTree, String) . |
@Nullable Void |
visitBinary(BinaryTree node,
@Nullable Void p)
Case 6: Check for redundant nullness tests
Case 7: unboxing case: primitive operations
|
@Nullable Void |
visitCompoundAssignment(CompoundAssignmentTree node,
@Nullable Void p)
Case 7: unboxing case: primitive operation
|
@Nullable Void |
visitConditionalExpression(ConditionalExpressionTree node,
@Nullable 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.
|
@Nullable Void |
visitDoWhileLoop(DoWhileLoopTree node,
@Nullable Void p) |
@Nullable Void |
visitEnhancedForLoop(EnhancedForLoopTree node,
@Nullable Void p)
Case 2: Check for implicit
.iterator call |
@Nullable Void |
visitForLoop(ForLoopTree node,
@Nullable Void p) |
@Nullable Void |
visitIf(IfTree node,
@Nullable Void p) |
@Nullable Void |
visitMemberSelect(MemberSelectTree node,
@Nullable Void p)
Case 1: Check for null dereferencing
|
@Nullable Void |
visitMethod(@Nullable MethodTree node,
@Nullable Void p)
Performs pseudo-assignment check: checks that the method obeys override
and subtype rules to all overridden methods.
|
@Nullable Void |
visitMethodInvocation(MethodInvocationTree node,
@Nullable Void p)
Performs a method invocation check.
|
@Nullable Void |
visitNewArray(NewArrayTree node,
@Nullable Void p) |
@Nullable Void |
visitSwitch(SwitchTree node,
@Nullable Void p) |
@Nullable Void |
visitSynchronized(SynchronizedTree node,
@Nullable Void p)
Case 5: Check for synchronizing locks
|
@Nullable Void |
visitThrow(ThrowTree node,
@Nullable Void p)
Case 4: Check for thrown exception nullness
|
@Nullable Void |
visitTypeCast(TypeCastTree node,
@Nullable Void p)
Case 7: unboxing case: casting to a primitive
|
@Nullable Void |
visitUnary(UnaryTree node,
@Nullable Void p)
Case 7: unboxing case: primitive operation
|
@Nullable Void |
visitWhileLoop(WhileLoopTree node,
@Nullable 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, visitNewClass, visitParameterizedType, visitReturn, visitTypeParameter, visitVariable
getCurrentPath, scan
reduce, scan, visitAnnotatedType, visitArrayType, visitBlock, visitBreak, visitCase, visitCatch, visitContinue, visitEmptyStatement, visitErroneous, visitExpressionStatement, visitImport, visitLabeledStatement, visitLambdaExpression, visitLiteral, visitMemberReference, visitModifiers, visitOther, visitParenthesized, visitPrimitiveType, visitTry, visitUnionType, visitWildcard
public NullnessVisitor(NullnessSubchecker checker, @Nullable CompilationUnitTree root)
NonNull
.checker
- the checker to useroot
- the root of the input program's AST to checkpublic @Nullable Void visitMemberSelect(MemberSelectTree node, @Nullable Void p)
visitMemberSelect
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitMemberSelect
in class TreeScanner<@Nullable Void,@Nullable Void>
public @Nullable Void visitEnhancedForLoop(EnhancedForLoopTree node, @Nullable Void p)
.iterator
callvisitEnhancedForLoop
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitEnhancedForLoop
in class BaseTypeVisitor<NullnessSubchecker>
public @Nullable Void visitArrayAccess(ArrayAccessTree node, @Nullable Void p)
visitArrayAccess
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitArrayAccess
in class BaseTypeVisitor<NullnessSubchecker>
public @Nullable Void visitNewArray(NewArrayTree node, @Nullable Void p)
visitNewArray
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitNewArray
in class BaseTypeVisitor<NullnessSubchecker>
public @Nullable Void visitThrow(ThrowTree node, @Nullable Void p)
visitThrow
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitThrow
in class TreeScanner<@Nullable Void,@Nullable Void>
public @Nullable Void visitSynchronized(SynchronizedTree node, @Nullable Void p)
visitSynchronized
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitSynchronized
in class TreeScanner<@Nullable Void,@Nullable Void>
public @Nullable Void visitAssert(AssertTree node, @Nullable Void p)
visitAssert
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitAssert
in class TreeScanner<@Nullable Void,@Nullable Void>
public @Nullable Void visitConditionalExpression(ConditionalExpressionTree node, @Nullable Void p)
BaseTypeVisitor
visitConditionalExpression
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitConditionalExpression
in class BaseTypeVisitor<NullnessSubchecker>
public @Nullable Void visitDoWhileLoop(DoWhileLoopTree node, @Nullable Void p)
visitDoWhileLoop
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitDoWhileLoop
in class TreeScanner<@Nullable Void,@Nullable Void>
public @Nullable Void visitWhileLoop(WhileLoopTree node, @Nullable Void p)
visitWhileLoop
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitWhileLoop
in class TreeScanner<@Nullable Void,@Nullable Void>
public @Nullable Void visitForLoop(ForLoopTree node, @Nullable Void p)
visitForLoop
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitForLoop
in class TreeScanner<@Nullable Void,@Nullable Void>
public @Nullable Void visitSwitch(SwitchTree node, @Nullable Void p)
visitSwitch
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitSwitch
in class TreeScanner<@Nullable Void,@Nullable Void>
protected void checkForRedundantTests(BinaryTree node)
public @Nullable Void visitBinary(BinaryTree node, @Nullable Void p)
visitBinary
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitBinary
in class TreeScanner<@Nullable Void,@Nullable Void>
public @Nullable Void visitUnary(UnaryTree node, @Nullable Void p)
visitUnary
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitUnary
in class BaseTypeVisitor<NullnessSubchecker>
public @Nullable Void visitCompoundAssignment(CompoundAssignmentTree node, @Nullable Void p)
visitCompoundAssignment
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitCompoundAssignment
in class BaseTypeVisitor<NullnessSubchecker>
public @Nullable Void visitTypeCast(TypeCastTree node, @Nullable Void p)
visitTypeCast
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitTypeCast
in class BaseTypeVisitor<NullnessSubchecker>
protected void commonAssignmentCheck(@Nullable Tree varTree, ExpressionTree valueExp, @ReadOnly 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 failspublic @Nullable Void visitMethod(@Nullable MethodTree node, @Nullable Void p)
BaseTypeVisitor
visitMethod
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitMethod
in class BaseTypeVisitor<NullnessSubchecker>
public @Nullable Void visitMethodInvocation(MethodInvocationTree node, @Nullable Void p)
BaseTypeVisitor
visitMethodInvocation
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitMethodInvocation
in class BaseTypeVisitor<NullnessSubchecker>
protected void checkDefaultConstructor(@Nullable ClassTree node)
checkDefaultConstructor
in class BaseTypeVisitor<NullnessSubchecker>
public @Nullable Void visitAssignment(AssignmentTree node, @Nullable Void p)
BaseTypeVisitor
BaseTypeVisitor.commonAssignmentCheck(Tree, ExpressionTree, String)
.
If the subtype check fails, it issues a "assignment.type.incompatible" error.visitAssignment
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitAssignment
in class BaseTypeVisitor<NullnessSubchecker>
protected Pair<Set<VariableElement>,Set<VariableElement>> getUninitializedFields(@Nullable ClassTree classTree, List<? extends @Nullable AnnotationMirror> annos)
protected boolean checkMethodInvocability(AnnotatedTypeMirror.AnnotatedExecutableType method, MethodInvocationTree node)
checkMethodInvocability
in class BaseTypeVisitor<NullnessSubchecker>
method
- the type of the invoked methodnode
- the method invocation nodeprotected boolean checkOverride(@Nullable MethodTree overriderTree, AnnotatedTypeMirror.AnnotatedDeclaredType enclosingType, AnnotatedTypeMirror.AnnotatedExecutableType overridden, AnnotatedTypeMirror.AnnotatedDeclaredType overriddenType, @Nullable 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>