mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-20 13:31:28 +07:00
IDEA-105110 (check repeatable annotation container applicability)
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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() { }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user