final class ControlFlowAnalysis extends java.lang.Object implements NodeTraversal.Callback, CompilerPass
Modifier and Type | Class and Description |
---|---|
private static class |
ControlFlowAnalysis.AstControlFlowGraph
A
ControlFlowGraph which provides a node comparator based on the
pre-order traversal of the AST. |
Modifier and Type | Field and Description |
---|---|
private java.util.Map<Node,java.lang.Integer> |
astPosition |
private int |
astPositionCounter |
private ControlFlowGraph<Node> |
cfg |
private AbstractCompiler |
compiler
Based roughly on the first few pages of
"Declarative Intraprocedural Flow Analysis of Java Source Code by
Nilsson-Nyman, Hedin, Magnusson & Ekman",
this pass computes the control flow graph from the AST.
|
private boolean |
edgeAnnotations |
private java.util.Deque<Node> |
exceptionHandler |
private com.google.common.collect.Multimap<Node,Node> |
finallyMap |
private java.util.Map<DiGraph.DiGraphNode<Node,ControlFlowGraph.Branch>,java.lang.Integer> |
nodePriorities |
private java.util.Comparator<DiGraph.DiGraphNode<Node,ControlFlowGraph.Branch>> |
priorityComparator |
private int |
priorityCounter |
private Node |
root |
private boolean |
shouldTraverseFunctionsAndClasses |
Constructor and Description |
---|
ControlFlowAnalysis(AbstractCompiler compiler,
boolean shouldTraverseFunctionsAndClasses,
boolean edgeAnnotations)
Constructor.
|
Modifier and Type | Method and Description |
---|---|
(package private) static Node |
computeFallThrough(Node n)
Computes the destination node of n when we want to fallthrough into the
subtree of n.
|
(package private) static Node |
computeFollowNode(Node node) |
(package private) static Node |
computeFollowNode(Node node,
ControlFlowAnalysis cfa) |
private static Node |
computeFollowNode(Node fromNode,
Node node,
ControlFlowAnalysis cfa)
Computes the follow() node of a given node and its parent.
|
private void |
connectToPossibleExceptionHandler(Node cfgNode,
Node target)
Connects cfgNode to the proper CATCH block if target subtree might throw
an exception.
|
private void |
createEdge(Node fromNode,
ControlFlowGraph.Branch branch,
Node toNode)
Connects the two nodes in the control flow graph.
|
(package private) static Node |
getCatchHandlerForBlock(Node block)
Locate the catch BLOCK given the first block in a TRY.
|
(package private) ControlFlowGraph<Node> |
getCfg() |
(package private) static Node |
getExceptionHandler(Node n)
Get the TRY block with a CATCH that would be run if n throws an exception.
|
private static Node |
getNextSiblingOfType(Node first,
int... types)
Get the next sibling (including itself) of one of the given types.
|
private void |
handleBreak(Node node) |
private void |
handleCase(Node node) |
private void |
handleCatch(Node node) |
private void |
handleContinue(Node node) |
private void |
handleDefault(Node node) |
private void |
handleDo(Node node) |
private void |
handleExpr(Node node) |
private void |
handleFor(Node forNode) |
private void |
handleFunction(Node node) |
private void |
handleIf(Node node) |
private void |
handleReturn(Node node) |
private void |
handleStmt(Node node) |
private void |
handleStmtList(Node node) |
private void |
handleSwitch(Node node) |
private void |
handleThrow(Node node) |
private void |
handleTry(Node node) |
private void |
handleWhile(Node node) |
private void |
handleWith(Node node) |
(package private) static boolean |
isBreakStructure(Node n,
boolean labeled)
Determines whether the given node can be terminated with a BREAK node.
|
static boolean |
isBreakTarget(Node target,
java.lang.String label)
Checks if target is actually the break target of labeled continue.
|
(package private) static boolean |
isContinueStructure(Node n)
Determines whether the given node can be advanced with a CONTINUE node.
|
(package private) static boolean |
isContinueTarget(Node target,
java.lang.String label)
Checks if target is actually the continue target of labeled continue.
|
private static boolean |
matchLabel(Node target,
java.lang.String label)
Check if label is actually referencing the target control structure.
|
static boolean |
mayThrowException(Node n)
Determines if the subtree might throw an exception.
|
private void |
prioritizeFromEntryNode(DiGraph.DiGraphNode<Node,ControlFlowGraph.Branch> entry)
Given an entry node, find all the nodes reachable from that node
and prioritize them.
|
void |
process(Node externs,
Node root)
Process the JS with root node root.
|
boolean |
shouldTraverse(NodeTraversal nodeTraversal,
Node n,
Node parent)
Visits a node in pre order (before visiting its children) and decides
whether this node's children should be traversed.
|
void |
visit(NodeTraversal t,
Node n,
Node parent)
Visits a node in postorder (after its children have been visited).
|
private final AbstractCompiler compiler
private ControlFlowGraph<Node> cfg
private java.util.Map<Node,java.lang.Integer> astPosition
private java.util.Map<DiGraph.DiGraphNode<Node,ControlFlowGraph.Branch>,java.lang.Integer> nodePriorities
private final java.util.Comparator<DiGraph.DiGraphNode<Node,ControlFlowGraph.Branch>> priorityComparator
private int astPositionCounter
private int priorityCounter
private final boolean shouldTraverseFunctionsAndClasses
private final boolean edgeAnnotations
private Node root
private final java.util.Deque<Node> exceptionHandler
ControlFlowAnalysis(AbstractCompiler compiler, boolean shouldTraverseFunctionsAndClasses, boolean edgeAnnotations)
compiler
- Compiler instance.shouldTraverseFunctions
- Whether functions should be traversededgeAnnotations
- Whether to allow edge annotations.ControlFlowGraph<Node> getCfg()
public void process(Node externs, Node root)
CompilerPass
process
in interface CompilerPass
externs
- Top of external JS treeroot
- Top of JS treeprivate void prioritizeFromEntryNode(DiGraph.DiGraphNode<Node,ControlFlowGraph.Branch> entry)
public boolean shouldTraverse(NodeTraversal nodeTraversal, Node n, Node parent)
NodeTraversal.Callback
Visits a node in pre order (before visiting its children) and decides
whether this node's children should be traversed. If children are
traversed, they will be visited by
NodeTraversal.Callback.visit(NodeTraversal, Node, Node)
in postorder.
Implementations can have side effects (e.g. modifying the parse tree).
shouldTraverse
in interface NodeTraversal.Callback
public void visit(NodeTraversal t, Node n, Node parent)
NodeTraversal.Callback
Visits a node in postorder (after its children have been visited).
A node is visited only if all its parents should be traversed
(NodeTraversal.Callback.shouldTraverse(NodeTraversal, Node, Node)
).
Implementations can have side effects (e.g. modifying the parse tree).
visit
in interface NodeTraversal.Callback
private void handleIf(Node node)
private void handleWhile(Node node)
private void handleDo(Node node)
private void handleFor(Node forNode)
private void handleSwitch(Node node)
private void handleCase(Node node)
private void handleDefault(Node node)
private void handleWith(Node node)
private void handleStmtList(Node node)
private void handleFunction(Node node)
private void handleExpr(Node node)
private void handleThrow(Node node)
private void handleTry(Node node)
private void handleCatch(Node node)
private void handleBreak(Node node)
private void handleContinue(Node node)
private void handleReturn(Node node)
private void handleStmt(Node node)
static Node computeFollowNode(Node node, ControlFlowAnalysis cfa)
private static Node computeFollowNode(Node fromNode, Node node, ControlFlowAnalysis cfa)
fromNode
- The original source node since node
is changed
during recursion.node
- The node that follow() should compute.static Node computeFallThrough(Node n)
private void createEdge(Node fromNode, ControlFlowGraph.Branch branch, Node toNode)
fromNode
- Source.toNode
- Destination.private void connectToPossibleExceptionHandler(Node cfgNode, Node target)
private static Node getNextSiblingOfType(Node first, int... types)
public static boolean isBreakTarget(Node target, java.lang.String label)
static boolean isContinueTarget(Node target, java.lang.String label)
private static boolean matchLabel(Node target, java.lang.String label)
public static boolean mayThrowException(Node n)
static boolean isBreakStructure(Node n, boolean labeled)
static boolean isContinueStructure(Node n)
static Node getExceptionHandler(Node n)