PsiType (PsiMethodCallExpression call, PsiMethod method, PsiType ret, JavaResolveResult result, LanguageLevel languageLevel, PsiFile file) { PsiSubstitutor substitutor = result.getSubstitutor(); substitutor.ensureValid(); PsiType substitutedReturnType = substitutor.substitute(ret); if (substitutedReturnType == null) { return TypeConversionUtil.erasure(ret); } if (result instanceof MethodCandidateInfo && ((MethodCandidateInfo)result).isErased()) { // 18.5.2 // if unchecked conversion was necessary, then this substitution provides the parameter types of the invocation type, // while the return type and thrown types are given by the erasure of m's type (without applying theta'). //due to https://bugs.openjdk.org/browse/JDK-8135087 erasure is called on substitutedReturnType and not on ret type itself as by spec return TypeConversionUtil.erasure(substitutedReturnType); } //15.12.2.6. Method Invocation Type // If unchecked conversion was necessary for the method to be applicable, // the parameter types of the invocation type are the parameter types of the method's type, // and the return type and thrown types are given by the erasures of the return type and thrown types of the method's type. if ((!languageLevel.isAtLeast(LanguageLevel.JDK_1_8) || call.getTypeArguments().length > 0) && method.hasTypeParameters() || !method.hasTypeParameters() && JavaVersionService.getInstance().isAtLeast(file, JavaSdkVersion.JDK_1_8)) { PsiType erased = TypeConversionUtil.erasure(substitutedReturnType); if (!substitutedReturnType.equals(erased) && result instanceof MethodCandidateInfo && ((MethodCandidateInfo)result).isApplicable()) { final PsiType[] args = call.getArgumentList().getExpressionTypes(); final PsiParameter[] parameters = method.getParameterList().getParameters(); final boolean varargs = ((MethodCandidateInfo)result).getApplicabilityLevel() == MethodCandidateInfo.ApplicabilityLevel.VARARGS; for (int i = 0; i < args.length; i++) { final PsiType parameterType = substitutor.substitute(PsiTypesUtil.getParameterType(parameters, i, varargs)); final PsiType expressionType = args[i]; if (expressionType != null && parameterType != null && JavaGenericsUtil.isRawToGeneric(parameterType, expressionType)) { return erased; } } } } if (PsiUtil.isRawSubstitutor(method, substitutor)) { final PsiType returnTypeErasure = TypeConversionUtil.erasure(ret); if (Comparing.equal(TypeConversionUtil.erasure(substitutedReturnType), returnTypeErasure)) { return returnTypeErasure; } } return PsiUtil.captureToplevelWildcards(substitutedReturnType, call); }