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);
}
}
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());
}
}
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);
}
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;
}
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;
}
Aggregations