use of org.eclipse.jdt.core.dom.Statement in project AutoRefactor by JnRouvignac.
the class AndroidViewHolderRefactoring method visit.
@Override
public boolean visit(MethodDeclaration node) {
Block body = node.getBody();
if (body != null && isMethod(node, "android.widget.Adapter", "getView", "int", "android.view.View", "android.view.ViewGroup")) {
final GetViewVariableVisitor visitor = new GetViewVariableVisitor();
body.accept(visitor);
if (visitor.canApplyRefactoring()) {
final ASTBuilder b = this.ctx.getASTBuilder();
final Refactorings r = this.ctx.getRefactorings();
final TypeNameDecider typeNameDecider = new TypeNameDecider(visitor.viewVariableName);
// Transform tree
// Create If statement
final SingleVariableDeclaration viewArg = parameters(node).get(1);
final Variable convertViewVar = new Variable(viewArg.getName().getIdentifier(), b);
final InfixExpression condition = b.infixExpr(convertViewVar.varName(), EQUALS, b.null0());
final Block thenBlock = b.block();
final IfStatement ifStmt = b.if0(condition, thenBlock);
r.insertBefore(ifStmt, visitor.viewAssignmentStmt);
final List<Statement> thenStmts = statements(thenBlock);
thenStmts.add(b.toStmt(b.assign(convertViewVar.varName(), ASSIGN, b.copy(visitor.getInflateExpr()))));
// assign to local view variable when necessary
if (!"convertView".equals(visitor.viewVariableName.getIdentifier())) {
Statement assignConvertViewToView = null;
if (visitor.viewVariableDeclFragment != null) {
assignConvertViewToView = b.declareStmt(b.copyType(visitor.viewVariableName, typeNameDecider), b.copy(visitor.viewVariableName), convertViewVar.varName());
} else if (visitor.viewVariableAssignment != null) {
assignConvertViewToView = b.toStmt(b.assign(b.copy(visitor.viewVariableName), ASSIGN, convertViewVar.varName()));
}
if (assignConvertViewToView != null) {
r.insertBefore(assignConvertViewToView, visitor.viewAssignmentStmt);
}
}
// make sure method returns the view to be reused
if (visitor.returnStmt != null) {
r.insertAfter(b.return0(b.copy(visitor.viewVariableName)), visitor.returnStmt);
r.remove(visitor.returnStmt);
}
// Optimize findViewById calls
final FindViewByIdVisitor findViewByIdVisitor = new FindViewByIdVisitor(visitor.viewVariableName);
body.accept(findViewByIdVisitor);
if (!findViewByIdVisitor.items.isEmpty()) {
// TODO JNR name conflict? Use VariableNameDecider
Variable viewHolderItemVar = new Variable("ViewHolderItem", "viewHolderItem", b);
// create ViewHolderItem class
r.insertBefore(createViewHolderItemClass(findViewByIdVisitor, viewHolderItemVar.typeName(), typeNameDecider), node);
// declare viewhHolderItem object
r.insertFirst(body, Block.STATEMENTS_PROPERTY, viewHolderItemVar.declareStmt());
// initialize viewHolderItem
thenStmts.add(b.toStmt(b.assign(viewHolderItemVar.varName(), ASSIGN, b.new0(viewHolderItemVar.type()))));
// Assign findViewById to ViewHolderItem
for (FindViewByIdVisitor.FindViewByIdItem item : findViewByIdVisitor.items) {
// ensure we are accessing convertView object
FieldAccess fieldAccess = b.fieldAccess(viewHolderItemVar.varName(), b.simpleName(item.variable.getIdentifier()));
// FIXME This does not work: not sure why??
// r.set(item.findViewByIdInvocation,
// MethodInvocation.EXPRESSION_PROPERTY, convertViewVar.varName());
item.findViewByIdInvocation.setExpression(convertViewVar.varName());
// FIXME For some reason b.copy() does not do what we would like
thenStmts.add(b.toStmt(b.assign(fieldAccess, ASSIGN, b.copySubtree(item.findViewByIdExpr))));
// replace previous findViewById with accesses to viewHolderItem
r.replace(item.findViewByIdExpr, b.copy(fieldAccess));
}
// store viewHolderItem in convertView
thenStmts.add(b.toStmt(b.invoke("convertView", "setTag", viewHolderItemVar.varName())));
// retrieve viewHolderItem from convertView
ifStmt.setElseStatement(b.block(b.toStmt(b.assign(viewHolderItemVar.varName(), ASSIGN, b.cast(viewHolderItemVar.type(), b.invoke("convertView", "getTag"))))));
}
r.remove(visitor.viewAssignmentStmt);
return DO_NOT_VISIT_SUBTREE;
}
}
return VISIT_SUBTREE;
}
use of org.eclipse.jdt.core.dom.Statement 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 boolean[] areCasesEmpty = new boolean[allCasesStmts.size()];
for (int i = 0; i < allCasesStmts.size(); i++) {
areCasesEmpty[i] = false;
}
removeStmtsFromCases(allCasesStmts, removedCaseStmts, areCasesEmpty);
if (allEmpty(areCasesEmpty)) {
r.removeButKeepComment(node);
return DO_NOT_VISIT_SUBTREE;
}
// Remove empty cases
if (areCasesEmpty[0]) {
if (areCasesEmpty.length == 2 && !areCasesEmpty[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.length; i++) {
if (areCasesEmpty[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;
}
use of org.eclipse.jdt.core.dom.Statement in project AutoRefactor by JnRouvignac.
the class DoWhileRatherThanDuplicateCodeRefactoring method visit.
@Override
public boolean visit(WhileStatement node) {
final List<Statement> whileStmts = asList(node.getBody());
if (whileStmts.isEmpty()) {
return VISIT_SUBTREE;
}
final List<Statement> previousStmts = new ArrayList<Statement>(whileStmts.size());
final ASTMatcher matcher = new ASTMatcher();
Statement previousStmt = getPreviousSibling(node);
int i = whileStmts.size() - 1;
while (i >= 0) {
if (previousStmt == null || !match(matcher, previousStmt, whileStmts.get(i))) {
return VISIT_SUBTREE;
}
i--;
previousStmts.add(previousStmt);
previousStmt = getPreviousSibling(previousStmt);
}
replaceWithDoWhile(node, previousStmts);
return DO_NOT_VISIT_SUBTREE;
}
use of org.eclipse.jdt.core.dom.Statement in project AutoRefactor by JnRouvignac.
the class ASTHelper method isEndingWithJump.
/**
* Return true if the statement falls through.
*
* @param stmt the statement
* @return true if the statement falls through.
*/
public static boolean isEndingWithJump(Statement stmt) {
final List<Statement> stmts = asList(stmt);
if (stmts.isEmpty()) {
return false;
}
final Statement lastStmt = stmts.get(stmts.size() - 1);
switch(lastStmt.getNodeType()) {
case RETURN_STATEMENT:
case THROW_STATEMENT:
case BREAK_STATEMENT:
case CONTINUE_STATEMENT:
return true;
case IF_STATEMENT:
final IfStatement ifStmt = (IfStatement) lastStmt;
final Statement thenStmt = ifStmt.getThenStatement();
final Statement elseStmt = ifStmt.getElseStatement();
return isEndingWithJump(thenStmt) && isEndingWithJump(elseStmt);
default:
return false;
}
}
use of org.eclipse.jdt.core.dom.Statement in project AutoRefactor by JnRouvignac.
the class ASTHelper method getPreviousStatement.
/**
* Returns the previous statement in the source file if it exists.
*
* @param startNode the start node
* @return the previous statement in the source file if it exists, null otherwise
*/
public static Statement getPreviousStatement(Statement startNode) {
final Statement previousSibling = getPreviousSibling(startNode);
if (previousSibling != null) {
return previousSibling;
}
final ASTNode parent = startNode.getParent();
if (parent instanceof Statement) {
return getPreviousStatement((Statement) parent);
}
return null;
}
Aggregations