Search in sources :

Example 16 with ASTVisitor

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

the class ApplyRefactoringsJob method applyRefactoring.

/**
 * Applies the refactorings provided inside the {@link AggregateASTVisitor} to the provided
 * {@link ICompilationUnit}.
 *
 * @param document the document where the compilation unit comes from
 * @param compilationUnit the compilation unit to refactor
 * @param refactoring the {@link AggregateASTVisitor} to apply to the compilation unit
 * @param options the Java project options used to compile the project
 * @param monitor the progress monitor of the current job
 * @throws Exception if any problem occurs
 *
 * @see <a
 * href="http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.jdt.doc.isv%2Fguide%2Fjdt_api_manip.htm"
 * >Eclipse JDT core - Manipulating Java code</a>
 * @see <a href="
 * http://help.eclipse.org/indigo/index.jsp?topic=/org.eclipse.platform.doc.isv/guide/workbench_cmd_menus.htm"
 * > Eclipse Platform Plug-in Developer Guide > Plugging into the workbench
 * > Basic workbench extension points using commands > org.eclipse.ui.menus</a>
 * @see <a
 * href="http://www.eclipse.org/articles/article.php?file=Article-JavaCodeManipulation_AST/index.html"
 * >Abstract Syntax Tree > Write it down</a>
 */
public void applyRefactoring(IDocument document, ICompilationUnit compilationUnit, AggregateASTVisitor refactoring, JavaProjectOptions options, SubMonitor monitor) throws Exception {
    // creation of DOM/AST from a ICompilationUnit
    final ASTParser parser = ASTParser.newParser(AST.JLS8);
    resetParser(compilationUnit, parser, options);
    CompilationUnit astRoot = (CompilationUnit) parser.createAST(null);
    final int maxIterations = 100;
    int iterationCount = 0;
    Set<ASTVisitor> lastLoopVisitors = Collections.emptySet();
    int nbLoopsWithSameVisitors = 0;
    monitor.setWorkRemaining(maxIterations);
    while (true) {
        if (iterationCount > maxIterations) {
            // Oops! Something went wrong.
            final String errorMsg = "An infinite loop has been detected for file " + getFileName(astRoot) + "." + " A possible cause is that code is being incorrectly" + " refactored one way then refactored back to what it was." + " Fix the code before pursuing." + getPossibleCulprits(nbLoopsWithSameVisitors, lastLoopVisitors);
            environment.getLogger().error(errorMsg, new IllegalStateException(astRoot, errorMsg));
            break;
        }
        final RefactoringContext ctx = new RefactoringContext(compilationUnit, astRoot, options, monitor, environment);
        refactoring.setRefactoringContext(ctx);
        final Refactorings refactorings = refactoring.getRefactorings(astRoot);
        if (!refactorings.hasRefactorings()) {
            // we are done with applying the refactorings.
            return;
        }
        // apply the refactorings and save the compilation unit
        refactorings.applyTo(document);
        final boolean hadUnsavedChanges = compilationUnit.hasUnsavedChanges();
        compilationUnit.getBuffer().setContents(document.get());
        // , null, null);
        if (!hadUnsavedChanges) {
            compilationUnit.save(null, true);
        }
        // I did not find any other way to directly modify the AST
        // while still keeping the resolved type bindings working.
        // Using astRoot.recordModifications() did not work:
        // type bindings were lost. Is there a way to recover them?
        // FIXME we should find a way to apply all the changes at
        // the AST level and refresh the bindings
        resetParser(compilationUnit, parser, options);
        astRoot = (CompilationUnit) parser.createAST(null);
        ++iterationCount;
        final Set<ASTVisitor> thisLoopVisitors = refactoring.getVisitorsContributingRefactoring();
        if (!thisLoopVisitors.equals(lastLoopVisitors)) {
            lastLoopVisitors = new HashSet<ASTVisitor>(thisLoopVisitors);
            nbLoopsWithSameVisitors = 0;
        } else {
            ++nbLoopsWithSameVisitors;
        }
    }
}
Also used : ICompilationUnit(org.eclipse.jdt.core.ICompilationUnit) CompilationUnit(org.eclipse.jdt.core.dom.CompilationUnit) IllegalStateException(org.autorefactor.util.IllegalStateException) ASTParser(org.eclipse.jdt.core.dom.ASTParser) RefactoringContext(org.autorefactor.refactoring.rules.RefactoringContext) AggregateASTVisitor(org.autorefactor.refactoring.rules.AggregateASTVisitor) ASTVisitor(org.eclipse.jdt.core.dom.ASTVisitor)

Example 17 with ASTVisitor

use of org.eclipse.jdt.core.dom.ASTVisitor in project che by eclipse.

the class ConvertIterableLoopOperation method satisfiesPreconditions.

/**
	 * Is this proposal applicable?
	 *
	 * @return A status with severity <code>IStatus.Error</code> if not
	 *         applicable
	 */
@Override
public final IStatus satisfiesPreconditions() {
    IStatus resultStatus = StatusInfo.OK_STATUS;
    if (JavaModelUtil.is50OrHigher(getJavaProject())) {
        resultStatus = checkExpressionCondition();
        if (resultStatus.getSeverity() == IStatus.ERROR)
            return resultStatus;
        List<Expression> updateExpressions = getForStatement().updaters();
        if (updateExpressions.size() == 1) {
            resultStatus = new StatusInfo(IStatus.WARNING, Messages.format(FixMessages.ConvertIterableLoopOperation_RemoveUpdateExpression_Warning, BasicElementLabels.getJavaCodeString(updateExpressions.get(0).toString())));
        } else if (updateExpressions.size() > 1) {
            resultStatus = new StatusInfo(IStatus.WARNING, FixMessages.ConvertIterableLoopOperation_RemoveUpdateExpressions_Warning);
        }
        for (final Iterator<Expression> outer = getForStatement().initializers().iterator(); outer.hasNext(); ) {
            final Expression initializer = outer.next();
            if (initializer instanceof VariableDeclarationExpression) {
                final VariableDeclarationExpression declaration = (VariableDeclarationExpression) initializer;
                List<VariableDeclarationFragment> fragments = declaration.fragments();
                if (fragments.size() != 1) {
                    //$NON-NLS-1$
                    return new StatusInfo(IStatus.ERROR, "");
                } else {
                    final VariableDeclarationFragment fragment = fragments.get(0);
                    fragment.accept(new ASTVisitor() {

                        @Override
                        public final boolean visit(final MethodInvocation node) {
                            final IMethodBinding binding = node.resolveMethodBinding();
                            if (binding != null) {
                                final ITypeBinding type = binding.getReturnType();
                                if (type != null) {
                                    final String qualified = type.getQualifiedName();
                                    if (qualified.startsWith("java.util.Enumeration<") || qualified.startsWith("java.util.Iterator<")) {
                                        //$NON-NLS-1$ //$NON-NLS-2$
                                        final Expression qualifier = node.getExpression();
                                        if (qualifier != null) {
                                            final ITypeBinding resolved = qualifier.resolveTypeBinding();
                                            if (resolved != null) {
                                                //$NON-NLS-1$
                                                final ITypeBinding iterable = getSuperType(resolved, "java.lang.Iterable");
                                                if (iterable != null) {
                                                    fExpression = qualifier;
                                                    fIterable = resolved;
                                                }
                                            }
                                        } else {
                                            final ITypeBinding declaring = binding.getDeclaringClass();
                                            if (declaring != null) {
                                                //$NON-NLS-1$
                                                final ITypeBinding superBinding = getSuperType(declaring, "java.lang.Iterable");
                                                if (superBinding != null) {
                                                    fIterable = superBinding;
                                                    fThis = true;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            return true;
                        }

                        @Override
                        public final boolean visit(final VariableDeclarationFragment node) {
                            final IVariableBinding binding = node.resolveBinding();
                            if (binding != null) {
                                final ITypeBinding type = binding.getType();
                                if (type != null) {
                                    //$NON-NLS-1$
                                    ITypeBinding iterator = getSuperType(type, "java.util.Iterator");
                                    if (iterator != null)
                                        fIteratorVariable = binding;
                                    else {
                                        //$NON-NLS-1$
                                        iterator = getSuperType(type, "java.util.Enumeration");
                                        if (iterator != null)
                                            fIteratorVariable = binding;
                                    }
                                }
                            }
                            return true;
                        }
                    });
                }
            }
        }
        final Statement statement = getForStatement().getBody();
        final boolean[] otherInvocationThenNext = new boolean[] { false };
        final int[] nextInvocationCount = new int[] { 0 };
        if (statement != null && fIteratorVariable != null) {
            final ITypeBinding elementType = getElementType(fIteratorVariable.getType());
            statement.accept(new ASTVisitor() {

                @Override
                public boolean visit(SimpleName node) {
                    IBinding nodeBinding = node.resolveBinding();
                    if (fElementVariable != null && fElementVariable.equals(nodeBinding)) {
                        fMakeFinal = false;
                    }
                    if (nodeBinding == fIteratorVariable) {
                        if (node.getLocationInParent() == MethodInvocation.EXPRESSION_PROPERTY) {
                            MethodInvocation invocation = (MethodInvocation) node.getParent();
                            String name = invocation.getName().getIdentifier();
                            if (name.equals("next") || name.equals("nextElement")) {
                                //$NON-NLS-1$ //$NON-NLS-2$
                                nextInvocationCount[0]++;
                                Expression left = null;
                                if (invocation.getLocationInParent() == Assignment.RIGHT_HAND_SIDE_PROPERTY) {
                                    left = ((Assignment) invocation.getParent()).getLeftHandSide();
                                } else if (invocation.getLocationInParent() == VariableDeclarationFragment.INITIALIZER_PROPERTY) {
                                    left = ((VariableDeclarationFragment) invocation.getParent()).getName();
                                }
                                return visitElementVariable(left);
                            }
                        }
                        otherInvocationThenNext[0] = true;
                    }
                    return true;
                }

                private boolean visitElementVariable(final Expression node) {
                    if (node != null) {
                        final ITypeBinding binding = node.resolveTypeBinding();
                        if (binding != null && elementType.equals(binding)) {
                            if (node instanceof Name) {
                                final Name name = (Name) node;
                                final IBinding result = name.resolveBinding();
                                if (result != null) {
                                    fOccurrences.add(node);
                                    fElementVariable = result;
                                    return false;
                                }
                            } else if (node instanceof FieldAccess) {
                                final FieldAccess access = (FieldAccess) node;
                                final IBinding result = access.resolveFieldBinding();
                                if (result != null) {
                                    fOccurrences.add(node);
                                    fElementVariable = result;
                                    return false;
                                }
                            }
                        }
                    }
                    return true;
                }
            });
            if (otherInvocationThenNext[0])
                return ERROR_STATUS;
            if (nextInvocationCount[0] > 1)
                return ERROR_STATUS;
            if (fElementVariable != null) {
                statement.accept(new ASTVisitor() {

                    @Override
                    public final boolean visit(final VariableDeclarationFragment node) {
                        if (node.getInitializer() instanceof NullLiteral) {
                            SimpleName name = node.getName();
                            if (elementType.equals(name.resolveTypeBinding()) && fElementVariable.equals(name.resolveBinding())) {
                                fOccurrences.add(name);
                            }
                        }
                        return true;
                    }
                });
            }
        }
        final ASTNode root = getForStatement().getRoot();
        if (root != null) {
            root.accept(new ASTVisitor() {

                @Override
                public final boolean visit(final ForStatement node) {
                    return false;
                }

                @Override
                public final boolean visit(final SimpleName node) {
                    final IBinding binding = node.resolveBinding();
                    if (binding != null && binding.equals(fElementVariable))
                        fAssigned = true;
                    return false;
                }
            });
        }
    }
    if ((fExpression != null || fThis) && fIterable != null && fIteratorVariable != null && !fAssigned) {
        return resultStatus;
    } else {
        return ERROR_STATUS;
    }
}
Also used : IMethodBinding(org.eclipse.jdt.core.dom.IMethodBinding) IStatus(org.eclipse.core.runtime.IStatus) SimpleName(org.eclipse.jdt.core.dom.SimpleName) IBinding(org.eclipse.jdt.core.dom.IBinding) MethodInvocation(org.eclipse.jdt.core.dom.MethodInvocation) SimpleName(org.eclipse.jdt.core.dom.SimpleName) Name(org.eclipse.jdt.core.dom.Name) Assignment(org.eclipse.jdt.core.dom.Assignment) VariableDeclarationFragment(org.eclipse.jdt.core.dom.VariableDeclarationFragment) ITypeBinding(org.eclipse.jdt.core.dom.ITypeBinding) ASTNode(org.eclipse.jdt.core.dom.ASTNode) ForStatement(org.eclipse.jdt.core.dom.ForStatement) EnhancedForStatement(org.eclipse.jdt.core.dom.EnhancedForStatement) Statement(org.eclipse.jdt.core.dom.Statement) ForStatement(org.eclipse.jdt.core.dom.ForStatement) EnhancedForStatement(org.eclipse.jdt.core.dom.EnhancedForStatement) VariableDeclarationExpression(org.eclipse.jdt.core.dom.VariableDeclarationExpression) IVariableBinding(org.eclipse.jdt.core.dom.IVariableBinding) ASTVisitor(org.eclipse.jdt.core.dom.ASTVisitor) Expression(org.eclipse.jdt.core.dom.Expression) VariableDeclarationExpression(org.eclipse.jdt.core.dom.VariableDeclarationExpression) StatusInfo(org.eclipse.jdt.internal.ui.dialogs.StatusInfo) FieldAccess(org.eclipse.jdt.core.dom.FieldAccess) NullLiteral(org.eclipse.jdt.core.dom.NullLiteral)

Example 18 with ASTVisitor

use of org.eclipse.jdt.core.dom.ASTVisitor in project flux by eclipse.

the class ASTNodes method getQualifiedTypeName.

/**
	 * Returns the (potentially qualified) name of a type, followed by array dimensions.
	 * Skips type arguments and type annotations.
	 * 
	 * @param type a type that has a name
	 * @return the name, followed by array dimensions
	 * @since 3.10
	 */
public static String getQualifiedTypeName(Type type) {
    final StringBuffer buffer = new StringBuffer();
    ASTVisitor visitor = new ASTVisitor() {

        @Override
        public boolean visit(SimpleType node) {
            buffer.append(node.getName().getFullyQualifiedName());
            return false;
        }

        @Override
        public boolean visit(QualifiedType node) {
            node.getQualifier().accept(this);
            buffer.append('.');
            buffer.append(node.getName().getIdentifier());
            return false;
        }

        @Override
        public boolean visit(NameQualifiedType node) {
            buffer.append(node.getQualifier().getFullyQualifiedName());
            buffer.append('.');
            buffer.append(node.getName().getIdentifier());
            return false;
        }

        @Override
        public boolean visit(ParameterizedType node) {
            node.getType().accept(this);
            return false;
        }

        @Override
        public void endVisit(ArrayType node) {
            for (int i = 0; i < node.dimensions().size(); i++) {
                //$NON-NLS-1$
                buffer.append("[]");
            }
        }
    };
    type.accept(visitor);
    return buffer.toString();
}
Also used : ParameterizedType(org.eclipse.jdt.core.dom.ParameterizedType) ArrayType(org.eclipse.jdt.core.dom.ArrayType) SimpleType(org.eclipse.jdt.core.dom.SimpleType) NameQualifiedType(org.eclipse.jdt.core.dom.NameQualifiedType) QualifiedType(org.eclipse.jdt.core.dom.QualifiedType) NameQualifiedType(org.eclipse.jdt.core.dom.NameQualifiedType) ASTVisitor(org.eclipse.jdt.core.dom.ASTVisitor)

Example 19 with ASTVisitor

use of org.eclipse.jdt.core.dom.ASTVisitor in project che by eclipse.

the class ImportRemover method divideTypeRefs.

private void divideTypeRefs(List<SimpleName> importNames, List<SimpleName> staticNames, List<SimpleName> removedRefs, List<SimpleName> unremovedRefs) {
    final List<int[]> removedStartsEnds = new ArrayList<int[]>();
    fRoot.accept(new ASTVisitor(true) {

        int fRemovingStart = -1;

        @Override
        public void preVisit(ASTNode node) {
            Object property = node.getProperty(PROPERTY_KEY);
            if (property == REMOVED) {
                if (fRemovingStart == -1) {
                    fRemovingStart = node.getStartPosition();
                } else {
                    /*
						 * Bug in client code: REMOVED node should not be nested inside another REMOVED node without
						 * an intermediate RETAINED node.
						 * Drop REMOVED property to prevent problems later (premature end of REMOVED section).
						 */
                    node.setProperty(PROPERTY_KEY, null);
                }
            } else if (property == RETAINED) {
                if (fRemovingStart != -1) {
                    removedStartsEnds.add(new int[] { fRemovingStart, node.getStartPosition() });
                    fRemovingStart = -1;
                } else {
                    /*
						 * Bug in client code: RETAINED node should not be nested inside another RETAINED node without
						 * an intermediate REMOVED node and must have an enclosing REMOVED node.
						 * Drop RETAINED property to prevent problems later (premature restart of REMOVED section).
						 */
                    node.setProperty(PROPERTY_KEY, null);
                }
            }
            super.preVisit(node);
        }

        @Override
        public void postVisit(ASTNode node) {
            Object property = node.getProperty(PROPERTY_KEY);
            if (property == RETAINED) {
                int end = node.getStartPosition() + node.getLength();
                fRemovingStart = end;
            } else if (property == REMOVED) {
                if (fRemovingStart != -1) {
                    int end = node.getStartPosition() + node.getLength();
                    removedStartsEnds.add(new int[] { fRemovingStart, end });
                    fRemovingStart = -1;
                }
            }
            super.postVisit(node);
        }
    });
    for (Iterator<SimpleName> iterator = importNames.iterator(); iterator.hasNext(); ) {
        SimpleName name = iterator.next();
        if (isInRemoved(name, removedStartsEnds))
            removedRefs.add(name);
        else
            unremovedRefs.add(name);
    }
    for (Iterator<SimpleName> iterator = staticNames.iterator(); iterator.hasNext(); ) {
        SimpleName name = iterator.next();
        if (isInRemoved(name, removedStartsEnds))
            removedRefs.add(name);
        else
            unremovedRefs.add(name);
    }
    for (Iterator<ImportDeclaration> iterator = fInlinedStaticImports.iterator(); iterator.hasNext(); ) {
        ImportDeclaration importDecl = iterator.next();
        Name name = importDecl.getName();
        if (name instanceof QualifiedName)
            name = ((QualifiedName) name).getName();
        removedRefs.add((SimpleName) name);
    }
}
Also used : SimpleName(org.eclipse.jdt.core.dom.SimpleName) QualifiedName(org.eclipse.jdt.core.dom.QualifiedName) ArrayList(java.util.ArrayList) ASTVisitor(org.eclipse.jdt.core.dom.ASTVisitor) SimpleName(org.eclipse.jdt.core.dom.SimpleName) Name(org.eclipse.jdt.core.dom.Name) QualifiedName(org.eclipse.jdt.core.dom.QualifiedName) ASTNode(org.eclipse.jdt.core.dom.ASTNode) ImportDeclaration(org.eclipse.jdt.core.dom.ImportDeclaration)

Example 20 with ASTVisitor

use of org.eclipse.jdt.core.dom.ASTVisitor in project processing by processing.

the class ASTUtils method findAllOccurrences.

protected static List<SimpleName> findAllOccurrences(ASTNode root, String bindingKey) {
    List<SimpleName> occurences = new ArrayList<>();
    root.getRoot().accept(new ASTVisitor() {

        @Override
        public boolean visit(SimpleName name) {
            IBinding binding = resolveBinding(name);
            if (binding != null && bindingKey.equals(binding.getKey())) {
                occurences.add(name);
            }
            return super.visit(name);
        }
    });
    return occurences;
}
Also used : SimpleName(org.eclipse.jdt.core.dom.SimpleName) IBinding(org.eclipse.jdt.core.dom.IBinding) ArrayList(java.util.ArrayList) ASTVisitor(org.eclipse.jdt.core.dom.ASTVisitor)

Aggregations

ASTVisitor (org.eclipse.jdt.core.dom.ASTVisitor)26 SimpleName (org.eclipse.jdt.core.dom.SimpleName)14 ICompilationUnit (org.eclipse.jdt.core.ICompilationUnit)10 ASTNode (org.eclipse.jdt.core.dom.ASTNode)9 CompilationUnit (org.eclipse.jdt.core.dom.CompilationUnit)9 ArrayList (java.util.ArrayList)8 Name (org.eclipse.jdt.core.dom.Name)7 EnhancedForStatement (org.eclipse.jdt.core.dom.EnhancedForStatement)5 ForStatement (org.eclipse.jdt.core.dom.ForStatement)5 IBinding (org.eclipse.jdt.core.dom.IBinding)5 LinkedList (java.util.LinkedList)4 ArrayType (org.eclipse.jdt.core.dom.ArrayType)4 Expression (org.eclipse.jdt.core.dom.Expression)4 ITypeBinding (org.eclipse.jdt.core.dom.ITypeBinding)4 IVariableBinding (org.eclipse.jdt.core.dom.IVariableBinding)4 MethodDeclaration (org.eclipse.jdt.core.dom.MethodDeclaration)4 ParameterizedType (org.eclipse.jdt.core.dom.ParameterizedType)4 SimpleType (org.eclipse.jdt.core.dom.SimpleType)4 Statement (org.eclipse.jdt.core.dom.Statement)4 TypeDeclaration (org.eclipse.jdt.core.dom.TypeDeclaration)4