mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[java-highlighting] Do not report incompatible type problems when operand is lambda parameter having unknown type
Such kind of error is induced by lambda resolution error, and in most of the cases the resolution error should be fixed first Fixes IDEA-361893 "Introduce local variable" should suggest for Function expression GitOrigin-RevId: 352d0f9040dd3e153e7d5b15ae61699b8c890194
This commit is contained in:
committed by
intellij-monorepo-bot
parent
5378001c87
commit
f592c31876
+10
-2
@@ -409,6 +409,10 @@ public final class HighlightUtil {
|
||||
PsiType rType = rExpression.getType();
|
||||
HighlightInfo.Builder errorResult = null;
|
||||
if (!TypeConversionUtil.isBinaryOperatorApplicable(opSign, lType, rType, true)) {
|
||||
if (lType instanceof PsiLambdaParameterType || rType instanceof PsiLambdaParameterType) {
|
||||
// Unresolved lambda parameter type is used: an error for parameter should be more descriptive, so let's avoid reporting type error
|
||||
return null;
|
||||
}
|
||||
String operatorText = operationSign.getText().substring(0, operationSign.getText().length() - 1);
|
||||
String message = JavaErrorBundle.message("binary.operator.not.applicable", operatorText,
|
||||
JavaHighlightUtil.formatType(lType),
|
||||
@@ -437,7 +441,8 @@ public final class HighlightUtil {
|
||||
// 15.26.2. Compound Assignment Operators
|
||||
IElementType opSign = TypeConversionUtil.convertEQtoOperation(sign);
|
||||
PsiType type = TypeConversionUtil.calcTypeForBinaryExpression(lType, rType, opSign, true);
|
||||
if (type == null || lType == null || TypeConversionUtil.areTypesConvertible(type, lType)) {
|
||||
if (type == null || lType == null || lType instanceof PsiLambdaParameterType || type instanceof PsiLambdaParameterType ||
|
||||
TypeConversionUtil.areTypesConvertible(type, lType)) {
|
||||
return null;
|
||||
}
|
||||
if (IncompleteModelUtil.isIncompleteModel(assignment) && IncompleteModelUtil.isPotentiallyConvertible(lType, rExpr)) {
|
||||
@@ -2026,6 +2031,9 @@ public final class HighlightUtil {
|
||||
for (int i = 1; i < operands.length; i++) {
|
||||
PsiExpression operand = operands[i];
|
||||
PsiType rType = operand.getType();
|
||||
if (lType instanceof PsiLambdaParameterType || rType instanceof PsiLambdaParameterType) {
|
||||
return null;
|
||||
}
|
||||
if (!TypeConversionUtil.isBinaryOperatorApplicable(operationSign, lType, rType, false) &&
|
||||
!(IncompleteModelUtil.isIncompleteModel(expression) &&
|
||||
IncompleteModelUtil.isPotentiallyConvertible(lType, rType, expression))) {
|
||||
@@ -2046,7 +2054,7 @@ public final class HighlightUtil {
|
||||
static HighlightInfo.Builder checkUnaryOperatorApplicable(@NotNull PsiJavaToken token, @Nullable PsiExpression expression) {
|
||||
if (expression != null && !TypeConversionUtil.isUnaryOperatorApplicable(token, expression)) {
|
||||
PsiType type = expression.getType();
|
||||
if (type == null) return null;
|
||||
if (type == null || type instanceof PsiLambdaParameterType) return null;
|
||||
String message = JavaErrorBundle.message("unary.operator.not.applicable", token.getText(), JavaHighlightUtil.formatType(type));
|
||||
|
||||
PsiElement parentExpr = token.getParent();
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
class IntStream {
|
||||
private void foo(IntStream s) {
|
||||
s.<error descr="Ambiguous method call: both 'IntStream.map(IntUnaryOperator)' and 'IntStream.map(ObjIntFunction<Object>)' match">map</error>(i -> <error descr="Operator '<<' cannot be applied to 'int', '<lambda parameter>'">1 << i</error>);
|
||||
s.<error descr="Ambiguous method call: both 'IntStream.map(IntUnaryOperator)' and 'IntStream.map(ObjIntFunction<Object>)' match">map</error>(i -> 1 << i);
|
||||
s.<error descr="Ambiguous method call: both 'IntStream.map(IntUnaryOperator)' and 'IntStream.map(ObjIntFunction<Object>)' match">map</error>(<warning descr="Parameter 'i' is never used">i</warning> -> 1);
|
||||
s.<error descr="Ambiguous method call: both 'IntStream.map(IntUnaryOperator)' and 'IntStream.map(ObjIntFunction<Object>)' match">map</error>(i -> i);
|
||||
}
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
class Test {
|
||||
int field;
|
||||
|
||||
void foo() {
|
||||
<error descr="Not a statement">i -> i + 1;</error>
|
||||
<error descr="Not a statement">i -> 1 + i;</error>
|
||||
<error descr="Not a statement">i -> 1 + 2 + i;</error>
|
||||
<error descr="Not a statement">i -> 1 + i + 2;</error>
|
||||
i -> <error descr="Operator '-' cannot be applied to 'int', 'java.lang.String'">1 - "xyz" - i</error>;
|
||||
|
||||
foo<error descr="Expected no arguments but found 1">(i -> ++i)</error>;
|
||||
|
||||
<error descr="Cannot resolve method 'bar' in 'Test'">bar</error>(i -> i += 2);
|
||||
<error descr="Cannot resolve method 'bar' in 'Test'">bar</error>(i -> field += i);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -14,7 +14,7 @@ class Test {
|
||||
}
|
||||
|
||||
void fooBar(IntStream1 instr){
|
||||
Supplier<Stream<Integer>> si = () -> instr.<error descr="Ambiguous method call: both 'IntStream1.map(IntFunction<Integer>)' and 'IntStream1.map(IntUnaryOperator)' match">map</error> ((i) -> (( <error descr="Operator '%' cannot be applied to '<lambda parameter>', 'int'">i % 2</error>) == 0) ? i : <error descr="Operator '-' cannot be applied to '<lambda parameter>'">-i</error>).boxed();
|
||||
Supplier<Stream<Integer>> si = () -> instr.<error descr="Ambiguous method call: both 'IntStream1.map(IntFunction<Integer>)' and 'IntStream1.map(IntUnaryOperator)' match">map</error> ((i) -> (( i % 2) == 0) ? i : -i).boxed();
|
||||
System.out.println(si);
|
||||
Supplier<Stream<Integer>> si1 = () -> instr.map <error descr="Ambiguous method call: both 'IntStream1.map(IntFunction<Integer>)' and 'IntStream1.map(IntUnaryOperator)' match">(null)</error>.boxed();
|
||||
System.out.println(si1);
|
||||
|
||||
+2
-2
@@ -14,10 +14,10 @@ abstract class Test {
|
||||
foo(x -> {
|
||||
return x += 1;
|
||||
});
|
||||
<error descr="Ambiguous method call: both 'Test.foo(A)' and 'Test.foo(B)' match">foo</error>(x -> <error descr="Incompatible types. Found: 'int', required: '<lambda parameter>'">x += 1</error>);
|
||||
<error descr="Ambiguous method call: both 'Test.foo(A)' and 'Test.foo(B)' match">foo</error>(x -> x += 1);
|
||||
foo(<warning descr="Parameter 'x' is never used">x</warning> -> 1);
|
||||
foo(x -> <error descr="Operator '!' cannot be applied to 'int'">!x</error>);
|
||||
<error descr="Ambiguous method call: both 'Test.foo(A)' and 'Test.foo(B)' match">foo</error>(x -> <error descr="Operator '++' cannot be applied to '<lambda parameter>'">++x</error>);
|
||||
<error descr="Ambiguous method call: both 'Test.foo(A)' and 'Test.foo(B)' match">foo</error>(x -> ++x);
|
||||
foo(<warning descr="Parameter 'x' is never used">x</warning> -> o instanceof String ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -49,6 +49,7 @@ class NewLambdaHighlightingTest extends LightJavaCodeInsightFixtureTestCase5 {
|
||||
@Test void testIDEA123869() { doTest(); }
|
||||
@Test void testIDEA123848() { doTest(); }
|
||||
@Test void testOnlyLambdaAtTypeParameterPlace() { doTest(); }
|
||||
@Test void testOperatorApplicabilityInUnresolvedLambdas() { doTest(); }
|
||||
@Test void testLiftedIntersectionType() { doTest(); }
|
||||
@Test void testInferenceFromReturnStatements() { doTest(); }
|
||||
@Test void testDownUpThroughLambdaReturnStatements() { doTest(); }
|
||||
|
||||
Reference in New Issue
Block a user