private static boolean containsError(PsiAnnotation annotation) { final PsiJavaCodeReferenceElement nameRef = annotation.getNameReferenceElement(); if (nameRef == null) { return true; } final PsiClass aClass = (PsiClass) nameRef.resolve(); if (aClass == null || !aClass.isAnnotationType()) { return true; } final Set<String> names = new HashSet<String>(); final PsiAnnotationParameterList annotationParameterList = annotation.getParameterList(); if (PsiUtilCore.hasErrorElementChild(annotationParameterList)) { return true; } final PsiNameValuePair[] attributes = annotationParameterList.getAttributes(); for (PsiNameValuePair attribute : attributes) { final PsiReference reference = attribute.getReference(); if (reference == null) { return true; } final PsiMethod method = (PsiMethod) reference.resolve(); if (method == null) { return true; } final PsiAnnotationMemberValue value = attribute.getValue(); if (value == null || PsiUtilCore.hasErrorElementChild(value)) { return true; } if (value instanceof PsiAnnotation && containsError((PsiAnnotation) value)) { return true; } if (!hasCorrectType(value, method.getReturnType())) { return true; } final String name = attribute.getName(); if (!names.add(name != null ? name : PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME)) { return true; } } for (PsiMethod method : aClass.getMethods()) { if (!(method instanceof PsiAnnotationMethod)) { continue; } final PsiAnnotationMethod annotationMethod = (PsiAnnotationMethod) method; if (annotationMethod.getDefaultValue() == null && !names.contains(annotationMethod.getName())) { return true; // missing a required argument } } return false; }
@Nullable public static HighlightInfo checkMissingAttributes(PsiAnnotation annotation) { PsiJavaCodeReferenceElement nameRef = annotation.getNameReferenceElement(); if (nameRef == null) return null; PsiClass aClass = (PsiClass) nameRef.resolve(); if (aClass != null && aClass.isAnnotationType()) { Set<String> names = new HashSet<String>(); PsiNameValuePair[] attributes = annotation.getParameterList().getAttributes(); for (PsiNameValuePair attribute : attributes) { final String name = attribute.getName(); if (name != null) { names.add(name); } else { names.add(PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME); } } PsiMethod[] annotationMethods = aClass.getMethods(); List<String> missed = new ArrayList<String>(); for (PsiMethod method : annotationMethods) { if (PsiUtil.isAnnotationMethod(method)) { PsiAnnotationMethod annotationMethod = (PsiAnnotationMethod) method; if (annotationMethod.getDefaultValue() == null) { if (!names.contains(annotationMethod.getName())) { missed.add(annotationMethod.getName()); } } } } if (!missed.isEmpty()) { StringBuffer buff = new StringBuffer("'" + missed.get(0) + "'"); for (int i = 1; i < missed.size(); i++) { buff.append(", "); buff.append("'").append(missed.get(i)).append("'"); } String description = JavaErrorMessages.message("annotation.missing.attribute", buff); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(nameRef) .descriptionAndTooltip(description) .create(); } } return null; }
@Nullable public static HighlightInfo checkAnnotationDeclaration( final PsiElement parent, final PsiReferenceList list) { if (PsiUtil.isAnnotationMethod(parent)) { PsiAnnotationMethod method = (PsiAnnotationMethod) parent; if (list == method.getThrowsList()) { String description = JavaErrorMessages.message("annotation.members.may.not.have.throws.list"); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(list) .descriptionAndTooltip(description) .create(); } } else if (parent instanceof PsiClass && ((PsiClass) parent).isAnnotationType()) { if (PsiKeyword.EXTENDS.equals(list.getFirstChild().getText())) { String description = JavaErrorMessages.message("annotation.may.not.have.extends.list"); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(list) .descriptionAndTooltip(description) .create(); } } return null; }
public static HighlightInfo checkClashesWithSuperMethods(@NotNull PsiAnnotationMethod psiMethod) { final PsiIdentifier nameIdentifier = psiMethod.getNameIdentifier(); if (nameIdentifier != null) { final PsiMethod[] methods = psiMethod.findDeepestSuperMethods(); for (PsiMethod method : methods) { final PsiClass containingClass = method.getContainingClass(); if (containingClass != null) { final String qualifiedName = containingClass.getQualifiedName(); if (CommonClassNames.JAVA_LANG_OBJECT.equals(qualifiedName) || CommonClassNames.JAVA_LANG_ANNOTATION_ANNOTATION.equals(qualifiedName)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(nameIdentifier) .descriptionAndTooltip( "@interface member clashes with '" + JavaHighlightUtil.formatMethod(method) + "' in " + HighlightUtil.formatClass(containingClass)) .create(); } } } } return null; }