mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 21:11:28 +07:00
[java-inspections] LambdaCanBeMethodReference: disable conversion in many cases when cast is required
Fixes IDEA-267865 Add a option for Java's method reference inspection that ignore lambda which can't convert into method reference without a cast GitOrigin-RevId: b6f762383d6ba1ef19a5de36e0ad53d107ba4e80
This commit is contained in:
committed by
intellij-monorepo-bot
parent
9f3d7463a1
commit
bcb843dd8f
@@ -1,21 +0,0 @@
|
||||
// "Replace lambda with method reference" "true"
|
||||
import java.util.*;
|
||||
class IDEA100385 {
|
||||
void foo(N<Double> n, List<Double> l){
|
||||
n.forEach((DoubleConsumer) l::add);
|
||||
}
|
||||
static interface N<E> {
|
||||
default void forEach(DoubleConsumer consumer) {
|
||||
}
|
||||
void forEach(Consumer<? super E> consumer);
|
||||
}
|
||||
|
||||
interface DoubleConsumer {
|
||||
void _(double d);
|
||||
}
|
||||
|
||||
interface Consumer<T> {
|
||||
public void accept(T t);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
// "Replace lambda with method reference" "true"
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
class Test {
|
||||
|
||||
private Preferences preferences;
|
||||
|
||||
{
|
||||
foo(short.class, (Writer<Short>) Preferences::putInt);
|
||||
}
|
||||
|
||||
private <T> void foo(Class<T> type, Writer<T> writer) {}
|
||||
|
||||
interface Writer<T> {
|
||||
void write(Preferences preferences, String key, T value);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Replace lambda with method reference" "true"
|
||||
// "Replace lambda with method reference" "false"
|
||||
import java.util.*;
|
||||
class IDEA100385 {
|
||||
void foo(N<Double> n, List<Double> l){
|
||||
@@ -0,0 +1,19 @@
|
||||
// "Replace lambda with method reference" "false"
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
class Foo {}
|
||||
class Bar {}
|
||||
class Something {
|
||||
static void stuff(Function<Foo, Bar> foo2bar) {}
|
||||
static void stuff(Supplier<Bar> sup4Bar) {}
|
||||
}
|
||||
class Something2 {
|
||||
static Bar bar(Foo foo) { return null; }
|
||||
static Bar bar() { return null; }
|
||||
}
|
||||
class Main {
|
||||
public static void main(String[] args) {
|
||||
Something.stuff(foo -> <caret>Something2.bar(foo));
|
||||
Something.stuff(() -> Something2.bar());
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Replace lambda with method reference" "true"
|
||||
// "Replace lambda with method reference" "false"
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
class Test {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// "Replace with forEach" "true"
|
||||
|
||||
import java.util.function.UnaryOperator;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class Main {
|
||||
@@ -12,6 +11,6 @@ public class Main {
|
||||
static boolean isGood(A a) {}
|
||||
|
||||
public long test() {
|
||||
Stream.iterate(new A(), (UnaryOperator<A>) Main::isGood, a -> a.next()).filter(a -> a.x < 3).forEach(System.out::println);
|
||||
Stream.iterate(new A(), a -> isGood(a), a -> a.next()).filter(a -> a.x < 3).forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
@@ -64,13 +64,9 @@ public class LambdaCanBeMethodReferenceInspection extends AbstractBaseJavaLocalI
|
||||
public void visitLambdaExpression(PsiLambdaExpression expression) {
|
||||
super.visitLambdaExpression(expression);
|
||||
final PsiElement body = expression.getBody();
|
||||
final PsiType functionalInterfaceType = expression.getFunctionalInterfaceType();
|
||||
if (functionalInterfaceType == null) return;
|
||||
MethodReferenceCandidate methodRefCandidate = extractMethodReferenceCandidateExpression(body);
|
||||
if (methodRefCandidate == null) return;
|
||||
final PsiExpression candidate =
|
||||
canBeMethodReferenceProblem(expression.getParameterList().getParameters(), functionalInterfaceType, null,
|
||||
methodRefCandidate.myExpression);
|
||||
final PsiExpression candidate = getLambdaToMethodReferenceConversionCandidate(expression, methodRefCandidate.myExpression);
|
||||
if (candidate == null) return;
|
||||
ProblemHighlightType type;
|
||||
if (methodRefCandidate.mySafeQualifier && methodRefCandidate.myConformsCodeStyle) {
|
||||
@@ -93,6 +89,24 @@ public class LambdaCanBeMethodReferenceInspection extends AbstractBaseJavaLocalI
|
||||
};
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiExpression getLambdaToMethodReferenceConversionCandidate(@NotNull PsiLambdaExpression expression,
|
||||
@NotNull PsiExpression methodRefCandidate) {
|
||||
PsiParameter[] parameters = expression.getParameterList().getParameters();
|
||||
PsiType functionalInterfaceType = expression.getFunctionalInterfaceType();
|
||||
if (functionalInterfaceType == null) return null;
|
||||
final PsiExpression candidate = canBeMethodReferenceProblem(parameters, functionalInterfaceType, null, methodRefCandidate);
|
||||
if (candidate == null) return null;
|
||||
boolean safeLambdaReplacement = LambdaUtil.isSafeLambdaReplacement(expression, () -> {
|
||||
String text = createMethodReferenceText(methodRefCandidate, functionalInterfaceType, parameters);
|
||||
// We already did the same operation inside canBeMethodReferenceProblem
|
||||
LOG.assertTrue(text != null);
|
||||
return JavaPsiFacade.getElementFactory(expression.getProject()).createExpressionFromText(text, expression);
|
||||
});
|
||||
if (!safeLambdaReplacement) return null;
|
||||
return candidate;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiExpression canBeMethodReferenceProblem(@Nullable final PsiElement body,
|
||||
final PsiVariable[] parameters,
|
||||
@@ -305,9 +319,7 @@ public class LambdaCanBeMethodReferenceInspection extends AbstractBaseJavaLocalI
|
||||
public static PsiExpression replaceLambdaWithMethodReference(@NotNull PsiLambdaExpression lambda) {
|
||||
MethodReferenceCandidate methodRefCandidate = extractMethodReferenceCandidateExpression(lambda.getBody());
|
||||
if (methodRefCandidate == null || !methodRefCandidate.mySafeQualifier || !methodRefCandidate.myConformsCodeStyle) return lambda;
|
||||
PsiExpression candidate =
|
||||
canBeMethodReferenceProblem(lambda.getParameterList().getParameters(), lambda.getFunctionalInterfaceType(), lambda,
|
||||
methodRefCandidate.myExpression);
|
||||
PsiExpression candidate = getLambdaToMethodReferenceConversionCandidate(lambda, methodRefCandidate.myExpression);
|
||||
return tryConvertToMethodReference(lambda, candidate);
|
||||
}
|
||||
|
||||
@@ -614,7 +626,7 @@ public class LambdaCanBeMethodReferenceInspection extends AbstractBaseJavaLocalI
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static PsiExpression tryConvertToMethodReference(@NotNull PsiLambdaExpression lambda, PsiElement body) {
|
||||
private static PsiExpression tryConvertToMethodReference(@NotNull PsiLambdaExpression lambda, PsiElement body) {
|
||||
Project project = lambda.getProject();
|
||||
PsiType functionalInterfaceType = lambda.getFunctionalInterfaceType();
|
||||
if (functionalInterfaceType == null || !functionalInterfaceType.isValid()) return lambda;
|
||||
|
||||
Reference in New Issue
Block a user