private void handleMethodNode(MethodNode methodNode, List<AnnotationNode> annotationNodes) {
if (methodNode == null) return;
for (AnnotationNode annotationNode : annotationNodes) {
final AnnotationProcessor annotationProcessor = createAnnotationProcessor(annotationNode);
if (annotationProcessor != null && annotationNode.getMember(CLOSURE_ATTRIBUTE_NAME) instanceof ClassExpression) {
boolean isPostcondition = AnnotationUtils.hasAnnotationOfType(annotationNode.getClassNode(), org.gcontracts.annotations.meta.Postcondition.class.getName());
ClassExpression closureClassExpression = (ClassExpression) annotationNode.getMember(CLOSURE_ATTRIBUTE_NAME);
ArgumentListExpression closureArgumentList = new ArgumentListExpression();
for (Parameter parameter : methodNode.getParameters()) {
closureArgumentList.addExpression(new VariableExpression(parameter));
}
if (methodNode.getReturnType() != ClassHelper.VOID_TYPE && isPostcondition && !(methodNode instanceof ConstructorNode)) {
VariableExpression variableExpression = new VariableExpression("result", methodNode.getReturnType());
variableExpression.setAccessedVariable(variableExpression);
closureArgumentList.addExpression(variableExpression);
}
if (isPostcondition && !(methodNode instanceof ConstructorNode)) {
VariableExpression variableExpression = new VariableExpression("old", new ClassNode(Map.class));
variableExpression.setAccessedVariable(variableExpression);
closureArgumentList.addExpression(variableExpression);
}
MethodCallExpression doCall = new MethodCallExpression(
new ConstructorCallExpression(annotationNode.getMember(CLOSURE_ATTRIBUTE_NAME).getType(), new ArgumentListExpression(VariableExpression.THIS_EXPRESSION, VariableExpression.THIS_EXPRESSION)),
"doCall",
closureArgumentList
);
ClassNode type = annotationNode.getMember(CLOSURE_ATTRIBUTE_NAME).getType();
doCall.setMethodTarget(type.getMethods("doCall").get(0));
final BooleanExpression booleanExpression = new BooleanExpression(doCall);
booleanExpression.setSourcePosition(annotationNode);
annotationProcessor.process(pci, pci.contract(), methodNode.getDeclaringClass(), methodNode, (BlockStatement) closureClassExpression.getNodeMetaData(AnnotationClosureVisitor.META_DATA_ORIGINAL_TRY_CATCH_BLOCK), booleanExpression);
// if the implementation method has no annotation, we need to set a dummy marker in order to find parent pre/postconditions
if (!AnnotationUtils.hasAnnotationOfType(methodNode, annotationNode.getClassNode().getName())) {
AnnotationNode annotationMarker = new AnnotationNode(annotationNode.getClassNode());
annotationMarker.setMember(CLOSURE_ATTRIBUTE_NAME, annotationNode.getMember(CLOSURE_ATTRIBUTE_NAME));