|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectpolyglot.visit.NodeVisitor
polyglot.visit.HaltingVisitor
polyglot.visit.ErrorHandlingVisitor
polyglot.visit.DataFlow
polyglot.visit.InitChecker
public class InitChecker
Visitor which checks that all local variables must be defined before use, and that final variables and fields are initialized correctly. The checking of the rules is implemented in the methods leaveCall(Node) and check(FlowGraph, Term, Item, Item).
Nested Class Summary | |
---|---|
protected static class |
InitChecker.ClassBodyInfo
This class is just a data structure containing relevant information needed for performing initialization checking of a class declaration. |
protected static class |
InitChecker.InitCount
Class representing the initialization counts of variables. |
protected static class |
InitChecker.MinMaxInitCount
Class to record counts of the minimum and maximum number of times a variable or field has been initialized or assigned to. |
Nested classes/interfaces inherited from class polyglot.visit.DataFlow |
---|
DataFlow.BoolItem, DataFlow.ConditionNavigator, DataFlow.FlowGraphSource, DataFlow.Item |
Field Summary | |
---|---|
protected static DataFlow.Item |
BOTTOM
|
protected InitChecker.ClassBodyInfo |
currCBI
|
Fields inherited from class polyglot.visit.DataFlow |
---|
dataflowOnEntry, flowCounter, flowgraphStack, forward |
Fields inherited from class polyglot.visit.ErrorHandlingVisitor |
---|
error, job, nf, ts |
Constructor Summary | |
---|---|
InitChecker(Job job,
TypeSystem ts,
NodeFactory nf)
|
Method Summary | |
---|---|
void |
check(FlowGraph graph,
Term n,
DataFlow.Item inItem,
java.util.Map outItems)
Check that the conditions of initialization are not broken. |
protected void |
checkFieldAssign(FlowGraph graph,
FieldAssign a,
polyglot.visit.InitChecker.DataFlowItem dfIn,
polyglot.visit.InitChecker.DataFlowItem dfOut)
Check that the assignment to a field is correct. |
protected void |
checkLocal(FlowGraph graph,
Local l,
polyglot.visit.InitChecker.DataFlowItem dfIn,
polyglot.visit.InitChecker.DataFlowItem dfOut)
Check that the local variable l is used correctly. |
protected void |
checkLocalAssign(FlowGraph graph,
LocalAssign a,
polyglot.visit.InitChecker.DataFlowItem dfIn,
polyglot.visit.InitChecker.DataFlowItem dfOut)
Check that the assignment to a local variable is correct. |
protected void |
checkLocalsUsedByInnerClass(FlowGraph graph,
ClassBody cb,
java.util.Set localsUsed,
polyglot.visit.InitChecker.DataFlowItem dfIn,
polyglot.visit.InitChecker.DataFlowItem dfOut)
Check that the set of LocalInstance s
localsUsed , which is the set of locals used in the inner
class declared by cb
are initialized before the class declaration. |
protected void |
checkNonStaticFinalFieldsInit(ClassBody cb)
Check that each non static final field has been initialized exactly once, taking into account the fact that constructors may call other constructors. |
protected void |
checkStaticFinalFieldsInit(ClassBody cb)
Check that each static final field is initialized exactly once. |
protected DataFlow.Item |
confluence(java.util.List items,
java.util.List itemKeys,
Term node,
FlowGraph graph)
The confluence operator for Initializer s and
Constructor s needs to be a
little special, as we are only concerned with non-exceptional flows in
these cases. |
DataFlow.Item |
confluence(java.util.List inItems,
Term node,
FlowGraph graph)
The confluence operator is essentially the union of all of the inItems. |
DataFlow.Item |
createInitialItem(FlowGraph graph,
Term node)
The initial item to be given to the entry point of the dataflow contains the init counts for the final fields. |
protected void |
dataflow(Expr root)
Construct a flow graph for the Expr provided, and call
dataflow(FlowGraph) . |
protected NodeVisitor |
enterCall(Node n)
Overridden superclass method. |
protected void |
finishConstructorDecl(FlowGraph graph,
ConstructorDecl cd,
polyglot.visit.InitChecker.DataFlowItem dfIn,
polyglot.visit.InitChecker.DataFlowItem dfOut)
Perform necessary actions upon seeing the ConstructorDecl cd . |
protected void |
finishInitializer(FlowGraph graph,
Initializer initializer,
polyglot.visit.InitChecker.DataFlowItem dfIn,
polyglot.visit.InitChecker.DataFlowItem dfOut)
Perform necessary actions upon seeing the Initializer initializer . |
java.util.Map |
flow(DataFlow.Item trueItem,
DataFlow.Item falseItem,
DataFlow.Item otherItem,
FlowGraph graph,
Term n,
java.util.Set succEdgeKeys)
Perform the appropriate flow operations for the Terms. |
protected java.util.Map |
flow(java.util.List inItems,
java.util.List inItemKeys,
FlowGraph graph,
Term n,
java.util.Set edgeKeys)
Produce new Item s as appropriate for the
Term n and the input Item s. |
protected java.util.Map |
flowConstructorCall(polyglot.visit.InitChecker.DataFlowItem inItem,
FlowGraph graph,
ConstructorCall cc,
java.util.Set succEdgeKeys)
Perform the appropriate flow operations for a constructor call |
protected java.util.Map |
flowFieldAssign(polyglot.visit.InitChecker.DataFlowItem inItem,
FlowGraph graph,
FieldAssign a,
java.util.Set succEdgeKeys)
Perform the appropriate flow operations for assignment to a field |
protected java.util.Map |
flowFormal(polyglot.visit.InitChecker.DataFlowItem inItem,
FlowGraph graph,
Formal f,
java.util.Set succEdgeKeys)
Perform the appropriate flow operations for declaration of a formal parameter |
protected java.util.Map |
flowLocalAssign(polyglot.visit.InitChecker.DataFlowItem inItem,
FlowGraph graph,
LocalAssign a,
java.util.Set succEdgeKeys)
Perform the appropriate flow operations for assignment to a local variable |
protected java.util.Map |
flowLocalDecl(polyglot.visit.InitChecker.DataFlowItem inItem,
FlowGraph graph,
LocalDecl ld,
java.util.Set succEdgeKeys)
Perform the appropriate flow operations for declaration of a local variable |
protected FlowGraph |
initGraph(CodeDecl code,
Term root)
Initialise the FlowGraph to be used in the dataflow analysis. |
protected boolean |
isFieldsTargetAppropriate(Field f)
Determine if we are interested in this field on the basis of the target of the field. |
Node |
leaveCall(Node n)
Postpone the checking of constructors until the end of the class declaration is encountered, to ensure that all initializers are processed first. |
protected void |
setupClassBody(ClassBody n)
|
Methods inherited from class polyglot.visit.DataFlow |
---|
constructItemsFromCondition, createCFGBuilder, currentFlowGraph, dataflow, dataflow, dumpFlowGraph, filterItems, filterItemsExceptionSubclass, filterItemsNonError, filterItemsNonException, findSCCs, flow, flowBooleanConditions, flowToBooleanFlow, hasTrueFalseBranches, itemsToMap, itemToMap, leave, post, safeConfluence, safeConfluence, safeConfluence |
Methods inherited from class polyglot.visit.ErrorHandlingVisitor |
---|
begin, catchErrors, enter, enterCall, enterError, errorQueue, job, leaveCall, nodeFactory, typeSystem |
Methods inherited from class polyglot.visit.HaltingVisitor |
---|
bypass, bypass, bypassChildren, copy, override, visitChildren |
Methods inherited from class polyglot.visit.NodeVisitor |
---|
enter, finish, finish, leave, override, toString, visitEdge |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
Field Detail |
---|
protected InitChecker.ClassBodyInfo currCBI
protected static final DataFlow.Item BOTTOM
Constructor Detail |
---|
public InitChecker(Job job, TypeSystem ts, NodeFactory nf)
Method Detail |
---|
protected FlowGraph initGraph(CodeDecl code, Term root)
initGraph
in class DataFlow
protected NodeVisitor enterCall(Node n) throws SemanticException
enterCall
in class DataFlow
SemanticException
public Node leaveCall(Node n) throws SemanticException
leaveCall
in class DataFlow
SemanticException
protected void setupClassBody(ClassBody n) throws SemanticException
SemanticException
protected void checkStaticFinalFieldsInit(ClassBody cb) throws SemanticException
cb
- The ClassBody of the class declaring the fields to check.
SemanticException
protected void checkNonStaticFinalFieldsInit(ClassBody cb) throws SemanticException
cb
- The ClassBody of the class declaring the fields to check.
SemanticException
protected void dataflow(Expr root) throws SemanticException
Expr
provided, and call
dataflow(FlowGraph)
. Is also responsible for calling
post(FlowGraph, Term)
after
dataflow(FlowGraph)
has been called.
There is no need to push a CFG onto the stack, as dataflow is not
performed on entry in this analysis.
SemanticException
public DataFlow.Item createInitialItem(FlowGraph graph, Term node)
createInitialItem
in class DataFlow
protected DataFlow.Item confluence(java.util.List items, java.util.List itemKeys, Term node, FlowGraph graph)
Initializer
s and
Constructor
s needs to be a
little special, as we are only concerned with non-exceptional flows in
these cases.
This method ensures that a slightly different confluence is performed
for these Term
s, otherwise
confluence(List, Term)
is called instead.
confluence
in class DataFlow
items
- List of Item
s that flow into node
.
This method will only be called if the list has at least 2
elements.itemKeys
- List of FlowGraph.ExceptionEdgeKey
s for
the edges that the corresponding Item
s in
items
flowed from.node
- Term
for which the items
are
flowing into.
public DataFlow.Item confluence(java.util.List inItems, Term node, FlowGraph graph)
confluence
in class DataFlow
inItems
- List of Item
s that flow into node
.
this method will only be called if the list has at least 2
elements.node
- Term
for which the items
are
flowing into.
protected java.util.Map flow(java.util.List inItems, java.util.List inItemKeys, FlowGraph graph, Term n, java.util.Set edgeKeys)
DataFlow
Item
s as appropriate for the
Term n
and the input Item
s. The default
implementation of this method is simply to call confluence
for the list of inItems, and pass the result to flow(Item, FlowGraph,
Term, Set). Subclasses may want to override this method if a finer grain
dataflow is required. Some subclasses may wish to override this method
to call flowToBooleanFlow
.
flow
in class DataFlow
inItems
- all the Items flowing into the node.inItemKeys
- the FlowGraph.EdgeKeys for the items in the list inItemsgraph
- the FlowGraph which the dataflow is operating onn
- the Term which this method must calculate the flow for.edgeKeys
- a set of FlowGraph.EdgeKeys, being all the
EdgeKeys of the edges leaving this node. The
returned Map must have mappings for all objects in this set.
public java.util.Map flow(DataFlow.Item trueItem, DataFlow.Item falseItem, DataFlow.Item otherItem, FlowGraph graph, Term n, java.util.Set succEdgeKeys)
flow
in class DataFlow
protected java.util.Map flowFormal(polyglot.visit.InitChecker.DataFlowItem inItem, FlowGraph graph, Formal f, java.util.Set succEdgeKeys)
protected java.util.Map flowLocalDecl(polyglot.visit.InitChecker.DataFlowItem inItem, FlowGraph graph, LocalDecl ld, java.util.Set succEdgeKeys)
protected java.util.Map flowLocalAssign(polyglot.visit.InitChecker.DataFlowItem inItem, FlowGraph graph, LocalAssign a, java.util.Set succEdgeKeys)
protected java.util.Map flowFieldAssign(polyglot.visit.InitChecker.DataFlowItem inItem, FlowGraph graph, FieldAssign a, java.util.Set succEdgeKeys)
protected java.util.Map flowConstructorCall(polyglot.visit.InitChecker.DataFlowItem inItem, FlowGraph graph, ConstructorCall cc, java.util.Set succEdgeKeys)
protected boolean isFieldsTargetAppropriate(Field f)
public void check(FlowGraph graph, Term n, DataFlow.Item inItem, java.util.Map outItems) throws SemanticException
check
in class DataFlow
SemanticException
protected void finishInitializer(FlowGraph graph, Initializer initializer, polyglot.visit.InitChecker.DataFlowItem dfIn, polyglot.visit.InitChecker.DataFlowItem dfOut)
initializer
.
protected void finishConstructorDecl(FlowGraph graph, ConstructorDecl cd, polyglot.visit.InitChecker.DataFlowItem dfIn, polyglot.visit.InitChecker.DataFlowItem dfOut)
cd
.
protected void checkLocal(FlowGraph graph, Local l, polyglot.visit.InitChecker.DataFlowItem dfIn, polyglot.visit.InitChecker.DataFlowItem dfOut) throws SemanticException
l
is used correctly.
SemanticException
protected void checkLocalAssign(FlowGraph graph, LocalAssign a, polyglot.visit.InitChecker.DataFlowItem dfIn, polyglot.visit.InitChecker.DataFlowItem dfOut) throws SemanticException
SemanticException
protected void checkFieldAssign(FlowGraph graph, FieldAssign a, polyglot.visit.InitChecker.DataFlowItem dfIn, polyglot.visit.InitChecker.DataFlowItem dfOut) throws SemanticException
SemanticException
protected void checkLocalsUsedByInnerClass(FlowGraph graph, ClassBody cb, java.util.Set localsUsed, polyglot.visit.InitChecker.DataFlowItem dfIn, polyglot.visit.InitChecker.DataFlowItem dfOut) throws SemanticException
LocalInstance
s
localsUsed
, which is the set of locals used in the inner
class declared by cb
are initialized before the class declaration.
SemanticException
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |