public abstract class AbstractFlow<ST extends FlowState> extends TreePathScanner<@Nullable Void,@Nullable Void> implements Flow
This implementation is based largely on javac
's dataflow analysis
module, which may be found in com.sun.tools.javac.comp.Flow
from 13
Sep 2007. It differs from that class in two ways:
javac
's Flow
.
It does not perform exception analysis, and performs liveness analysis only
to the extent required for the GEN-KILL analysis.
BitSet
, the Compiler Tree API) over those in
com.sun.tools.javac
(for these reasons, examining a diff against that
class would not be particularly enlightening).
javac
's Flow
class, methods named "visit*" perform
analysis for a particular type of tree node, while methods named "scan*"
perform the analysis for a general, higher-level class of structural element.
Typically "visit*" methods delegate to "scan*" methods. As an example,
visitIf(com.sun.source.tree.IfTree, java.lang.Void)
, visitWhileLoop(com.sun.source.tree.WhileLoopTree, java.lang.Void)
, visitAssert(com.sun.source.tree.AssertTree, java.lang.Void)
, and
visitConditionalExpression(com.sun.source.tree.ConditionalExpressionTree, java.lang.Void)
all use scanCond(com.sun.source.tree.ExpressionTree)
for analyzing
conditions and handling branching.
A separate instance of the analysis must be created for each compilation unit.
Modifier and Type | Field and Description |
---|---|
protected boolean |
alive
Stores the result of liveness analysis, required by the GEN-KILL analysis
for proper handling of jumps (break, return, throw, etc.).
|
protected QualifierHierarchy |
annoRelations
The hierarchy for the type qualifiers that this class infers.
|
protected AnnotatedTypes |
atypes
Utility class for operations on annotated types.
|
protected SourceChecker |
checker
The checker to which this instance belongs.
|
protected PrintStream |
debug
Where to print debugging messages; set via
setDebug(java.io.PrintStream) . |
protected AnnotatedTypeFactory |
factory
Utility class for determining annotated types.
|
protected Map<@Nullable Tree,Set<@Nullable AnnotationMirror>> |
flowResults
Stores the results of the analysis (source location to qualifier).
|
protected ST |
flowState
Tracks the state of the inference.
|
protected ST |
flowState_whenFalse
Tracks the state of the inference in a false branch.
|
protected ST |
flowState_whenTrue
Tracks the state of the inference in a true branch.
|
protected @Nullable CompilationUnitTree |
root
The file that's being analyzed.
|
Constructor and Description |
---|
AbstractFlow(BaseTypeChecker checker,
@Nullable CompilationUnitTree root,
Set<@Nullable AnnotationMirror> annotations,
AnnotatedTypeFactory factory)
Creates a new analysis.
|
getCurrentPath, scan
reduce, scan, visitAnnotatedType, visitArrayType, visitBinary, visitCase, visitCatch, visitCompilationUnit, visitEmptyStatement, visitErroneous, visitExpressionStatement, visitInstanceOf, visitLabeledStatement, visitLambdaExpression, visitLiteral, visitMemberReference, visitModifiers, visitNewArray, visitNewClass, visitOther, visitParameterizedType, visitParenthesized, visitPrimitiveType, visitSwitch, visitSynchronized, visitTypeParameter, visitUnary, visitUnionType, visitWildcard
protected PrintStream debug
setDebug(java.io.PrintStream)
.protected final SourceChecker checker
protected final @Nullable CompilationUnitTree root
protected final AnnotatedTypeFactory factory
protected final AnnotatedTypes atypes
protected final Map<@Nullable Tree,Set<@Nullable AnnotationMirror>> flowResults
protected ST extends FlowState flowState
protected ST extends FlowState flowState_whenTrue
javac
's Flow
, saving/restoring via local variables
handles nested branches.
This field is only non-null/valid if flowState is null.flowState
protected ST extends FlowState flowState_whenFalse
javac
's Flow
, saving/restoring via local variables
handles nested branches.
This field is only non-null/valid if flowState is null.flowState
protected boolean alive
protected final QualifierHierarchy annoRelations
public AbstractFlow(BaseTypeChecker checker, @Nullable CompilationUnitTree root, Set<@Nullable AnnotationMirror> annotations, AnnotatedTypeFactory factory)
AnnotatedTypeFactory
to obtain annotated types.checker
- the current checkerroot
- the compilation unit that will be scannedannotations
- the annotations to trackfactory
- the factory class that will be used to get annotated
types, or null
if the default factory should be usedprotected abstract ST createFlowState(Set<@Nullable AnnotationMirror> annotations)
annotations
- The annotations that can be inferred.public void setDebug(PrintStream debug)
Flow
PrintStream
for printing debug messages, such as
System.out
or System.err
, or null if no debugging output
should be emitted (the default).public void scan(@Nullable Tree tree)
Flow
public Set<@Nullable AnnotationMirror> test(@Nullable Tree tree)
public static void addFlowResult(Map<@Nullable Tree,Set<@Nullable AnnotationMirror>> flowResults, @Nullable Tree tree, @Nullable AnnotationMirror anno)
public static void removeFlowResult(Map<@Nullable Tree,Set<@Nullable AnnotationMirror>> flowResults, @Nullable Tree tree, @Nullable AnnotationMirror anno)
protected abstract void newVar(VariableTree tree)
tree
- the variable to registerprotected abstract void propagate(@Nullable Tree lhs, ExpressionTree rhs)
If only type information (and not a Tree
) is available, use
propagateFromType(Tree, AnnotatedTypeMirror)
instead.
lhs
- the left-hand side of the assignmentrhs
- the right-hand side of the assignmentprotected void recordBits(@Nullable TreePath path)
path
- protected void scanDef(@Nullable Tree tree)
tree
- the definition being scannedprotected void scanStat(StatementTree tree)
tree
- the statement being scannedprotected void scanStats(List<? extends StatementTree> trees)
trees
- the statements being scannedprotected void scanCond(ExpressionTree tree)
tree
- the condition being scannedprotected ST copyState(ST in)
protected void scanExpr(ExpressionTree tree)
tree
- the expression being scannedpublic @Nullable Void visitClass(@Nullable ClassTree node, @Nullable Void p)
visitClass
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitClass
in class TreeScanner<@Nullable Void,@Nullable Void>
public @Nullable Void visitImport(ImportTree tree, @Nullable Void p)
visitImport
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitImport
in class TreeScanner<@Nullable Void,@Nullable Void>
public @Nullable Void visitTypeCast(TypeCastTree node, @Nullable Void p)
visitTypeCast
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitTypeCast
in class TreeScanner<@Nullable Void,@Nullable Void>
public @Nullable Void visitAnnotation(AnnotationTree tree, @Nullable Void p)
visitAnnotation
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitAnnotation
in class TreeScanner<@Nullable Void,@Nullable Void>
public @Nullable Void visitIdentifier(IdentifierTree node, @Nullable Void p)
visitIdentifier
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitIdentifier
in class TreeScanner<@Nullable Void,@Nullable Void>
public @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 visitVariable(VariableTree node, @Nullable Void p)
visitVariable
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitVariable
in class TreeScanner<@Nullable Void,@Nullable Void>
public @Nullable Void visitAssignment(AssignmentTree node, @Nullable Void p)
visitAssignment
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitAssignment
in class TreeScanner<@Nullable Void,@Nullable Void>
public @Nullable Void visitCompoundAssignment(CompoundAssignmentTree node, @Nullable Void p)
visitCompoundAssignment
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitCompoundAssignment
in class TreeScanner<@Nullable Void,@Nullable Void>
protected static boolean containsKey(@Nullable Tree tree, Collection<@ReadOnly String> keys)
protected static boolean inferFromAssert(AssertTree node, SourceChecker checker)
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)
visitConditionalExpression
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitConditionalExpression
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 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 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 visitEnhancedForLoop(EnhancedForLoopTree node, @Nullable Void p)
visitEnhancedForLoop
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitEnhancedForLoop
in class TreeScanner<@Nullable Void,@Nullable Void>
public @Nullable Void visitBreak(BreakTree node, @Nullable Void p)
visitBreak
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitBreak
in class TreeScanner<@Nullable Void,@Nullable Void>
public @Nullable Void visitContinue(ContinueTree node, @Nullable Void p)
visitContinue
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitContinue
in class TreeScanner<@Nullable Void,@Nullable Void>
public @Nullable Void visitReturn(ReturnTree node, @Nullable Void p)
visitReturn
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitReturn
in class TreeScanner<@Nullable Void,@Nullable Void>
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 visitMethodInvocation(MethodInvocationTree node, @Nullable Void p)
visitMethodInvocation
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitMethodInvocation
in class TreeScanner<@Nullable Void,@Nullable Void>
protected void checkArguments(List<? extends @Mutable AnnotatedTypeMirror> requiredArgs, List<? extends ExpressionTree> passedArgs)
protected abstract void clearOnCall(@Nullable MethodTree enclMeth, @NonNull ExecutableElement method)
enclMeth
- The method within which "method" is called.
Might be null if the invocation is in a field initializer.method
- The invoked method.public @Nullable Void visitBlock(@Nullable BlockTree node, @Nullable Void p)
visitBlock
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitBlock
in class TreeScanner<@Nullable Void,@Nullable Void>
public @Nullable Void visitMethod(@Nullable MethodTree node, @Nullable Void p)
visitMethod
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitMethod
in class TreeScanner<@Nullable Void,@Nullable Void>
public void visitMethodEndCallback(@Nullable MethodTree node)
node
- public @Nullable Void visitArrayAccess(ArrayAccessTree node, @Nullable Void p)
visitArrayAccess
in interface TreeVisitor<@Nullable Void,@Nullable Void>
visitArrayAccess
in class TreeScanner<@Nullable Void,@Nullable Void>
protected boolean varDefHasAnnotation(@Nullable MethodTree enclMeth, @Nullable AnnotationMirror annotation, @Nullable Element var)
enclMeth
- the method within which the check happens;
null e.g. in field initializersannotation
- the annotation to check forvar
- the variable to check