PsiSubstitutor (@NotNull PsiClass derivedClass, @NotNull GlobalSearchScope scope, @NotNull PsiClass superClass) { ScopedClassHierarchy hierarchy = getHierarchy(derivedClass, scope); Map<PsiClass, PsiClassType.ClassResolveResult> map = hierarchy.mySupersWithSubstitutors; if (map == null) { map = CollectionFactory.createCustomHashingStrategyMap(CLASS_HASHING_STRATEGY); RecursionGuard.StackStamp stamp = RecursionManager.markStack(); hierarchy.visitType(JavaPsiFacade.getElementFactory(derivedClass.getProject()).createType(derivedClass, PsiSubstitutor.EMPTY), map); if (stamp.mayCacheNow()) { hierarchy.mySupersWithSubstitutors = map; } } PsiClassType.ClassResolveResult resolveResult = map.get(superClass); if (resolveResult == null) return null; PsiClass cachedClass = Objects.requireNonNull(resolveResult.getElement()); PsiSubstitutor cachedSubstitutor = resolveResult.getSubstitutor(); return cachedClass == superClass ? cachedSubstitutor : mirrorSubstitutor(superClass, cachedClass, cachedSubstitutor); }