use of org.gcontracts.common.spi.AnnotationProcessor in project gcontracts by andresteingress.
the class AnnotationProcessorVisitor method createAnnotationProcessor.
private AnnotationProcessor createAnnotationProcessor(AnnotationNode annotationNode) {
ClassExpression annotationProcessingAnno = null;
List<AnnotationNode> annotations = annotationNode.getClassNode().redirect().getAnnotations();
for (AnnotationNode anno : annotations) {
Class typeClass = anno.getClassNode().getTypeClass();
if (typeClass.getName().equals("org.gcontracts.annotations.meta.AnnotationProcessorImplementation")) {
annotationProcessingAnno = (ClassExpression) anno.getMember("value");
break;
}
}
if (annotationProcessingAnno == null)
throw new GroovyBugError("Annotation processing class could not be found! This indicates a bug in GContracts, please file an issue!");
try {
final Class clz = Class.forName(annotationProcessingAnno.getType().getTypeClass().getName());
return (AnnotationProcessor) clz.newInstance();
} catch (InstantiationException e) {
} catch (IllegalAccessException e) {
} catch (ClassNotFoundException e) {
}
throw new GroovyBugError("Annotation processing class could not be instantiated! This indicates a bug in GContracts, please file an issue!");
}
use of org.gcontracts.common.spi.AnnotationProcessor in project gcontracts by andresteingress.
the class AnnotationProcessorVisitor method handleClassNode.
private void handleClassNode(final ClassNode classNode) {
final List<AnnotationNode> annotationNodes = AnnotationUtils.hasMetaAnnotations(classNode, ContractElement.class.getName());
for (AnnotationNode annotationNode : annotationNodes) {
final AnnotationProcessor annotationProcessor = createAnnotationProcessor(annotationNode);
if (annotationProcessor != null && annotationNode.getMember(CLOSURE_ATTRIBUTE_NAME) instanceof ClassExpression) {
final ClassExpression closureClassExpression = (ClassExpression) annotationNode.getMember(CLOSURE_ATTRIBUTE_NAME);
MethodCallExpression doCall = new MethodCallExpression(new ConstructorCallExpression(closureClassExpression.getType(), new ArgumentListExpression(VariableExpression.THIS_EXPRESSION, VariableExpression.THIS_EXPRESSION)), "doCall", ArgumentListExpression.EMPTY_ARGUMENTS);
doCall.setMethodTarget(closureClassExpression.getType().getMethods("doCall").get(0));
final BooleanExpression booleanExpression = new BooleanExpression(doCall);
booleanExpression.setSourcePosition(annotationNode);
annotationProcessor.process(pci, pci.contract(), classNode, (BlockStatement) closureClassExpression.getNodeMetaData(AnnotationClosureVisitor.META_DATA_ORIGINAL_TRY_CATCH_BLOCK), booleanExpression);
}
}
}
use of org.gcontracts.common.spi.AnnotationProcessor in project gcontracts by andresteingress.
the class AnnotationProcessorVisitor method handleMethodNode.
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));
annotationMarker.setRuntimeRetention(true);
annotationMarker.setSourceRetention(false);
methodNode.addAnnotation(annotationMarker);
}
}
}
}
Aggregations