Search in sources :

Example 31 with BooleanExpression

use of org.codehaus.groovy.ast.expr.BooleanExpression in project groovy by apache.

the class AssertionWriter method writeSourcelessAssertText.

private void writeSourcelessAssertText(AssertStatement statement) {
    MethodVisitor mv = controller.getMethodVisitor();
    OperandStack operandStack = controller.getOperandStack();
    BooleanExpression booleanExpression = statement.getBooleanExpression();
    // push expression string onto stack
    String expressionText = booleanExpression.getText();
    List<String> list = new ArrayList<String>();
    addVariableNames(booleanExpression, list);
    if (list.isEmpty()) {
        mv.visitLdcInsn(expressionText);
    } else {
        boolean first = true;
        // let's create a new expression
        mv.visitTypeInsn(NEW, "java/lang/StringBuffer");
        mv.visitInsn(DUP);
        mv.visitLdcInsn(expressionText + ". Values: ");
        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuffer", "<init>", "(Ljava/lang/String;)V", false);
        // TODO: maybe use more special type StringBuffer here
        operandStack.push(ClassHelper.OBJECT_TYPE);
        int tempIndex = controller.getCompileStack().defineTemporaryVariable("assert", true);
        for (String name : list) {
            String text = name + " = ";
            if (first) {
                first = false;
            } else {
                text = ", " + text;
            }
            mv.visitVarInsn(ALOAD, tempIndex);
            mv.visitLdcInsn(text);
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "append", "(Ljava/lang/Object;)Ljava/lang/StringBuffer;", false);
            mv.visitInsn(POP);
            mv.visitVarInsn(ALOAD, tempIndex);
            new VariableExpression(name).visit(controller.getAcg());
            operandStack.box();
            mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/InvokerHelper", "toString", "(Ljava/lang/Object;)Ljava/lang/String;", false);
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", false);
            mv.visitInsn(POP);
            operandStack.remove(1);
        }
        mv.visitVarInsn(ALOAD, tempIndex);
        controller.getCompileStack().removeVar(tempIndex);
    }
}
Also used : BooleanExpression(org.codehaus.groovy.ast.expr.BooleanExpression) ArrayList(java.util.ArrayList) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 32 with BooleanExpression

use of org.codehaus.groovy.ast.expr.BooleanExpression in project groovy by apache.

the class AssertionWriter method addVariableNames.

private void addVariableNames(Expression expression, List<String> list) {
    if (expression instanceof BooleanExpression) {
        BooleanExpression boolExp = (BooleanExpression) expression;
        addVariableNames(boolExp.getExpression(), list);
    } else if (expression instanceof BinaryExpression) {
        BinaryExpression binExp = (BinaryExpression) expression;
        addVariableNames(binExp.getLeftExpression(), list);
        addVariableNames(binExp.getRightExpression(), list);
    } else if (expression instanceof VariableExpression) {
        VariableExpression varExp = (VariableExpression) expression;
        list.add(varExp.getName());
    }
}
Also used : BooleanExpression(org.codehaus.groovy.ast.expr.BooleanExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression)

Example 33 with BooleanExpression

use of org.codehaus.groovy.ast.expr.BooleanExpression in project groovy by apache.

the class AnnotationClosureVisitor method visitClass.

@Override
public void visitClass(ClassNode node) {
    if (node == null)
        return;
    if (!(CandidateChecks.isInterfaceContractsCandidate(node) || CandidateChecks.isContractsCandidate(node)))
        return;
    classNode = node;
    if (classNode.getNodeMetaData(PROCESSED) == null && CandidateChecks.isContractsCandidate(node)) {
        final List<AnnotationNode> annotationNodes = AnnotationUtils.hasMetaAnnotations(node, ContractElement.class.getName());
        for (AnnotationNode annotationNode : annotationNodes) {
            Expression expression = annotationNode.getMember(CLOSURE_ATTRIBUTE_NAME);
            if (expression == null || expression instanceof ClassExpression)
                continue;
            ClosureExpression closureExpression = (ClosureExpression) expression;
            ClosureExpressionValidator validator = new ClosureExpressionValidator(classNode, null, annotationNode, sourceUnit);
            validator.visitClosureExpression(closureExpression);
            validator.secondPass(closureExpression);
            List<Parameter> parameters = new ArrayList<>(Arrays.asList(closureExpression.getParameters()));
            final List<BooleanExpression> booleanExpressions = ExpressionUtils.getBooleanExpression(closureExpression);
            if (booleanExpressions == null || booleanExpressions.isEmpty())
                continue;
            BlockStatement closureBlockStatement = (BlockStatement) closureExpression.getCode();
            BlockStatement newClosureBlockStatement = TryCatchBlockGenerator.generateTryCatchBlock(ClassHelper.makeWithoutCaching(ClassInvariantViolation.class), "<" + annotationNode.getClassNode().getName() + "> " + classNode.getName() + " \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(closureExpression.getVariableScope());
            rewrittenClosureExpression.setType(closureExpression.getType());
            ClassNode closureClassNode = contractClosureWriter.createClosureClass(classNode, null, rewrittenClosureExpression, false, false, Opcodes.ACC_PUBLIC);
            classNode.getModule().addClass(closureClassNode);
            final ClassExpression value = new ClassExpression(closureClassNode);
            value.setSourcePosition(annotationNode);
            BlockStatement value1 = TryCatchBlockGenerator.generateTryCatchBlockForInlineMode(ClassHelper.makeWithoutCaching(ClassInvariantViolation.class), "<" + annotationNode.getClassNode().getName() + "> " + classNode.getName() + " \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(classNode);
        }
    }
    super.visitClass(node);
    // generate closure classes for the super class and all implemented interfaces
    visitClass(node.getSuperClass());
    for (ClassNode i : node.getInterfaces()) {
        visitClass(i);
    }
    markProcessed(classNode);
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) ContractElement(org.apache.groovy.contracts.annotations.meta.ContractElement) ArrayList(java.util.ArrayList) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) ClassInvariantViolation(org.apache.groovy.contracts.ClassInvariantViolation) BooleanExpression(org.codehaus.groovy.ast.expr.BooleanExpression) AnnotationNode(org.codehaus.groovy.ast.AnnotationNode) 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) Parameter(org.codehaus.groovy.ast.Parameter) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression)

Example 34 with BooleanExpression

use of org.codehaus.groovy.ast.expr.BooleanExpression in project groovy by apache.

the class BaseGenerator method addCallsToSuperMethodNodeAnnotationClosure.

// TODO: what about constructor method nodes - does it find a constructor node in the super class?
protected BooleanExpression addCallsToSuperMethodNodeAnnotationClosure(final ClassNode type, final MethodNode methodNode, final Class<? extends Annotation> annotationType, BooleanExpression booleanExpression, boolean isPostcondition) {
    final List<AnnotationNode> nextContractElementAnnotations = AnnotationUtils.getAnnotationNodeInHierarchyWithMetaAnnotation(type.getSuperClass(), methodNode, ClassHelper.makeWithoutCaching(annotationType));
    if (nextContractElementAnnotations.isEmpty()) {
        if (methodNode.getNodeMetaData(META_DATA_USE_INLINE_MODE) == null)
            methodNode.setNodeMetaData(META_DATA_USE_INLINE_MODE, Boolean.TRUE);
        return booleanExpression;
    }
    for (AnnotationNode nextContractElementAnnotation : nextContractElementAnnotations) {
        ClassExpression classExpression = (ClassExpression) nextContractElementAnnotation.getMember(BaseVisitor.CLOSURE_ATTRIBUTE_NAME);
        if (classExpression == null)
            continue;
        ArgumentListExpression callArgumentList = new ArgumentListExpression();
        for (Parameter parameter : methodNode.getParameters()) {
            callArgumentList.addExpression(varX(parameter));
        }
        if (isPostcondition && !isPrimitiveVoid(methodNode.getReturnType()) && !(methodNode instanceof ConstructorNode)) {
            callArgumentList.addExpression(localVarX("result", methodNode.getReturnType()));
        }
        if (isPostcondition && !(methodNode instanceof ConstructorNode)) {
            callArgumentList.addExpression(localVarX("old", new ClassNode(Map.class)));
        }
        ArgumentListExpression newInstanceArguments = args(classExpression, new ArrayExpression(ClassHelper.OBJECT_TYPE, Arrays.<Expression>asList(VariableExpression.THIS_EXPRESSION, VariableExpression.THIS_EXPRESSION)));
        MethodCallExpression doCall = callX(callX(ClassHelper.makeWithoutCaching(InvokerHelper.class), "invokeConstructorOf", newInstanceArguments), "doCall", callArgumentList);
        doCall.setMethodTarget(classExpression.getType().getMethods("doCall").get(0));
        booleanExpression.setSourcePosition(nextContractElementAnnotation);
        booleanExpression = boolX(binX(booleanExpression, isPostcondition ? Token.newSymbol(Types.LOGICAL_AND, -1, -1) : Token.newSymbol(Types.LOGICAL_OR, -1, -1), boolX(doCall)));
    }
    return booleanExpression;
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) AnnotationNode(org.codehaus.groovy.ast.AnnotationNode) BooleanExpression(org.codehaus.groovy.ast.expr.BooleanExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArrayExpression(org.codehaus.groovy.ast.expr.ArrayExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) ConstructorNode(org.codehaus.groovy.ast.ConstructorNode) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) Parameter(org.codehaus.groovy.ast.Parameter) ArrayExpression(org.codehaus.groovy.ast.expr.ArrayExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression)

Example 35 with BooleanExpression

use of org.codehaus.groovy.ast.expr.BooleanExpression in project groovy by apache.

the class ClassInvariantGenerator method addCallsToSuperAnnotationClosure.

private BooleanExpression addCallsToSuperAnnotationClosure(final ClassNode type, final Class<? extends Annotation> annotationType, BooleanExpression booleanExpression) {
    final List<AnnotationNode> nextContractElementAnnotations = AnnotationUtils.getAnnotationNodeInHierarchyWithMetaAnnotation(type.getSuperClass(), ClassHelper.makeWithoutCaching(annotationType));
    if (nextContractElementAnnotations.isEmpty())
        return booleanExpression;
    for (AnnotationNode nextContractElementAnnotation : nextContractElementAnnotations) {
        ClassExpression classExpression = (ClassExpression) nextContractElementAnnotation.getMember(BaseVisitor.CLOSURE_ATTRIBUTE_NAME);
        if (classExpression == null)
            continue;
        MethodCallExpression doCall = callX(ctorX(classExpression.getType(), args(VariableExpression.THIS_EXPRESSION, VariableExpression.THIS_EXPRESSION)), "doCall");
        doCall.setMethodTarget(classExpression.getType().getMethods("doCall").get(0));
        final BooleanExpression rightExpression = boolX(doCall);
        booleanExpression.setSourcePosition(nextContractElementAnnotation);
        booleanExpression = boolX(binX(booleanExpression, AND, rightExpression));
    }
    return booleanExpression;
}
Also used : BooleanExpression(org.codehaus.groovy.ast.expr.BooleanExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) AnnotationNode(org.codehaus.groovy.ast.AnnotationNode) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression)

Aggregations

BooleanExpression (org.codehaus.groovy.ast.expr.BooleanExpression)48 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)30 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)24 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)24 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)23 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)23 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)19 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)18 Expression (org.codehaus.groovy.ast.expr.Expression)18 ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)16 IfStatement (org.codehaus.groovy.ast.stmt.IfStatement)16 ConstructorCallExpression (org.codehaus.groovy.ast.expr.ConstructorCallExpression)15 Statement (org.codehaus.groovy.ast.stmt.Statement)14 ReturnStatement (org.codehaus.groovy.ast.stmt.ReturnStatement)13 ClosureExpression (org.codehaus.groovy.ast.expr.ClosureExpression)12 DeclarationExpression (org.codehaus.groovy.ast.expr.DeclarationExpression)12 EmptyExpression (org.codehaus.groovy.ast.expr.EmptyExpression)12 PropertyExpression (org.codehaus.groovy.ast.expr.PropertyExpression)12 TernaryExpression (org.codehaus.groovy.ast.expr.TernaryExpression)12 TupleExpression (org.codehaus.groovy.ast.expr.TupleExpression)12