MaybeReachingVariableUse( ControlFlowGraph<Node> cfg, Scope jsScope, AbstractCompiler compiler) { super(cfg, new ReachingUsesJoinOp()); this.jsScope = jsScope; this.escaped = new HashSet<Var>(); // TODO(user): Maybe compute it somewhere else and re-use the escape // local set here. computeEscaped(jsScope, escaped, compiler); }
@Override ReachingUses flowThrough(Node n, ReachingUses input) { ReachingUses output = new ReachingUses(input); // If there's an ON_EX edge, this cfgNode may or may not get executed. // We can express this concisely by just pretending this happens in // a conditional. boolean conditional = hasExceptionHandler(n); computeMayUse(n, n, output, conditional); return output; }
private boolean hasExceptionHandler(Node cfgNode) { List<DiGraphEdge<Node, Branch>> branchEdges = getCfg().getOutEdges(cfgNode); for (DiGraphEdge<Node, Branch> edge : branchEdges) { if (edge.getValue() == Branch.ON_EX) { return true; } } return false; }
addToUseIfLocal(n.getString(), cfgNode, output); return; case Token.DO: case Token.IF: computeMayUse( NodeUtil.getConditionExpression(n), cfgNode, output, conditional); return; computeMayUse( NodeUtil.getConditionExpression(n), cfgNode, output, conditional); } else { removeFromUseIfLocal(lhs.getString(), output); computeMayUse(rhs, cfgNode, output, conditional); computeMayUse(n.getLastChild(), cfgNode, output, true); computeMayUse(n.getFirstChild(), cfgNode, output, conditional); return; computeMayUse(n.getLastChild(), cfgNode, output, true); computeMayUse(n.getSecondChild(), cfgNode, output, true); computeMayUse(n.getFirstChild(), cfgNode, output, conditional); return; computeMayUse(varName.getFirstChild(), cfgNode, output, conditional); if (!conditional) { removeFromUseIfLocal(varName.getString(), output);
reachingUses = new MaybeReachingVariableUse(cfg, t.getScope(), compiler); reachingUses.analyze(); while (!candidates.isEmpty()) { Candidate c = candidates.iterator().next();
Collection<Node> uses = reachingUses.getUses(varName, getDefCfgNode());
if (NodeUtil.isLhsByDestructuring(n)) { if (!conditional) { removeFromUseIfLocal(n.getString(), output); addToUseIfLocal(n.getString(), cfgNode, output); case IF: case FOR: computeMayUse(NodeUtil.getConditionExpression(n), cfgNode, output, conditional); return; removeFromUseIfLocal(lhs.getString(), output); } else if (lhs.isDestructuringPattern()) { computeMayUse(lhs, cfgNode, output, true); computeMayUse(rhs, cfgNode, output, conditional); return; computeMayUse(n.getLastChild(), cfgNode, output, true); computeMayUse(n.getFirstChild(), cfgNode, output, conditional); return; computeMayUse(n.getLastChild(), cfgNode, output, true); computeMayUse(n.getSecondChild(), cfgNode, output, true); computeMayUse(n.getFirstChild(), cfgNode, output, conditional); return; computeMayUse(varName.getFirstChild(), cfgNode, output, conditional); computeMayUse(varName.getSecondChild(), cfgNode, output, conditional);
reachingUses = new MaybeReachingVariableUse(cfg, t.getScope(), compiler, scopeCreator); reachingUses.analyze(); while (!candidates.isEmpty()) { Candidate c = candidates.iterator().next();
Collection<Node> uses = reachingUses.getUses(varName, getDefCfgNode());
@Override ReachingUses flowThrough(Node n, ReachingUses input) { ReachingUses output = new ReachingUses(input); // If there's an ON_EX edge, this cfgNode may or may not get executed. // We can express this concisely by just pretending this happens in // a conditional. boolean conditional = hasExceptionHandler(n); computeMayUse(n, n, output, conditional); return output; }
private boolean hasExceptionHandler(Node cfgNode) { List<DiGraphEdge<Node, Branch>> branchEdges = getCfg().getOutEdges(cfgNode); for (DiGraphEdge<Node, Branch> edge : branchEdges) { if (edge.getValue() == Branch.ON_EX) { return true; } } return false; }
MaybeReachingVariableUse( ControlFlowGraph<Node> cfg, Scope jsScope, AbstractCompiler compiler, Es6SyntacticScopeCreator scopeCreator) { super(cfg, new ReachingUsesJoinOp()); this.escaped = new HashSet<>(); this.allVarsInFn = new HashMap<>(); this.orderedVars = new ArrayList<>(); // TODO(user): Maybe compute it somewhere else and re-use the escape // local set here. computeEscaped(jsScope.getParent(), escaped, compiler, scopeCreator); NodeUtil.getAllVarsDeclaredInFunction( allVarsInFn, orderedVars, compiler, scopeCreator, jsScope.getParent()); }
/** * Gets a list of nodes that may be using the value assigned to {@code name} * in {@code defNode}. {@code defNode} must be one of the control flow graph * nodes. * * @param name name of the variable. It can only be names of local variable * that are not function parameters, escaped variables or variables * declared in catch. * @param defNode The list of upward exposed use for the variable. */ Collection<Node> getUses(String name, Node defNode) { GraphNode<Node, Branch> n = getCfg().getNode(defNode); checkNotNull(n); FlowState<ReachingUses> state = n.getAnnotation(); return state.getOut().mayUseMap.get(allVarsInFn.get(name)); } }
/** * Gets a list of nodes that may be using the value assigned to {@code name} * in {@code defNode}. {@code defNode} must be one of the control flow graph * nodes. * * @param name name of the variable. It can only be names of local variable * that are not function parameters, escaped variables or variables * declared in catch. * @param defNode The list of upward exposed use for the variable. */ Collection<Node> getUses(String name, Node defNode) { GraphNode<Node, Branch> n = getCfg().getNode(defNode); Preconditions.checkNotNull(n); FlowState<ReachingUses> state = n.getAnnotation(); return state.getOut().mayUseMap.get(jsScope.getVar(name)); } }