Search in sources :

Example 1 with Postcondition

use of org.apache.groovy.contracts.annotations.meta.Postcondition in project groovy by apache.

the class AnnotationClosureVisitor method replaceWithClosureClassReference.

private void replaceWithClosureClassReference(AnnotationNode annotationNode, MethodNode methodNode) {
    Validate.notNull(annotationNode);
    Validate.notNull(methodNode);
    // check whether this is a pre- or postcondition
    boolean isPostcondition = AnnotationUtils.hasAnnotationOfType(annotationNode.getClassNode(), org.apache.groovy.contracts.annotations.meta.Postcondition.class.getName());
    Expression expression = annotationNode.getMember(CLOSURE_ATTRIBUTE_NAME);
    if (expression == null || expression instanceof ClassExpression)
        return;
    ClosureExpression closureExpression = (ClosureExpression) expression;
    ClassCodeExpressionTransformer transformer = new OldPropertyExpressionTransformer(methodNode);
    TransformingCodeVisitor visitor = new TransformingCodeVisitor(transformer);
    visitor.visitClosureExpression(closureExpression);
    ClosureExpressionValidator validator = new ClosureExpressionValidator(classNode, methodNode, annotationNode, sourceUnit);
    validator.visitClosureExpression(closureExpression);
    validator.secondPass(closureExpression);
    List<Parameter> parameters = new ArrayList<>(Arrays.asList(closureExpression.getParameters()));
    parameters.addAll(new ArrayList<>(Arrays.asList(methodNode.getParameters())));
    final List<BooleanExpression> booleanExpressions = ExpressionUtils.getBooleanExpression(closureExpression);
    if (booleanExpressions == null || booleanExpressions.isEmpty())
        return;
    BlockStatement closureBlockStatement = (BlockStatement) closureExpression.getCode();
    BlockStatement newClosureBlockStatement = TryCatchBlockGenerator.generateTryCatchBlock(isPostcondition ? ClassHelper.makeWithoutCaching(PostconditionViolation.class) : ClassHelper.makeWithoutCaching(PreconditionViolation.class), "<" + annotationNode.getClassNode().getName() + "> " + classNode.getName() + "." + methodNode.getTypeDescriptor() + " \n\n", AssertStatementCreationUtility.getAssertionStatements(booleanExpressions));
    newClosureBlockStatement.setSourcePosition(closureBlockStatement);
    ClosureExpression rewrittenClosureExpression = new ClosureExpression(parameters.toArray(Parameter.EMPTY_ARRAY), newClosureBlockStatement);
    rewrittenClosureExpression.setSourcePosition(closureExpression);
    rewrittenClosureExpression.setDeclaringClass(closureExpression.getDeclaringClass());
    rewrittenClosureExpression.setSynthetic(true);
    rewrittenClosureExpression.setVariableScope(correctVariableScope(closureExpression.getVariableScope(), methodNode));
    rewrittenClosureExpression.setType(closureExpression.getType());
    boolean isConstructor = methodNode instanceof ConstructorNode;
    ClassNode closureClassNode = contractClosureWriter.createClosureClass(classNode, methodNode, rewrittenClosureExpression, isPostcondition && !isConstructor, isPostcondition && !isConstructor, Opcodes.ACC_PUBLIC);
    classNode.getModule().addClass(closureClassNode);
    final ClassExpression value = new ClassExpression(closureClassNode);
    value.setSourcePosition(annotationNode);
    BlockStatement value1 = TryCatchBlockGenerator.generateTryCatchBlockForInlineMode(isPostcondition ? ClassHelper.makeWithoutCaching(PostconditionViolation.class) : ClassHelper.makeWithoutCaching(PreconditionViolation.class), "<" + annotationNode.getClassNode().getName() + "> " + classNode.getName() + "." + methodNode.getTypeDescriptor() + " \n\n", AssertStatementCreationUtility.getAssertionStatements(booleanExpressions));
    value1.setNodeMetaData(META_DATA_USE_EXECUTION_TRACKER, validator.isMethodCalls());
    value.setNodeMetaData(META_DATA_ORIGINAL_TRY_CATCH_BLOCK, value1);
    annotationNode.setMember(CLOSURE_ATTRIBUTE_NAME, value);
    markClosureReplaced(methodNode);
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) ArrayList(java.util.ArrayList) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) BooleanExpression(org.codehaus.groovy.ast.expr.BooleanExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) BooleanExpression(org.codehaus.groovy.ast.expr.BooleanExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) PrefixExpression(org.codehaus.groovy.ast.expr.PrefixExpression) PostfixExpression(org.codehaus.groovy.ast.expr.PostfixExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) ConstructorNode(org.codehaus.groovy.ast.ConstructorNode) TransformingCodeVisitor(org.codehaus.groovy.ast.TransformingCodeVisitor) Parameter(org.codehaus.groovy.ast.Parameter) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) Postcondition(org.apache.groovy.contracts.annotations.meta.Postcondition) ClassCodeExpressionTransformer(org.codehaus.groovy.ast.ClassCodeExpressionTransformer)

Example 2 with Postcondition

use of org.apache.groovy.contracts.annotations.meta.Postcondition in project groovy by apache.

the class PostconditionGenerator method generateDefaultPostconditionStatement.

/**
 * Adds a default postcondition if a postcondition has already been defined for this {@link org.codehaus.groovy.ast.MethodNode}
 * in a super-class.
 *
 * @param type   the current {@link org.codehaus.groovy.ast.ClassNode} of the given <tt>methodNode</tt>
 * @param method the {@link org.codehaus.groovy.ast.MethodNode} to create the default postcondition for
 */
public void generateDefaultPostconditionStatement(final ClassNode type, final MethodNode method) {
    // if another precondition is available we'll evaluate to false
    boolean isAnotherPostconditionAvailable = AnnotationUtils.getAnnotationNodeInHierarchyWithMetaAnnotation(type.getSuperClass(), method, ClassHelper.makeWithoutCaching(Postcondition.class)).size() > 0;
    if (!isAnotherPostconditionAvailable)
        return;
    // if another post-condition is available we need to add a default expression of TRUE
    // since post-conditions are usually connected with a logical AND
    final BooleanExpression postconditionBooleanExpression = addCallsToSuperMethodNodeAnnotationClosure(method.getDeclaringClass(), method, Postcondition.class, new BooleanExpression(ConstantExpression.TRUE), true);
    if (postconditionBooleanExpression.getExpression() == ConstantExpression.TRUE)
        return;
    final BlockStatement blockStatement = wrapAssertionBooleanExpression(type, method, postconditionBooleanExpression, "postcondition");
    addPostcondition(method, blockStatement);
}
Also used : BooleanExpression(org.codehaus.groovy.ast.expr.BooleanExpression) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) Postcondition(org.apache.groovy.contracts.annotations.meta.Postcondition)

Aggregations

Postcondition (org.apache.groovy.contracts.annotations.meta.Postcondition)2 BooleanExpression (org.codehaus.groovy.ast.expr.BooleanExpression)2 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)2 ArrayList (java.util.ArrayList)1 ClassCodeExpressionTransformer (org.codehaus.groovy.ast.ClassCodeExpressionTransformer)1 ClassNode (org.codehaus.groovy.ast.ClassNode)1 ConstructorNode (org.codehaus.groovy.ast.ConstructorNode)1 Parameter (org.codehaus.groovy.ast.Parameter)1 TransformingCodeVisitor (org.codehaus.groovy.ast.TransformingCodeVisitor)1 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)1 CastExpression (org.codehaus.groovy.ast.expr.CastExpression)1 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)1 ClosureExpression (org.codehaus.groovy.ast.expr.ClosureExpression)1 ConstructorCallExpression (org.codehaus.groovy.ast.expr.ConstructorCallExpression)1 Expression (org.codehaus.groovy.ast.expr.Expression)1 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)1 PostfixExpression (org.codehaus.groovy.ast.expr.PostfixExpression)1 PrefixExpression (org.codehaus.groovy.ast.expr.PrefixExpression)1 PropertyExpression (org.codehaus.groovy.ast.expr.PropertyExpression)1 StaticMethodCallExpression (org.codehaus.groovy.ast.expr.StaticMethodCallExpression)1