PsiType (PsiExpression expr) { final PsiReferenceExpression ref = (PsiReferenceExpression)expr; final PsiExpression qualifier = ref.getQualifierExpression(); if (qualifier == null) { final PsiElement resolvee = ref.resolve(); if (resolvee == null) { return null; } return resolvee instanceof PsiClass ? JavaPsiFacade.getElementFactory(resolvee.getProject()).createType((PsiClass)resolvee, PsiSubstitutor.EMPTY) : getType(resolvee); } else { final PsiType qualifierType = evaluateType(qualifier); if (!(qualifierType instanceof PsiArrayType)) { final PsiElement element = ref.resolve(); final PsiClassType.ClassResolveResult result = resolveType(qualifierType); final PsiClass aClass = result.getElement(); if (aClass != null) { final PsiSubstitutor aSubst = result.getSubstitutor(); if (element instanceof PsiField field) { PsiType aType = field.getType(); final PsiClass superClass = field.getContainingClass(); if (InheritanceUtil.isInheritorOrSelf(aClass, superClass, true)) { aType = TypeConversionUtil.getSuperClassSubstitutor(superClass, aClass, PsiSubstitutor.EMPTY).substitute(aType); } return aSubst.substitute(aType); } else if (element instanceof PsiMethod method){ PsiType aType = method.getReturnType(); final PsiClass superClass = method.getContainingClass(); if (InheritanceUtil.isInheritorOrSelf(aClass, superClass, true)) { aType = TypeConversionUtil.getSuperClassSubstitutor(superClass, aClass, PsiSubstitutor.EMPTY).substitute(aType); } else if (InheritanceUtil.isInheritorOrSelf(superClass, aClass, true)) { final PsiMethod[] methods = method.findSuperMethods(aClass); if (methods.length > 0) { aType = methods[0].getReturnType(); } /*} final Pair<PsiType, PsiType> pair = myRules.bindTypeParameters(qualifier.getType(), qualifierType, method, ref, myLabeler); if (pair != null) { final PsiClass psiClass = PsiUtil.resolveClassInType(aType); if (psiClass instanceof PsiTypeParameter) { aSubst = aSubst.put((PsiTypeParameter)psiClass, pair.getSecond()); }*/ } return aSubst.substitute(aType); } } } } return null; }