Search in sources :

Example 6 with CatchStatement

use of org.codehaus.groovy.ast.stmt.CatchStatement in project groovy by apache.

the class ReturnAdder method addReturnsIfNeeded.

private Statement addReturnsIfNeeded(final Statement statement, final VariableScope scope) {
    if (statement instanceof ReturnStatement || statement instanceof ThrowStatement || statement instanceof EmptyStatement || statement instanceof BytecodeSequence) {
        return statement;
    }
    if (statement == null) {
        ReturnStatement returnStatement = new ReturnStatement(nullX());
        listener.returnStatementAdded(returnStatement);
        return returnStatement;
    }
    if (statement instanceof ExpressionStatement) {
        Expression expression = ((ExpressionStatement) statement).getExpression();
        ReturnStatement returnStatement = new ReturnStatement(expression);
        returnStatement.copyStatementLabels(statement);
        returnStatement.setSourcePosition(statement.getLineNumber() < 0 ? expression : statement);
        listener.returnStatementAdded(returnStatement);
        return returnStatement;
    }
    if (statement instanceof SynchronizedStatement) {
        SynchronizedStatement syncStatement = (SynchronizedStatement) statement;
        Statement code = addReturnsIfNeeded(syncStatement.getCode(), scope);
        if (doAdd)
            syncStatement.setCode(code);
        return syncStatement;
    }
    if (statement instanceof IfStatement) {
        IfStatement ifElseStatement = (IfStatement) statement;
        Statement ifBlock = addReturnsIfNeeded(ifElseStatement.getIfBlock(), scope);
        Statement elseBlock = addReturnsIfNeeded(ifElseStatement.getElseBlock(), scope);
        if (doAdd) {
            ifElseStatement.setIfBlock(ifBlock);
            ifElseStatement.setElseBlock(elseBlock);
        }
        return ifElseStatement;
    }
    if (statement instanceof SwitchStatement) {
        SwitchStatement switchStatement = (SwitchStatement) statement;
        Statement defaultStatement = switchStatement.getDefaultStatement();
        List<CaseStatement> caseStatements = switchStatement.getCaseStatements();
        for (Iterator<CaseStatement> it = caseStatements.iterator(); it.hasNext(); ) {
            CaseStatement caseStatement = it.next();
            Statement code = adjustSwitchCaseCode(caseStatement.getCode(), scope, // GROOVY-9896: return if no default and last case lacks break
            defaultStatement == EmptyStatement.INSTANCE && !it.hasNext());
            if (doAdd)
                caseStatement.setCode(code);
        }
        defaultStatement = adjustSwitchCaseCode(defaultStatement, scope, true);
        if (doAdd)
            switchStatement.setDefaultStatement(defaultStatement);
        return switchStatement;
    }
    if (statement instanceof TryCatchStatement) {
        TryCatchStatement tryCatchFinally = (TryCatchStatement) statement;
        boolean[] missesReturn = new boolean[1];
        new ReturnAdder(returnStatement -> missesReturn[0] = true).addReturnsIfNeeded(tryCatchFinally.getFinallyStatement(), scope);
        boolean hasFinally = !(tryCatchFinally.getFinallyStatement() instanceof EmptyStatement);
        // there is nothing to do
        if (hasFinally && !missesReturn[0])
            return tryCatchFinally;
        // add returns to try and catch blocks
        Statement tryStatement = addReturnsIfNeeded(tryCatchFinally.getTryStatement(), scope);
        if (doAdd)
            tryCatchFinally.setTryStatement(tryStatement);
        for (CatchStatement catchStatement : tryCatchFinally.getCatchStatements()) {
            Statement code = addReturnsIfNeeded(catchStatement.getCode(), scope);
            if (doAdd)
                catchStatement.setCode(code);
        }
        return tryCatchFinally;
    }
    if (statement instanceof BlockStatement) {
        BlockStatement blockStatement = (BlockStatement) statement;
        if (blockStatement.isEmpty()) {
            ReturnStatement returnStatement = new ReturnStatement(nullX());
            returnStatement.copyStatementLabels(blockStatement);
            returnStatement.setSourcePosition(blockStatement);
            listener.returnStatementAdded(returnStatement);
            return returnStatement;
        } else {
            List<Statement> statements = blockStatement.getStatements();
            int lastIndex = statements.size() - 1;
            Statement last = addReturnsIfNeeded(statements.get(lastIndex), blockStatement.getVariableScope());
            if (doAdd)
                statements.set(lastIndex, last);
            return blockStatement;
        }
    }
    List<Statement> statements = new ArrayList<>(2);
    statements.add(statement);
    ReturnStatement returnStatement = new ReturnStatement(nullX());
    listener.returnStatementAdded(returnStatement);
    statements.add(returnStatement);
    BlockStatement blockStatement = new BlockStatement(statements, new VariableScope(scope));
    blockStatement.setSourcePosition(statement);
    return blockStatement;
}
Also used : Statement(org.codehaus.groovy.ast.stmt.Statement) VariableScope(org.codehaus.groovy.ast.VariableScope) Iterator(java.util.Iterator) BreakStatement(org.codehaus.groovy.ast.stmt.BreakStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) SynchronizedStatement(org.codehaus.groovy.ast.stmt.SynchronizedStatement) ArrayList(java.util.ArrayList) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) Objects(java.util.Objects) SwitchStatement(org.codehaus.groovy.ast.stmt.SwitchStatement) IfStatement(org.codehaus.groovy.ast.stmt.IfStatement) List(java.util.List) MethodNode(org.codehaus.groovy.ast.MethodNode) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) ThrowStatement(org.codehaus.groovy.ast.stmt.ThrowStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) GeneralUtils.nullX(org.codehaus.groovy.ast.tools.GeneralUtils.nullX) CaseStatement(org.codehaus.groovy.ast.stmt.CaseStatement) Expression(org.codehaus.groovy.ast.expr.Expression) DefaultGroovyMethods.last(org.codehaus.groovy.runtime.DefaultGroovyMethods.last) Statement(org.codehaus.groovy.ast.stmt.Statement) BreakStatement(org.codehaus.groovy.ast.stmt.BreakStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) SynchronizedStatement(org.codehaus.groovy.ast.stmt.SynchronizedStatement) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) SwitchStatement(org.codehaus.groovy.ast.stmt.SwitchStatement) IfStatement(org.codehaus.groovy.ast.stmt.IfStatement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) ThrowStatement(org.codehaus.groovy.ast.stmt.ThrowStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) CaseStatement(org.codehaus.groovy.ast.stmt.CaseStatement) CaseStatement(org.codehaus.groovy.ast.stmt.CaseStatement) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) ArrayList(java.util.ArrayList) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) SynchronizedStatement(org.codehaus.groovy.ast.stmt.SynchronizedStatement) IfStatement(org.codehaus.groovy.ast.stmt.IfStatement) SwitchStatement(org.codehaus.groovy.ast.stmt.SwitchStatement) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) Expression(org.codehaus.groovy.ast.expr.Expression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) ThrowStatement(org.codehaus.groovy.ast.stmt.ThrowStatement) VariableScope(org.codehaus.groovy.ast.VariableScope)

Example 7 with CatchStatement

use of org.codehaus.groovy.ast.stmt.CatchStatement in project groovy by apache.

the class FinalVariableAnalyzer method visitTryCatchFinally.

@Override
public void visitTryCatchFinally(final TryCatchStatement statement) {
    visitStatement(statement);
    Map<Variable, VariableState> beforeTryState = new HashMap<>(getState());
    pushState();
    Statement tryStatement = statement.getTryStatement();
    tryStatement.visit(this);
    Map<Variable, VariableState> afterTryState = new HashMap<>(getState());
    Statement finallyStatement = statement.getFinallyStatement();
    List<Map<Variable, VariableState>> afterStates = new ArrayList<>();
    // the try finally case
    finallyStatement.visit(this);
    if (!returningBlock(tryStatement)) {
        afterStates.add(new HashMap<>(getState()));
    }
    popState();
    // now the finally only case but only if no catches
    if (statement.getCatchStatements().isEmpty()) {
        finallyStatement.visit(this);
        if (!returningBlock(tryStatement)) {
            afterStates.add(new HashMap<>(getState()));
        }
    }
    for (CatchStatement catchStatement : statement.getCatchStatements()) {
        // We don't try to analyse which statement within the try block might have thrown an exception.
        // We make a crude assumption that anywhere from none to all of the statements might have been executed.
        // Run visitor for both scenarios so the eager checks will be performed for either of these cases.
        visitCatchFinally(beforeTryState, afterStates, catchStatement, finallyStatement);
        visitCatchFinally(afterTryState, afterStates, catchStatement, finallyStatement);
    }
    // after states can only be empty if try and catch statements all return in which case nothing to do
    if (afterStates.isEmpty())
        return;
    // now adjust the state variables - any early returns won't have gotten here
    // but we need to check that the same status was observed by all paths
    // and mark as ambiguous if needed
    Map<Variable, VariableState> corrected = afterStates.remove(0);
    for (Map<Variable, VariableState> nextState : afterStates) {
        for (Map.Entry<Variable, VariableState> entry : corrected.entrySet()) {
            Variable var = entry.getKey();
            VariableState currentCorrectedState = entry.getValue();
            VariableState candidateCorrectedState = nextState.get(var);
            if (currentCorrectedState == VariableState.is_ambiguous)
                continue;
            if (currentCorrectedState != candidateCorrectedState) {
                if (currentCorrectedState == VariableState.is_uninitialized || candidateCorrectedState == VariableState.is_uninitialized) {
                    corrected.put(var, VariableState.is_ambiguous);
                } else {
                    corrected.put(var, VariableState.is_var);
                }
            }
        }
    }
    getState().putAll(corrected);
}
Also used : Variable(org.codehaus.groovy.ast.Variable) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) HashMap(java.util.HashMap) Statement(org.codehaus.groovy.ast.stmt.Statement) ThrowStatement(org.codehaus.groovy.ast.stmt.ThrowStatement) CaseStatement(org.codehaus.groovy.ast.stmt.CaseStatement) ContinueStatement(org.codehaus.groovy.ast.stmt.ContinueStatement) BreakStatement(org.codehaus.groovy.ast.stmt.BreakStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) SwitchStatement(org.codehaus.groovy.ast.stmt.SwitchStatement) IfStatement(org.codehaus.groovy.ast.stmt.IfStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) ArrayList(java.util.ArrayList) HashMap(java.util.HashMap) Map(java.util.Map)

Example 8 with CatchStatement

use of org.codehaus.groovy.ast.stmt.CatchStatement in project groovy by apache.

the class CodeVisitorSupport method visitTryCatchFinally.

@Override
public void visitTryCatchFinally(TryCatchStatement statement) {
    statement.getTryStatement().visit(this);
    for (CatchStatement catchStatement : statement.getCatchStatements()) {
        catchStatement.visit(this);
    }
    statement.getFinallyStatement().visit(this);
}
Also used : CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement)

Example 9 with CatchStatement

use of org.codehaus.groovy.ast.stmt.CatchStatement in project groovy by apache.

the class StaticTypeCheckingVisitor method visitTryCatchFinally.

@Override
public void visitTryCatchFinally(final TryCatchStatement statement) {
    List<CatchStatement> catchStatements = statement.getCatchStatements();
    for (CatchStatement catchStatement : catchStatements) {
        ClassNode exceptionType = catchStatement.getExceptionType();
        typeCheckingContext.controlStructureVariables.put(catchStatement.getVariable(), exceptionType);
    }
    try {
        super.visitTryCatchFinally(statement);
    } finally {
        for (CatchStatement catchStatement : catchStatements) {
            typeCheckingContext.controlStructureVariables.remove(catchStatement.getVariable());
        }
    }
}
Also used : StaticTypeCheckingSupport.findDGMMethodsForClassNode(org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.findDGMMethodsForClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement)

Example 10 with CatchStatement

use of org.codehaus.groovy.ast.stmt.CatchStatement in project groovy by apache.

the class TryCatchBlockGenerator method generateTryCatchBlockForInlineMode.

public static BlockStatement generateTryCatchBlockForInlineMode(final ClassNode assertionErrorClass, final String message, final Statement assertStatement) {
    final Class powerAssertionErrorClass = loadPowerAssertionErrorClass();
    if (powerAssertionErrorClass == null)
        throw new GroovyBugError("groovy-contracts needs Groovy 1.7 or above!");
    VariableExpression newError = localVarX("newError", assertionErrorClass);
    Statement block = block(// newError = message + error.message
    declS(newError, ctorX(assertionErrorClass, args(binX(constX(message), PLUS, callX(varX(param(ClassHelper.makeWithoutCaching(powerAssertionErrorClass), "error")), "getMessage"))))), // newError.stackTrace = error.stackTrace
    stmt(callX(newError, "setStackTrace", args(callX(varX(param(ClassHelper.makeWithoutCaching(powerAssertionErrorClass), "error")), "getStackTrace")))), throwS(newError));
    CatchStatement catchStatement = catchS(param(ClassHelper.makeWithoutCaching(powerAssertionErrorClass), "error"), block);
    return block(tryCatchS(assertStatement, EmptyStatement.INSTANCE, catchStatement));
}
Also used : CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) Statement(org.codehaus.groovy.ast.stmt.Statement) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) GroovyBugError(org.codehaus.groovy.GroovyBugError) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression)

Aggregations

CatchStatement (org.codehaus.groovy.ast.stmt.CatchStatement)18 TryCatchStatement (org.codehaus.groovy.ast.stmt.TryCatchStatement)16 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)15 IfStatement (org.codehaus.groovy.ast.stmt.IfStatement)11 Statement (org.codehaus.groovy.ast.stmt.Statement)11 EmptyStatement (org.codehaus.groovy.ast.stmt.EmptyStatement)10 ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)10 ThrowStatement (org.codehaus.groovy.ast.stmt.ThrowStatement)10 ReturnStatement (org.codehaus.groovy.ast.stmt.ReturnStatement)9 BreakStatement (org.codehaus.groovy.ast.stmt.BreakStatement)8 CaseStatement (org.codehaus.groovy.ast.stmt.CaseStatement)8 SwitchStatement (org.codehaus.groovy.ast.stmt.SwitchStatement)8 Parameter (org.codehaus.groovy.ast.Parameter)7 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)7 ContinueStatement (org.codehaus.groovy.ast.stmt.ContinueStatement)7 ForStatement (org.codehaus.groovy.ast.stmt.ForStatement)7 ClassNode (org.codehaus.groovy.ast.ClassNode)6 SynchronizedStatement (org.codehaus.groovy.ast.stmt.SynchronizedStatement)6 Expression (org.codehaus.groovy.ast.expr.Expression)5 AssertStatement (org.codehaus.groovy.ast.stmt.AssertStatement)5