Repeatable annotations highlighting text corrected

This commit is contained in:
Roman Shevchenko
2013-04-16 13:31:10 +02:00
parent 43f7e52e38
commit 8110c941f6
3 changed files with 38 additions and 38 deletions

View File

@@ -195,14 +195,14 @@ public class AnnotationsHighlightUtil {
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(element).descriptionAndTooltip(description).create();
}
PsiClass collector = getRepeatableCollector(metaAnno);
if (collector != null) {
String collectorName = collector.getQualifiedName();
if (collectorName != null) {
PsiAnnotation collectorAnno = owner.findAnnotation(collectorName);
if (collectorAnno != null) {
String description = JavaErrorMessages.message("annotation.collector.wrong.place", collectorName);
return annotationError(collectorAnno, description);
PsiClass container = getRepeatableContainer(metaAnno);
if (container != null) {
String containerName = container.getQualifiedName();
if (containerName != null) {
PsiAnnotation containerAnno = owner.findAnnotation(containerName);
if (containerAnno != null) {
String description = JavaErrorMessages.message("annotation.container.wrong.place", containerName);
return annotationError(containerAnno, description);
}
}
}
@@ -482,7 +482,7 @@ public class AnnotationsHighlightUtil {
}
return null;
}
@Nullable
public static HighlightInfo checkAnnotationDeclaration(final PsiElement parent, final PsiReferenceList list) {
if (PsiUtil.isAnnotationMethod(parent)) {
@@ -565,9 +565,9 @@ public class AnnotationsHighlightUtil {
String description = doCheckRepeatableAnnotation(annotation);
if (description != null) {
PsiAnnotationMemberValue collectorRef = PsiImplUtil.findAttributeValue(annotation, null);
if (collectorRef != null) {
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(collectorRef).descriptionAndTooltip(description).create();
PsiAnnotationMemberValue containerRef = PsiImplUtil.findAttributeValue(annotation, null);
if (containerRef != null) {
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(containerRef).descriptionAndTooltip(description).create();
}
}
@@ -580,26 +580,26 @@ public class AnnotationsHighlightUtil {
if (!(owner instanceof PsiModifierList)) return null;
PsiElement target = ((PsiModifierList)owner).getParent();
if (!(target instanceof PsiClass) || !((PsiClass)target).isAnnotationType()) return null;
PsiClass collector = getRepeatableCollector(annotation);
if (collector == null) return null;
PsiClass container = getRepeatableContainer(annotation);
if (container == null) return null;
PsiMethod[] methods = collector.findMethodsByName("value", false);
PsiMethod[] methods = container.findMethodsByName("value", false);
if (methods.length == 0) {
return JavaErrorMessages.message("annotation.container.no.value", collector.getQualifiedName());
return JavaErrorMessages.message("annotation.container.no.value", container.getQualifiedName());
}
if (methods.length == 1) {
PsiType expected = new PsiImmediateClassType((PsiClass)target, PsiSubstitutor.EMPTY).createArrayType();
if (!expected.equals(methods[0].getReturnType())) {
return JavaErrorMessages.message("annotation.container.bad.type", collector.getQualifiedName(), HighlightUtil.formatType(expected));
return JavaErrorMessages.message("annotation.container.bad.type", container.getQualifiedName(), HighlightUtil.formatType(expected));
}
}
RetentionPolicy targetPolicy = getRetentionPolicy((PsiClass)target);
if (targetPolicy != null) {
RetentionPolicy collectorPolicy = getRetentionPolicy(collector);
if (collectorPolicy != null && targetPolicy.compareTo(collectorPolicy) > 0) {
return JavaErrorMessages.message("annotation.container.low.retention", collector.getQualifiedName(), collectorPolicy);
RetentionPolicy containerPolicy = getRetentionPolicy(container);
if (containerPolicy != null && targetPolicy.compareTo(containerPolicy) > 0) {
return JavaErrorMessages.message("annotation.container.low.retention", container.getQualifiedName(), containerPolicy);
}
}
@@ -607,14 +607,14 @@ public class AnnotationsHighlightUtil {
}
@Nullable
private static PsiClass getRepeatableCollector(PsiAnnotation annotation) {
PsiAnnotationMemberValue collectorRef = PsiImplUtil.findAttributeValue(annotation, null);
if (!(collectorRef instanceof PsiClassObjectAccessExpression)) return null;
PsiType collectorType = ((PsiClassObjectAccessExpression)collectorRef).getOperand().getType();
if (!(collectorType instanceof PsiClassType)) return null;
PsiClass collector = ((PsiClassType)collectorType).resolve();
if (collector == null || !collector.isAnnotationType()) return null;
return collector;
private static PsiClass getRepeatableContainer(PsiAnnotation annotation) {
PsiAnnotationMemberValue containerRef = PsiImplUtil.findAttributeValue(annotation, null);
if (!(containerRef instanceof PsiClassObjectAccessExpression)) return null;
PsiType containerType = ((PsiClassObjectAccessExpression)containerRef).getOperand().getType();
if (!(containerType instanceof PsiClassType)) return null;
PsiClass container = ((PsiClassType)containerType).resolve();
if (container == null || !container.isAnnotationType()) return null;
return container;
}
@Nullable

View File

@@ -20,12 +20,12 @@ annotation.not.allowed.ref=Annotation not applicable to this kind of reference
annotation.not.allowed.static=Static member qualifying type may not be annotated
annotation.not.allowed.void='void' type may not be annotated
annotation.not.allowed.class=Class literal type may not be annotated
annotation.container.no.value=Invalid containing annotation ''{0}'': no ''value'' method declared
annotation.container.bad.type=Invalid containing annotation ''{0}'': ''value'' method should have type ''{1}''
annotation.container.low.retention=Containing annotation ''{0}'' has shorter retention (''{1}'') than the contained annotation
annotation.container.no.value=Invalid container annotation ''{0}'': no ''value'' method declared
annotation.container.bad.type=Invalid container annotation ''{0}'': ''value'' method should have type ''{1}''
annotation.container.low.retention=Container annotation ''{0}'' has shorter retention (''{1}'') than the contained annotation
annotation.duplicate.explained=Duplicate annotation. {0}
annotation.non.repeatable=The declaration of ''{0}'' does not have a valid java.lang.annotation.Repeatable annotation
annotation.collector.wrong.place=Containing annotation ''{0}'' must not be present at the same time as the element it contains
annotation.container.wrong.place=Container annotation ''{0}'' must not be present at the same time as the element it contains
# These aren't unused.
# suppress inspection "UnusedProperty"

View File

@@ -3,13 +3,13 @@ import java.util.*;
import static java.lang.annotation.ElementType.*;
@interface AA1 { }
@Repeatable(<error descr="Invalid containing annotation 'AA1': no 'value' method declared">AA1.class</error>) @interface A1 { }
@Repeatable(<error descr="Invalid container annotation 'AA1': no 'value' method declared">AA1.class</error>) @interface A1 { }
@interface AA2 { String[] value(); }
@Repeatable(<error descr="Invalid containing annotation 'AA2': 'value' method should have type 'A2[]'">AA2.class</error>) @interface A2 { }
@Repeatable(<error descr="Invalid container annotation 'AA2': 'value' method should have type 'A2[]'">AA2.class</error>) @interface A2 { }
@interface AA3 { A3[] value(); }
@Repeatable(<error descr="Containing annotation 'AA3' has shorter retention ('CLASS') than the contained annotation">AA3.class</error>)
@Repeatable(<error descr="Container annotation 'AA3' has shorter retention ('CLASS') than the contained annotation">AA3.class</error>)
@Retention(RetentionPolicy.RUNTIME) @interface A3 { }
@interface A4 { }
@@ -18,14 +18,14 @@ import static java.lang.annotation.ElementType.*;
class C4 { }
@A4 class C4bis { }
@<error descr="Duplicate annotation. Invalid containing annotation 'AA1': no 'value' method declared">A1</error>
@<error descr="Duplicate annotation. Invalid containing annotation 'AA1': no 'value' method declared">A1</error>
@<error descr="Duplicate annotation. Invalid container annotation 'AA1': no 'value' method declared">A1</error>
@<error descr="Duplicate annotation. Invalid container annotation 'AA1': no 'value' method declared">A1</error>
class C5 { }
@A1 class C5bis { }
@interface AA6 { A6[] value() default { }; }
@Repeatable(AA6.class) @interface A6 { }
@A6 @A6 <error descr="Containing annotation 'AA6' must not be present at the same time as the element it contains">@AA6</error> class C6 { }
@A6 @A6 <error descr="Container annotation 'AA6' must not be present at the same time as the element it contains">@AA6</error> class C6 { }
@A6 @A6 class C6bis1 { }
@A6 @AA6 class C6bis2 { }