[java-inspections] LambdaUtil#isSafeLambdaReplacement: check whether functional interface type matches exactly

GitOrigin-RevId: 04b67615268182a09ce3a211547dc8213997eb58
This commit is contained in:
Tagir Valeev
2021-10-20 12:28:28 +07:00
committed by intellij-monorepo-bot
parent 5eb047fe70
commit 308d1fd0e6
11 changed files with 14 additions and 61 deletions

View File

@@ -917,8 +917,13 @@ public final class LambdaUtil {
if (resultCopy.getElement() != oldTarget) return false;
String copyMessage = resultCopy instanceof MethodCandidateInfo ? ((MethodCandidateInfo)resultCopy).getInferenceErrorMessage() : null;
if (!Objects.equals(origErrorMessage, copyMessage)) return false;
if (function instanceof PsiFunctionalExpression && ((PsiFunctionalExpression)function).getFunctionalInterfaceType() == null) {
return false;
if (function instanceof PsiFunctionalExpression) {
PsiType functionalType = ((PsiFunctionalExpression)function).getFunctionalInterfaceType();
if (functionalType == null) return false;
PsiType lambdaFunctionalType = lambda.getFunctionalInterfaceType();
if (lambdaFunctionalType != null && !functionalType.getCanonicalText().equals(lambdaFunctionalType.getCanonicalText())) {
return false;
}
}
if (origType instanceof PsiClassType && !((PsiClassType)origType).isRaw() &&
//when lambda has no formal parameter types, it's ignored during applicability check

View File

@@ -1,13 +0,0 @@
// "Replace lambda with method reference" "true"
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import java.util.stream.Stream;
class Test {
public <T> void some(Stream<AtomicReference<T>> stream) {
stream.map((Function<AtomicReference<T>, ? extends Class<? extends AtomicReference>>) AtomicReference<T>::getClass);
}
}

View File

@@ -1,16 +0,0 @@
// "Replace lambda with method reference" "true"
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
class Test {
public Test(String s) {}
public static void define(Supplier<?> moduleConstructor){}
public static void define(Function<?, ?> moduleConstructor){}
public static void define(BiFunction<?, ?, ?> moduleConstructor){}
{
define((Function<String, Object>) Test::new);
}
}

View File

@@ -1,23 +0,0 @@
// "Replace lambda with method reference" "true"
import java.util.function.Function;
class Box<T>
{
public Box(T value)
{
this._value = value;
}
private final T _value;
public T getValue()
{
return this._value;
}
{
foo((Function<Box<String>, String>) Box::getValue);
}
<K> void foo(Function<Box<K>, K> f){}
}

View File

@@ -1,4 +1,4 @@
// "Replace lambda with method reference" "true"
// "Replace lambda with method reference" "false"
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Stream;

View File

@@ -1,4 +1,4 @@
// "Replace lambda with method reference" "true"
// "Replace lambda with method reference" "false"
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;

View File

@@ -1,4 +1,4 @@
// "Replace lambda with method reference" "true"
// "Replace lambda with method reference" "false"
import java.util.function.Function;
class Box<T>

View File

@@ -5,7 +5,7 @@ import java.util.stream.Collectors;
class Test {
public static <T> List<TokenFilter<T>> fromString(final T src, Function<T, List<String>> extractor) {
final List<TokenFilter<T>> result = extractor.apply(src).stream().map((Function<String, TokenFilter<T>>) TokenFilter::new).collect(Collectors.toList());
final List<TokenFilter<T>> result = extractor.apply(src).stream().map(st -> new TokenFilter<T>(st)).collect(Collectors.toList());
return result;
}

View File

@@ -1,4 +1,4 @@
// "Remove redundant types" "true"
// "Remove redundant types" "false"
class Test2 {
class Y<T>{
T t;

View File

@@ -11,6 +11,6 @@ class Test2 {
static <T> I<T> bar(I<T> i){return i;}
{
Test2.bar(y<caret> -> y.t);
Test2.bar((Y<St<caret>ring> y) -> y.t.substring(1));
}
}

View File

@@ -61,7 +61,7 @@ public class RedundantLambdaParameterTypeInspectionTest extends LightJavaCodeIns
}
public void testCallNoTypeArgs() {
doTest();
assertIntentionNotAvailable();
}
public void testCallNoTypeArgs1() {