Search in sources :

Example 1 with TryCatchStatement

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

the class FinalVariableAnalyzer method visitTryCatchFinally.

@Override
public void visitTryCatchFinally(final TryCatchStatement statement) {
    visitStatement(statement);
    Map<Variable, VariableState> beforeTryCatch = new HashMap<Variable, VariableState>(getState());
    statement.getTryStatement().visit(this);
    for (CatchStatement catchStatement : statement.getCatchStatements()) {
        catchStatement.visit(this);
    }
    Statement finallyStatement = statement.getFinallyStatement();
    // we need to recall which final variables are unassigned so cloning the current state
    Map<Variable, VariableState> afterTryCatchState = new HashMap<Variable, VariableState>(getState());
    if (finallyStatement instanceof EmptyStatement) {
        // dispatching to EmptyStatement will not call back visitor,
        // must call our visitEmptyStatement explicitly
        visitEmptyStatement((EmptyStatement) finallyStatement);
    } else {
        finallyStatement.visit(this);
    }
    // and now we must reset to uninitialized state variables which were only initialized during try/catch
    Map<Variable, VariableState> afterFinally = new HashMap<Variable, VariableState>(getState());
    for (Map.Entry<Variable, VariableState> entry : afterFinally.entrySet()) {
        Variable var = entry.getKey();
        VariableState afterFinallyState = entry.getValue();
        VariableState beforeTryCatchState = beforeTryCatch.get(var);
        if (afterFinallyState == VariableState.is_final && beforeTryCatchState != VariableState.is_final && afterTryCatchState.get(var) != beforeTryCatchState) {
            getState().put(var, beforeTryCatchState == null ? VariableState.is_uninitialized : beforeTryCatchState);
        }
    }
}
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) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) IfStatement(org.codehaus.groovy.ast.stmt.IfStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) HashMap(java.util.HashMap) Map(java.util.Map)

Example 2 with TryCatchStatement

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

the class AntlrParserPlugin method tryStatement.

protected Statement tryStatement(AST tryStatementNode) {
    AST tryNode = tryStatementNode.getFirstChild();
    Statement tryStatement = statement(tryNode);
    Statement finallyStatement = EmptyStatement.INSTANCE;
    AST node = tryNode.getNextSibling();
    // let's do the catch nodes
    List<CatchStatement> catches = new ArrayList<CatchStatement>();
    for (; node != null && isType(LITERAL_catch, node); node = node.getNextSibling()) {
        final List<CatchStatement> catchStatements = catchStatement(node);
        catches.addAll(catchStatements);
    }
    if (isType(LITERAL_finally, node)) {
        finallyStatement = statement(node);
        node = node.getNextSibling();
    }
    if (finallyStatement instanceof EmptyStatement && catches.isEmpty()) {
        throw new ASTRuntimeException(tryStatementNode, "A try statement must have at least one catch or finally block.");
    }
    TryCatchStatement tryCatchStatement = new TryCatchStatement(tryStatement, finallyStatement);
    configureAST(tryCatchStatement, tryStatementNode);
    for (CatchStatement statement : catches) {
        tryCatchStatement.addCatch(statement);
    }
    return tryCatchStatement;
}
Also used : AST(antlr.collections.AST) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) CaseStatement(org.codehaus.groovy.ast.stmt.CaseStatement) ForStatement(org.codehaus.groovy.ast.stmt.ForStatement) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) IfStatement(org.codehaus.groovy.ast.stmt.IfStatement) AssertStatement(org.codehaus.groovy.ast.stmt.AssertStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) Statement(org.codehaus.groovy.ast.stmt.Statement) WhileStatement(org.codehaus.groovy.ast.stmt.WhileStatement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ThrowStatement(org.codehaus.groovy.ast.stmt.ThrowStatement) ContinueStatement(org.codehaus.groovy.ast.stmt.ContinueStatement) BreakStatement(org.codehaus.groovy.ast.stmt.BreakStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) SynchronizedStatement(org.codehaus.groovy.ast.stmt.SynchronizedStatement) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) SwitchStatement(org.codehaus.groovy.ast.stmt.SwitchStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) ArrayList(java.util.ArrayList) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement)

Example 3 with TryCatchStatement

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

the class StaticTypeCheckingVisitor method visitTryCatchFinally.

@Override
public void visitTryCatchFinally(final TryCatchStatement statement) {
    final 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 : LowestUpperBoundClassNode(org.codehaus.groovy.ast.tools.WideningCategories.LowestUpperBoundClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement)

Example 4 with TryCatchStatement

use of org.codehaus.groovy.ast.stmt.TryCatchStatement in project groovy-core by groovy.

the class FinalVariableAnalyzer method visitTryCatchFinally.

@Override
public void visitTryCatchFinally(final TryCatchStatement statement) {
    visitStatement(statement);
    Map<Variable, VariableState> beforeTryCatch = new HashMap<Variable, VariableState>(getState());
    statement.getTryStatement().visit(this);
    for (CatchStatement catchStatement : statement.getCatchStatements()) {
        catchStatement.visit(this);
    }
    Statement finallyStatement = statement.getFinallyStatement();
    // we need to recall which final variables are unassigned so cloning the current state
    Map<Variable, VariableState> afterTryCatchState = new HashMap<Variable, VariableState>(getState());
    if (finallyStatement instanceof EmptyStatement) {
        // dispatching to EmptyStatement will not call back visitor,
        // must call our visitEmptyStatement explicitly
        visitEmptyStatement((EmptyStatement) finallyStatement);
    } else {
        finallyStatement.visit(this);
    }
    // and now we must reset to uninitialized state variables which were only initialized during try/catch
    Map<Variable, VariableState> afterFinally = new HashMap<Variable, VariableState>(getState());
    for (Map.Entry<Variable, VariableState> entry : afterFinally.entrySet()) {
        Variable var = entry.getKey();
        VariableState afterFinallyState = entry.getValue();
        VariableState beforeTryCatchState = beforeTryCatch.get(var);
        if (afterFinallyState == VariableState.is_final && beforeTryCatchState != VariableState.is_final && afterTryCatchState.get(var) != beforeTryCatchState) {
            getState().put(var, beforeTryCatchState == null ? VariableState.is_uninitialized : beforeTryCatchState);
        }
    }
}
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) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) IfStatement(org.codehaus.groovy.ast.stmt.IfStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) HashMap(java.util.HashMap) Map(java.util.Map)

Example 5 with TryCatchStatement

use of org.codehaus.groovy.ast.stmt.TryCatchStatement in project groovy-core by groovy.

the class StatementWriter method writeTryCatchFinally.

public void writeTryCatchFinally(TryCatchStatement statement) {
    controller.getAcg().onLineNumber(statement, "visitTryCatchFinally");
    writeStatementLabel(statement);
    MethodVisitor mv = controller.getMethodVisitor();
    CompileStack compileStack = controller.getCompileStack();
    OperandStack operandStack = controller.getOperandStack();
    Statement tryStatement = statement.getTryStatement();
    final Statement finallyStatement = statement.getFinallyStatement();
    // start try block, label needed for exception table
    Label tryStart = new Label();
    mv.visitLabel(tryStart);
    BlockRecorder tryBlock = makeBlockRecorder(finallyStatement);
    tryBlock.startRange(tryStart);
    tryStatement.visit(controller.getAcg());
    // goto finally part
    Label finallyStart = new Label();
    mv.visitJumpInsn(GOTO, finallyStart);
    Label tryEnd = new Label();
    mv.visitLabel(tryEnd);
    tryBlock.closeRange(tryEnd);
    // pop for "makeBlockRecorder(finallyStatement)"
    controller.getCompileStack().pop();
    BlockRecorder catches = makeBlockRecorder(finallyStatement);
    for (CatchStatement catchStatement : statement.getCatchStatements()) {
        ClassNode exceptionType = catchStatement.getExceptionType();
        String exceptionTypeInternalName = BytecodeHelper.getClassInternalName(exceptionType);
        // start catch block, label needed for exception table
        Label catchStart = new Label();
        mv.visitLabel(catchStart);
        catches.startRange(catchStart);
        // create exception variable and store the exception
        Parameter exceptionVariable = catchStatement.getVariable();
        compileStack.pushState();
        compileStack.defineVariable(exceptionVariable, true);
        // handle catch body
        catchStatement.visit(controller.getAcg());
        // place holder to avoid problems with empty catch blocks
        mv.visitInsn(NOP);
        // pop for the variable
        controller.getCompileStack().pop();
        // end of catch
        Label catchEnd = new Label();
        mv.visitLabel(catchEnd);
        catches.closeRange(catchEnd);
        // goto finally start
        mv.visitJumpInsn(GOTO, finallyStart);
        compileStack.writeExceptionTable(tryBlock, catchStart, exceptionTypeInternalName);
    }
    // Label used to handle exceptions in catches and regularly
    // visited finals.
    Label catchAny = new Label();
    // add "catch any" block to exception table for try part we do this 
    // after the exception blocks, because else this one would supersede
    // any of those otherwise
    compileStack.writeExceptionTable(tryBlock, catchAny, null);
    // same for the catch parts
    compileStack.writeExceptionTable(catches, catchAny, null);
    // pop for "makeBlockRecorder(catches)"
    compileStack.pop();
    // start finally
    mv.visitLabel(finallyStart);
    finallyStatement.visit(controller.getAcg());
    //**
    mv.visitInsn(NOP);
    // goto after all-catching block
    Label skipCatchAll = new Label();
    mv.visitJumpInsn(GOTO, skipCatchAll);
    // start a block catching any Exception
    mv.visitLabel(catchAny);
    //store exception
    //TODO: maybe define a Throwable and use it here instead of Object
    operandStack.push(ClassHelper.OBJECT_TYPE);
    int anyExceptionIndex = compileStack.defineTemporaryVariable("exception", true);
    finallyStatement.visit(controller.getAcg());
    // load the exception and rethrow it
    mv.visitVarInsn(ALOAD, anyExceptionIndex);
    mv.visitInsn(ATHROW);
    mv.visitLabel(skipCatchAll);
}
Also used : BlockRecorder(org.codehaus.groovy.classgen.asm.CompileStack.BlockRecorder) ClassNode(org.codehaus.groovy.ast.ClassNode) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) Statement(org.codehaus.groovy.ast.stmt.Statement) WhileStatement(org.codehaus.groovy.ast.stmt.WhileStatement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ThrowStatement(org.codehaus.groovy.ast.stmt.ThrowStatement) CaseStatement(org.codehaus.groovy.ast.stmt.CaseStatement) DoWhileStatement(org.codehaus.groovy.ast.stmt.DoWhileStatement) ContinueStatement(org.codehaus.groovy.ast.stmt.ContinueStatement) ForStatement(org.codehaus.groovy.ast.stmt.ForStatement) 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) AssertStatement(org.codehaus.groovy.ast.stmt.AssertStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) Label(org.objectweb.asm.Label) Parameter(org.codehaus.groovy.ast.Parameter) MethodVisitor(org.objectweb.asm.MethodVisitor)

Aggregations

TryCatchStatement (org.codehaus.groovy.ast.stmt.TryCatchStatement)11 CatchStatement (org.codehaus.groovy.ast.stmt.CatchStatement)8 Statement (org.codehaus.groovy.ast.stmt.Statement)8 ClassNode (org.codehaus.groovy.ast.ClassNode)6 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)6 EmptyStatement (org.codehaus.groovy.ast.stmt.EmptyStatement)6 IfStatement (org.codehaus.groovy.ast.stmt.IfStatement)6 ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)4 ReturnStatement (org.codehaus.groovy.ast.stmt.ReturnStatement)4 ThrowStatement (org.codehaus.groovy.ast.stmt.ThrowStatement)4 Expression (org.codehaus.groovy.ast.expr.Expression)3 AssertStatement (org.codehaus.groovy.ast.stmt.AssertStatement)3 BreakStatement (org.codehaus.groovy.ast.stmt.BreakStatement)3 CaseStatement (org.codehaus.groovy.ast.stmt.CaseStatement)3 ContinueStatement (org.codehaus.groovy.ast.stmt.ContinueStatement)3 ForStatement (org.codehaus.groovy.ast.stmt.ForStatement)3 SwitchStatement (org.codehaus.groovy.ast.stmt.SwitchStatement)3 SynchronizedStatement (org.codehaus.groovy.ast.stmt.SynchronizedStatement)3 WhileStatement (org.codehaus.groovy.ast.stmt.WhileStatement)3 HashMap (java.util.HashMap)2