Search in sources :

Example 11 with CatchStatement

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

the class ControllerActionTransformer method wrapMethodBodyWithExceptionHandling.

/**
 * This will wrap the method body in a try catch block which does something
 * like this:
 * <pre>
 * try {
 *     // original method body here
 * } catch (Exception $caughtException) {
 *     Method $method = getExceptionHandlerMethod($caughtException.getClass())
 *     if($method) {
 *         return $method.invoke(this, $caughtException)
 *     } else {
 *         throw $caughtException
 *     }
 * }
 * </pre>
 * @param methodNode the method to add the try catch block to
 */
protected void wrapMethodBodyWithExceptionHandling(final ClassNode controllerClassNode, final MethodNode methodNode) {
    final BlockStatement catchBlockCode = new BlockStatement();
    final String caughtExceptionArgumentName = "$caughtException";
    final Expression caughtExceptionVariableExpression = new VariableExpression(caughtExceptionArgumentName);
    final Expression caughtExceptionTypeExpression = new PropertyExpression(caughtExceptionVariableExpression, "class");
    final Expression thisExpression = new VariableExpression("this");
    final MethodCallExpression getExceptionHandlerMethodCall = new MethodCallExpression(thisExpression, "getExceptionHandlerMethodFor", caughtExceptionTypeExpression);
    applyDefaultMethodTarget(getExceptionHandlerMethodCall, controllerClassNode);
    final ClassNode reflectMethodClassNode = new ClassNode(Method.class);
    final String exceptionHandlerMethodVariableName = "$method";
    final Expression exceptionHandlerMethodExpression = new VariableExpression(exceptionHandlerMethodVariableName, new ClassNode(Method.class));
    final Expression declareExceptionHandlerMethod = new DeclarationExpression(new VariableExpression(exceptionHandlerMethodVariableName, reflectMethodClassNode), Token.newSymbol(Types.EQUALS, 0, 0), getExceptionHandlerMethodCall);
    final ArgumentListExpression invokeArguments = new ArgumentListExpression();
    invokeArguments.addExpression(thisExpression);
    invokeArguments.addExpression(caughtExceptionVariableExpression);
    final MethodCallExpression invokeExceptionHandlerMethodExpression = new MethodCallExpression(new VariableExpression(exceptionHandlerMethodVariableName), "invoke", invokeArguments);
    applyDefaultMethodTarget(invokeExceptionHandlerMethodExpression, reflectMethodClassNode);
    final Statement returnStatement = new ReturnStatement(invokeExceptionHandlerMethodExpression);
    final Statement throwCaughtExceptionStatement = new ThrowStatement(caughtExceptionVariableExpression);
    final Statement ifExceptionHandlerMethodExistsStatement = new IfStatement(new BooleanExpression(exceptionHandlerMethodExpression), returnStatement, throwCaughtExceptionStatement);
    catchBlockCode.addStatement(new ExpressionStatement(declareExceptionHandlerMethod));
    catchBlockCode.addStatement(ifExceptionHandlerMethodExistsStatement);
    final CatchStatement catchStatement = new CatchStatement(new Parameter(new ClassNode(Exception.class), caughtExceptionArgumentName), catchBlockCode);
    final Statement methodBody = methodNode.getCode();
    BlockStatement tryBlock = new BlockStatement();
    BlockStatement codeToHandleAllowedMethods = getCodeToHandleAllowedMethods(controllerClassNode, methodNode.getName());
    tryBlock.addStatement(codeToHandleAllowedMethods);
    tryBlock.addStatement(methodBody);
    final TryCatchStatement tryCatchStatement = new TryCatchStatement(tryBlock, new EmptyStatement());
    tryCatchStatement.addCatch(catchStatement);
    final ArgumentListExpression argumentListExpression = new ArgumentListExpression();
    argumentListExpression.addExpression(new ConstantExpression(ALLOWED_METHODS_HANDLED_ATTRIBUTE_NAME));
    final PropertyExpression requestPropertyExpression = new PropertyExpression(new VariableExpression("this"), "request");
    final Expression removeAttributeMethodCall = new MethodCallExpression(requestPropertyExpression, "removeAttribute", argumentListExpression);
    final Expression getAttributeMethodCall = new MethodCallExpression(requestPropertyExpression, "getAttribute", new ArgumentListExpression(new ConstantExpression(ALLOWED_METHODS_HANDLED_ATTRIBUTE_NAME)));
    final VariableExpression attributeValueExpression = new VariableExpression("$allowed_methods_attribute_value", ClassHelper.make(Object.class));
    final Expression initializeAttributeValue = new DeclarationExpression(attributeValueExpression, Token.newSymbol(Types.EQUALS, 0, 0), getAttributeMethodCall);
    final Expression attributeValueMatchesMethodNameExpression = new BinaryExpression(new ConstantExpression(methodNode.getName()), Token.newSymbol(Types.COMPARE_EQUAL, 0, 0), attributeValueExpression);
    final Statement ifAttributeValueMatchesMethodName = new IfStatement(new BooleanExpression(attributeValueMatchesMethodNameExpression), new ExpressionStatement(removeAttributeMethodCall), new EmptyStatement());
    final BlockStatement blockToRemoveAttribute = new BlockStatement();
    blockToRemoveAttribute.addStatement(new ExpressionStatement(initializeAttributeValue));
    blockToRemoveAttribute.addStatement(ifAttributeValueMatchesMethodName);
    final TryCatchStatement tryCatchToRemoveAttribute = new TryCatchStatement(blockToRemoveAttribute, new EmptyStatement());
    tryCatchToRemoveAttribute.addCatch(new CatchStatement(new Parameter(ClassHelper.make(Exception.class), "$exceptionRemovingAttribute"), new EmptyStatement()));
    tryCatchStatement.setFinallyStatement(tryCatchToRemoveAttribute);
    methodNode.setCode(tryCatchStatement);
}
Also used : CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) IfStatement(org.codehaus.groovy.ast.stmt.IfStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) Statement(org.codehaus.groovy.ast.stmt.Statement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ThrowStatement(org.codehaus.groovy.ast.stmt.ThrowStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) DelegatingMethod(grails.compiler.DelegatingMethod) ControllerMethod(grails.web.controllers.ControllerMethod) Method(java.lang.reflect.Method) IfStatement(org.codehaus.groovy.ast.stmt.IfStatement) BooleanExpression(org.codehaus.groovy.ast.expr.BooleanExpression) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) MapExpression(org.codehaus.groovy.ast.expr.MapExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) GrailsASTUtils.buildGetPropertyExpression(org.grails.compiler.injection.GrailsASTUtils.buildGetPropertyExpression) GrailsASTUtils.buildSetPropertyExpression(org.grails.compiler.injection.GrailsASTUtils.buildSetPropertyExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) TernaryExpression(org.codehaus.groovy.ast.expr.TernaryExpression) BooleanExpression(org.codehaus.groovy.ast.expr.BooleanExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) EmptyExpression(org.codehaus.groovy.ast.expr.EmptyExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) GrailsASTUtils.buildGetMapExpression(org.grails.compiler.injection.GrailsASTUtils.buildGetMapExpression) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) MapEntryExpression(org.codehaus.groovy.ast.expr.MapEntryExpression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) RequestParameter(grails.web.RequestParameter) GrailsASTUtils.buildGetPropertyExpression(org.grails.compiler.injection.GrailsASTUtils.buildGetPropertyExpression) GrailsASTUtils.buildSetPropertyExpression(org.grails.compiler.injection.GrailsASTUtils.buildSetPropertyExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) ThrowStatement(org.codehaus.groovy.ast.stmt.ThrowStatement)

Example 12 with CatchStatement

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

the class AntlrParserPlugin method catchStatement.

protected List<CatchStatement> catchStatement(AST catchNode) {
    AST node = catchNode.getFirstChild();
    List<CatchStatement> catches = new LinkedList<CatchStatement>();
    Statement code = statement(node.getNextSibling());
    if (MULTICATCH == node.getType()) {
        AST variableNode = node.getNextSibling();
        final AST multicatches = node.getFirstChild();
        if (multicatches.getType() != MULTICATCH_TYPES) {
            // catch (e)
            // catch (def e)
            String variable = identifier(multicatches);
            Parameter catchParameter = new Parameter(ClassHelper.DYNAMIC_TYPE, variable);
            CatchStatement answer = new CatchStatement(catchParameter, code);
            configureAST(answer, catchNode);
            catches.add(answer);
        } else {
            // catch (Exception e)
            // catch (Exception1 | Exception2 e)
            AST exceptionNodes = multicatches.getFirstChild();
            String variable = identifier(multicatches.getNextSibling());
            while (exceptionNodes != null) {
                ClassNode exceptionType = buildName(exceptionNodes);
                Parameter catchParameter = new Parameter(exceptionType, variable);
                CatchStatement answer = new CatchStatement(catchParameter, code);
                configureAST(answer, catchNode);
                catches.add(answer);
                exceptionNodes = exceptionNodes.getNextSibling();
            }
        }
    }
    return catches;
}
Also used : EnumConstantClassNode(org.codehaus.groovy.ast.EnumConstantClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) 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) Parameter(org.codehaus.groovy.ast.Parameter) LinkedList(java.util.LinkedList)

Example 13 with CatchStatement

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

the class StatementWriter method writeTryCatchFinally.

public void writeTryCatchFinally(final TryCatchStatement statement) {
    writeStatementLabel(statement);
    MethodVisitor mv = controller.getMethodVisitor();
    CompileStack compileStack = controller.getCompileStack();
    OperandStack operandStack = controller.getOperandStack();
    Statement tryStatement = statement.getTryStatement();
    Statement finallyStatement = statement.getFinallyStatement();
    BlockRecorder tryBlock = makeBlockRecorder(finallyStatement);
    startRange(tryBlock, mv);
    tryStatement.visit(controller.getAcg());
    // skip past catch block(s)
    Label finallyStart = new Label();
    boolean fallthroughFinally = false;
    if (maybeFallsThrough(tryStatement)) {
        mv.visitJumpInsn(GOTO, finallyStart);
        fallthroughFinally = true;
    }
    closeRange(tryBlock, mv);
    // pop for BlockRecorder
    compileStack.pop();
    BlockRecorder catches = makeBlockRecorder(finallyStatement);
    for (CatchStatement catchStatement : statement.getCatchStatements()) {
        Label catchBlock = startRange(catches, mv);
        // create variable for the exception
        compileStack.pushState();
        // TODO: Is it okay that "catch (e)" makes variable type Object?
        compileStack.defineVariable(catchStatement.getVariable(), true);
        // handle catch body
        catchStatement.visit(controller.getAcg());
        // placeholder to avoid problems with empty catch block
        mv.visitInsn(NOP);
        // pop for the variable
        compileStack.pop();
        // end of catch
        closeRange(catches, mv);
        if (maybeFallsThrough(catchStatement.getCode())) {
            mv.visitJumpInsn(GOTO, finallyStart);
            fallthroughFinally = true;
        }
        compileStack.writeExceptionTable(tryBlock, catchBlock, BytecodeHelper.getClassInternalName(catchStatement.getExceptionType()));
    }
    // used to handle exceptions in catches and regularly visited finals
    Label catchAll = new Label(), afterCatchAll = new Label();
    // add "catch all" block to exception table for try part; we do this
    // after the exception blocks so they are not superseded by this one
    compileStack.writeExceptionTable(tryBlock, catchAll, null);
    // same for the catch parts
    compileStack.writeExceptionTable(catches, catchAll, null);
    // pop for BlockRecorder
    compileStack.pop();
    if (fallthroughFinally) {
        mv.visitLabel(finallyStart);
        finallyStatement.visit(controller.getAcg());
        // skip over the catch-finally-rethrow
        mv.visitJumpInsn(GOTO, afterCatchAll);
    }
    mv.visitLabel(catchAll);
    operandStack.push(ClassHelper.THROWABLE_TYPE);
    int anyThrowable = compileStack.defineTemporaryVariable("throwable", true);
    finallyStatement.visit(controller.getAcg());
    // load the throwable and rethrow it
    mv.visitVarInsn(ALOAD, anyThrowable);
    mv.visitInsn(ATHROW);
    if (fallthroughFinally)
        mv.visitLabel(afterCatchAll);
    compileStack.removeVar(anyThrowable);
}
Also used : BlockRecorder(org.codehaus.groovy.classgen.asm.CompileStack.BlockRecorder) 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) 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) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 14 with CatchStatement

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

the class CategoryASTTransformation method transformReferencesToThis.

// --------------------------------------------------------------------------
private void transformReferencesToThis(final ClassNode targetClass, final ClassNode sourceClass, final SourceUnit sourceUnit) {
    final Reference<Parameter> selfParameter = new Reference<>();
    final LinkedList<Set<String>> varStack = new LinkedList<>();
    Set<String> names = new HashSet<>();
    for (FieldNode fn : sourceClass.getFields()) names.add(fn.getName());
    for (PropertyNode pn : sourceClass.getProperties()) names.add(pn.getName());
    varStack.add(names);
    ClassCodeExpressionTransformer transformer = new ClassCodeExpressionTransformer() {

        // GROOVY-6510: track closure containment
        private boolean inClosure;

        private void addVariablesToStack(final Parameter[] parameter) {
            Set<String> names = new HashSet<>(varStack.getLast());
            for (Parameter p : parameter) names.add(p.getName());
            varStack.add(names);
        }

        private Expression createThisExpression() {
            VariableExpression ve = new VariableExpression("$this", targetClass);
            ve.setClosureSharedVariable(true);
            return ve;
        }

        @Override
        protected SourceUnit getSourceUnit() {
            return sourceUnit;
        }

        @Override
        public Expression transform(final Expression expression) {
            if (expression instanceof VariableExpression) {
                VariableExpression ve = (VariableExpression) expression;
                if (ve.isThisExpression()) {
                    Expression thisExpression = createThisExpression();
                    thisExpression.setSourcePosition(ve);
                    return thisExpression;
                } else if (!inClosure && !ve.isSuperExpression() && !varStack.getLast().contains(ve.getName())) {
                    PropertyExpression pe = new PropertyExpression(createThisExpression(), ve.getName());
                    pe.setSourcePosition(ve);
                    return pe;
                }
            } else if (expression instanceof MethodCallExpression) {
                MethodCallExpression mce = (MethodCallExpression) expression;
                if (inClosure && mce.isImplicitThis() && isThisExpression(mce.getObjectExpression())) {
                    // GROOVY-6510: preserve implicit-this semantics
                    mce.setArguments(transform(mce.getArguments()));
                    mce.setMethod(transform(mce.getMethod()));
                    return mce;
                }
            } else if (expression instanceof ClosureExpression) {
                ClosureExpression ce = (ClosureExpression) expression;
                addVariablesToStack(hasImplicitParameter(ce) ? params(param(ClassHelper.OBJECT_TYPE, "it")) : getParametersSafe(ce));
                ce.getVariableScope().putReferencedLocalVariable(selfParameter.get());
                addAll(varStack.getLast(), "owner", "delegate", "thisObject");
                boolean closure = inClosure;
                inClosure = true;
                ce.getCode().visit(this);
                varStack.removeLast();
                inClosure = closure;
            }
            return super.transform(expression);
        }

        @Override
        public void visitBlockStatement(final BlockStatement statement) {
            Set<String> names = new HashSet<>(varStack.getLast());
            varStack.add(names);
            super.visitBlockStatement(statement);
            varStack.remove(names);
        }

        @Override
        public void visitCatchStatement(final CatchStatement statement) {
            varStack.getLast().add(statement.getVariable().getName());
            super.visitCatchStatement(statement);
            varStack.getLast().remove(statement.getVariable().getName());
        }

        @Override
        public void visitClosureExpression(final ClosureExpression expression) {
        }

        @Override
        public void visitDeclarationExpression(final DeclarationExpression expression) {
            if (expression.isMultipleAssignmentDeclaration()) {
                for (Expression e : expression.getTupleExpression().getExpressions()) {
                    VariableExpression ve = (VariableExpression) e;
                    varStack.getLast().add(ve.getName());
                }
            } else {
                VariableExpression ve = expression.getVariableExpression();
                varStack.getLast().add(ve.getName());
            }
            super.visitDeclarationExpression(expression);
        }

        @Override
        public void visitExpressionStatement(final ExpressionStatement statement) {
            // GROOVY-3543: visit the declaration expressions so that declaration variables get added on the varStack
            if (statement.getExpression() instanceof DeclarationExpression) {
                statement.getExpression().visit(this);
            }
            super.visitExpressionStatement(statement);
        }

        @Override
        public void visitForLoop(final ForStatement statement) {
            Expression exp = statement.getCollectionExpression();
            exp.visit(this);
            Parameter loopParam = statement.getVariable();
            if (loopParam != null) {
                varStack.getLast().add(loopParam.getName());
            }
            super.visitForLoop(statement);
        }

        @Override
        public void visitMethod(final MethodNode node) {
            addVariablesToStack(node.getParameters());
            super.visitMethod(node);
            varStack.removeLast();
        }
    };
    for (MethodNode method : sourceClass.getMethods()) {
        if (!method.isStatic()) {
            Parameter p = new Parameter(targetClass, "$this");
            p.setClosureSharedVariable(true);
            selfParameter.set(p);
            Parameter[] oldParams = method.getParameters();
            Parameter[] newParams = new Parameter[oldParams.length + 1];
            newParams[0] = p;
            System.arraycopy(oldParams, 0, newParams, 1, oldParams.length);
            method.setModifiers(method.getModifiers() | Opcodes.ACC_STATIC);
            method.setParameters(newParams);
            transformer.visitMethod(method);
        }
    }
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) MethodNode(org.codehaus.groovy.ast.MethodNode) PropertyNode(org.codehaus.groovy.ast.PropertyNode) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ForStatement(org.codehaus.groovy.ast.stmt.ForStatement) HashSet(java.util.HashSet) ClassCodeExpressionTransformer(org.codehaus.groovy.ast.ClassCodeExpressionTransformer) FieldNode(org.codehaus.groovy.ast.FieldNode) Reference(groovy.lang.Reference) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) LinkedList(java.util.LinkedList) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) ExpressionUtils.isThisExpression(org.apache.groovy.ast.tools.ExpressionUtils.isThisExpression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) Parameter(org.codehaus.groovy.ast.Parameter) ClosureUtils.hasImplicitParameter(org.codehaus.groovy.ast.tools.ClosureUtils.hasImplicitParameter)

Example 15 with CatchStatement

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

the class TryWithResourcesASTTransformation method createFinallyBlockForNewTryCatchStatement.

/*
     *   finally {
     *       if (Identifier != null) {
     *           if (#primaryExc != null) {
     *              try {
     *                  Identifier.close();
     *              } catch (Throwable #suppressedExc) {
     *                  #primaryExc.addSuppressed(#suppressedExc);
     *              }
     *           } else {
     *               Identifier.close();
     *           }
     *       }
     *   }
     *
     * We can simplify the above code to a Groovy version as follows:
     *
     *   finally {
     *      if (#primaryExc != null)
     *         try {
     *             Identifier?.close();
     *         } catch (Throwable #suppressedExc) {
     *             #primaryExc.addSuppressed(#suppressedExc);
     *         }
     *      else
     *          Identifier?.close();
     *
     *   }
     *
     */
private BlockStatement createFinallyBlockForNewTryCatchStatement(String primaryExcName, String firstResourceIdentifierName) {
    BlockStatement finallyBlock = new BlockStatement();
    // primaryExc != null
    BooleanExpression conditionExpression = new BooleanExpression(new BinaryExpression(new VariableExpression(primaryExcName), newSymbol(Types.COMPARE_NOT_EQUAL, -1, -1), new ConstantExpression(null)));
    // try-catch statement
    TryCatchStatement newTryCatchStatement = tryCatchS(astBuilder.createBlockStatement(this.createCloseResourceStatement(firstResourceIdentifierName)));
    String suppressedExcName = this.genSuppressedExcName();
    newTryCatchStatement.addCatch(// catch (Throwable #suppressedExc) { .. }
    new CatchStatement(new Parameter(ClassHelper.THROWABLE_TYPE.getPlainNodeReference(), suppressedExcName), // #primaryExc.addSuppressed(#suppressedExc);
    astBuilder.createBlockStatement(this.createAddSuppressedStatement(primaryExcName, suppressedExcName))));
    // if (#primaryExc != null) { ... }
    IfStatement ifStatement = new IfStatement(conditionExpression, newTryCatchStatement, // Identifier?.close();
    this.createCloseResourceStatement(firstResourceIdentifierName));
    astBuilder.appendStatementsToBlockStatement(finallyBlock, ifStatement);
    return astBuilder.createBlockStatement(finallyBlock);
}
Also used : IfStatement(org.codehaus.groovy.ast.stmt.IfStatement) BooleanExpression(org.codehaus.groovy.ast.expr.BooleanExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) Parameter(org.codehaus.groovy.ast.Parameter) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) 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