checkers.flow
Class Flow

java.lang.Object
  extended by com.sun.source.util.TreeScanner<R,P>
      extended by com.sun.source.util.TreePathScanner<Void,Void>
          extended by checkers.flow.Flow
All Implemented Interfaces:
TreeVisitor<Void,Void>

public class Flow
extends TreePathScanner<Void,Void>

Provides a generalized flow-sensitive qualifier inference for the checkers framework.

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:

  1. It performs a GEN-KILL analysis for qualifiers that is similar to the initialization/uninitialization analysis in javac's Flow. It does not perform exception analysis, and performs liveness analysis only to the extent required for the GEN-KILL analysis.
  2. Whenever possible, this implementation prefers the use of classes in the public API (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).
As in 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.Tree) for analyzing conditions and handling branching.

A separate instance of the analysis must be created for each compilation unit.


Field Summary
Modifier and Type Field and Description
protected  QualifierHierarchy annoRelations
          The hierarchy for the type qualifiers that this class infers.
protected  GenKillBits<AnnotationMirror> annos
          Tracks the annotated state of each variable during flow.
protected  GenKillBits<AnnotationMirror> annosWhenFalse
          Tracks the annotated state of each variable in a false branch.
protected  GenKillBits<AnnotationMirror> annosWhenTrue
          Tracks the annotated state of each variable in a true branch.
protected  Set<AnnotationMirror> annotations
          The annotations (qualifiers) to infer.
protected  AnnotatedTypes atypes
          Utility class for operations on annotated types.
protected  SourceChecker checker
          The checker to which this instance belongs.
protected  Elements elements
          Utilities for Elements.
protected  ProcessingEnvironment env
          The processing environment to use.
protected  AnnotatedTypeFactory factory
          Utility class for determining annotated types.
protected  Map<Tree,AnnotationMirror> flowResults
          Stores the results of the analysis (source location to qualifier).
protected  CompilationUnitTree root
          The file that's being analyzed.
protected  List<VariableElement> vars
          Maps variables to a bit index.
 
Constructor Summary
Constructor and Description
Flow(BaseTypeChecker checker, CompilationUnitTree root, Set<AnnotationMirror> annotations, AnnotatedTypeFactory factory)
          Creates a new analysis.
 
Method Summary
Modifier and Type Method and Description
protected static boolean containsKey(Tree tree, Collection<String> keys)
           
protected  void merge()
          Merge the bitset after a conditional branch.
protected  void popLastLevel()
           
protected  void pushNewLevel()
           
protected  void recordBits(TreePath path)
          Record the value of the annotation bit for the given usage of a variable, so that a type-checker may use its value after the analysis has finished.
 Void scan(Tree tree, Void p)
           
protected  void scanCond(Tree tree)
          Called whenever a conditional expression is scanned.
protected  void scanDef(Tree tree)
          Called whenever a definition is scanned.
protected  void scanExpr(ExpressionTree tree)
          Called whenever an expression is scanned.
protected  void scanStat(StatementTree tree)
          Called whenever a statement is scanned.
protected  void scanStats(List<? extends StatementTree> trees)
          Called whenever a block of statements is scanned.
 void setDebug(PrintStream debug)
          Sets the PrintStream for printing debug messages, such as System.out or System.err, or null if no debugging output should be emitted.
protected  void split()
          Split the bitset before a conditional branch.
 AnnotationMirror test(Tree tree)
          Determines the inference result for tree.
 Void visitAnnotation(AnnotationTree tree, Void p)
           
 Void visitAssert(AssertTree node, Void p)
           
 Void visitAssignment(AssignmentTree node, Void p)
           
 Void visitBlock(BlockTree node, Void p)
           
 Void visitBreak(BreakTree node, Void p)
           
 Void visitClass(ClassTree node, Void p)
           
 Void visitCompoundAssignment(CompoundAssignmentTree node, Void p)
           
 Void visitConditionalExpression(ConditionalExpressionTree node, Void p)
           
 Void visitContinue(ContinueTree node, Void p)
           
 Void visitDoWhileLoop(DoWhileLoopTree node, Void p)
           
 Void visitEnhancedForLoop(EnhancedForLoopTree node, Void p)
           
 Void visitForLoop(ForLoopTree node, Void p)
           
 Void visitIdentifier(IdentifierTree node, Void p)
           
 Void visitIf(IfTree node, Void p)
           
 Void visitImport(ImportTree tree, Void p)
           
 Void visitMemberSelect(MemberSelectTree node, Void p)
           
 Void visitMethod(MethodTree node, Void p)
           
 Void visitMethodInvocation(MethodInvocationTree node, Void p)
           
 Void visitReturn(ReturnTree node, Void p)
           
 Void visitThrow(ThrowTree node, Void p)
           
 Void visitTry(TryTree node, Void p)
           
 Void visitTypeCast(TypeCastTree node, Void p)
           
 Void visitVariable(VariableTree node, Void p)
           
 Void visitWhileLoop(WhileLoopTree node, Void p)
           
 
Methods inherited from class com.sun.source.util.TreePathScanner
getCurrentPath, scan
 
Methods inherited from class com.sun.source.util.TreeScanner
reduce, scan, visitAnnotatedType, visitArrayAccess, visitArrayType, visitBinary, visitCase, visitCatch, visitCompilationUnit, visitEmptyStatement, visitErroneous, visitExpressionStatement, visitInstanceOf, visitLabeledStatement, visitLiteral, visitModifiers, visitNewArray, visitNewClass, visitOther, visitParameterizedType, visitParenthesized, visitPrimitiveType, visitSwitch, visitSynchronized, visitTypeParameter, visitUnary, visitWildcard
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

checker

protected final SourceChecker checker
The checker to which this instance belongs.


env

protected final ProcessingEnvironment env
The processing environment to use.


root

protected final CompilationUnitTree root
The file that's being analyzed.


annotations

protected final Set<AnnotationMirror> annotations
The annotations (qualifiers) to infer. The relationship among them is determined using BaseTypeChecker.getQualifierHierarchy(). By consulting the hierarchy, the analysis will only infer a qualifier on a type if it is more restrictive (i.e. a subtype) than the existing qualifier for that type.


factory

protected final AnnotatedTypeFactory factory
Utility class for determining annotated types.


atypes

protected final AnnotatedTypes atypes
Utility class for operations on annotated types.


vars

protected final List<VariableElement> vars
Maps variables to a bit index. This index is also used as the bit index to determine a variable's annotatedness using annos/annosWhenTrue/annosWhenFalse.


flowResults

protected final Map<Tree,AnnotationMirror> flowResults
Stores the results of the analysis (source location to qualifier).


annos

protected GenKillBits<AnnotationMirror> annos
Tracks the annotated state of each variable during flow. Bit indices correspond exactly to indices in vars. This field is set to null immediately after splitting for a branch, and is set to some combination (usually boolean "and") of annosWhenTrue and annosWhenFalse after merging. Since it is used when visiting the true and false branches, however, it may be non-null concurrently with annosWhenTrue and annosWhenFalse.


annosWhenTrue

protected GenKillBits<AnnotationMirror> annosWhenTrue
Tracks the annotated state of each variable in a true branch. As in javac's Flow, saving/restoring via local variables handles nested branches. Bit indices correspond exactly to indices in vars. This field is copied from annos when splitting for a branch and is set to null immediately after merging.

See Also:
annos

annosWhenFalse

protected GenKillBits<AnnotationMirror> annosWhenFalse
Tracks the annotated state of each variable in a false branch. As in javac's Flow, saving/restoring via local variables handles nested branches. Bit indices correspond exactly to indices in vars. This field is copied from annos when splitting for a branch and is set to null immediately after merging.

See Also:
annos

annoRelations

protected final QualifierHierarchy annoRelations
The hierarchy for the type qualifiers that this class infers.


elements

protected final Elements elements
Utilities for Elements.

Constructor Detail

Flow

public Flow(BaseTypeChecker checker,
            CompilationUnitTree root,
            Set<AnnotationMirror> annotations,
            AnnotatedTypeFactory factory)
Creates a new analysis. The analysis will use the given AnnotatedTypeFactory to obtain annotated types.

Parameters:
checker - the current checker
root - the compilation unit that will be scanned
annotations - the annotations to track
factory - the factory class that will be used to get annotated types, or null if the default factory should be used
Method Detail

setDebug

public void setDebug(PrintStream debug)
Sets the PrintStream for printing debug messages, such as System.out or System.err, or null if no debugging output should be emitted.


scan

public Void scan(Tree tree,
                 Void p)
Overrides:
scan in class TreePathScanner<Void,Void>

test

public AnnotationMirror test(Tree tree)
Determines the inference result for tree.

Parameters:
tree - the tree to test
Returns:
the annotation inferred for a tree, or null if no annotation was inferred for that tree

split

protected void split()
Split the bitset before a conditional branch.


merge

protected void merge()
Merge the bitset after a conditional branch.


recordBits

protected void recordBits(TreePath path)
Record the value of the annotation bit for the given usage of a variable, so that a type-checker may use its value after the analysis has finished.

Parameters:
path -

scanDef

protected void scanDef(Tree tree)
Called whenever a definition is scanned.

Parameters:
tree - the definition being scanned

scanStat

protected void scanStat(StatementTree tree)
Called whenever a statement is scanned.

Parameters:
tree - the statement being scanned

scanStats

protected void scanStats(List<? extends StatementTree> trees)
Called whenever a block of statements is scanned.

Parameters:
trees - the statements being scanned

scanCond

protected void scanCond(Tree tree)
Called whenever a conditional expression is scanned.

Parameters:
tree - the condition being scanned

scanExpr

protected void scanExpr(ExpressionTree tree)
Called whenever an expression is scanned.

Parameters:
tree - the expression being scanned

visitClass

public Void visitClass(ClassTree node,
                       Void p)
Specified by:
visitClass in interface TreeVisitor<Void,Void>
Overrides:
visitClass in class TreeScanner<Void,Void>

visitImport

public Void visitImport(ImportTree tree,
                        Void p)
Specified by:
visitImport in interface TreeVisitor<Void,Void>
Overrides:
visitImport in class TreeScanner<Void,Void>

visitTypeCast

public Void visitTypeCast(TypeCastTree node,
                          Void p)
Specified by:
visitTypeCast in interface TreeVisitor<Void,Void>
Overrides:
visitTypeCast in class TreeScanner<Void,Void>

visitAnnotation

public Void visitAnnotation(AnnotationTree tree,
                            Void p)
Specified by:
visitAnnotation in interface TreeVisitor<Void,Void>
Overrides:
visitAnnotation in class TreeScanner<Void,Void>

visitIdentifier

public Void visitIdentifier(IdentifierTree node,
                            Void p)
Specified by:
visitIdentifier in interface TreeVisitor<Void,Void>
Overrides:
visitIdentifier in class TreeScanner<Void,Void>

visitMemberSelect

public Void visitMemberSelect(MemberSelectTree node,
                              Void p)
Specified by:
visitMemberSelect in interface TreeVisitor<Void,Void>
Overrides:
visitMemberSelect in class TreeScanner<Void,Void>

visitVariable

public Void visitVariable(VariableTree node,
                          Void p)
Specified by:
visitVariable in interface TreeVisitor<Void,Void>
Overrides:
visitVariable in class TreeScanner<Void,Void>

visitAssignment

public Void visitAssignment(AssignmentTree node,
                            Void p)
Specified by:
visitAssignment in interface TreeVisitor<Void,Void>
Overrides:
visitAssignment in class TreeScanner<Void,Void>

visitCompoundAssignment

public Void visitCompoundAssignment(CompoundAssignmentTree node,
                                    Void p)
Specified by:
visitCompoundAssignment in interface TreeVisitor<Void,Void>
Overrides:
visitCompoundAssignment in class TreeScanner<Void,Void>

visitEnhancedForLoop

public Void visitEnhancedForLoop(EnhancedForLoopTree node,
                                 Void p)
Specified by:
visitEnhancedForLoop in interface TreeVisitor<Void,Void>
Overrides:
visitEnhancedForLoop in class TreeScanner<Void,Void>

containsKey

protected static boolean containsKey(Tree tree,
                                     Collection<String> keys)

pushNewLevel

protected void pushNewLevel()

popLastLevel

protected void popLastLevel()

visitAssert

public Void visitAssert(AssertTree node,
                        Void p)
Specified by:
visitAssert in interface TreeVisitor<Void,Void>
Overrides:
visitAssert in class TreeScanner<Void,Void>

visitIf

public Void visitIf(IfTree node,
                    Void p)
Specified by:
visitIf in interface TreeVisitor<Void,Void>
Overrides:
visitIf in class TreeScanner<Void,Void>

visitConditionalExpression

public Void visitConditionalExpression(ConditionalExpressionTree node,
                                       Void p)
Specified by:
visitConditionalExpression in interface TreeVisitor<Void,Void>
Overrides:
visitConditionalExpression in class TreeScanner<Void,Void>

visitWhileLoop

public Void visitWhileLoop(WhileLoopTree node,
                           Void p)
Specified by:
visitWhileLoop in interface TreeVisitor<Void,Void>
Overrides:
visitWhileLoop in class TreeScanner<Void,Void>

visitDoWhileLoop

public Void visitDoWhileLoop(DoWhileLoopTree node,
                             Void p)
Specified by:
visitDoWhileLoop in interface TreeVisitor<Void,Void>
Overrides:
visitDoWhileLoop in class TreeScanner<Void,Void>

visitForLoop

public Void visitForLoop(ForLoopTree node,
                         Void p)
Specified by:
visitForLoop in interface TreeVisitor<Void,Void>
Overrides:
visitForLoop in class TreeScanner<Void,Void>

visitBreak

public Void visitBreak(BreakTree node,
                       Void p)
Specified by:
visitBreak in interface TreeVisitor<Void,Void>
Overrides:
visitBreak in class TreeScanner<Void,Void>

visitContinue

public Void visitContinue(ContinueTree node,
                          Void p)
Specified by:
visitContinue in interface TreeVisitor<Void,Void>
Overrides:
visitContinue in class TreeScanner<Void,Void>

visitReturn

public Void visitReturn(ReturnTree node,
                        Void p)
Specified by:
visitReturn in interface TreeVisitor<Void,Void>
Overrides:
visitReturn in class TreeScanner<Void,Void>

visitThrow

public Void visitThrow(ThrowTree node,
                       Void p)
Specified by:
visitThrow in interface TreeVisitor<Void,Void>
Overrides:
visitThrow in class TreeScanner<Void,Void>

visitTry

public Void visitTry(TryTree node,
                     Void p)
Specified by:
visitTry in interface TreeVisitor<Void,Void>
Overrides:
visitTry in class TreeScanner<Void,Void>

visitMethodInvocation

public Void visitMethodInvocation(MethodInvocationTree node,
                                  Void p)
Specified by:
visitMethodInvocation in interface TreeVisitor<Void,Void>
Overrides:
visitMethodInvocation in class TreeScanner<Void,Void>

visitBlock

public Void visitBlock(BlockTree node,
                       Void p)
Specified by:
visitBlock in interface TreeVisitor<Void,Void>
Overrides:
visitBlock in class TreeScanner<Void,Void>

visitMethod

public Void visitMethod(MethodTree node,
                        Void p)
Specified by:
visitMethod in interface TreeVisitor<Void,Void>
Overrides:
visitMethod in class TreeScanner<Void,Void>