[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
This commit is contained in:
Tagir Valeev
2025-10-24 20:14:10 +00:00
committed by intellij-monorepo-bot
parent 364ff06791
commit b8d03cf021
@@ -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();
}
}
}