diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspectionBase.java index 3c03a892ec2c..e8af11c737bb 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspectionBase.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspectionBase.java @@ -594,6 +594,7 @@ public class UnusedDeclarationInspectionBase extends GlobalInspectionTool { private final Map> myClassIDtoMethods = new HashMap<>(); private final Set myInstantiatedClasses = new HashSet<>(); private int myInstantiatedClassesCount; + private final Set myProcessedClasses = new HashSet<>(); private final Set myProcessedMethods = new HashSet<>(); private final Set myProcessedFunctionalExpressions = new HashSet<>(); private final Stack myNextRound = new Stack<>(); @@ -646,15 +647,13 @@ public class UnusedDeclarationInspectionBase extends GlobalInspectionTool { } @Override public void visitClass(@NotNull RefClass refClass) { - boolean alreadyActive = refClass.isReachable(); - ((RefClassImpl)refClass).setReachable(true); - - if (!alreadyActive) { + if (myProcessedClasses.add(refClass)) { + ((RefClassImpl)refClass).setReachable(true); // Process class's static initializers. makeReachable(refClass); - } - addInstantiatedClass(refClass); + addInstantiatedClass(refClass); + } } @Override public void visitField(@NotNull RefField field) { diff --git a/java/java-tests/testData/inspection/deadCode/annotationInitializedByInheritedClassReference/expected.xml b/java/java-tests/testData/inspection/deadCode/annotationInitializedByInheritedClassReference/expected.xml new file mode 100644 index 000000000000..d704d58ed391 --- /dev/null +++ b/java/java-tests/testData/inspection/deadCode/annotationInitializedByInheritedClassReference/expected.xml @@ -0,0 +1,4 @@ + + + + diff --git a/java/java-tests/testData/inspection/deadCode/annotationInitializedByInheritedClassReference/src/AnnotationsUtil.java b/java/java-tests/testData/inspection/deadCode/annotationInitializedByInheritedClassReference/src/AnnotationsUtil.java new file mode 100644 index 000000000000..48e0557eff20 --- /dev/null +++ b/java/java-tests/testData/inspection/deadCode/annotationInitializedByInheritedClassReference/src/AnnotationsUtil.java @@ -0,0 +1,20 @@ +import java.lang.annotation.*; + +public class AnnotationsUtil { + @Inherited + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.TYPE) + private @interface PerClassLifeCycle { + } + + @PerClassLifeCycle + private static class BaseMetaAnnotatedTestCase { + } + + private static class SpecializedTestCase extends BaseMetaAnnotatedTestCase { + } + + public static void main(String[] args) { + System.out.println(SpecializedTestCase.class); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/UnusedDeclarationInspectionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/UnusedDeclarationInspectionTest.java index d9c8c8d9e996..eb058e84961e 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/UnusedDeclarationInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/UnusedDeclarationInspectionTest.java @@ -131,6 +131,10 @@ public class UnusedDeclarationInspectionTest extends AbstractUnusedDeclarationTe doTest(); } + public void testAnnotationInitializedByInheritedClassReference() { + doTest(); + } + public void testUnusedEnum() { doTest5(); }