use of org.autorefactor.refactoring.ASTMatcherSameVariablesAndMethods in project AutoRefactor by JnRouvignac.
the class CommonCodeInIfElseStatementRefactoring method visit.
// TODO handle switch statements
// TODO also handle ternary operator, ConditionalExpression
@Override
public boolean visit(IfStatement node) {
if (node.getElseStatement() == null) {
return VISIT_SUBTREE;
}
if (!(node.getParent() instanceof Block)) {
// when not inside curly braces
return VISIT_SUBTREE;
}
final ASTBuilder b = this.ctx.getASTBuilder();
final Refactorings r = this.ctx.getRefactorings();
final List<List<Statement>> allCasesStmts = new ArrayList<List<Statement>>();
final List<List<ASTNode>> removedCaseStmts = new LinkedList<List<ASTNode>>();
// collect all the if / else if / else if / ... / else cases
if (collectAllCases(allCasesStmts, node)) {
// initialize removedCaseStmts list
for (int i = 0; i < allCasesStmts.size(); i++) {
removedCaseStmts.add(new LinkedList<ASTNode>());
}
// if all cases exist
final ASTMatcher matcher = new ASTMatcherSameVariablesAndMethods();
final int minSize = minSize(allCasesStmts);
final List<Statement> caseStmts = allCasesStmts.get(0);
boolean result = VISIT_SUBTREE;
// identify matching statements starting from the beginning of each case
for (int stmtIndex = 0; stmtIndex < minSize; stmtIndex++) {
if (!match(matcher, allCasesStmts, true, stmtIndex, 0, allCasesStmts.size())) {
break;
}
r.insertBefore(b.copy(caseStmts.get(stmtIndex)), node);
removeStmts(allCasesStmts, true, stmtIndex, removedCaseStmts);
result = DO_NOT_VISIT_SUBTREE;
}
// identify matching statements starting from the end of each case
for (int stmtIndex = 1; 0 <= minSize - stmtIndex; stmtIndex++) {
if (!match(matcher, allCasesStmts, false, stmtIndex, 0, allCasesStmts.size()) || anyContains(removedCaseStmts, allCasesStmts, stmtIndex)) {
break;
}
r.insertAfter(b.copy(caseStmts.get(caseStmts.size() - stmtIndex)), node);
removeStmts(allCasesStmts, false, stmtIndex, removedCaseStmts);
result = DO_NOT_VISIT_SUBTREE;
}
// remove the nodes common to all cases
final List<Boolean> areCasesEmpty = new ArrayList<Boolean>(allCasesStmts.size());
for (int i = 0; i < allCasesStmts.size(); i++) {
areCasesEmpty.add(Boolean.FALSE);
}
removeStmtsFromCases(allCasesStmts, removedCaseStmts, areCasesEmpty);
if (allEmpty(areCasesEmpty)) {
// TODO JNR keep comments
r.remove(node);
return DO_NOT_VISIT_SUBTREE;
}
// remove empty cases
if (areCasesEmpty.get(0)) {
if (areCasesEmpty.size() == 2 && !areCasesEmpty.get(1)) {
// then clause is empty and there is only one else clause
// => revert if statement
r.replace(node, b.if0(b.not(b.parenthesizeIfNeeded(b.move(node.getExpression()))), b.move(node.getElseStatement())));
} else {
r.replace(node.getThenStatement(), b.block());
}
result = DO_NOT_VISIT_SUBTREE;
}
for (int i = 1; i < areCasesEmpty.size(); i++) {
if (areCasesEmpty.get(i)) {
final Statement firstStmt = allCasesStmts.get(i).get(0);
r.remove(findNodeToRemove(firstStmt, firstStmt.getParent()));
result = DO_NOT_VISIT_SUBTREE;
}
}
return result;
}
return VISIT_SUBTREE;
}
Aggregations