IDEA-105110 (check repeatable annotation container applicability)

This commit is contained in:
Roman Shevchenko
2013-04-16 16:23:13 +02:00
parent 8110c941f6
commit aec23d1dab
4 changed files with 30 additions and 1 deletions

View File

@@ -205,6 +205,14 @@ public class AnnotationsHighlightUtil {
return annotationError(containerAnno, description);
}
}
PsiAnnotation.TargetType[] targets = PsiImplUtil.getTargetsForLocation(owner);
PsiAnnotation.TargetType applicable = PsiImplUtil.findApplicableTarget(container, targets);
if (applicable == null) {
String target = JavaErrorMessages.message("annotation.target." + targets[0]);
String message = JavaErrorMessages.message("annotation.container.not.applicable", containerName, target);
return annotationError(annotation, message);
}
}
}
@@ -603,6 +611,14 @@ public class AnnotationsHighlightUtil {
}
}
Set<PsiAnnotation.TargetType> repeatableTargets = PsiImplUtil.getAnnotationTargets((PsiClass)target);
if (repeatableTargets != null) {
Set<PsiAnnotation.TargetType> containerTargets = PsiImplUtil.getAnnotationTargets(container);
if (containerTargets != null && !repeatableTargets.containsAll(containerTargets)) {
return JavaErrorMessages.message("annotation.container.wide.target", container.getQualifiedName());
}
}
return null;
}

View File

@@ -372,7 +372,7 @@ public class PsiImplUtil {
// todo[r.sh] cache?
@Nullable
private static Set<TargetType> getAnnotationTargets(PsiClass annotationType) {
public static Set<TargetType> getAnnotationTargets(PsiClass annotationType) {
if (!annotationType.isAnnotationType()) return null;
PsiModifierList modifierList = annotationType.getModifierList();
if (modifierList == null) return null;

View File

@@ -23,9 +23,11 @@ annotation.not.allowed.class=Class literal type may not be annotated
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.container.wide.target=Target of container annotation ''{0}'' is not a subset of target of this 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.container.wrong.place=Container annotation ''{0}'' must not be present at the same time as the element it contains
annotation.container.not.applicable=Container annotation ''@{0}'' is not applicable to {1}
# These aren't unused.
# suppress inspection "UnusedProperty"

View File

@@ -42,3 +42,14 @@ class DupTypeAnno {
static <T> void m() { }
}
@interface AA7 { A7[] value() default { }; }
@Target({METHOD}) @Repeatable(<error descr="Target of container annotation 'AA7' is not a subset of target of this annotation">AA7.class</error>) @interface A7 { }
@Target({METHOD}) @interface AA8 { A8[] value() default { }; }
@Target({METHOD, FIELD}) @Repeatable(AA8.class) @interface A8 { }
class C8 {
@A8 int f1;
<error descr="Container annotation '@AA8' is not applicable to field">@A8</error> <error descr="Container annotation '@AA8' is not applicable to field">@A8</error> int f2;
@A8 @A8 void m() { }
}