method refs: prefer unhandled exception to wrong return type error (IDEA-160251)

This commit is contained in:
Anna Kozlova
2016-08-25 17:36:03 +03:00
parent 5de45cb0af
commit 2ec75e05a1
3 changed files with 43 additions and 20 deletions
@@ -1291,8 +1291,8 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
.descriptionAndTooltip("Method reference expression is not expected here").create());
}
final PsiType functionalInterfaceType = expression.getFunctionalInterfaceType();
if (!myHolder.hasErrorResults()) {
final PsiType functionalInterfaceType = expression.getFunctionalInterfaceType();
if (functionalInterfaceType != null) {
final boolean notFunctional = !LambdaUtil.isFunctionalType(functionalInterfaceType);
if (notFunctional) {
@@ -1300,6 +1300,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
.descriptionAndTooltip(functionalInterfaceType.getPresentableText() + " is not a functional interface").create());
}
}
}
if (!myHolder.hasErrorResults()) {
final PsiElement referenceNameElement = expression.getReferenceNameElement();
if (referenceNameElement instanceof PsiKeyword) {
@@ -1312,25 +1313,14 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
}
}
}
if (!myHolder.hasErrorResults()) {
final PsiClassType.ClassResolveResult resolveResult = checkFunctionalInterfaceTypeAccessible(expression, functionalInterfaceType);
if (!myHolder.hasErrorResults()) {
checkFunctionalInterfaceTypeAccessible(expression, functionalInterfaceType);
}
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());
}
}
}
if (!myHolder.hasErrorResults() && functionalInterfaceType != null) {
final String errorMessage = PsiMethodReferenceUtil.checkMethodReferenceContext(expression);
if (errorMessage != null) {
myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(errorMessage).create());
}
}
@@ -1358,10 +1348,18 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
myHolder.add(HighlightUtil.checkUnhandledExceptions(expression, expression.getTextRange()));
}
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());
}
}
if (!myHolder.hasErrorResults()) {
if (results.length == 0 || results[0] instanceof MethodCandidateInfo &&
!((MethodCandidateInfo)results[0]).isApplicable() &&
expression.getFunctionalInterfaceType() != null) {
functionalInterfaceType != null) {
String description = null;
if (results.length == 1) {
description = ((MethodCandidateInfo)results[0]).getInferenceErrorMessage();
@@ -0,0 +1,21 @@
import java.util.List;
class Test {
@FunctionalInterface
interface SomeInterface<T, R> {
R someMethod(T val);
}
public <T, R> void consume(SomeInterface<T, R> someInterface) {
}
private List<Integer> produce(Integer val) throws Exception {
return null;
}
public void failure() {
consume(<error descr="Unhandled exception: java.lang.Exception">this::produce</error>);
}
}
@@ -521,6 +521,10 @@ public class NewMethodRefHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest();
}
public void testCheckReturnTypeOfMethodReferenceWhenTheRestIsGood() throws Exception {
doTest();
}
private void doTest() {
doTest(false);
}