new inference: report inference errors of containing call for lambdas

This commit is contained in:
Anna Kozlova
2015-11-20 21:41:40 +01:00
parent 19a7ef3488
commit be2db1f940
9 changed files with 28 additions and 25 deletions

View File

@@ -322,21 +322,15 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
myHolder.add(result);
}
else {
if (!LambdaUtil.isLambdaFullyInferred(expression, functionalInterfaceType) && !expression.hasFormalParameterTypes()) {
final PsiCallExpression callExpression = PsiTreeUtil.getParentOfType(expression, PsiCallExpression.class);
String description;
if (callExpression != null) {
final JavaResolveResult result = callExpression.resolveMethodGenerics();
description = result instanceof MethodCandidateInfo ? ((MethodCandidateInfo)result).getInferenceErrorMessage() : null;
}
else {
description = null;
}
if (description == null) {
description = "Cyclic inference";
}
HighlightInfo result =
HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(description).create();
final PsiElement parent = PsiUtil.skipParenthesizedExprUp(expression.getParent());
final PsiCallExpression callExpression = parent instanceof PsiExpressionList && parent.getParent() instanceof PsiCallExpression ?
(PsiCallExpression)parent.getParent() : null;
final JavaResolveResult containingCallResolveResult = callExpression != null ? callExpression.resolveMethodGenerics() : null;
final String errorMessage = containingCallResolveResult instanceof MethodCandidateInfo ?
((MethodCandidateInfo)containingCallResolveResult).getInferenceErrorMessage() : null;
if (errorMessage != null) {
HighlightInfo result = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
.range(expression).descriptionAndTooltip(errorMessage).create();
myHolder.add(result);
}
else {

View File

@@ -341,7 +341,7 @@ public class InferenceSession {
}
if (!additionalConstraints.isEmpty() && !proceedWithAdditionalConstraints(additionalConstraints)) {
return prepareSubstitution().putAll(retrieveNonPrimitiveEqualsBounds(myInferenceVariables));
return prepareSubstitution();
}
}
}

View File

@@ -122,7 +122,10 @@ public class CheckedExceptionCompatibilityConstraint extends InputOutputConstrai
if (expectedNonProperThrownTypes.isEmpty()) {
for (PsiType thrownType : thrownTypes) {
if (!isAddressed(expectedThrownTypes, thrownType)) return false;
if (!isAddressed(expectedThrownTypes, thrownType)) {
session.registerIncompatibleErrorMessage("Unhandled exception: " + thrownType.getPresentableText());
return false;
}
}
} else {
final ArrayList<PsiType> expectedProperTypes = new ArrayList<PsiType>(expectedThrownTypes);

View File

@@ -21,7 +21,7 @@ class NoInferenceResult {
m((String s1) -> s1.length());
m((String s1) -> s1);
m1<error descr="'m1(T)' in 'NoInferenceResult' cannot be applied to '(<lambda expression>)'">(() -> { })</error>;
m1(<error descr="Object is not a functional interface">() -> { }</error>);
Foo<String> foo = new Foo<String>();
foo.map(v -> null);

View File

@@ -12,7 +12,9 @@ class TypeArgsConsistency {
I<Integer> i1 = (i, j) -> i + j;
foo((i, j) -> i + j);
I<Integer> i2 = bar((i, j) -> i + j);
I<Integer> i3 = bar((i, j) -> <error descr="Bad return type in lambda expression: String cannot be converted to Integer">"" + i + j</error>);
I<Integer> i3 = bar(<error descr="inference variable X has incompatible bounds:
equality constraints: Integer
lower bounds: String">(i, j) -> "" + i + j</error>);
}
}
@@ -30,7 +32,7 @@ class TypeArgsConsistency1 {
I<Integer> i1 = (i, j) -> i + j;
foo((i, j) -> i + j);
I<Integer> i2 =bar((i, j) -> i) ;
I<Integer> i3 = bar((i, j) -> <error descr="Bad return type in lambda expression: String cannot be converted to int">"" + i + j</error>);
I<Integer> i3 = bar(<error descr="Bad return type in lambda expression: String cannot be converted to int">(i, j) -> "" + i + j</error>);
}
}
@@ -43,7 +45,9 @@ class TypeArgsConsistency2 {
I<Integer> i1 = bar(x -> x);
I1<Integer> i2 = bar1(x -> 1);
I2<String> aI2 = bar2(x -> "");
I2<Integer> aI28 = bar2( x-> <error descr="Bad return type in lambda expression: String cannot be converted to Integer">""</error>);
I2<Integer> aI28 = bar2( <error descr="inference variable T has incompatible bounds:
equality constraints: Integer
lower bounds: String">x-> ""</error>);
I2<Integer> i3 = bar2(x -> x);
I2<Integer> i4 = bar2(x -> foooI());
System.out.println(i4.foo(2));

View File

@@ -14,7 +14,7 @@ class NoLambda {
static <T> T id(T i2) {return i2;}
{
id<error descr="'id(T)' in 'NoLambda' cannot be applied to '(<lambda expression>)'">(() -> {System.out.println("hi");})</error>;
id(<error descr="Object is not a functional interface">() -> {System.out.println("hi");}</error>);
NoLambda.<Runnable>id(() -> {System.out.println("hi");});
}
}

View File

@@ -5,7 +5,7 @@ import java.util.function.Consumer;
class Test {
public static void main(String[] args) {
Iterable<Consumer<Reader>> i = Arrays.asList((r) -> <error descr="Unhandled exception: java.io.IOException">r.read()</error>);
Iterable<Consumer<Reader>> i = Arrays.asList(<error descr="Unhandled exception: IOException">(r) -> r.read()</error>);
Iterable<Consumer<Reader>> i1 = Arrays.<Consumer<Reader>>asList((r) -> <error descr="Unhandled exception: java.io.IOException">r.read()</error>);
}
}

View File

@@ -9,7 +9,9 @@ class Test {
<R> SuperFoo<R> foo(I<R> ax) { return null; }
SuperFoo<String> ls = foo(() -> <error descr="Bad return type in lambda expression: Foo<X> cannot be converted to SuperFoo<R>">new Foo<>()</error>);
SuperFoo<String> ls = foo(<error descr="inference variable R has incompatible bounds:
equality constraints: String
upper bounds: Object, Number">() -> new Foo<>()</error>);
SuperFoo<Integer> li = foo(() -> new Foo<>());
SuperFoo<?> lw = foo(() -> new Foo<>());
}

View File

@@ -7,7 +7,7 @@ class Test {
<T extends Runnable> void call1(T t) {}
{
call<error descr="'call(T)' in 'Test' cannot be applied to '(<lambda expression>)'">(() -> {})</error>;
call(<error descr="Object is not a functional interface">() -> {}</error>);
call1(() -> {});
}
}