Search in sources :

Example 1 with AggregateASTVisitor

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

use of org.autorefactor.refactoring.rules.AggregateASTVisitor 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, IProgressMonitor monitor) throws Exception {
    // creation of DOM/AST from a ICompilationUnit
    final ASTParser parser = ASTParser.newParser(AST.JLS4);
    resetParser(compilationUnit, parser, options);
    CompilationUnit astRoot = (CompilationUnit) parser.createAST(null);
    int totalNbLoops = 0;
    Set<ASTVisitor> lastLoopVisitors = Collections.emptySet();
    int nbLoopsWithSameVisitors = 0;
    while (true) {
        if (totalNbLoops > 100) {
            // 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);
        ++totalNbLoops;
        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 3 with AggregateASTVisitor

use of org.autorefactor.refactoring.rules.AggregateASTVisitor in project AutoRefactor by JnRouvignac.

the class ApplyRefactoringsJob method run0.

private IStatus run0(IProgressMonitor monitor) throws Exception {
    if (refactoringUnits.isEmpty()) {
        // No java project exists.
        return Status.OK_STATUS;
    }
    final SubMonitor loopMonitor = SubMonitor.convert(monitor, refactoringUnits.size());
    try {
        RefactoringUnit toRefactor;
        while ((toRefactor = refactoringUnits.poll()) != null) {
            final ICompilationUnit compilationUnit = toRefactor.getCompilationUnit();
            final JavaProjectOptions options = toRefactor.getOptions();
            try {
                loopMonitor.subTask("Applying refactorings to " + getClassName(compilationUnit));
                final AggregateASTVisitor refactoring = new AggregateASTVisitor(refactoringRulesToApply);
                applyRefactoring(compilationUnit, refactoring, options, loopMonitor.newChild(1));
            } catch (OperationCanceledException e) {
                throw e;
            } catch (Exception e) {
                final String msg = "Exception when applying refactorings to file \"" + compilationUnit.getPath() + "\": " + e.getMessage();
                throw new UnhandledException(null, msg, e);
            }
        }
    } finally {
        loopMonitor.done();
    }
    return Status.OK_STATUS;
}
Also used : UnhandledException(org.autorefactor.util.UnhandledException) ICompilationUnit(org.eclipse.jdt.core.ICompilationUnit) OperationCanceledException(org.eclipse.core.runtime.OperationCanceledException) SubMonitor(org.eclipse.core.runtime.SubMonitor) AggregateASTVisitor(org.autorefactor.refactoring.rules.AggregateASTVisitor) OperationCanceledException(org.eclipse.core.runtime.OperationCanceledException) IllegalStateException(org.autorefactor.util.IllegalStateException) UnhandledException(org.autorefactor.util.UnhandledException)

Aggregations

AggregateASTVisitor (org.autorefactor.refactoring.rules.AggregateASTVisitor)3 IllegalStateException (org.autorefactor.util.IllegalStateException)3 ICompilationUnit (org.eclipse.jdt.core.ICompilationUnit)3 RefactoringContext (org.autorefactor.refactoring.rules.RefactoringContext)2 ASTParser (org.eclipse.jdt.core.dom.ASTParser)2 ASTVisitor (org.eclipse.jdt.core.dom.ASTVisitor)2 CompilationUnit (org.eclipse.jdt.core.dom.CompilationUnit)2 UnhandledException (org.autorefactor.util.UnhandledException)1 OperationCanceledException (org.eclipse.core.runtime.OperationCanceledException)1 SubMonitor (org.eclipse.core.runtime.SubMonitor)1