/** * @param attrName the name * @param expression the expression * @param attrType the type */ protected void visitAnnotationExpression(String attrName, AnnotationConstantExpression expression, ClassNode attrType) { AnnotationNode annotationNode = (AnnotationNode) expression.getValue(); AnnotationVisitor visitor = new AnnotationVisitor(this.source, this.errorCollector); // TODO track Deprecated usage and give a warning? visitor.visit(annotationNode); }
visitListExpression(attrName, le, attrType.getComponentType()); } else if (attrExp instanceof ClosureExpression) { addError("Annotation list attributes must use Groovy notation [el1, el2]", attrExp); } else { annotation.setMember(attrName, listExp); visitExpression(attrName, listExp, attrType); visitConstantExpression(attrName, getConstantExpression(attrExp, attrType), ClassHelper.getWrapper(attrType)); } else if (ClassHelper.STRING_TYPE.equals(attrType)) { visitConstantExpression(attrName, getConstantExpression(attrExp, attrType), ClassHelper.STRING_TYPE); } else if (ClassHelper.CLASS_Type.equals(attrType)) { if (!(attrExp instanceof ClassExpression || attrExp instanceof ClosureExpression)) { addError("Only classes and closures can be used for attribute '" + attrName + "'", attrExp); visitEnumExpression(attrName, (PropertyExpression) attrExp, attrType); } else { addError("Expected enum value for attribute " + attrName, attrExp); } else if (isValidAnnotationClass(attrType)) { if (attrExp instanceof AnnotationConstantExpression) { visitAnnotationExpression(attrName, (AnnotationConstantExpression) attrExp, attrType); } else { addError("Expected annotation of type '" + attrType.getName() + "' for attribute " + attrName, attrExp); addError("Unexpected type " + attrType.getName(), attrExp);
public AnnotationNode visit(AnnotationNode node) { this.annotation = node; this.reportClass = node.getClassNode(); if (!isValidAnnotationClass(node.getClassNode())) { addError("class " + node.getClassNode().getName() + " is not an annotation"); return node; } // check if values have been passed for all annotation attributes that don't have defaults if (!checkIfMandatoryAnnotationValuesPassed(node)) { return node; } // if enum constants have been used, check if they are all valid if (!checkIfValidEnumConstsAreUsed(node)) { return node; } Map<String, Expression> attributes = node.getMembers(); for (Map.Entry<String, Expression> entry : attributes.entrySet()) { String attrName = entry.getKey(); ClassNode attrType = getAttributeType(node, attrName); Expression attrExpr = transformInlineConstants(entry.getValue(), attrType); entry.setValue(attrExpr); visitExpression(attrName, attrExpr, attrType); } VMPluginFactory.getPlugin().configureAnnotation(node); return this.annotation; }
protected void visitConstantExpression(String attrName, ConstantExpression constExpr, ClassNode attrType) { ClassNode constType = constExpr.getType(); ClassNode wrapperType = ClassHelper.getWrapper(constType); if (!hasCompatibleType(attrType, wrapperType)) { addError("Attribute '" + attrName + "' should have type '" + attrType.getName() + "'; but found type '" + constType.getName() + "'", constExpr); } }
visitListExpression(attrName, (ListExpression) attrExp, attrType.getComponentType()); } else if (attrExp instanceof ClosureExpression) { addError("Annotation list attributes must use Groovy notation [el1, el2]", attrExp); } else { annotation.setMember(attrName, listExp); visitExpression(attrName, listExp, attrType); visitConstantExpression(attrName, (ConstantExpression) attrExp, ClassHelper.getWrapper(ClassHelper.make(attrType))); } else if(String.class.equals(attrType)) { visitConstantExpression(attrName, (ConstantExpression) attrExp, ClassHelper.make(String.class)); } else if(Class.class.equals(attrType)) { } else if(isEnum(attrType)) { if(attrExp instanceof PropertyExpression) { visitEnumExpression(attrName, (PropertyExpression) attrExp, ClassHelper.make(attrType)); } else { addError("Value not defined for annotation attribute " + attrName, attrExp); } else if(isAnnotation(attrType)) { visitAnnotationExpression(attrName, (AnnotationConstantExpression) attrExp, attrType);
private void visitConstructorOrMethod(MethodNode node, int methodTarget) { visitAnnotations(node, methodTarget); for (int i = 0; i < node.getParameters().length; i++) { Parameter parameter = node.getParameters()[i]; visitAnnotations(parameter, AnnotationNode.PARAMETER_TARGET); } if (this.currentClass.isAnnotationDefinition() && !node.isStaticConstructor()) { ErrorCollector errorCollector = new ErrorCollector(this.source.getConfiguration()); AnnotationVisitor visitor = new AnnotationVisitor(this.source, errorCollector); visitor.setReportClass(currentClass); visitor.checkReturnType(node.getReturnType(), node); if (node.getParameters().length > 0) { addError("Annotation members may not have parameters.", node.getParameters()[0]); } if (node.getExceptions().length > 0) { addError("Annotation members may not have a throws clause.", node.getExceptions()[0]); } ReturnStatement code = (ReturnStatement) node.getCode(); if (code != null) { visitor.visitExpression(node.getName(), code.getExpression(), node.getReturnType()); visitor.checkCircularReference(currentClass, node.getReturnType(), code.getExpression()); } this.source.getErrorCollector().addCollectorContents(errorCollector); } Statement code = node.getCode(); if (code != null) { code.visit(this); } }
private void visitConstructorOrMethod(MethodNode node, int methodTarget) { visitAnnotations(node, methodTarget); for (int i = 0; i < node.getParameters().length; i++) { Parameter parameter = node.getParameters()[i]; visitAnnotations(parameter, AnnotationNode.PARAMETER_TARGET); } if (this.currentClass.isAnnotationDefinition()) { ErrorCollector errorCollector = new ErrorCollector(this.source.getConfiguration()); AnnotationVisitor visitor = new AnnotationVisitor(this.source, errorCollector); visitor.setReportClass(currentClass); visitor.checkReturnType(node.getReturnType(),node); if (node.getParameters().length>0) { addError ("Annotation members may not have parameters.",node.getParameters()[0]); } if (node.getExceptions().length>0) { addError ("Annotation members may not have a throws clause.",node.getExceptions()[0]); } ReturnStatement code = (ReturnStatement) node.getCode(); if (code!=null) { visitor.visitExpression(node.getName(),code.getExpression(),node.getReturnType()); visitor.checkcircularReference(currentClass,node.getReturnType(),code.getExpression()); } this.source.getErrorCollector().addCollectorContents(errorCollector); } }
public void checkReturnType(ClassNode attrType, ASTNode node) { if (attrType.isArray()) { checkReturnType(attrType.getComponentType(), node); } else if (ClassHelper.isPrimitiveType(attrType)) { } else if (ClassHelper.STRING_TYPE.equals(attrType)) { } else if (ClassHelper.CLASS_Type.equals(attrType)) { } else if (attrType.isDerivedFrom(ClassHelper.Enum_Type)) { } else if (isValidAnnotationClass(attrType)) { } else { addError("Unexpected return type " + attrType.getName(), node); } }
protected void addError(String msg) { addError(msg, this.annotation); }
public AnnotationNode visit(AnnotationNode node) { if(!isValidAnnotationClass(node)) { node.setValid(false); return node; addError("Current type was not yet resolved. Cannot introspect it."); node.setValid(false); return node; extractAnnotationMeta(this.annotationClass); String attrName = (String) entry.getKey(); Expression attrExpr = (Expression) entry.getValue(); Class attrType = getAttributeType(attrName); if(attrType == null) { addError("Unknown attribute '" + attrName + "'", attrExpr); break; visitExpression(attrName, attrExpr, attrType); addError("Required attributes " + this.requiredAttrTypes.keySet() + " not found", this.annotation);
public void checkCircularReference(ClassNode searchClass, ClassNode attrType, Expression startExp) { if (!isValidAnnotationClass(attrType)) return; if (!(startExp instanceof AnnotationConstantExpression)) { addError("Found '" + startExp.getText() + "' when expecting an Annotation Constant", startExp); return; } AnnotationConstantExpression ace = (AnnotationConstantExpression) startExp; AnnotationNode annotationNode = (AnnotationNode) ace.getValue(); if (annotationNode.getClassNode().equals(searchClass)) { addError("Circular reference discovered in " + searchClass.getName(), startExp); return; } ClassNode cn = annotationNode.getClassNode(); for (MethodNode method : cn.getMethods()) { if (method.getReturnType().equals(searchClass)) { addError("Circular reference discovered in " + cn.getName(), startExp); } ReturnStatement code = (ReturnStatement) method.getCode(); if (code == null) continue; checkCircularReference(searchClass, method.getReturnType(), code.getExpression()); } }
public void checkcircularReference(ClassNode searchClass, ClassNode attrType,Expression startExp) { if (!isValidAnnotationClass(attrType)) return; AnnotationConstantExpression ace = (AnnotationConstantExpression) startExp; AnnotationNode annotationNode = (AnnotationNode) ace.getValue(); if (annotationNode.getClassNode().equals(searchClass)) { addError ("Cirecular reference discovered in "+searchClass.getName(),startExp); return; } ClassNode cn = annotationNode.getClassNode(); List methods = cn.getMethods(); for(Iterator it=methods.iterator(); it.hasNext();) { MethodNode method = (MethodNode) it.next(); if (method.getReturnType().equals(searchClass)) { addError ("Cirecular reference discovered in "+cn.getName(),startExp); } ReturnStatement code = (ReturnStatement) method.getCode(); if (code==null) continue; checkcircularReference(searchClass,method.getReturnType(),code.getExpression()); } }
protected void visitListExpression(String attrName, ListExpression listExpr, ClassNode elementType) { for (Expression expression : listExpr.getExpressions()) { visitExpression(attrName, expression, elementType); } }
private void initializeRetention(Class annotationClass, Class retentionClass, Object retentionAnnotation) { Object retentionPolicyEnum = invoke(retentionClass, "value", EMPTY_ARG_TYPES, retentionAnnotation, EMPTY_ARGS); if (retentionPolicyEnum == null) { addError("Cannot read @RetentionPolicy on the @" + annotationClass.getName() + ExtendedVerifier.JVM_ERROR_MESSAGE); return; } if("RUNTIME".equals(retentionPolicyEnum.toString())) { this.annotation.setRuntimeRetention(true); } else if("SOURCE".equals(retentionPolicyEnum.toString())) { this.annotation.setSourceRetention(true); } }
private void initializeAnnotationMeta(Class annotationClass) { Object[] annotations = (Object[]) invoke(annotationClass.getClass(), "getAnnotations", EMPTY_ARG_TYPES, annotationClass, EMPTY_ARGS); if (annotations == null) { addError("Cannot retrieve annotation meta information. " + ExtendedVerifier.JVM_ERROR_MESSAGE); return; } for(int i = 0; i < annotations.length; i++) { Class annotationType = (Class) invoke(this.annotationRootClass, "annotationType", EMPTY_ARG_TYPES, annotations[i], EMPTY_ARGS); if (annotationType == null) continue; if ("java.lang.annotation.Retention".equals(annotationType.getName())) { initializeRetention(annotationClass, annotationType, annotations[i]); } else if("java.lang.annotation.Target".equals(annotationType.getName())) { initializeTarget(annotationClass, annotationType, annotations[i]); } } }
private void visitConstructorOrMethod(MethodNode node, int methodTarget) { visitAnnotations(node, methodTarget); for (int i = 0; i < node.getParameters().length; i++) { Parameter parameter = node.getParameters()[i]; visitAnnotations(parameter, AnnotationNode.PARAMETER_TARGET); } if (this.currentClass.isAnnotationDefinition() && !node.isStaticConstructor()) { ErrorCollector errorCollector = new ErrorCollector(this.source.getConfiguration()); AnnotationVisitor visitor = new AnnotationVisitor(this.source, errorCollector); visitor.setReportClass(currentClass); visitor.checkReturnType(node.getReturnType(), node); if (node.getParameters().length > 0) { addError("Annotation members may not have parameters.", node.getParameters()[0]); } if (node.getExceptions().length > 0) { addError("Annotation members may not have a throws clause.", node.getExceptions()[0]); } ReturnStatement code = (ReturnStatement) node.getCode(); if (code != null) { visitor.visitExpression(node.getName(), code.getExpression(), node.getReturnType()); visitor.checkCircularReference(currentClass, node.getReturnType(), code.getExpression()); } this.source.getErrorCollector().addCollectorContents(errorCollector); } }
public void visitMethod(MethodNode node) { visitAnnotations(node, AnnotationNode.METHOD_TARGET); for (int i = 0; i < node.getParameters().length; i++) { Parameter parameter = node.getParameters()[i]; visitAnnotations(parameter, AnnotationNode.PARAMETER_TARGET); } if (this.currentClass.isAnnotationDefinition()) { ErrorCollector errorCollector = new ErrorCollector(this.source.getConfiguration()); AnnotationVisitor visitor = new AnnotationVisitor(this.source, errorCollector); visitor.setReportClass(currentClass); visitor.checkReturnType(node.getReturnType(),node); if (node.getParameters().length>0) { addError ("Annotation members may not have parameters.",node.getParameters()[0]); } if (node.getExceptions().length>0) { addError ("Annotation members may not have a throws clause.",node.getExceptions()[0]); } ReturnStatement code = (ReturnStatement) node.getCode(); if (code!=null) { visitor.visitExpression(node.getName(),code.getExpression(),node.getReturnType()); visitor.checkcircularReference(currentClass,node.getReturnType(),code.getExpression()); } this.source.getErrorCollector().addCollectorContents(errorCollector); } }
public void checkReturnType(ClassNode attrType, ASTNode node) { if (attrType.isArray()) { checkReturnType(attrType.getComponentType(), node); } else if (ClassHelper.isPrimitiveType(attrType)) { return; } else if (ClassHelper.STRING_TYPE.equals(attrType)) { return; } else if (ClassHelper.CLASS_Type.equals(attrType)) { return; } else if (attrType.isDerivedFrom(ClassHelper.Enum_Type)) { return; } else if (isValidAnnotationClass(attrType)) { return; } else { addError("Unexpected return type " + attrType.getName(), node); } }
private ConstantExpression getConstantExpression(Expression exp, ClassNode attrType) { Expression result = exp; if (!(result instanceof ConstantExpression)) { result = transformInlineConstants(result, attrType); } if (result instanceof ConstantExpression) { return (ConstantExpression) result; } String base = "Expected '" + exp.getText() + "' to be an inline constant of type " + attrType.getName(); if (exp instanceof PropertyExpression) { addError(base + " not a property expression", exp); } else if (exp instanceof VariableExpression && ((VariableExpression)exp).getAccessedVariable() instanceof FieldNode) { addError(base + " not a field expression", exp); } else { addError(base, exp); } return ConstantExpression.EMPTY_EXPRESSION; }
public void checkCircularReference(ClassNode searchClass, ClassNode attrType, Expression startExp) { if (!isValidAnnotationClass(attrType)) return; if (!(startExp instanceof AnnotationConstantExpression)) { addError("Found '" + startExp.getText() + "' when expecting an Annotation Constant", startExp); return; } AnnotationConstantExpression ace = (AnnotationConstantExpression) startExp; AnnotationNode annotationNode = (AnnotationNode) ace.getValue(); if (annotationNode.getClassNode().equals(searchClass)) { addError("Circular reference discovered in " + searchClass.getName(), startExp); return; } ClassNode cn = annotationNode.getClassNode(); for (MethodNode method : cn.getMethods()) { if (method.getReturnType().equals(searchClass)) { addError("Circular reference discovered in " + cn.getName(), startExp); } ReturnStatement code = (ReturnStatement) method.getCode(); if (code == null) continue; checkCircularReference(searchClass, method.getReturnType(), code.getExpression()); } }