mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
fix cast introduction in LambdaCanBeMethodReferenceInspection#replaceLambdaWithMethodReference
This commit is contained in:
+1
-1
@@ -232,7 +232,7 @@ public class ComparatorCombinatorsInspection extends BaseJavaBatchLocalInspectio
|
||||
PsiParameter[] parameters = lambda.getParameterList().getParameters();
|
||||
PsiElement body = lambda.getBody();
|
||||
if (body == null) return;
|
||||
if (LambdaCanBeMethodReferenceInspection.replaceLambdaWithMethodReference(factory, lambda) == lambda) {
|
||||
if (LambdaCanBeMethodReferenceInspection.replaceLambdaWithMethodReference(lambda) == lambda) {
|
||||
PsiParameter parameter = parameters[0];
|
||||
String name = parameter.getName();
|
||||
SuggestedNameInfo nameCandidate = null;
|
||||
|
||||
+47
-44
@@ -308,27 +308,18 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
|
||||
public static void replaceAllLambdasWithMethodReferences(PsiElement root) {
|
||||
Collection<PsiLambdaExpression> lambdas = PsiTreeUtil.findChildrenOfType(root, PsiLambdaExpression.class);
|
||||
if(!lambdas.isEmpty()) {
|
||||
PsiElementFactory factory = JavaPsiFacade.getElementFactory(root.getProject());
|
||||
for(PsiLambdaExpression lambda : lambdas) {
|
||||
replaceLambdaWithMethodReference(factory, lambda);
|
||||
replaceLambdaWithMethodReference(lambda);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static PsiExpression replaceLambdaWithMethodReference(PsiElementFactory factory, PsiLambdaExpression lambda) {
|
||||
PsiType type = lambda.getFunctionalInterfaceType();
|
||||
if(type == null) return lambda;
|
||||
String methodReference =
|
||||
convertToMethodReference(lambda.getBody(), lambda.getParameterList().getParameters(), type, lambda);
|
||||
if(methodReference == null) return lambda;
|
||||
PsiTypeCastExpression replacement = (PsiTypeCastExpression)lambda.replace(
|
||||
factory.createExpressionFromText("(" + lambda.getFunctionalInterfaceType().getCanonicalText() + ")" + methodReference, lambda));
|
||||
if (RedundantCastUtil.isCastRedundant(replacement)) {
|
||||
final PsiExpression operand = replacement.getOperand();
|
||||
LOG.assertTrue(operand != null);
|
||||
return (PsiExpression)replacement.replace(operand);
|
||||
}
|
||||
return replacement;
|
||||
@NotNull
|
||||
public static PsiExpression replaceLambdaWithMethodReference(@NotNull PsiLambdaExpression lambda) {
|
||||
PsiElement body = LambdaUtil.extractSingleExpressionFromBody(lambda.getBody());
|
||||
final PsiExpression candidate = new LambdaCanBeMethodReferenceInspection()
|
||||
.canBeMethodReferenceProblem(body, lambda.getParameterList().getParameters(), lambda.getFunctionalInterfaceType(), lambda);
|
||||
return tryConvertToMethodReference(lambda, candidate);
|
||||
}
|
||||
|
||||
private static boolean checkQualifier(PsiElement qualifier) {
|
||||
@@ -599,34 +590,46 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
|
||||
if (!FileModificationService.getInstance().preparePsiElementForWrite(element)) return;
|
||||
final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(element, PsiLambdaExpression.class);
|
||||
if (lambdaExpression == null) return;
|
||||
PsiType functionalInterfaceType = lambdaExpression.getFunctionalInterfaceType();
|
||||
if (functionalInterfaceType == null || !functionalInterfaceType.isValid()) return;
|
||||
final PsiType denotableFunctionalInterfaceType = RefactoringChangeUtil.getTypeByExpression(lambdaExpression);
|
||||
if (denotableFunctionalInterfaceType == null) return;
|
||||
|
||||
Collection<PsiComment> comments = ContainerUtil.map(PsiTreeUtil.findChildrenOfType(lambdaExpression, PsiComment.class),
|
||||
(comment) -> (PsiComment)comment.copy());
|
||||
|
||||
final String methodRefText = createMethodReferenceText(element, functionalInterfaceType,
|
||||
lambdaExpression.getParameterList().getParameters());
|
||||
|
||||
if (methodRefText != null) {
|
||||
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
|
||||
final PsiExpression psiExpression = factory.createExpressionFromText(methodRefText, lambdaExpression);
|
||||
final SmartTypePointer typePointer = SmartTypePointerManager.getInstance(project).createSmartTypePointer(denotableFunctionalInterfaceType);
|
||||
PsiElement replace = lambdaExpression.replace(psiExpression);
|
||||
final PsiType functionalTypeAfterReplacement = GenericsUtil.getVariableTypeByExpressionType(((PsiMethodReferenceExpression)replace).getFunctionalInterfaceType());
|
||||
functionalInterfaceType = typePointer.getType();
|
||||
if (functionalTypeAfterReplacement == null || functionalInterfaceType != null && !functionalTypeAfterReplacement.equals(functionalInterfaceType)) { //ambiguity
|
||||
final PsiTypeCastExpression cast = (PsiTypeCastExpression)factory.createExpressionFromText("(A)a", replace);
|
||||
cast.getCastType().replace(factory.createTypeElement(functionalInterfaceType));
|
||||
cast.getOperand().replace(replace);
|
||||
replace = replace.replace(cast);
|
||||
}
|
||||
|
||||
AnonymousCanBeLambdaInspection.restoreComments(comments, replace);
|
||||
JavaCodeStyleManager.getInstance(project).shortenClassReferences(replace);
|
||||
}
|
||||
tryConvertToMethodReference(lambdaExpression, element);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static PsiExpression tryConvertToMethodReference(@NotNull PsiLambdaExpression lambda, PsiElement body) {
|
||||
Project project = lambda.getProject();
|
||||
PsiType functionalInterfaceType = lambda.getFunctionalInterfaceType();
|
||||
if (functionalInterfaceType == null || !functionalInterfaceType.isValid()) return lambda;
|
||||
final PsiType denotableFunctionalInterfaceType = RefactoringChangeUtil.getTypeByExpression(lambda);
|
||||
if (denotableFunctionalInterfaceType == null) return lambda;
|
||||
|
||||
Collection<PsiComment> comments = ContainerUtil.map(PsiTreeUtil.findChildrenOfType(lambda, PsiComment.class),
|
||||
(comment) -> (PsiComment)comment.copy());
|
||||
|
||||
final String methodRefText = createMethodReferenceText(body, functionalInterfaceType, lambda.getParameterList().getParameters());
|
||||
|
||||
if (methodRefText != null) {
|
||||
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
|
||||
final PsiExpression psiExpression = factory.createExpressionFromText(methodRefText, lambda);
|
||||
final SmartTypePointer typePointer = SmartTypePointerManager.getInstance(project).createSmartTypePointer(denotableFunctionalInterfaceType);
|
||||
PsiExpression replace = (PsiExpression)lambda.replace(psiExpression);
|
||||
final PsiType functionalTypeAfterReplacement = GenericsUtil.getVariableTypeByExpressionType(((PsiMethodReferenceExpression)replace).getFunctionalInterfaceType());
|
||||
functionalInterfaceType = typePointer.getType();
|
||||
if (functionalInterfaceType != null && (functionalTypeAfterReplacement == null ||
|
||||
!functionalTypeAfterReplacement.equals(functionalInterfaceType))) { //ambiguity
|
||||
final PsiTypeCastExpression cast = (PsiTypeCastExpression)factory.createExpressionFromText("(A)a", replace);
|
||||
PsiTypeElement castType = cast.getCastType();
|
||||
LOG.assertTrue(castType != null);
|
||||
castType.replace(factory.createTypeElement(functionalInterfaceType));
|
||||
PsiExpression castOperand = cast.getOperand();
|
||||
LOG.assertTrue(castOperand != null);
|
||||
castOperand.replace(replace);
|
||||
replace = (PsiExpression)replace.replace(cast);
|
||||
}
|
||||
|
||||
AnonymousCanBeLambdaInspection.restoreComments(comments, replace);
|
||||
JavaCodeStyleManager.getInstance(project).shortenClassReferences(replace);
|
||||
return replace;
|
||||
}
|
||||
return lambda;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -285,8 +285,7 @@ public class IntroduceParameterDialog extends RefactoringDialog {
|
||||
if (myCbCollapseToLambda.isVisible() && myCbCollapseToLambda.isSelected() && parameterInitializer != null) {
|
||||
PsiExpression lambda = AnonymousCanBeLambdaInspection.replaceAnonymousWithLambda(parameterInitializer, selectedType);
|
||||
if (lambda != null) {
|
||||
lambda = LambdaCanBeMethodReferenceInspection.replaceLambdaWithMethodReference(JavaPsiFacade.getElementFactory(getProject()),
|
||||
(PsiLambdaExpression)lambda);
|
||||
lambda = LambdaCanBeMethodReferenceInspection.replaceLambdaWithMethodReference((PsiLambdaExpression)lambda);
|
||||
processor.setParameterInitializer(lambda);
|
||||
}
|
||||
}
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// "Replace with anyMatch()" "true"
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class Main {
|
||||
public List<? extends CharSequence> getList() {return Arrays.asList("a");}
|
||||
public boolean test() {
|
||||
return getList().stream().map(CharSequence::toString).anyMatch(s -> !s.isEmpty());
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -3,12 +3,11 @@
|
||||
import java.awt.*;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class Main {
|
||||
private Point field = new Point(0, 0);
|
||||
|
||||
public Point find(List<Point> points) {
|
||||
return points.stream().filter((Predicate<Point>) Objects::nonNull).findFirst().orElse(field);
|
||||
return points.stream().filter(Objects::nonNull).findFirst().orElse(field);
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -3,12 +3,11 @@
|
||||
import java.awt.*;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class Main {
|
||||
private static Point ZERO = new Point(0, 0);
|
||||
|
||||
public static Point find(List<Point> points) {
|
||||
return points.stream().filter((Predicate<Point>) Objects::nonNull).findFirst().orElse(ZERO);
|
||||
return points.stream().filter(Objects::nonNull).findFirst().orElse(ZERO);
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// "Replace with anyMatch()" "true"
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class Main {
|
||||
public List<? extends CharSequence> getList() {return Arrays.asList("a");}
|
||||
public boolean test() {
|
||||
for(CharSequence cs : ge<caret>tList()) {
|
||||
String s = cs.toString();
|
||||
if(!s.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user