PsiType (@NotNull PsiReferenceExpressionImpl expr) { PsiFile file = expr.getContainingFile(); Project project = file.getProject(); ResolveResult[] results = ResolveCache.getInstance(project).resolveWithCaching(expr, OurGenericsResolver.INSTANCE, true, false, file); JavaResolveResult result = results.length == 1 ? (JavaResolveResult)results[0] : null; PsiElement resolve = result == null ? null : result.getElement(); if (resolve == null) { ASTNode refName = expr.findChildByRole(ChildRole.REFERENCE_NAME); if (refName != null && "length".equals(refName.getText())) { ASTNode qualifier = expr.findChildByRole(ChildRole.QUALIFIER); if (qualifier != null && ElementType.EXPRESSION_BIT_SET.contains(qualifier.getElementType())) { PsiType type = SourceTreeToPsiMap.<PsiExpression>treeToPsiNotNull(qualifier).getType(); if (type instanceof PsiArrayType) { return PsiTypes.intType(); } } } return null; } if (!(resolve instanceof PsiVariable)) return null; PsiType type = ((PsiVariable)resolve).getType(); PsiType ret = type instanceof PsiEllipsisType ? ((PsiEllipsisType)type).toArrayType() : type; if (!ret.isValid()) { PsiUtil.ensureValidType(ret, "invalid type of " + resolve + " of class " + resolve.getClass() + ", valid=" + resolve.isValid()); } PsiTypeParameterListOwner owner = null; if (resolve instanceof PsiField && !((PsiField)resolve).hasModifierProperty(PsiModifier.STATIC)) { owner = ((PsiField)resolve).getContainingClass(); } LanguageLevel languageLevel = PsiUtil.getLanguageLevel(file); if (ret instanceof PsiClassType) { ret = ((PsiClassType)ret).setLanguageLevel(languageLevel); } if (languageLevel.isAtLeast(LanguageLevel.JDK_1_5)) { PsiSubstitutor substitutor = result.getSubstitutor(); if (owner == null || !PsiUtil.isRawSubstitutor(owner, substitutor)) { PsiType substitutedType = substitutor.substitute(ret); PsiUtil.ensureValidType(substitutedType); PsiType normalized = PsiImplUtil.normalizeWildcardTypeByPosition(substitutedType, expr); PsiUtil.ensureValidType(normalized); return PsiClassImplUtil.correctType(normalized, expr.getResolveScope()); } } return PsiClassImplUtil.correctType(TypeConversionUtil.erasure(ret), expr.getResolveScope()); }