use of org.codehaus.groovy.ast.TransformingCodeVisitor 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);
}
Aggregations