diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java
index c630d666059f..a8a4ae72797d 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java
@@ -1202,12 +1202,22 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression)
.descriptionAndTooltip(HighlightUtil.buildProblemWithAccessDescription(expression, resolveResult)).create());
}
- }
- if (functionalInterfaceType != null && LambdaUtil.getFunctionalInterfaceMethod(functionalInterfaceType) != null && !myHolder.hasErrorResults()) {
- final String errorMessage = PsiMethodReferenceUtil.checkMethodReferenceContext(expression);
- if (errorMessage != null) {
- myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(errorMessage).create());
+ final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
+ if (interfaceMethod != null) {
+ if (!myHolder.hasErrorResults()) {
+ final String errorMessage = PsiMethodReferenceUtil.checkMethodReferenceContext(expression);
+ if (errorMessage != null) {
+ myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(errorMessage).create());
+ }
+ }
+
+ if (!myHolder.hasErrorResults()) {
+ final String badReturnTypeMessage = PsiMethodReferenceUtil.checkReturnType(expression, result, functionalInterfaceType);
+ if (badReturnTypeMessage != null) {
+ myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(badReturnTypeMessage).create());
+ }
+ }
}
}
}
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java b/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java
index 5727fe05524a..df72de732a5d 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java
@@ -45,6 +45,36 @@ public class PsiMethodReferenceUtil {
return false;
}
+ public static String checkReturnType(PsiMethodReferenceExpression expression, JavaResolveResult result, PsiType functionalInterfaceType) {
+ final QualifierResolveResult qualifierResolveResult = getQualifierResolveResult(expression);
+ final PsiElement resolve = result.getElement();
+ if (resolve instanceof PsiMethod) {
+ PsiSubstitutor subst = PsiSubstitutor.EMPTY;
+ subst = subst.putAll(qualifierResolveResult.getSubstitutor());
+ subst = subst.putAll(result.getSubstitutor());
+
+ 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(((PsiMethod)resolve).getContainingClass(), subst);
+ }
+ if (!TypeConversionUtil.isAssignable(interfaceReturnType, methodReturnType, false)) {
+ return "Bad return type in method reference: cannot convert " + methodReturnType.getCanonicalText() + " to " + interfaceReturnType.getCanonicalText();
+ }
+ }
+ }
+ return null;
+ }
+
public static class QualifierResolveResult {
private final PsiClass myContainingClass;
private final PsiSubstitutor mySubstitutor;
@@ -178,7 +208,7 @@ public class PsiMethodReferenceUtil {
if (methodReturnType == null) {
methodReturnType = JavaPsiFacade.getElementFactory(methodReferenceExpression.getProject()).createType(((PsiMethod)resolve).getContainingClass(), subst);
}
- if (!TypeConversionUtil.isAssignable(interfaceReturnType, methodReturnType, false)) return false;
+ //if (!TypeConversionUtil.isAssignable(interfaceReturnType, methodReturnType, false)) return false;
}
if (areAcceptable(signature1, signature2, qualifierResolveResult.getContainingClass(), qualifierResolveResult.getSubstitutor(), ((PsiMethod)resolve).isVarArgs())) return true;
} else if (resolve instanceof PsiClass) {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/AccessModifiers.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/AccessModifiers.java
index a00d50183870..bc235b224c31 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/AccessModifiers.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/AccessModifiers.java
@@ -64,12 +64,12 @@ class MyTest1 {
}
void foo(Object[] arr) {
- I1 c1 = arr :: clone;
+ I1 c1 = arr :: clone;
I2 c2 = arr :: clone;
- I3 c3 = arr::clone;
- I4 c5 = arr::clone;
+ I3 c3 = arr::clone;
+ I4 c5 = arr::clone;
I5 c4 = this::getClass;
- I6 c6 = this::getClass;
+ I6 c6 = this::getClass;
}
}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/GetClassSpecifics.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/GetClassSpecifics.java
index 6c5a26f6a87f..868fada42363 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/GetClassSpecifics.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/GetClassSpecifics.java
@@ -10,6 +10,6 @@ class GetClassTest {
void test(int[] iarr, List ls) {
GetCl c4 = ls::getClass;
- GetClReturnTypeProblems c5 = ls::getClass;
+ GetClReturnTypeProblems c5 = ls::getClass;
}
}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/InferenceFromReturnType.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/InferenceFromReturnType.java
index d158b7478f52..69fea2d6a671 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/InferenceFromReturnType.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/InferenceFromReturnType.java
@@ -45,11 +45,11 @@ class MyTestConstructor {
}
private static void foo(I1 i) {System.out.println(i);}
- private static void foo(I2 i) {System.out.println(i);}
+ private static void foo(I2 i) {System.out.println(i);}
private static void foo(I3 i) {System.out.println(i);}
static {
- foo(Foo::new);
+ foo(Foo::new);
}
}
@@ -74,10 +74,10 @@ class MyTestMethod {
static Foo m() { return null; }
private static void foo(I1 i) {System.out.println(i);}
- private static void foo(I2 i) {System.out.println(i);}
+ private static void foo(I2 i) {System.out.println(i);}
private static void foo(I3 i) {System.out.println(i);}
static {
- foo(MyTestMethod::m);
+ foo(MyTestMethod::m);
}
}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/ReturnTypeSpecific.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/ReturnTypeSpecific.java
index a86f8040ed5f..249114c65b88 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/ReturnTypeSpecific.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/ReturnTypeSpecific.java
@@ -20,7 +20,7 @@ class MyTest {
System.out.println(i);
}
- private static void foo(I2 i) {
+ private static void foo(I2 i) {
System.out.println(i);
}
@@ -29,7 +29,7 @@ class MyTest {
}
public static void main(String[] args) {
- foo(Foo::m);
+ foo(Foo::m);
}
}