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

GitOrigin-RevId: 6a494c11f8e658f6bebef2f97623a0ab4801a672
This commit is contained in:
Bas Leijdekkers
2024-05-25 14:17:41 +02:00
committed by intellij-monorepo-bot
parent 9cc711b7f6
commit 2b4e8631ef
5 changed files with 40 additions and 8 deletions

View File

@@ -123,7 +123,7 @@ public final class UnusedSymbolUtil {
if (helper.isLocallyUsed(field)) {
return true;
}
if (field instanceof PsiEnumConstant && isEnumValuesMethodUsed(project, containingFile, field, helper)) {
if (field instanceof PsiEnumConstant enumConstant && isEnumMethodUsed(project, containingFile, enumConstant, helper)) {
return true;
}
return !weAreSureThereAreNoUsages(project, containingFile, field, helper);
@@ -315,14 +315,16 @@ public final class UnusedSymbolUtil {
return ContainerUtil.process(toSearch, m -> JavaFindUsagesHelper.processElementUsages(m, options, usageInfoProcessor));
}
private static boolean isEnumValuesMethodUsed(@NotNull Project project,
@NotNull PsiFile containingFile,
@NotNull PsiMember member,
@NotNull GlobalUsageHelper helper) {
final PsiClass containingClass = member.getContainingClass();
private static boolean isEnumMethodUsed(@NotNull Project project,
@NotNull PsiFile containingFile,
@NotNull PsiEnumConstant enumConstant,
@NotNull GlobalUsageHelper helper) {
final PsiClass containingClass = enumConstant.getContainingClass();
if (!(containingClass instanceof PsiClassImpl)) return true;
final PsiMethod valuesMethod = ((PsiClassImpl)containingClass).getValuesMethod();
return valuesMethod == null || isMethodUsed(project, containingFile, valuesMethod, helper);
final PsiMethod valueOfMethod = ((PsiClassImpl)containingClass).getValueOfMethod();
return valuesMethod == null || isMethodUsed(project, containingFile, valuesMethod, helper) ||
valueOfMethod == null || isMethodUsed(project, containingFile, valueOfMethod, helper);
}
private static boolean canBeReferencedViaWeirdNames(@NotNull PsiMember member, @NotNull PsiFile containingFile) {

View File

@@ -97,7 +97,8 @@ public final class ClassInnerStuffCache {
return PsiKeyword.SEALED.equals(myClass.getName()) && PsiUtil.isAvailable(JavaFeature.SEALED_CLASSES, myClass);
}
private @Nullable PsiMethod getValueOfMethod() {
@Nullable
PsiMethod getValueOfMethod() {
return myClass.isEnum() && !isAnonymousClass()
? internMember(CachedValuesManager.getProjectPsiDependentCache(myClass, ClassInnerStuffCache::makeValueOfMethod))
: null;

View File

@@ -568,4 +568,8 @@ public class PsiClassImpl extends JavaStubPsiElement<PsiClassStub<?>> implements
public @Nullable PsiMethod getValuesMethod() {
return myInnersCache.getValuesMethod();
}
public @Nullable PsiMethod getValueOfMethod() {
return myInnersCache.getValueOfMethod();
}
}

View File

@@ -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();
}
}

View File

@@ -29,6 +29,7 @@ public class UnusedSymbolLocalTest extends DaemonAnalyzerTestCase {
public void testLocalClass() throws Exception { doTest(); }
public void testRepeatableAnnotation() throws Exception { doTest(); }
public void testPrivateConstructor() throws Exception { doTest(); }
public void testEnumValueOf() throws Exception { doTest(); }
public void testImplicitClassInstanceMainWithoutParams() {
IdeaTestUtil.withLevel(myModule, LanguageLevel.JDK_21_PREVIEW, () -> {
try {