[java] consider enum constants used in batch inspection when valueOf() is called (IDEA-293797)

GitOrigin-RevId: 787c7356063bfbc11bbdc751dba55dd76f142e84
This commit is contained in:
Bas Leijdekkers
2024-05-29 14:19:54 +00:00
committed by intellij-monorepo-bot
parent 362d0555e5
commit 32ee8e3135
5 changed files with 55 additions and 19 deletions
@@ -251,9 +251,6 @@ public sealed abstract class RefJavaElementImpl extends RefElementImpl implement
((RefJavaElementImpl)refWhat).markReferenced(this, forWriting, forReading, expression);
}
} else {
if (psiWhat instanceof PsiMethod) {
markEnumUsedIfValuesMethod((PsiMethod)psiWhat, expression);
}
getRefManager().fireNodeMarkedReferenced(psiWhat, psiFrom);
}
}
@@ -309,20 +306,4 @@ public sealed abstract class RefJavaElementImpl extends RefElementImpl implement
}
return super.getIcon(expanded);
}
private void markEnumUsedIfValuesMethod(PsiMethod psiWhat, UExpression expression) {
//TODO support kotlin enums
final PsiClass containingClass = psiWhat.getContainingClass();
if (containingClass != null && containingClass.isEnum() && "values".equals(psiWhat.getName())) {
for (PsiField enumConstant : containingClass.getFields()) {
if (enumConstant instanceof PsiEnumConstant) {
final RefJavaElementImpl enumConstantReference = (RefJavaElementImpl)getRefManager().getReference(enumConstant);
if (enumConstantReference != null) {
addOutReference(enumConstantReference);
enumConstantReference.markReferenced(this, false, true, expression);
}
}
}
}
}
}
@@ -272,6 +272,9 @@ public final class RefJavaUtilImpl extends RefJavaUtil {
}
}
}
else if (refResolved == null && psiResolved instanceof PsiMethod method) {
markEnumUsedIfValuesMethod(method, node);
}
if (psiResolved instanceof PsiMember psiMember) {
//TODO support kotlin
@@ -285,6 +288,27 @@ public final class RefJavaUtilImpl extends RefJavaUtil {
return true;
}
private void markEnumUsedIfValuesMethod(PsiMethod psiWhat, UExpression expression) {
//TODO support kotlin enums
final PsiClass containingClass = psiWhat.getContainingClass();
if (containingClass == null || !containingClass.isEnum()) {
return;
}
String methodName = psiWhat.getName();
if (!"values".equals(methodName) && !"valueOf".equals(methodName)) {
return;
}
for (PsiField enumConstant : containingClass.getFields()) {
if (enumConstant instanceof PsiEnumConstant) {
final RefJavaElementImpl enumConstantReference = (RefJavaElementImpl)refFrom.getRefManager().getReference(enumConstant);
if (enumConstantReference != null) {
refFrom.addOutReference(enumConstantReference);
enumConstantReference.markReferenced(refFrom, false, true, expression);
}
}
}
}
@Override
public boolean visitCallableReferenceExpression(@NotNull UCallableReferenceExpression methodRef) {
UExpression qualifierExpression = methodRef.getQualifierExpression();
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<problems>
</problems>
@@ -0,0 +1,24 @@
class Main {
public static void main(String[] args) {
System.out.println(Foo.valueOf(args[0]).getSomething());
}
public enum Foo {
ONE {
@Override
public String getSomething() {
return "ONE";
}
},
TWO {
@Override
public String getSomething() {
return "TWO";
}
};
public abstract String getSomething();
}
}
@@ -190,6 +190,10 @@ public class UnusedDeclarationInspectionTest extends AbstractUnusedDeclarationTe
public void testEnumValues() {
doTest();
}
public void testEnumValueOf() {
doTest();
}
public void testUsagesInAnonymous() {
doTest();