PsiType (PsiType resultType, String superClassName, Map<String, Function<? super PsiType, ? extends PsiType>> downstreamCorrectors) { PsiClass resultClass = PsiUtil.resolveClassInClassTypeOnly(resultType); if(resultClass == null) return resultType; PsiSubstitutor origSubstitutor = ((PsiClassType)resultType).resolveGenerics().getSubstitutor(); PsiSubstitutor substitutor = origSubstitutor; Project project = resultClass.getProject(); PsiClass superClass = JavaPsiFacade.getInstance(project).findClass(superClassName, resultClass.getResolveScope()); if(superClass == null) return resultType; PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getMaybeSuperClassSubstitutor(superClass, resultClass, PsiSubstitutor.EMPTY); if(superClassSubstitutor == null) { // inconsistent class hierarchy: probably something is not resolved return resultType; } for (PsiTypeParameter baseParameter : superClass.getTypeParameters()) { PsiClass substitution = PsiUtil.resolveClassInClassTypeOnly(superClassSubstitutor.substitute(baseParameter)); if(substitution instanceof PsiTypeParameter subClassParameter) { PsiType origType = origSubstitutor.substitute(subClassParameter); PsiType replacedType = GenericsUtil.eliminateWildcards(origType, false, true); replacedType = downstreamCorrectors.getOrDefault(subClassParameter.getName(), Function.identity()).apply(replacedType); if(replacedType != origType) { substitutor = substitutor.put(subClassParameter, replacedType); } } } return substitutor == origSubstitutor ? resultType : JavaPsiFacade.getElementFactory(project).createType(resultClass, substitutor); }