Search in sources :

Example 21 with Refactorings

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;
}
Also used : Variable(org.autorefactor.refactoring.Variable) SingleVariableDeclaration(org.eclipse.jdt.core.dom.SingleVariableDeclaration) ExpressionStatement(org.eclipse.jdt.core.dom.ExpressionStatement) SwitchStatement(org.eclipse.jdt.core.dom.SwitchStatement) Statement(org.eclipse.jdt.core.dom.Statement) IfStatement(org.eclipse.jdt.core.dom.IfStatement) ReturnStatement(org.eclipse.jdt.core.dom.ReturnStatement) VariableDeclarationStatement(org.eclipse.jdt.core.dom.VariableDeclarationStatement) Refactorings(org.autorefactor.refactoring.Refactorings) ASTBuilder(org.autorefactor.refactoring.ASTBuilder) IfStatement(org.eclipse.jdt.core.dom.IfStatement) InfixExpression(org.eclipse.jdt.core.dom.InfixExpression) Block(org.eclipse.jdt.core.dom.Block) TypeNameDecider(org.autorefactor.refactoring.TypeNameDecider) FieldAccess(org.eclipse.jdt.core.dom.FieldAccess)

Example 22 with Refactorings

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;
}
Also used : Statement(org.eclipse.jdt.core.dom.Statement) IfStatement(org.eclipse.jdt.core.dom.IfStatement) Refactorings(org.autorefactor.refactoring.Refactorings) ArrayList(java.util.ArrayList) ASTBuilder(org.autorefactor.refactoring.ASTBuilder) LinkedList(java.util.LinkedList) ASTNode(org.eclipse.jdt.core.dom.ASTNode) Block(org.eclipse.jdt.core.dom.Block) ArrayList(java.util.ArrayList) List(java.util.List) LinkedList(java.util.LinkedList) ASTMatcherSameVariablesAndMethods(org.autorefactor.refactoring.ASTMatcherSameVariablesAndMethods) ASTMatcher(org.eclipse.jdt.core.dom.ASTMatcher)

Example 23 with Refactorings

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));
    }
}
Also used : Refactorings(org.autorefactor.refactoring.Refactorings) Block(org.eclipse.jdt.core.dom.Block) ASTBuilder(org.autorefactor.refactoring.ASTBuilder)

Example 24 with Refactorings

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;
}
Also used : ASTHelper.hasOperator(org.autorefactor.refactoring.ASTHelper.hasOperator) Operator(org.eclipse.jdt.core.dom.InfixExpression.Operator) InfixExpression(org.eclipse.jdt.core.dom.InfixExpression) Expression(org.eclipse.jdt.core.dom.Expression) PrefixExpression(org.eclipse.jdt.core.dom.PrefixExpression) PrefixExpression(org.eclipse.jdt.core.dom.PrefixExpression) Refactorings(org.autorefactor.refactoring.Refactorings) InfixExpression(org.eclipse.jdt.core.dom.InfixExpression) ArrayList(java.util.ArrayList) List(java.util.List) ListIterator(java.util.ListIterator) ASTBuilder(org.autorefactor.refactoring.ASTBuilder)

Example 25 with Refactorings

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;
}
Also used : Expression(org.eclipse.jdt.core.dom.Expression) ForStatement(org.eclipse.jdt.core.dom.ForStatement) DoStatement(org.eclipse.jdt.core.dom.DoStatement) Statement(org.eclipse.jdt.core.dom.Statement) IfStatement(org.eclipse.jdt.core.dom.IfStatement) EnhancedForStatement(org.eclipse.jdt.core.dom.EnhancedForStatement) WhileStatement(org.eclipse.jdt.core.dom.WhileStatement) Refactorings(org.autorefactor.refactoring.Refactorings) ASTBuilder(org.autorefactor.refactoring.ASTBuilder)

Aggregations

Refactorings (org.autorefactor.refactoring.Refactorings)27 ASTBuilder (org.autorefactor.refactoring.ASTBuilder)23 Expression (org.eclipse.jdt.core.dom.Expression)8 InfixExpression (org.eclipse.jdt.core.dom.InfixExpression)6 IfStatement (org.eclipse.jdt.core.dom.IfStatement)5 MethodInvocation (org.eclipse.jdt.core.dom.MethodInvocation)5 Statement (org.eclipse.jdt.core.dom.Statement)5 List (java.util.List)3 Block (org.eclipse.jdt.core.dom.Block)3 PrefixExpression (org.eclipse.jdt.core.dom.PrefixExpression)3 ArrayList (java.util.ArrayList)2 TypeNameDecider (org.autorefactor.refactoring.TypeNameDecider)2 Variable (org.autorefactor.refactoring.Variable)2 ASTMatcher (org.eclipse.jdt.core.dom.ASTMatcher)2 ASTNode (org.eclipse.jdt.core.dom.ASTNode)2 DoStatement (org.eclipse.jdt.core.dom.DoStatement)2 EnhancedForStatement (org.eclipse.jdt.core.dom.EnhancedForStatement)2 ForStatement (org.eclipse.jdt.core.dom.ForStatement)2 IMethodBinding (org.eclipse.jdt.core.dom.IMethodBinding)2 ITypeBinding (org.eclipse.jdt.core.dom.ITypeBinding)2