Search in sources :

Example 1 with Variable

use of org.autorefactor.refactoring.Variable 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 2 with Variable

use of org.autorefactor.refactoring.Variable 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)

Aggregations

ASTBuilder (org.autorefactor.refactoring.ASTBuilder)2 Refactorings (org.autorefactor.refactoring.Refactorings)2 TypeNameDecider (org.autorefactor.refactoring.TypeNameDecider)2 Variable (org.autorefactor.refactoring.Variable)2 VariableDeclarationStatement (org.eclipse.jdt.core.dom.VariableDeclarationStatement)2 Block (org.eclipse.jdt.core.dom.Block)1 ExpressionStatement (org.eclipse.jdt.core.dom.ExpressionStatement)1 FieldAccess (org.eclipse.jdt.core.dom.FieldAccess)1 ITypeBinding (org.eclipse.jdt.core.dom.ITypeBinding)1 IfStatement (org.eclipse.jdt.core.dom.IfStatement)1 InfixExpression (org.eclipse.jdt.core.dom.InfixExpression)1 MethodInvocation (org.eclipse.jdt.core.dom.MethodInvocation)1 ReturnStatement (org.eclipse.jdt.core.dom.ReturnStatement)1 SingleVariableDeclaration (org.eclipse.jdt.core.dom.SingleVariableDeclaration)1 Statement (org.eclipse.jdt.core.dom.Statement)1 SwitchStatement (org.eclipse.jdt.core.dom.SwitchStatement)1 Type (org.eclipse.jdt.core.dom.Type)1