From b8d03cf021d806a27dcb129b2008f3a62f9819b2 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Fri, 24 Oct 2025 15:26:15 +0200 Subject: [PATCH] [java-psi] PsiClassUtil#isThrowable: try traversing the hierarchy directly We only need to traverse superclasses, not the interfaces, and may stop at any generic parameter. While there's no additional caching (like in super-class substitutor), it's still could be faster GitOrigin-RevId: 8aec1d2f375d4c0f74e949b5b70d959a3330a432 --- .../com/intellij/psi/util/PsiClassUtil.java | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/java/java-psi-api/src/com/intellij/psi/util/PsiClassUtil.java b/java/java-psi-api/src/com/intellij/psi/util/PsiClassUtil.java index 9683201824d5..9963647b00b6 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/PsiClassUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/PsiClassUtil.java @@ -40,12 +40,19 @@ public final class PsiClassUtil { * @return true if class is {@code java.lang.Throwable} or legally inherits from it. */ public static boolean isThrowable(@NotNull PsiClass psiClass) { - if (psiClass.isInterface()) return false; - if (psiClass.getTypeParameters().length > 0) return false; // Valid throwables are never generic - if (CommonClassNames.JAVA_LANG_THROWABLE.equals(psiClass.getQualifiedName())) return true; - PsiClass throwableClass = - JavaPsiFacade.getInstance(psiClass.getProject()).findClass(CommonClassNames.JAVA_LANG_THROWABLE, psiClass.getResolveScope()); - if (throwableClass == null) return false; - return psiClass.isInheritor(throwableClass, true); + if (psiClass instanceof PsiAnonymousClass) { + psiClass = ((PsiAnonymousClass)psiClass).getBaseClassType().resolve(); + } + while (true) { + if (psiClass == null) return false; + if (psiClass.isInterface()) return false; + if (psiClass.getTypeParameters().length > 0) return false; // Valid throwables are never generic + if (CommonClassNames.JAVA_LANG_THROWABLE.equals(psiClass.getQualifiedName())) return true; + PsiClassType[] types = psiClass.getExtendsListTypes(); + if (types.length == 0) return false; + PsiClassType type = types[0]; + if (type.getParameterCount() != 0) return false; + psiClass = type.resolve(); + } } } \ No newline at end of file