mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Java: handle @Repeatable annotations better in “Unused declaration” inspection
GitOrigin-RevId: 677f2c52ac069497147398dce1b42709e78ff445
This commit is contained in:
committed by
intellij-monorepo-bot
parent
33881c73d1
commit
153827d95f
+1
-26
@@ -4,7 +4,6 @@ package com.intellij.codeInspection.deadCode;
|
||||
import com.intellij.analysis.AnalysisBundle;
|
||||
import com.intellij.analysis.AnalysisScope;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.AnnotationsHighlightUtil;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.codeInspection.ex.EntryPointsManager;
|
||||
import com.intellij.codeInspection.ex.EntryPointsManagerBase;
|
||||
@@ -27,7 +26,6 @@ import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.PsiClassImplUtil;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.PsiMethodUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.uast.UastMetaLanguage;
|
||||
import com.intellij.util.containers.Stack;
|
||||
import org.jdom.Element;
|
||||
@@ -345,7 +343,6 @@ public class UnusedDeclarationInspectionBase extends GlobalInspectionTool {
|
||||
LOG.assertTrue(processedSuspicious != null, "phase: " + phase);
|
||||
|
||||
Collection<Language> uastLanguages = Language.findInstance(UastMetaLanguage.class).getMatchingLanguages();
|
||||
boolean[] requestAdded = {false};
|
||||
globalContext.getRefManager().iterate(new RefJavaVisitor() {
|
||||
@Override
|
||||
public void visitField(@NotNull RefField refField) {
|
||||
@@ -362,7 +359,6 @@ public class UnusedDeclarationInspectionBase extends GlobalInspectionTool {
|
||||
getEntryPointsManager(globalContext).addEntryPoint(refField, false);
|
||||
return false;
|
||||
});
|
||||
requestAdded[0] = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -384,15 +380,12 @@ public class UnusedDeclarationInspectionBase extends GlobalInspectionTool {
|
||||
}
|
||||
}
|
||||
UMethod uMethod = refMethod.getUastElement();
|
||||
if (uMethod != null && (RefSerializationUtil.isSerializationMethod(uMethod, refMethod.getOwnerClass()) ||
|
||||
// todo this method potentially leads to INRE. Perhaps, it should be reconsidered/deleted (IJ-CR-5556)
|
||||
belongsToRepeatableAnnotationContainer(uMethod, refMethod.getOwnerClass()))) {
|
||||
if (uMethod != null && (RefSerializationUtil.isSerializationMethod(uMethod, refMethod.getOwnerClass()))) {
|
||||
getEntryPointsManager(globalContext).addEntryPoint(refMethod, false);
|
||||
}
|
||||
else if (!refMethod.isExternalOverride() && !PsiModifier.PRIVATE.equals(refMethod.getAccessModifier())) {
|
||||
processedSuspicious.addAll(refMethod.getDerivedMethods());
|
||||
enqueueMethodUsages(globalContext, refMethod);
|
||||
requestAdded[0] = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -419,7 +412,6 @@ public class UnusedDeclarationInspectionBase extends GlobalInspectionTool {
|
||||
});
|
||||
|
||||
queryQualifiedNameUsages(refClass);
|
||||
requestAdded[0] = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -440,7 +432,6 @@ public class UnusedDeclarationInspectionBase extends GlobalInspectionTool {
|
||||
getEntryPointsManager(globalContext).addEntryPoint(refClass, false);
|
||||
}
|
||||
}
|
||||
requestAdded[0] = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -449,22 +440,6 @@ public class UnusedDeclarationInspectionBase extends GlobalInspectionTool {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean belongsToRepeatableAnnotationContainer(@NotNull UMethod uMethod, @Nullable RefClass ownerRefClass) {
|
||||
if (ownerRefClass == null) return false;
|
||||
if (!PsiUtil.isLanguageLevel8OrHigher(uMethod.getJavaPsi())) return false;
|
||||
if (!"value".equals(uMethod.getName())) return false;
|
||||
if (!ownerRefClass.isAnnotationType()) return false;
|
||||
PsiType returnType = uMethod.getReturnType();
|
||||
if (!(returnType instanceof PsiArrayType)) return false;
|
||||
PsiClass returnTypeClass = PsiUtil.resolveClassInType(returnType);
|
||||
if (returnTypeClass == null || !returnTypeClass.isAnnotationType()) return false;
|
||||
RefElement repeatableAnn = ownerRefClass.getRefManager().getReference(returnTypeClass);
|
||||
if (repeatableAnn == null || !repeatableAnn.isReferenced()) return false;
|
||||
PsiAnnotation repeatableAnnContainer = returnTypeClass.getAnnotation(CommonClassNames.JAVA_LANG_ANNOTATION_REPEATABLE);
|
||||
if (repeatableAnnContainer == null) return false;
|
||||
return AnnotationsHighlightUtil.doCheckRepeatableAnnotation(repeatableAnnContainer) == null;
|
||||
}
|
||||
|
||||
private static void enqueueMethodUsages(@NotNull GlobalInspectionContext globalContext, @NotNull RefMethod refMethod) {
|
||||
if (refMethod.getSuperMethods().isEmpty()) {
|
||||
globalContext.getExtension(GlobalJavaInspectionContext.CONTEXT).enqueueMethodUsagesProcessor(refMethod, psiReference -> {
|
||||
|
||||
+22
-1
@@ -75,10 +75,32 @@ public final class RefJavaUtilImpl extends RefJavaUtil {
|
||||
final RefElement refClass = refManager.getReference(javaClass.getOriginalElement());
|
||||
if (refClass != null) refClass.initializeIfNeeded();
|
||||
refFrom.addReference(refClass, javaClass.getOriginalElement(), decl, false, true, null);
|
||||
checkRepeatableAnnotation(javaClass, node);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void checkRepeatableAnnotation(PsiClass annotationClass, UAnnotation annotation) {
|
||||
if (!CommonClassNames.JAVA_LANG_ANNOTATION_REPEATABLE.equals(annotationClass.getQualifiedName())) return;
|
||||
UExpression value = annotation.findAttributeValue("value");
|
||||
while (value instanceof UParenthesizedExpression parenth) {
|
||||
value = parenth.getExpression();
|
||||
}
|
||||
if (!(value instanceof UClassLiteralExpression classLiteralExpression)) return;
|
||||
PsiClass aClass = PsiUtil.resolveClassInClassTypeOnly(classLiteralExpression.getType());
|
||||
if (aClass == null) return;
|
||||
RefClassImpl refClass =
|
||||
ObjectUtils.tryCast(refManager.getReference(aClass.getOriginalElement()), RefClassImpl.class);
|
||||
if (refClass == null) return;
|
||||
refClass.initializeIfNeeded();
|
||||
for (RefEntity child : refClass.getChildren()) {
|
||||
if (child instanceof RefMethod method && "value()".equals(method.getName())) {
|
||||
refFrom.addReference(method, null, decl, false, true, null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visitTypeReferenceExpression(@NotNull UTypeReferenceExpression node) {
|
||||
PsiType type = node.getType();
|
||||
@@ -232,7 +254,6 @@ public final class RefJavaUtilImpl extends RefJavaUtil {
|
||||
boolean writing = isAccessedForWriting(node);
|
||||
boolean reading = isAccessedForReading(node);
|
||||
if (refResolved != null) refResolved.initializeIfNeeded();
|
||||
refFrom.initializeIfNeeded();
|
||||
refFrom.addReference(refResolved, psiResolved, decl, writing, reading, node);
|
||||
|
||||
if (refResolved instanceof RefMethodImpl refMethod) {
|
||||
|
||||
@@ -10,16 +10,6 @@
|
||||
<line>5</line>
|
||||
<description>Method owner class is never instantiated OR An instantiation is not reachable from entry points.</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>RepeatableAnnotation.java</file>
|
||||
<line>12</line>
|
||||
<description>Method is never used.</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>RepeatableAnnotation.java</file>
|
||||
<line>21</line>
|
||||
<description>Method owner class is never instantiated OR An instantiation is not reachable from entry points.</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>RepeatableAnnotation.java</file>
|
||||
<line>25</line>
|
||||
|
||||
Reference in New Issue
Block a user