InferenceSession (InferenceSession session, PsiExpression expression, PsiType targetType, boolean registerErrorOnFailure) { if (!PsiPolyExpressionUtil.isPolyExpression(expression)) { return session; } final PsiExpressionList argumentList = ((PsiCall)expression).getArgumentList(); if (argumentList != null) { final MethodCandidateInfo currentMethod = session.getCurrentMethod(argumentList); PsiType returnType = null; PsiTypeParameter[] typeParams = null; final JavaResolveResult resolveResult = currentMethod != null ? null : PsiDiamondType.getDiamondsAwareResolveResult((PsiCall)expression); PsiMethod method = currentMethod != null ? currentMethod.getElement() : resolveResult instanceof MethodCandidateInfo ? ((MethodCandidateInfo)resolveResult).getElement() : null; if (method != null && !method.isConstructor()) { returnType = method.getReturnType(); typeParams = method.getTypeParameters(); } else if (resolveResult != null) { final PsiClass psiClass = method != null ? method.getContainingClass() : (PsiClass)resolveResult.getElement(); if (psiClass != null) { returnType = JavaPsiFacade.getElementFactory(argumentList.getProject()).createType(psiClass, PsiSubstitutor.EMPTY); typeParams = psiClass.getTypeParameters(); if (method != null && method.hasTypeParameters()) { typeParams = ArrayUtil.mergeArrays(typeParams, method.getTypeParameters()); } } } else { return session; } if (typeParams != null) { PsiSubstitutor siteSubstitutor = InferenceSession.chooseSiteSubstitutor(currentMethod, resolveResult, method); InferenceSession callSession = new InferenceSession(typeParams, siteSubstitutor, expression.getManager(), expression, session.getInferencePolicy()); callSession.propagateVariables(session); if (method != null) { final PsiExpression[] args = argumentList.getExpressions(); final PsiParameter[] parameters = method.getParameterList().getParameters(); callSession.initExpressionConstraints(parameters, args, method, InferenceSession.chooseVarargsMode(currentMethod, resolveResult)); } if (callSession.repeatInferencePhases()) { if (PsiTypes.voidType().equals(targetType)) { return callSession; } if (returnType != null) { callSession.registerReturnTypeConstraints(siteSubstitutor.substitute(returnType), targetType, expression); } if (callSession.repeatInferencePhases()) { if (callSession.isErased() && !JavaGenericsUtil.isReifiableType(targetType) && session.getInferenceVariable(targetType) == null) { session.setErased(); } return callSession; } } //copy incompatible message if any final List<@Nls String> messages = callSession.getIncompatibleErrorMessages(); if (messages != null) { for (@Nls String message : messages) { session.registerIncompatibleErrorMessage(message); } } return null; } else if (registerErrorOnFailure) { //keep a sign that an inference failed session.registerIncompatibleErrorMessage(JavaPsiBundle.message("error.incompatible.type.failed.to.resolve.argument")); return null; } } return session; }