From 19af166e5d20946791589b3b3a31042a34250640 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Wed, 19 Oct 2016 16:24:11 +0700 Subject: [PATCH] IDEA-CR-14593: MethodRefCanBeReplacedWithLambdaInspection#isWithSideEffects -> LambdaRefactoringUtil#canConvertToLambda; mapToFlatMap extracted --- .../intention/impl/InlineStreamMapAction.java | 26 +++++++++++++++---- .../util/LambdaRefactoringUtil.java | 14 +++++++++- ...dRefCanBeReplacedWithLambdaInspection.java | 21 +++------------ 3 files changed, 38 insertions(+), 23 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/InlineStreamMapAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/InlineStreamMapAction.java index 7dbb7f3a3fce..cf3dcba1c3a5 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/InlineStreamMapAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/InlineStreamMapAction.java @@ -31,8 +31,8 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.refactoring.util.LambdaRefactoringUtil; import com.intellij.util.IncorrectOperationException; import com.siyeh.ig.psiutils.ParenthesesUtils; -import com.siyeh.ig.style.MethodRefCanBeReplacedWithLambdaInspection; import one.util.streamex.StreamEx; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -87,8 +87,7 @@ public class InlineStreamMapAction extends PsiElementBaseIntentionAction { return lambdaExpression.getParameterList().getParametersCount() == 1 && (!requireExpressionLambda || LambdaUtil.extractSingleExpressionFromBody(lambdaExpression.getBody()) != null); } else if(expression instanceof PsiMethodReferenceExpression) { - PsiMethodReferenceExpression methodReference = (PsiMethodReferenceExpression)expression; - return !MethodRefCanBeReplacedWithLambdaInspection.isWithSideEffects(methodReference); + return LambdaRefactoringUtil.canConvertToLambda((PsiMethodReferenceExpression)expression); } return false; } @@ -161,12 +160,29 @@ public class InlineStreamMapAction extends PsiElementBaseIntentionAction { } } if(nextName.equals("flatMap") && prevClassName.equals(CommonClassNames.JAVA_UTIL_STREAM_STREAM)) { - String mapMethod = translateMap(prevName); - return "flatM"+mapMethod.substring(1); + return mapToFlatMap(prevName); } return null; } + @Contract(pure = true) + @Nullable + private static String mapToFlatMap(String mapMethod) { + switch (mapMethod) { + case "map": + return "flatMap"; + case "mapToInt": + return "flatMapToInt"; + case "mapToLong": + return "flatMapToLong"; + case "mapToDouble": + return "flatMapToDouble"; + } + // Something unsupported passed: ignore + return null; + } + + @Contract(pure = true) @NotNull private static String translateMap(String nextMethod) { switch (nextMethod) { diff --git a/java/java-impl/src/com/intellij/refactoring/util/LambdaRefactoringUtil.java b/java/java-impl/src/com/intellij/refactoring/util/LambdaRefactoringUtil.java index 6763e30c1864..e5d467213976 100644 --- a/java/java-impl/src/com/intellij/refactoring/util/LambdaRefactoringUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/util/LambdaRefactoringUtil.java @@ -77,7 +77,6 @@ public class LambdaRefactoringUtil { final PsiParameter[] psiParameters = resolve instanceof PsiMethod ? ((PsiMethod)resolve).getParameterList().getParameters() : null; final StringBuilder buf = new StringBuilder("("); - LOG.assertTrue(functionalInterfaceType != null); buf.append(GenericsUtil.getVariableTypeByExpressionType(functionalInterfaceType).getCanonicalText()).append(")("); final PsiParameterList parameterList = interfaceMethod.getParameterList(); final PsiParameter[] parameters = parameterList.getParameters(); @@ -103,6 +102,7 @@ public class LambdaRefactoringUtil { else { initialName = parameter.getName(); } + LOG.assertTrue(initialName != null); baseName = codeStyleManager.variableNameToPropertyName(initialName, VariableKind.PARAMETER); } @@ -265,4 +265,16 @@ public class LambdaRefactoringUtil { } } } + + /** + * Checks whether method reference can be converted to lambda without significant semantics change + * (i.e. method reference qualifier has no side effects) + * + * @param methodReferenceExpression method reference to check + * @return true if method reference can be converted to lambda + */ + public static boolean canConvertToLambda(PsiMethodReferenceExpression methodReferenceExpression) { + final PsiExpression qualifierExpression = methodReferenceExpression.getQualifierExpression(); + return qualifierExpression != null && !SideEffectChecker.mayHaveSideEffects(qualifierExpression); + } } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/style/MethodRefCanBeReplacedWithLambdaInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/style/MethodRefCanBeReplacedWithLambdaInspection.java index 4d755dcf77d1..9cfe67755b83 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/style/MethodRefCanBeReplacedWithLambdaInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/style/MethodRefCanBeReplacedWithLambdaInspection.java @@ -34,14 +34,10 @@ import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; -import com.siyeh.ig.psiutils.SideEffectChecker; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.List; - public class MethodRefCanBeReplacedWithLambdaInspection extends BaseInspection { @Nls @@ -74,16 +70,6 @@ public class MethodRefCanBeReplacedWithLambdaInspection extends BaseInspection { return null; } - public static boolean isWithSideEffects(PsiMethodReferenceExpression methodReferenceExpression) { - final PsiExpression qualifierExpression = methodReferenceExpression.getQualifierExpression(); - if (qualifierExpression != null) { - final List sideEffects = new ArrayList<>(); - SideEffectChecker.checkSideEffects(qualifierExpression, sideEffects); - return !sideEffects.isEmpty(); - } - return false; - } - private static class MethodRefToLambdaVisitor extends BaseInspectionVisitor { @Override public void visitMethodReferenceExpression(PsiMethodReferenceExpression methodReferenceExpression) { @@ -92,12 +78,13 @@ public class MethodRefCanBeReplacedWithLambdaInspection extends BaseInspection { if (interfaceType != null && LambdaUtil.getFunctionalInterfaceMethod(interfaceType) != null && methodReferenceExpression.resolve() != null) { - registerError(methodReferenceExpression, getFixFactory(isWithSideEffects(methodReferenceExpression), isOnTheFly())); + registerError(methodReferenceExpression, + getFixFactory(LambdaRefactoringUtil.canConvertToLambda(methodReferenceExpression), isOnTheFly())); } } - private static FixFactory getFixFactory(boolean withSideEffects, boolean onTheFly) { - if (!withSideEffects) return MethodRefToLambdaFix::new; + private static FixFactory getFixFactory(boolean canConvert, boolean onTheFly) { + if (canConvert) return MethodRefToLambdaFix::new; if (onTheFly || ApplicationManager.getApplication().isUnitTestMode()) return SideEffectsMethodRefToLambdaFix::new; return null; }