PsiType (@NotNull PsiParameter parameter) { PsiType type = getType(parameter); if (type instanceof PsiArrayType) { return type; } PsiClassType.ClassResolveResult result = PsiUtil.resolveGenericsClassInType(type); PsiClass psiClass = result.getElement(); if (psiClass == null) { return type; } Set<PsiTypeParameter> usedTypeParameters = new HashSet<>(); CommonJavaRefactoringUtil.collectTypeParameters(usedTypeParameters, parameter); usedTypeParameters.removeIf(usedTypeParameter -> parameter.getDeclarationScope() != usedTypeParameter.getOwner()); PsiSubstitutor subst = PsiSubstitutor.EMPTY; for (PsiTypeParameter usedTypeParameter : usedTypeParameters) { PsiType bound = TypeConversionUtil.typeParameterErasure(usedTypeParameter); PsiManager manager = usedTypeParameter.getManager(); subst = subst.put(usedTypeParameter, bound == null ? PsiWildcardType.createUnbounded(manager) : bound.equalsToText(CommonClassNames.JAVA_LANG_OBJECT) ? bound : PsiWildcardType.createExtends(manager, bound)); } PsiSubstitutor substitutor = PsiSubstitutor.EMPTY; Map<PsiTypeParameter, PsiType> typeMap = result.getSubstitutor().getSubstitutionMap(); for (PsiTypeParameter typeParameter : typeMap.keySet()) { PsiType psiType = typeMap.get(typeParameter); substitutor = substitutor.put(typeParameter, psiType != null ? subst.substitute(psiType) : null); } if (psiClass instanceof PsiTypeParameter) { return GenericsUtil.getVariableTypeByExpressionType(subst.substitute((PsiTypeParameter)psiClass)); } return JavaPsiFacade.getElementFactory(parameter.getProject()).createType(psiClass, substitutor); }