use of org.autorefactor.refactoring.Refactorings 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.autorefactor.refactoring.Refactorings 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.autorefactor.refactoring.Refactorings in project AutoRefactor by JnRouvignac.
the class InlineCodeRatherThanPeremptoryConditionRefactoring method replaceBlockByPlainCode.
@SuppressWarnings("unchecked")
private void replaceBlockByPlainCode(final Statement sourceNode, final Statement unconditionnalStatement) {
final ASTBuilder b = this.ctx.getASTBuilder();
final Refactorings r = this.ctx.getRefactorings();
if (unconditionnalStatement instanceof Block && sourceNode.getParent() instanceof Block) {
r.replace(sourceNode, b.copyRange(((Block) unconditionnalStatement).statements()));
} else {
r.replace(sourceNode, b.copy(unconditionnalStatement));
}
}
use of org.autorefactor.refactoring.Refactorings in project AutoRefactor by JnRouvignac.
the class PushNegationDownRefactoring method visit.
@Override
public boolean visit(PrefixExpression node) {
if (!hasOperator(node, NOT)) {
return VISIT_SUBTREE;
}
final ASTBuilder b = ctx.getASTBuilder();
final Refactorings r = ctx.getRefactorings();
final Expression operand = removeParentheses(node.getOperand());
if (operand instanceof PrefixExpression) {
final PrefixExpression pe = (PrefixExpression) operand;
if (hasOperator(pe, NOT)) {
r.replace(node, b.move(pe.getOperand()));
return DO_NOT_VISIT_SUBTREE;
}
} else if (operand instanceof InfixExpression) {
final InfixExpression ie = (InfixExpression) operand;
final Operator reverseOp = (Operator) OperatorEnum.getOperator(ie).getReverseBooleanOperator();
if (reverseOp != null) {
List<Expression> allOperands = new ArrayList<Expression>(allOperands(ie));
if (Arrays.<Operator>asList(CONDITIONAL_AND, CONDITIONAL_OR, AND, OR).contains(ie.getOperator())) {
for (ListIterator<Expression> it = allOperands.listIterator(); it.hasNext(); ) {
it.set(b.negate(it.next()));
}
} else {
allOperands = b.move(allOperands);
}
r.replace(node, b.parenthesize(b.infixExpr(reverseOp, allOperands)));
return DO_NOT_VISIT_SUBTREE;
}
} else {
final Boolean constant = getBooleanLiteral(operand);
if (constant != null) {
r.replace(node, b.boolean0(!constant));
return DO_NOT_VISIT_SUBTREE;
}
}
return VISIT_SUBTREE;
}
use of org.autorefactor.refactoring.Refactorings in project AutoRefactor by JnRouvignac.
the class RemoveEmptyIfRefactoring method visit.
@Override
public boolean visit(IfStatement node) {
final Refactorings r = this.ctx.getRefactorings();
final Statement thenStmt = node.getThenStatement();
final Statement elseStmt = node.getElseStatement();
if (elseStmt != null && asList(elseStmt).isEmpty()) {
r.remove(elseStmt);
return DO_NOT_VISIT_SUBTREE;
} else if (thenStmt != null && asList(thenStmt).isEmpty()) {
final ASTBuilder b = this.ctx.getASTBuilder();
final Expression condition = node.getExpression();
if (elseStmt != null) {
r.replace(node, b.if0(b.negate(condition), b.move(elseStmt)));
} else if (isPassive(condition)) {
removeBlock(node, r, b);
return DO_NOT_VISIT_SUBTREE;
}
}
return VISIT_SUBTREE;
}
Aggregations