Search in sources :

Example 36 with MethodInvocation

use of org.eclipse.jdt.core.dom.MethodInvocation in project AutoRefactor by JnRouvignac.

the class AbstractClassSubstituteRefactoring method canInstantiationBeRefactored.

private boolean canInstantiationBeRefactored(final ASTNode node, final List<VariableDeclaration> variablesToRefactor, final List<MethodInvocation> methodCallsToRefactorAlone, final List<MethodInvocation> methodCallsToRefactorWithVariable) {
    final List<MethodInvocation> localMethodCallsToRefactor = new ArrayList<MethodInvocation>();
    ASTNode childNode = node;
    do {
        ASTNode parentNode = childNode.getParent();
        switch(parentNode.getNodeType()) {
            case ASSIGNMENT:
            case RETURN_STATEMENT:
            case CAST_EXPRESSION:
            case INSTANCEOF_EXPRESSION:
                return false;
            case SINGLE_VARIABLE_DECLARATION:
            case VARIABLE_DECLARATION_EXPRESSION:
            case VARIABLE_DECLARATION_FRAGMENT:
            case VARIABLE_DECLARATION_STATEMENT:
                final VariableDeclaration varDecl = (VariableDeclaration) parentNode;
                final VariableDeclarationStatement variableDeclaration = (VariableDeclarationStatement) varDecl.getParent();
                if (hasType(variableDeclaration.getType().resolveBinding(), getExistingClassCanonicalName())) {
                    variablesToRefactor.add(varDecl);
                    methodCallsToRefactorWithVariable.addAll(localMethodCallsToRefactor);
                    return true;
                }
                return false;
            case METHOD_INVOCATION:
                final MethodInvocation mi = (MethodInvocation) parentNode;
                if (isObjectPassedInParameter(childNode, mi) || !canMethodBeRefactored(mi, localMethodCallsToRefactor)) {
                    return false;
                } else if (!isMethodReturningExistingClass(mi)) {
                    methodCallsToRefactorAlone.addAll(localMethodCallsToRefactor);
                    return true;
                }
                break;
            case PARENTHESIZED_EXPRESSION:
                break;
            default:
                methodCallsToRefactorAlone.addAll(localMethodCallsToRefactor);
                return true;
        }
        childNode = parentNode;
    } while (true);
}
Also used : ArrayList(java.util.ArrayList) ASTNode(org.eclipse.jdt.core.dom.ASTNode) VariableDeclarationStatement(org.eclipse.jdt.core.dom.VariableDeclarationStatement) MethodInvocation(org.eclipse.jdt.core.dom.MethodInvocation) VariableDeclaration(org.eclipse.jdt.core.dom.VariableDeclaration)

Example 37 with MethodInvocation

use of org.eclipse.jdt.core.dom.MethodInvocation in project AutoRefactor by JnRouvignac.

the class MapEliminateKeySetCallsRefactoring method replaceEntryIterationByKeyIteration.

private void replaceEntryIterationByKeyIteration(EnhancedForStatement enhancedFor, final Expression mapExpression, final SingleVariableDeclaration parameter, final List<MethodInvocation> getValueMis) {
    final ASTBuilder b = ctx.getASTBuilder();
    final Refactorings r = ctx.getRefactorings();
    final VariableDefinitionsUsesVisitor keyUseVisitor = new VariableDefinitionsUsesVisitor(parameter);
    enhancedFor.getBody().accept(keyUseVisitor);
    int keyUses = keyUseVisitor.getUses().size();
    final int insertionPoint = asList(enhancedFor.getBody()).get(0).getStartPosition() - 1;
    final Variable entryVar = new Variable(new VariableNameDecider(enhancedFor.getBody(), insertionPoint).suggest("entry", "mapEntry"), b);
    final TypeNameDecider typeNameDecider = new TypeNameDecider(parameter);
    final MethodInvocation getValueMi0 = getValueMis.get(0);
    final ITypeBinding typeBinding = getValueMi0.getExpression().resolveTypeBinding();
    if (typeBinding != null && typeBinding.isRawType()) {
        // for (Object key : map.keySet()) => for (Object key : map.entrySet())
        r.set(enhancedFor, EXPRESSION_PROPERTY, b.invoke(b.move(mapExpression), "entrySet"));
        final Type objectType = b.type(typeNameDecider.useSimplestPossibleName("java.lang.Object"));
        final Variable objectVar = new Variable(new VariableNameDecider(enhancedFor.getBody(), insertionPoint).suggest("obj"), b);
        r.set(enhancedFor, PARAMETER_PROPERTY, b.declareSingleVariable(objectVar.varNameRaw(), objectType));
        // for (Map.Entry<K, V> mapEntry : map.entrySet()) {
        // Map.Entry mapEntry = (Map.Entry) obj; // <--- add this statement
        // Object key = mapEntry.getKey(); // <--- add this statement
        final Type mapKeyType = b.copy(parameter.getType());
        final VariableDeclarationStatement newKeyDecl = b.declareStmt(mapKeyType, b.move(parameter.getName()), b.invoke(entryVar.varName(), "getKey"));
        r.insertFirst(enhancedFor.getBody(), Block.STATEMENTS_PROPERTY, newKeyDecl);
        if (keyUses > getValueMis.size()) {
            String mapEntryTypeName = typeNameDecider.useSimplestPossibleName("java.util.Map.Entry");
            final VariableDeclarationStatement newEntryDecl = b.declareStmt(b.type(mapEntryTypeName), entryVar.varName(), b.cast(b.type(mapEntryTypeName), objectVar.varName()));
            r.insertFirst(enhancedFor.getBody(), Block.STATEMENTS_PROPERTY, newEntryDecl);
        }
    } else {
        // for (K key : map.keySet()) => for (K key : map.entrySet())
        r.set(enhancedFor, EXPRESSION_PROPERTY, b.invoke(b.move(mapExpression), "entrySet"));
        // for (K key : map.entrySet()) => for (Map.Entry<K, V> mapEntry : map.entrySet())
        final Type mapEntryType = createMapEntryType(parameter, getValueMi0, typeNameDecider);
        r.set(enhancedFor, PARAMETER_PROPERTY, b.declareSingleVariable(entryVar.varNameRaw(), mapEntryType));
        if (keyUses > getValueMis.size()) {
            // for (Map.Entry<K, V> mapEntry : map.entrySet()) {
            // K key = mapEntry.getKey(); // <--- add this statement
            final Type mapKeyType = b.copy(parameter.getType());
            final VariableDeclarationStatement newKeyDeclaration = b.declareStmt(mapKeyType, b.move(parameter.getName()), b.invoke(entryVar.varName(), "getKey"));
            r.insertFirst(enhancedFor.getBody(), Block.STATEMENTS_PROPERTY, newKeyDeclaration);
        }
    }
    // Replace all occurrences of map.get(key) => mapEntry.getValue()
    for (MethodInvocation getValueMi : getValueMis) {
        r.replace(getValueMi, b.invoke(entryVar.varName(), "getValue"));
    }
}
Also used : Type(org.eclipse.jdt.core.dom.Type) Variable(org.autorefactor.refactoring.Variable) ITypeBinding(org.eclipse.jdt.core.dom.ITypeBinding) Refactorings(org.autorefactor.refactoring.Refactorings) VariableDeclarationStatement(org.eclipse.jdt.core.dom.VariableDeclarationStatement) MethodInvocation(org.eclipse.jdt.core.dom.MethodInvocation) TypeNameDecider(org.autorefactor.refactoring.TypeNameDecider) ASTBuilder(org.autorefactor.refactoring.ASTBuilder)

Example 38 with MethodInvocation

use of org.eclipse.jdt.core.dom.MethodInvocation in project AutoRefactor by JnRouvignac.

the class MapEliminateKeySetCallsRefactoring method visit.

@Override
public boolean visit(EnhancedForStatement enhancedFor) {
    final Expression foreachExpr = enhancedFor.getExpression();
    if (isKeySetMethod(foreachExpr)) {
        // From 'for (K key : map.keySet()) { }'
        // -> mapExpression become 'map', parameter become 'K key'
        final Expression mapExpression = ((MethodInvocation) foreachExpr).getExpression();
        if (mapExpression == null) {
            // not implemented
            return VISIT_SUBTREE;
        }
        final SingleVariableDeclaration parameter = enhancedFor.getParameter();
        final List<MethodInvocation> getValueMis = collectMapGetValueCalls(mapExpression, parameter, enhancedFor.getBody());
        if (!getValueMis.isEmpty() && haveSameTypeBindings(getValueMis)) {
            replaceEntryIterationByKeyIteration(enhancedFor, mapExpression, parameter, getValueMis);
            return DO_NOT_VISIT_SUBTREE;
        }
    }
    return VISIT_SUBTREE;
}
Also used : Expression(org.eclipse.jdt.core.dom.Expression) SingleVariableDeclaration(org.eclipse.jdt.core.dom.SingleVariableDeclaration) MethodInvocation(org.eclipse.jdt.core.dom.MethodInvocation)

Example 39 with MethodInvocation

use of org.eclipse.jdt.core.dom.MethodInvocation in project AutoRefactor by JnRouvignac.

the class StringBuilderRefactoring method readAppendMethod.

private Expression readAppendMethod(final Expression expr, final LinkedList<Pair<ITypeBinding, Expression>> allOperands, final AtomicBoolean isRefactoringNeeded, final AtomicBoolean isInstanceCreationToRewrite) {
    final Expression exp = removeParentheses(expr);
    if (isStringBuilderOrBuffer(exp)) {
        if (exp instanceof MethodInvocation) {
            final MethodInvocation mi = (MethodInvocation) exp;
            if ("append".equals(mi.getName().getIdentifier()) && arguments(mi).size() == 1) {
                final Expression arg0 = arguments(mi).get(0);
                readSubExpressions(arg0, allOperands, isRefactoringNeeded);
                return readAppendMethod(mi.getExpression(), allOperands, isRefactoringNeeded, isInstanceCreationToRewrite);
            }
        } else if (exp instanceof ClassInstanceCreation) {
            final ClassInstanceCreation cic = (ClassInstanceCreation) exp;
            if (arguments(cic).size() == 1) {
                final Expression arg0 = arguments(cic).get(0);
                if (isStringBuilderOrBuffer(cic) && (hasType(arg0, "java.lang.String") || instanceOf(arg0, "java.lang.CharSequence"))) {
                    isInstanceCreationToRewrite.set(true);
                    readSubExpressions(arg0, allOperands, isRefactoringNeeded);
                }
            } else if (arguments(cic).isEmpty() && !allOperands.isEmpty() && ((allOperands.getFirst().getFirst() != null) ? hasType(allOperands.getFirst().getFirst(), "java.lang.String") : hasType(allOperands.getFirst().getSecond(), "java.lang.String"))) {
                isInstanceCreationToRewrite.set(true);
                isRefactoringNeeded.set(true);
            }
            return cic;
        } else {
            return expr;
        }
    }
    return null;
}
Also used : ClassInstanceCreation(org.eclipse.jdt.core.dom.ClassInstanceCreation) Expression(org.eclipse.jdt.core.dom.Expression) InfixExpression(org.eclipse.jdt.core.dom.InfixExpression) MethodInvocation(org.eclipse.jdt.core.dom.MethodInvocation)

Example 40 with MethodInvocation

use of org.eclipse.jdt.core.dom.MethodInvocation in project AutoRefactor by JnRouvignac.

the class StringRefactoring method visit.

@Override
public boolean visit(MethodInvocation node) {
    final Expression expr = node.getExpression();
    final ASTNode parent = node.getParent();
    final ASTBuilder b = this.ctx.getASTBuilder();
    final Refactorings r = ctx.getRefactorings();
    final boolean isStringValueOf = isStringValueOf(node);
    if (isMethod(node, "java.lang.Object", "toString")) {
        if (hasType(expr, "java.lang.String")) {
            // if node is already a String, no need to call toString()
            r.replace(node, b.move(expr));
            return DO_NOT_VISIT_SUBTREE;
        } else if (parent.getNodeType() == INFIX_EXPRESSION) {
            // if node is in a String context, no need to call toString()
            final InfixExpression ie = (InfixExpression) node.getParent();
            final Expression leftOp = ie.getLeftOperand();
            final Expression rightOp = ie.getRightOperand();
            final boolean leftOpIsString = hasType(leftOp, "java.lang.String");
            final boolean rightOpIsString = hasType(rightOp, "java.lang.String");
            final MethodInvocation lmi = as(leftOp, MethodInvocation.class);
            final MethodInvocation rmi = as(rightOp, MethodInvocation.class);
            if (!node.equals(lmi) && !node.equals(rmi) && (leftOpIsString || rightOpIsString)) {
                // node is in the extended operands
                r.replace(node, replaceToString(node.getExpression()));
                return DO_NOT_VISIT_SUBTREE;
            } else if (leftOpIsString && isMethod(rmi, "java.lang.Object", "toString")) {
                r.replace(rmi, replaceToString(rmi.getExpression()));
                return DO_NOT_VISIT_SUBTREE;
            } else if (rightOpIsString && node.equals(lmi)) {
                r.replace(lmi, replaceToString(lmi.getExpression()));
                return DO_NOT_VISIT_SUBTREE;
            }
        }
    } else if (isStringValueOf && hasType(arg0(node), "java.lang.String")) {
        if ((arg0(node) instanceof StringLiteral) || (arg0(node) instanceof InfixExpression)) {
            r.replace(node, b.parenthesizeIfNeeded(b.move(arg0(node))));
            return DO_NOT_VISIT_SUBTREE;
        }
    } else if ((isToStringForPrimitive(node) || isStringValueOf) && parent.getNodeType() == INFIX_EXPRESSION) {
        // if node is in a String context, no need to call toString()
        final InfixExpression ie = (InfixExpression) node.getParent();
        final Expression lo = ie.getLeftOperand();
        final Expression ro = ie.getRightOperand();
        if (node.equals(lo)) {
            if (hasType(ro, "java.lang.String")) {
                replaceStringValueOfByArg0(lo, node);
                return DO_NOT_VISIT_SUBTREE;
            }
        } else if (node.equals(ro)) {
            if (hasType(lo, "java.lang.String") && // to avoid compilation errors post refactoring
            !r.hasBeenRefactored(lo)) {
                replaceStringValueOfByArg0(ro, node);
                return DO_NOT_VISIT_SUBTREE;
            }
        } else {
            // left or right operation is necessarily a string, so just replace
            replaceStringValueOfByArg0(node, node);
            return DO_NOT_VISIT_SUBTREE;
        }
    } else if (isMethod(node, "java.lang.String", "equals", "java.lang.Object")) {
        final MethodInvocation leftInvocation = as(node.getExpression(), MethodInvocation.class);
        final MethodInvocation rightInvocation = as(arg0(node), MethodInvocation.class);
        if (leftInvocation != null && rightInvocation != null && ((isMethod(leftInvocation, "java.lang.String", "toLowerCase") && isMethod(rightInvocation, "java.lang.String", "toLowerCase")) || (isMethod(leftInvocation, "java.lang.String", "toUpperCase") && isMethod(rightInvocation, "java.lang.String", "toUpperCase")))) {
            final Expression leftExpr = leftInvocation.getExpression();
            final Expression rightExpr = rightInvocation.getExpression();
            r.replace(node, b.invoke(b.copy(leftExpr), "equalsIgnoreCase", b.copy(rightExpr)));
            return DO_NOT_VISIT_SUBTREE;
        }
    } else if (isMethod(node, "java.lang.String", "equalsIgnoreCase", "java.lang.String")) {
        final AtomicBoolean isRefactoringNeeded = new AtomicBoolean(false);
        final Expression leftExpr = getReducedStringExpression(node.getExpression(), isRefactoringNeeded);
        final Expression rightExpr = getReducedStringExpression(arg0(node), isRefactoringNeeded);
        if (isRefactoringNeeded.get()) {
            r.replace(node, b.invoke(b.copy(leftExpr), "equalsIgnoreCase", b.copy(rightExpr)));
            return DO_NOT_VISIT_SUBTREE;
        }
    }
    return VISIT_SUBTREE;
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) StringLiteral(org.eclipse.jdt.core.dom.StringLiteral) Expression(org.eclipse.jdt.core.dom.Expression) InfixExpression(org.eclipse.jdt.core.dom.InfixExpression) ASTNode(org.eclipse.jdt.core.dom.ASTNode) Refactorings(org.autorefactor.refactoring.Refactorings) InfixExpression(org.eclipse.jdt.core.dom.InfixExpression) MethodInvocation(org.eclipse.jdt.core.dom.MethodInvocation) ASTBuilder(org.autorefactor.refactoring.ASTBuilder)

Aggregations

MethodInvocation (org.eclipse.jdt.core.dom.MethodInvocation)265 Expression (org.eclipse.jdt.core.dom.Expression)112 SuperMethodInvocation (org.eclipse.jdt.core.dom.SuperMethodInvocation)59 ASTNode (org.eclipse.jdt.core.dom.ASTNode)53 SimpleName (org.eclipse.jdt.core.dom.SimpleName)53 InfixExpression (org.eclipse.jdt.core.dom.InfixExpression)51 ASTRewrite (org.autorefactor.jdt.core.dom.ASTRewrite)48 ASTNodeFactory (org.autorefactor.jdt.internal.corext.dom.ASTNodeFactory)47 ITypeBinding (org.eclipse.jdt.core.dom.ITypeBinding)43 ArrayList (java.util.ArrayList)40 CastExpression (org.eclipse.jdt.core.dom.CastExpression)40 TextEditGroup (org.eclipse.text.edits.TextEditGroup)37 MethodDeclaration (org.eclipse.jdt.core.dom.MethodDeclaration)34 Block (org.eclipse.jdt.core.dom.Block)33 VariableDeclarationFragment (org.eclipse.jdt.core.dom.VariableDeclarationFragment)33 ClassInstanceCreation (org.eclipse.jdt.core.dom.ClassInstanceCreation)31 PrefixExpression (org.eclipse.jdt.core.dom.PrefixExpression)31 AST (org.eclipse.jdt.core.dom.AST)30 IMethodBinding (org.eclipse.jdt.core.dom.IMethodBinding)29 ThisExpression (org.eclipse.jdt.core.dom.ThisExpression)28