mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-30 02:09:59 +07:00
IDEA-105101 Java: bad code is green: cyclic annotation element types
(JLS 9.6.1. Annotation Type Elements)
This commit is contained in:
@@ -442,13 +442,29 @@ public class AnnotationsHighlightUtil {
|
||||
public static HighlightInfo checkCyclicMemberType(PsiTypeElement typeElement, PsiClass aClass) {
|
||||
LOG.assertTrue(aClass.isAnnotationType());
|
||||
PsiType type = typeElement.getType();
|
||||
if (type instanceof PsiClassType && ((PsiClassType)type).resolve() == aClass) {
|
||||
final Set<PsiClass> checked = new HashSet<PsiClass>();
|
||||
if (cyclicDependencies(aClass, type, checked)) {
|
||||
String description = JavaErrorMessages.message("annotation.cyclic.element.type");
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(typeElement).descriptionAndTooltip(description).create();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean cyclicDependencies(PsiClass aClass, PsiType type, Set<PsiClass> checked) {
|
||||
final PsiClass resolvedClass = PsiUtil.resolveClassInType(type);
|
||||
if (resolvedClass != null && resolvedClass.isAnnotationType()) {
|
||||
if (aClass == resolvedClass) {
|
||||
return true;
|
||||
}
|
||||
if (!checked.add(resolvedClass) || !resolvedClass.getManager().isInProject(resolvedClass)) return false;
|
||||
final PsiMethod[] methods = resolvedClass.getMethods();
|
||||
for (PsiMethod method : methods) {
|
||||
if (cyclicDependencies(aClass, method.getReturnType(), checked)) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkAnnotationDeclaration(final PsiElement parent, final PsiReferenceList list) {
|
||||
if (PsiUtil.isAnnotationMethod(parent)) {
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
@interface A1 {
|
||||
<error descr="Cyclic annotation element type">B1</error> value();
|
||||
}
|
||||
|
||||
@interface B1 {
|
||||
<error descr="Cyclic annotation element type">A1</error> value();
|
||||
}
|
||||
|
||||
@interface C1 {
|
||||
A1 value();
|
||||
}
|
||||
|
||||
@interface D1 {
|
||||
<error descr="Cyclic annotation element type">D1</error> value();
|
||||
}
|
||||
|
||||
enum E1 {
|
||||
E_1;
|
||||
|
||||
@F(E_1)
|
||||
void foo() {
|
||||
}
|
||||
}
|
||||
|
||||
@interface F {
|
||||
E1 value();
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import java.util.Collection;
|
||||
|
||||
@interface Anno {
|
||||
Anno[] nested() default {};
|
||||
<error descr="Cyclic annotation element type">Anno[]</error> nested() default {};
|
||||
}
|
||||
|
||||
abstract class C {
|
||||
|
||||
@@ -46,6 +46,8 @@ public class AnnotationsHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
public void testTypeAnnotations() { doTest8(false); }
|
||||
public void testRepeatable() { doTest8(false); }
|
||||
|
||||
public void testPingPongAnnotationTypesDependencies() { doTest(false);}
|
||||
|
||||
private void doTest(boolean checkWarnings) {
|
||||
setLanguageLevel(LanguageLevel.JDK_1_7);
|
||||
doTest(BASE_PATH + "/" + getTestName(true) + ".java", checkWarnings, false);
|
||||
|
||||
Reference in New Issue
Block a user