use of org.autorefactor.cfg.CFGEdgeBuilder in project AutoRefactor by JnRouvignac.
the class CFGBuilder method buildCFG.
/**
* Builds a CFG for the provided node.
*
* @param node the node for which to build a CFG.
* @return the entry block to the CFG of this method declaration
*/
public CFGBasicBlock buildCFG(MethodDeclaration node) {
final CFGBasicBlock entryBlock = newEntryBlock(node);
this.exitBlock = newExitBlock(node);
addDeclarations(entryBlock, parameters(node));
try {
final ThrowerBlocks throwers = new ThrowerBlocks();
final CFGEdgeBuilder liveEdge = new CFGEdgeBuilder(entryBlock);
final LivenessState liveAfterBody = buildCFG(node.getBody(), LivenessState.of(liveEdge), throwers);
if (!liveAfterBody.liveEdges.isEmpty()) {
if (node.getReturnType2() == null || // added for unit tests
node.getReturnType2().resolveBinding() == null || "void".equals(node.getReturnType2().resolveBinding().getName())) {
buildEdges(liveAfterBody, exitBlock);
} else {
throw new IllegalStateException(node, "Did not expect to find any edges to build " + "for a constructor or a non void method return type.");
}
}
if (!this.edgesToBuild.isEmpty()) {
throw new IllegalStateException(node, "At this point, there should not be any edges left to build. Left edges: " + this.edgesToBuild);
}
List<CFGBasicBlock> throwingBlocks = throwers.selectBlocksThrowing(null);
if (!throwingBlocks.isEmpty()) {
for (CFGBasicBlock throwingBlock : throwingBlocks) {
// TODO JNR
}
}
List<CFGEdgeBuilder> throwingEdges = throwers.selectEdgesThrowing(null);
if (!throwingEdges.isEmpty()) {
for (CFGEdgeBuilder throwingEdge : throwingEdges) {
// TODO JNR
}
}
return entryBlock;
} finally {
this.exitBlock = null;
}
}
use of org.autorefactor.cfg.CFGEdgeBuilder in project AutoRefactor by JnRouvignac.
the class CFGBuilder method buildEdgesAfterBranchableStmt.
private void buildEdgesAfterBranchableStmt(Statement node, final LivenessState liveAfterBranchableStmt, final CFGBasicBlock whereToBranchBlock) {
final Map<CFGEdgeBuilder, Boolean> toBuild = this.edgesToBuild.remove(node);
if (isNotEmpty(toBuild)) {
Set<Entry<CFGEdgeBuilder, Boolean>> set = toBuild.entrySet();
for (Iterator<Entry<CFGEdgeBuilder, Boolean>> iter = set.iterator(); iter.hasNext(); ) {
Entry<CFGEdgeBuilder, Boolean> entry = iter.next();
final CFGEdgeBuilder builder = entry.getKey();
final boolean isBreakStmt = entry.getValue();
if (isBreakStmt) {
liveAfterBranchableStmt.add(builder);
} else {
// this is a continue statement
builder.withTarget(whereToBranchBlock).build();
iter.remove();
}
}
}
}
use of org.autorefactor.cfg.CFGEdgeBuilder in project AutoRefactor by JnRouvignac.
the class CFGBuilder method buildCFG.
/**
* Builds a CFG for the provided node.
*
* @param node the node for which to build a CFG.
* @param state the blocks liveness state before current node
* @param throwers the thrower blocks information
* @return the blocks liveness state after current node
*/
public LivenessState buildCFG(DoStatement node, LivenessState state, ThrowerBlocks throwers) {
final CFGBasicBlock basicBlock = getCFGBasicBlock(node, state.nextStmtWillCreateNewBlock());
final LivenessState newLiveState = new LivenessState(basicBlock, new CFGEdgeBuilder(basicBlock));
final LivenessState liveAfterLoop = buildCFG(node.getBody(), newLiveState, throwers);
CFGBasicBlock conditionBlock = getCFGBasicBlock(node.getExpression(), liveAfterLoop.nextStmtWillCreateNewBlock());
addVariableAccess(conditionBlock, node.getExpression(), READ, throwers);
buildEdge(node.getExpression(), true, conditionBlock, basicBlock);
LivenessState liveAfterStmt = LivenessState.of(new CFGEdgeBuilder(node.getExpression(), false, conditionBlock));
buildEdgesAfterBranchableStmt(node, liveAfterStmt, basicBlock);
return liveAfterStmt;
}
use of org.autorefactor.cfg.CFGEdgeBuilder in project AutoRefactor by JnRouvignac.
the class CFGBuilder method buildCFG.
/**
* Builds a CFG for the provided node.
*
* @param node the node for which to build a CFG.
* @param state the blocks liveness state before current node
* @param throwers the thrower blocks information
* @return the blocks liveness state after current node
*/
public LivenessState buildCFG(EnhancedForStatement node, LivenessState state, ThrowerBlocks throwers) {
final CFGBasicBlock basicBlock = getCFGBasicBlock(node, state.nextStmtWillCreateNewBlock());
addDeclaration(basicBlock, node.getParameter(), DECL_INIT | WRITE);
final LivenessState newLiveState = LivenessState.of(new CFGEdgeBuilder(basicBlock));
final LivenessState liveAfterBody = buildCFG(node.getBody(), newLiveState, throwers);
buildEdges(liveAfterBody, basicBlock);
final LivenessState liveAfterStmt = LivenessState.of(new CFGEdgeBuilder(basicBlock));
buildEdgesAfterBranchableStmt(node, liveAfterStmt, basicBlock);
return liveAfterStmt.nextStmtWillCreateNewBlock();
}
use of org.autorefactor.cfg.CFGEdgeBuilder in project AutoRefactor by JnRouvignac.
the class CFGBuilder method buildCFG.
/**
* Builds a CFG for the provided node.
*
* @param node the node for which to build a CFG.
* @param switchConditionBasicBlock the basic block for the switch condition
* @param state the blocks liveness state before current node
* @param throwers the thrower blocks information
* @return the blocks liveness state after current node
*/
public LivenessState buildCFG(SwitchCase node, CFGBasicBlock switchConditionBasicBlock, LivenessState state, ThrowerBlocks throwers) {
// the current live blocks will be empty if there was a break,
// or populated in case of fall-through.
addVariableAccess(switchConditionBasicBlock, node.getExpression(), READ, throwers);
// add an edge going from the condition of the switch
// (state.liveBasicBlock is the condition of the switch)
state.add(new CFGEdgeBuilder(node.getExpression(), true, switchConditionBasicBlock));
return state.nextStmtWillCreateNewBlock();
}
Aggregations