Search in sources :

Example 1 with IllegalStateException

use of org.autorefactor.util.IllegalStateException in project AutoRefactor by JnRouvignac.

the class ReduceVariableScopeRefactoring method replace.

private void replace(VariableAccess varDecl, VariableAccess varAccess) {
    final ASTBuilder b = this.ctx.getASTBuilder();
    final AST ast = b.getAST();
    final ASTNode scope = varAccess.getScope();
    final Name varName = varAccess.getVariableName();
    final Type varType = getType(varDecl.getVariableName().getParent());
    if (scope instanceof Block) {
        final List<Statement> stmts = statements((Block) scope);
        for (int i = 0; i < stmts.size(); i++) {
            final Statement stmt = stmts.get(i);
            // FIXME i=0
            final Expression parentExpr = getAncestor(varName, Expression.class);
            // FIXME i=0
            final Statement parentStmt = getAncestor(parentExpr, Statement.class);
            if (stmt.equals(parentStmt)) {
                final VariableDeclarationFragment vdf = getVariableDeclarationFragment(parentExpr, varName);
                final VariableDeclarationStatement vds = ast.newVariableDeclarationStatement(vdf);
                vds.setType(varType);
                this.ctx.getRefactorings().replace(stmt, vds);
                break;
            }
        }
    } else if (scope instanceof EnhancedForStatement) {
        final EnhancedForStatement efs = (EnhancedForStatement) scope;
        final EnhancedForStatement newEfs = b.copy(efs);
        newEfs.setParameter(b.copy(efs.getParameter()));
        newEfs.setExpression(b.copy(efs.getExpression()));
        final Statement parentStmt = getAncestor(varName, Statement.class);
        if (equalNotNull(efs.getBody(), parentStmt)) {
            newEfs.setBody(copy(efs.getBody(), varName));
        }
        this.ctx.getRefactorings().replace(efs, newEfs);
    } else if (scope instanceof ForStatement) {
        final ForStatement fs = (ForStatement) scope;
        final ForStatement newFs = b.copy(fs);
        final List<Expression> initializers = initializers(newFs);
        if (initializers.size() == 1) {
            final Expression init = initializers.remove(0);
            final VariableDeclarationFragment vdf = getVariableDeclarationFragment(init, varName);
            final VariableDeclarationExpression vde = ast.newVariableDeclarationExpression(vdf);
            vde.setType(varType);
            initializers.add(vde);
            this.ctx.getRefactorings().replace(fs, newFs);
        // TODO JNR
        // if (equalNotNull(fs.getBody(), parentStmt)) {
        // newFs.setBody(copy(fs.getBody()));
        // }
        } else {
            throw new NotImplementedException(scope, "for more than one initializer in for loop.");
        }
    } else if (scope instanceof WhileStatement) {
        final WhileStatement ws = (WhileStatement) scope;
        final WhileStatement newWs = ast.newWhileStatement();
        newWs.setExpression(b.copy(ws.getExpression()));
        final Statement parentStmt = getAncestor(varName, Statement.class);
        if (equalNotNull(ws.getBody(), parentStmt)) {
            newWs.setBody(copy(ws.getBody(), varName));
        }
        this.ctx.getRefactorings().replace(ws, newWs);
    } else if (scope instanceof IfStatement) {
        final IfStatement is = (IfStatement) scope;
        final IfStatement newIs = ast.newIfStatement();
        newIs.setExpression(b.copy(is.getExpression()));
        final Statement parentStmt = getAncestor(varName, Statement.class);
        if (equalNotNull(is.getThenStatement(), parentStmt)) {
            newIs.setThenStatement(copy(is.getThenStatement(), varName));
            if (is.getElseStatement() != null) {
                newIs.setElseStatement(b.copy(is.getElseStatement()));
            }
            this.ctx.getRefactorings().replace(is, newIs);
        } else if (equalNotNull(is.getElseStatement(), parentStmt)) {
            if (is.getThenStatement() != null) {
                newIs.setThenStatement(b.copy(is.getThenStatement()));
            }
            newIs.setElseStatement(copy(is.getElseStatement(), varName));
            this.ctx.getRefactorings().replace(is, newIs);
        } else {
            throw new IllegalStateException(is, "Parent statement should be inside the then or else statement of this if statement: " + is);
        }
    } else {
        throw new NotImplementedException(scope);
    }
}
Also used : IllegalStateException(org.autorefactor.util.IllegalStateException) AST(org.eclipse.jdt.core.dom.AST) ExpressionStatement(org.eclipse.jdt.core.dom.ExpressionStatement) Statement(org.eclipse.jdt.core.dom.Statement) IfStatement(org.eclipse.jdt.core.dom.IfStatement) WhileStatement(org.eclipse.jdt.core.dom.WhileStatement) ForStatement(org.eclipse.jdt.core.dom.ForStatement) EnhancedForStatement(org.eclipse.jdt.core.dom.EnhancedForStatement) VariableDeclarationStatement(org.eclipse.jdt.core.dom.VariableDeclarationStatement) VariableDeclarationExpression(org.eclipse.jdt.core.dom.VariableDeclarationExpression) NotImplementedException(org.autorefactor.util.NotImplementedException) WhileStatement(org.eclipse.jdt.core.dom.WhileStatement) ASTBuilder(org.autorefactor.refactoring.ASTBuilder) SimpleName(org.eclipse.jdt.core.dom.SimpleName) Name(org.eclipse.jdt.core.dom.Name) QualifiedName(org.eclipse.jdt.core.dom.QualifiedName) IfStatement(org.eclipse.jdt.core.dom.IfStatement) Type(org.eclipse.jdt.core.dom.Type) PostfixExpression(org.eclipse.jdt.core.dom.PostfixExpression) Expression(org.eclipse.jdt.core.dom.Expression) InfixExpression(org.eclipse.jdt.core.dom.InfixExpression) VariableDeclarationExpression(org.eclipse.jdt.core.dom.VariableDeclarationExpression) VariableDeclarationFragment(org.eclipse.jdt.core.dom.VariableDeclarationFragment) ASTNode(org.eclipse.jdt.core.dom.ASTNode) Block(org.eclipse.jdt.core.dom.Block) VariableDeclarationStatement(org.eclipse.jdt.core.dom.VariableDeclarationStatement) EnhancedForStatement(org.eclipse.jdt.core.dom.EnhancedForStatement) ForStatement(org.eclipse.jdt.core.dom.ForStatement) EnhancedForStatement(org.eclipse.jdt.core.dom.EnhancedForStatement)

Example 2 with IllegalStateException

use of org.autorefactor.util.IllegalStateException in project AutoRefactor by JnRouvignac.

the class CFGBuilder method buildCFG.

/**
 * Builds a CFG for the provided node.
 *
 * @param node the node for which to build a CFG.
 * @return the entry block to the CFG of this method declaration
 */
public CFGBasicBlock buildCFG(MethodDeclaration node) {
    final CFGBasicBlock entryBlock = newEntryBlock(node);
    this.exitBlock = newExitBlock(node);
    addDeclarations(entryBlock, parameters(node));
    try {
        final ThrowerBlocks throwers = new ThrowerBlocks();
        final CFGEdgeBuilder liveEdge = new CFGEdgeBuilder(entryBlock);
        final LivenessState liveAfterBody = buildCFG(node.getBody(), LivenessState.of(liveEdge), throwers);
        if (!liveAfterBody.liveEdges.isEmpty()) {
            if (node.getReturnType2() == null || // added for unit tests
            node.getReturnType2().resolveBinding() == null || "void".equals(node.getReturnType2().resolveBinding().getName())) {
                buildEdges(liveAfterBody, exitBlock);
            } else {
                throw new IllegalStateException(node, "Did not expect to find any edges to build " + "for a constructor or a non void method return type.");
            }
        }
        if (!this.edgesToBuild.isEmpty()) {
            throw new IllegalStateException(node, "At this point, there should not be any edges left to build. Left edges: " + this.edgesToBuild);
        }
        List<CFGBasicBlock> throwingBlocks = throwers.selectBlocksThrowing(null);
        if (!throwingBlocks.isEmpty()) {
            for (CFGBasicBlock throwingBlock : throwingBlocks) {
            // TODO JNR
            }
        }
        List<CFGEdgeBuilder> throwingEdges = throwers.selectEdgesThrowing(null);
        if (!throwingEdges.isEmpty()) {
            for (CFGEdgeBuilder throwingEdge : throwingEdges) {
            // TODO JNR
            }
        }
        return entryBlock;
    } finally {
        this.exitBlock = null;
    }
}
Also used : IllegalStateException(org.autorefactor.util.IllegalStateException) CFGEdgeBuilder(org.autorefactor.cfg.CFGEdgeBuilder)

Example 3 with IllegalStateException

use of org.autorefactor.util.IllegalStateException 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 4 with IllegalStateException

use of org.autorefactor.util.IllegalStateException in project AutoRefactor by JnRouvignac.

the class CFGBuilder method getLineAndColumn.

private LineAndColumn getLineAndColumn(final int position) {
    // TODO Use CompilationUnit.getLineNumber() and
    // CompilationUnit.getColumnNumber()
    // Return SourceLocation class with also startNodePosition to be used for graph
    // node names
    // line number and column number are then used as comments for the node
    // file starts with line 1
    int lineNo = 1;
    int lastMatchPosition = 0;
    Matcher matcher = NEWLINE.matcher(source);
    while (matcher.find()) {
        MatchResult matchResult = matcher.toMatchResult();
        if (matchResult.end() >= position) {
            String startOfLine = this.source.substring(lastMatchPosition, position);
            int nbChars = countCharacters(startOfLine, tabSize);
            // + 1 because line starts with column 1
            return new LineAndColumn(position, lineNo, nbChars + 1);
        }
        lastMatchPosition = matchResult.end();
        ++lineNo;
    }
    // $NON-NLS-1$
    throw new IllegalStateException(null, "A line and column number should have been found");
}
Also used : IllegalStateException(org.autorefactor.util.IllegalStateException) Matcher(java.util.regex.Matcher) MatchResult(java.util.regex.MatchResult)

Example 5 with IllegalStateException

use of org.autorefactor.util.IllegalStateException 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)

Aggregations

IllegalStateException (org.autorefactor.util.IllegalStateException)9 ICompilationUnit (org.eclipse.jdt.core.ICompilationUnit)3 ASTNode (org.eclipse.jdt.core.dom.ASTNode)3 ASTParser (org.eclipse.jdt.core.dom.ASTParser)3 ASTVisitor (org.eclipse.jdt.core.dom.ASTVisitor)3 CompilationUnit (org.eclipse.jdt.core.dom.CompilationUnit)3 AggregateASTVisitor (org.autorefactor.refactoring.rules.AggregateASTVisitor)2 RefactoringContext (org.autorefactor.refactoring.rules.RefactoringContext)2 Expression (org.eclipse.jdt.core.dom.Expression)2 ArrayList (java.util.ArrayList)1 MatchResult (java.util.regex.MatchResult)1 Matcher (java.util.regex.Matcher)1 CFGEdgeBuilder (org.autorefactor.cfg.CFGEdgeBuilder)1 ASTRewrite (org.autorefactor.jdt.core.dom.ASTRewrite)1 CompilationUnitRewrite (org.autorefactor.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite)1 AggregateASTVisitor (org.autorefactor.jdt.internal.ui.fix.AggregateASTVisitor)1 ASTBuilder (org.autorefactor.refactoring.ASTBuilder)1 ASTHelper.asExpression (org.autorefactor.refactoring.ASTHelper.asExpression)1 NotImplementedException (org.autorefactor.util.NotImplementedException)1 AST (org.eclipse.jdt.core.dom.AST)1