public void analyze(final String variable, final DefiniteAssignmentStatus initialStatus) { this.variableName = variable; try { unassignedVariableUses.clear(); for (final DefiniteAssignmentNode node : allNodes) { node.setNodeStatus(DefiniteAssignmentStatus.CODE_UNREACHABLE); for (final ControlFlowEdge edge : node.getOutgoing()) { edgeStatus.put(edge, DefiniteAssignmentStatus.CODE_UNREACHABLE); } } changeNodeStatus(allNodes.get(analyzedRangeStart), initialStatus); while (!nodesWithModifiedInput.isEmpty()) { final DefiniteAssignmentNode node = nodesWithModifiedInput.poll(); DefiniteAssignmentStatus inputStatus = DefiniteAssignmentStatus.CODE_UNREACHABLE; for (final ControlFlowEdge edge : node.getIncoming()) { inputStatus = mergeStatus(inputStatus, edgeStatus.get(edge)); } changeNodeStatus(node, inputStatus); } } finally { this.variableName = null; } }
private void changeEdgeStatus(final ControlFlowEdge edge, final DefiniteAssignmentStatus newStatus) { final DefiniteAssignmentStatus oldStatus = edgeStatus.get(edge); if (oldStatus == newStatus) { return; } // // Ensure that status cannot change after it is definitely assigned.. // if (oldStatus == DefiniteAssignmentStatus.DEFINITELY_ASSIGNED) { return; } // // Ensure that status cannot change back to unreachable after it was once reachable. // if (newStatus == DefiniteAssignmentStatus.CODE_UNREACHABLE || newStatus == DefiniteAssignmentStatus.ASSIGNED_AFTER_FALSE_EXPRESSION || newStatus == DefiniteAssignmentStatus.ASSIGNED_AFTER_TRUE_EXPRESSION) { throw new IllegalStateException("Illegal edge output status:" + newStatus); } edgeStatus.put(edge, newStatus); final DefiniteAssignmentNode targetNode = (DefiniteAssignmentNode) edge.getTo(); if (analyzedRangeStart <= targetNode.getIndex() && targetNode.getIndex() <= analyzedRangeEnd) { nodesWithModifiedInput.add(targetNode); } }
public DefiniteAssignmentStatus getBeforeLoopCondition(final Statement statement) { return conditionNodeMap.get(statement).getNodeStatus(); }
private void changeNodeStatus(final DefiniteAssignmentNode node, final DefiniteAssignmentStatus inputStatus) { if (node.getNodeStatus() == inputStatus) { return; node.setNodeStatus(inputStatus); switch (node.getType()) { case StartNode: case BetweenStatements: { if (!(node.getNextStatement() instanceof IfElseStatement)) { if (inputStatus == DefiniteAssignmentStatus.DEFINITELY_ASSIGNED) { outputStatus = DefiniteAssignmentStatus.DEFINITELY_ASSIGNED; outputStatus = cleanSpecialValues(node.getNextStatement().acceptVisitor(visitor, inputStatus)); if (node.getNextStatement() instanceof ForEachStatement) { final ForEachStatement forEach = (ForEachStatement) node.getNextStatement(); assert node.getNextStatement() instanceof IfElseStatement || node.getNextStatement() instanceof WhileStatement || node.getNextStatement() instanceof DoWhileStatement || node.getNextStatement() instanceof ForStatement; final Expression condition = node.getNextStatement().getChildByRole(Roles.CONDITION); for (final ControlFlowEdge edge : node.getOutgoing()) { if (edge.getType() == ControlFlowEdgeType.ConditionTrue && outputStatus == DefiniteAssignmentStatus.ASSIGNED_AFTER_TRUE_EXPRESSION) { if (node.getPreviousStatement().getRole() == TryCatchStatement.FINALLY_BLOCK_ROLE &&
private void changeNodeStatus(final DefiniteAssignmentNode node, final DefiniteAssignmentStatus inputStatus) { if (node.getNodeStatus() == inputStatus) { return; node.setNodeStatus(inputStatus); switch (node.getType()) { case StartNode: case BetweenStatements: { if (!(node.getNextStatement() instanceof IfElseStatement)) { if (inputStatus == DefiniteAssignmentStatus.DEFINITELY_ASSIGNED) { outputStatus = DefiniteAssignmentStatus.DEFINITELY_ASSIGNED; outputStatus = cleanSpecialValues(node.getNextStatement().acceptVisitor(visitor, inputStatus)); if (node.getNextStatement() instanceof ForEachStatement) { final ForEachStatement forEach = (ForEachStatement) node.getNextStatement(); assert node.getNextStatement() instanceof IfElseStatement || node.getNextStatement() instanceof WhileStatement || node.getNextStatement() instanceof DoWhileStatement || node.getNextStatement() instanceof ForStatement; final Expression condition = node.getNextStatement().getChildByRole(Roles.CONDITION); for (final ControlFlowEdge edge : node.getOutgoing()) { if (edge.getType() == ControlFlowEdgeType.ConditionTrue && outputStatus == DefiniteAssignmentStatus.ASSIGNED_AFTER_TRUE_EXPRESSION) { if (node.getPreviousStatement().getRole() == TryCatchStatement.FINALLY_BLOCK_ROLE &&
private void changeNodeStatus(final DefiniteAssignmentNode node, final DefiniteAssignmentStatus inputStatus) { if (node.getNodeStatus() == inputStatus) { return; node.setNodeStatus(inputStatus); switch (node.getType()) { case StartNode: case BetweenStatements: { if (!(node.getNextStatement() instanceof IfElseStatement)) { if (inputStatus == DefiniteAssignmentStatus.DEFINITELY_ASSIGNED) { outputStatus = DefiniteAssignmentStatus.DEFINITELY_ASSIGNED; outputStatus = cleanSpecialValues(node.getNextStatement().acceptVisitor(visitor, inputStatus)); if (node.getNextStatement() instanceof ForEachStatement) { final ForEachStatement forEach = (ForEachStatement) node.getNextStatement(); assert node.getNextStatement() instanceof IfElseStatement || node.getNextStatement() instanceof WhileStatement || node.getNextStatement() instanceof DoWhileStatement || node.getNextStatement() instanceof ForStatement; final Expression condition = node.getNextStatement().getChildByRole(Roles.CONDITION); for (final ControlFlowEdge edge : node.getOutgoing()) { if (edge.getType() == ControlFlowEdgeType.ConditionTrue && outputStatus == DefiniteAssignmentStatus.ASSIGNED_AFTER_TRUE_EXPRESSION) { if (node.getPreviousStatement().getRole() == TryCatchStatement.FINALLY_BLOCK_ROLE &&
final DefiniteAssignmentNode node = allNodes.get(i); node.setIndex(i); if (node.getType() == ControlFlowNodeType.StartNode || node.getType() == ControlFlowNodeType.BetweenStatements) { for (AstNode child = node.getNextStatement().getLastChild(); child != null; child = child.getPreviousSibling()) { insertAnonymousMethods(i + 1, child, builder); if (node.getType() == ControlFlowNodeType.StartNode || node.getType() == ControlFlowNodeType.BetweenStatements) { beginNodeMap.put(node.getNextStatement(), node); if (node.getType() == ControlFlowNodeType.BetweenStatements || node.getType() == ControlFlowNodeType.EndNode) { endNodeMap.put(node.getPreviousStatement(), node); if (node.getType() == ControlFlowNodeType.LoopCondition) { conditionNodeMap.put(node.getNextStatement(), node);
public DefiniteAssignmentAnalysis(final Statement rootStatement, final Function<AstNode, ResolveResult> resolver) { VerifyArgument.notNull(rootStatement, "rootStatement"); VerifyArgument.notNull(resolver, "resolver"); this.resolver = resolver; final DerivedControlFlowGraphBuilder builder = new DerivedControlFlowGraphBuilder(); builder.setEvaluateOnlyPrimitiveConstants(true); for (final ControlFlowNode node : builder.buildControlFlowGraph(rootStatement, resolver)) { allNodes.add((DefiniteAssignmentNode) node); } for (int i = 0; i < allNodes.size(); i++) { final DefiniteAssignmentNode node = allNodes.get(i); node.setIndex(i); if (node.getType() == ControlFlowNodeType.StartNode || node.getType() == ControlFlowNodeType.BetweenStatements) { beginNodeMap.put(node.getNextStatement(), node); } if (node.getType() == ControlFlowNodeType.BetweenStatements || node.getType() == ControlFlowNodeType.EndNode) { endNodeMap.put(node.getPreviousStatement(), node); } if (node.getType() == ControlFlowNodeType.LoopCondition) { conditionNodeMap.put(node.getNextStatement(), node); } } this.analyzedRangeStart = 0; this.analyzedRangeEnd = allNodes.size() - 1; }
private void changeEdgeStatus(final ControlFlowEdge edge, final DefiniteAssignmentStatus newStatus) { final DefiniteAssignmentStatus oldStatus = edgeStatus.get(edge); if (oldStatus == newStatus) { return; } // // Ensure that status cannot change after it is definitely assigned.. // if (oldStatus == DefiniteAssignmentStatus.DEFINITELY_ASSIGNED) { return; } // // Ensure that status cannot change back to unreachable after it was once reachable. // if (newStatus == DefiniteAssignmentStatus.CODE_UNREACHABLE || newStatus == DefiniteAssignmentStatus.ASSIGNED_AFTER_FALSE_EXPRESSION || newStatus == DefiniteAssignmentStatus.ASSIGNED_AFTER_TRUE_EXPRESSION) { throw new IllegalStateException("Illegal edge output status:" + newStatus); } edgeStatus.put(edge, newStatus); final DefiniteAssignmentNode targetNode = (DefiniteAssignmentNode) edge.getTo(); if (analyzedRangeStart <= targetNode.getIndex() && targetNode.getIndex() <= analyzedRangeEnd) { nodesWithModifiedInput.add(targetNode); } }
private void changeEdgeStatus(final ControlFlowEdge edge, final DefiniteAssignmentStatus newStatus) { final DefiniteAssignmentStatus oldStatus = edgeStatus.get(edge); if (oldStatus == newStatus) { return; } // // Ensure that status cannot change after it is definitely assigned.. // if (oldStatus == DefiniteAssignmentStatus.DEFINITELY_ASSIGNED) { return; } // // Ensure that status cannot change back to unreachable after it was once reachable. // if (newStatus == DefiniteAssignmentStatus.CODE_UNREACHABLE || newStatus == DefiniteAssignmentStatus.ASSIGNED_AFTER_FALSE_EXPRESSION || newStatus == DefiniteAssignmentStatus.ASSIGNED_AFTER_TRUE_EXPRESSION) { throw new IllegalStateException("Illegal edge output status:" + newStatus); } edgeStatus.put(edge, newStatus); final DefiniteAssignmentNode targetNode = (DefiniteAssignmentNode) edge.getTo(); if (analyzedRangeStart <= targetNode.getIndex() && targetNode.getIndex() <= analyzedRangeEnd) { nodesWithModifiedInput.add(targetNode); } }
public DefiniteAssignmentAnalysis(final Statement rootStatement, final Function<AstNode, ResolveResult> resolver) { VerifyArgument.notNull(rootStatement, "rootStatement"); VerifyArgument.notNull(resolver, "resolver"); this.resolver = resolver; final DerivedControlFlowGraphBuilder builder = new DerivedControlFlowGraphBuilder(); builder.setEvaluateOnlyPrimitiveConstants(true); for (final ControlFlowNode node : builder.buildControlFlowGraph(rootStatement, resolver)) { allNodes.add((DefiniteAssignmentNode) node); } for (int i = 0; i < allNodes.size(); i++) { final DefiniteAssignmentNode node = allNodes.get(i); node.setIndex(i); if (node.getType() == ControlFlowNodeType.StartNode || node.getType() == ControlFlowNodeType.BetweenStatements) { beginNodeMap.put(node.getNextStatement(), node); } if (node.getType() == ControlFlowNodeType.BetweenStatements || node.getType() == ControlFlowNodeType.EndNode) { endNodeMap.put(node.getPreviousStatement(), node); } if (node.getType() == ControlFlowNodeType.LoopCondition) { conditionNodeMap.put(node.getNextStatement(), node); } } this.analyzedRangeStart = 0; this.analyzedRangeEnd = allNodes.size() - 1; }
public void analyze(final String variable, final DefiniteAssignmentStatus initialStatus) { this.variableName = variable; try { unassignedVariableUses.clear(); for (final DefiniteAssignmentNode node : allNodes) { node.setNodeStatus(DefiniteAssignmentStatus.CODE_UNREACHABLE); for (final ControlFlowEdge edge : node.getOutgoing()) { edgeStatus.put(edge, DefiniteAssignmentStatus.CODE_UNREACHABLE); } } changeNodeStatus(allNodes.get(analyzedRangeStart), initialStatus); while (!nodesWithModifiedInput.isEmpty()) { final DefiniteAssignmentNode node = nodesWithModifiedInput.poll(); DefiniteAssignmentStatus inputStatus = DefiniteAssignmentStatus.CODE_UNREACHABLE; for (final ControlFlowEdge edge : node.getIncoming()) { inputStatus = mergeStatus(inputStatus, edgeStatus.get(edge)); } changeNodeStatus(node, inputStatus); } } finally { this.variableName = null; } }
public void analyze(final String variable, final DefiniteAssignmentStatus initialStatus) { this.variableName = variable; try { unassignedVariableUses.clear(); for (final DefiniteAssignmentNode node : allNodes) { node.setNodeStatus(DefiniteAssignmentStatus.CODE_UNREACHABLE); for (final ControlFlowEdge edge : node.getOutgoing()) { edgeStatus.put(edge, DefiniteAssignmentStatus.CODE_UNREACHABLE); } } changeNodeStatus(allNodes.get(analyzedRangeStart), initialStatus); while (!nodesWithModifiedInput.isEmpty()) { final DefiniteAssignmentNode node = nodesWithModifiedInput.poll(); DefiniteAssignmentStatus inputStatus = DefiniteAssignmentStatus.CODE_UNREACHABLE; for (final ControlFlowEdge edge : node.getIncoming()) { inputStatus = mergeStatus(inputStatus, edgeStatus.get(edge)); } changeNodeStatus(node, inputStatus); } } finally { this.variableName = null; } }
public DefiniteAssignmentStatus getStatusAfter(final Statement statement) { return endNodeMap.get(statement).getNodeStatus(); }
public DefiniteAssignmentStatus getStatusBefore(final Statement statement) { return beginNodeMap.get(statement).getNodeStatus(); }
public DefiniteAssignmentStatus getBeforeLoopCondition(final Statement statement) { return conditionNodeMap.get(statement).getNodeStatus(); }
public DefiniteAssignmentStatus getStatusAfter(final Statement statement) { return endNodeMap.get(statement).getNodeStatus(); }
public DefiniteAssignmentStatus getStatusBefore(final Statement statement) { return beginNodeMap.get(statement).getNodeStatus(); }
public boolean isPotentiallyAssigned() { for (final DefiniteAssignmentNode node : allNodes) { final DefiniteAssignmentStatus status = node.getNodeStatus(); if (status == null) return true; switch (status) { case POTENTIALLY_ASSIGNED: case DEFINITELY_ASSIGNED: case ASSIGNED_AFTER_TRUE_EXPRESSION: case ASSIGNED_AFTER_FALSE_EXPRESSION: return true; } } return false; }
public boolean isPotentiallyAssigned() { for (final DefiniteAssignmentNode node : allNodes) { final DefiniteAssignmentStatus status = node.getNodeStatus(); if (status == null) return true; switch (status) { case POTENTIALLY_ASSIGNED: case DEFINITELY_ASSIGNED: case ASSIGNED_AFTER_TRUE_EXPRESSION: case ASSIGNED_AFTER_FALSE_EXPRESSION: return true; } } return false; }