public static String checkReturnType( PsiMethodReferenceExpression expression, JavaResolveResult result, PsiType functionalInterfaceType) { final PsiElement resolve = result.getElement(); if (resolve instanceof PsiMethod) { final PsiClass containingClass = ((PsiMethod) resolve).getContainingClass(); LOG.assertTrue(containingClass != null); PsiSubstitutor subst = result.getSubstitutor(); PsiClass qContainingClass = getQualifierResolveResult(expression).getContainingClass(); if (qContainingClass != null && isReceiverType(functionalInterfaceType, containingClass, (PsiMethod) resolve)) { subst = TypeConversionUtil.getClassSubstitutor(containingClass, qContainingClass, subst); LOG.assertTrue(subst != null); } final PsiType interfaceReturnType = LambdaUtil.getFunctionalInterfaceReturnType(functionalInterfaceType); PsiType returnType = PsiTypesUtil.patchMethodGetClassReturnType( expression, expression, (PsiMethod) resolve, null, PsiUtil.getLanguageLevel(expression)); if (returnType == null) { returnType = ((PsiMethod) resolve).getReturnType(); } PsiType methodReturnType = subst.substitute(returnType); if (interfaceReturnType != null && interfaceReturnType != PsiType.VOID) { if (methodReturnType == null) { methodReturnType = JavaPsiFacade.getElementFactory(expression.getProject()) .createType(containingClass, subst); } if (!TypeConversionUtil.isAssignable(interfaceReturnType, methodReturnType, false)) { return "Bad return type in method reference: cannot convert " + methodReturnType.getCanonicalText() + " to " + interfaceReturnType.getCanonicalText(); } } } return null; }
@Nullable private static PsiType getResultType( PsiMethodCallExpression call, PsiReferenceExpression methodExpression, JavaResolveResult result, @NotNull final LanguageLevel languageLevel) { final PsiMethod method = (PsiMethod) result.getElement(); if (method == null) return null; boolean is15OrHigher = languageLevel.compareTo(LanguageLevel.JDK_1_5) >= 0; final PsiType getClassReturnType = PsiTypesUtil.patchMethodGetClassReturnType( call, methodExpression, method, new Condition<IElementType>() { @Override public boolean value(IElementType type) { return type != JavaElementType.CLASS; } }, languageLevel); if (getClassReturnType != null) { return getClassReturnType; } PsiType ret = method.getReturnType(); if (ret == null) return null; if (ret instanceof PsiClassType) { ret = ((PsiClassType) ret).setLanguageLevel(languageLevel); } if (is15OrHigher) { return captureReturnType(call, method, ret, result, languageLevel); } return TypeConversionUtil.erasure(ret); }