From bbd50dacc2ff026ceb0b17bd886cb8aebded96c9 Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Thu, 5 May 2016 12:21:29 +0300 Subject: [PATCH] guava inspection: negate isEmpty method conversion IDEA-154952 --- .../GuavaFluentIterableConversionRule.java | 34 ++++++++++++------- .../guava/chainedFluentIterable_after.java | 2 +- .../controlflow/DoubleNegationInspection.java | 2 +- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaFluentIterableConversionRule.java b/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaFluentIterableConversionRule.java index 2635b15893c6..9d6410332de1 100644 --- a/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaFluentIterableConversionRule.java +++ b/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaFluentIterableConversionRule.java @@ -18,7 +18,6 @@ package com.intellij.refactoring.typeMigration.rules.guava; import com.intellij.codeInspection.java18StreamApi.PseudoLambdaReplaceTemplate; import com.intellij.codeInspection.java18StreamApi.StreamApiConstants; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.NotNullLazyValue; import com.intellij.psi.*; import com.intellij.psi.codeStyle.JavaCodeStyleManager; @@ -26,7 +25,6 @@ import com.intellij.psi.codeStyle.SuggestedNameInfo; import com.intellij.psi.codeStyle.VariableKind; import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiTypesUtil; -import com.intellij.psi.util.TypeConversionUtil; import com.intellij.refactoring.typeMigration.TypeConversionDescriptor; import com.intellij.refactoring.typeMigration.TypeConversionDescriptorBase; import com.intellij.refactoring.typeMigration.TypeEvaluator; @@ -37,6 +35,7 @@ import com.intellij.util.SmartList; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.Stack; import com.intellij.util.containers.hash.HashMap; +import com.siyeh.ig.controlflow.DoubleNegationInspection; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -96,7 +95,6 @@ public class GuavaFluentIterableConversionRule extends BaseGuavaTypeConversionRu } static { - DESCRIPTORS_MAP.put("isEmpty", new TypeConversionDescriptorFactory("$q$.isEmpty()", "$q$.findAny().isPresent()", false)); DESCRIPTORS_MAP.put("skip", new TypeConversionDescriptorFactory("$q$.skip($p$)", "$q$.skip($p$)", false, true, true)); DESCRIPTORS_MAP.put("limit", new TypeConversionDescriptorFactory("$q$.limit($p$)", "$q$.limit($p$)", false, true, true)); DESCRIPTORS_MAP.put("first", new TypeConversionDescriptorFactory("$q$.first()", "$q$.findFirst()", false, true, false)); @@ -158,6 +156,21 @@ public class GuavaFluentIterableConversionRule extends BaseGuavaTypeConversionRu }; } else if (methodName.equals("filter")) { descriptorBase = FluentIterableConversionUtil.getFilterDescriptor(method); + } else if (methodName.equals("isEmpty")) { + descriptorBase = new TypeConversionDescriptor("$q$.isEmpty()", null) { + @Override + public PsiExpression replace(PsiExpression expression, TypeEvaluator evaluator) { + final PsiElement parent = expression.getParent(); + boolean isDoubleNegation = false; + if (parent instanceof PsiExpression && DoubleNegationInspection.isNegation((PsiExpression)parent)) { + isDoubleNegation = true; + expression = (PsiExpression)parent.replace(expression); + } + setReplaceByString((isDoubleNegation ? "" : "!") + "$q$.findAny().isPresent()"); + return super.replace(expression, evaluator); + } + }; + needSpecifyType = false; } else if (methodName.equals("transformAndConcat")) { descriptorBase = new FluentIterableConversionUtil.TransformAndConcatConversionRule(); @@ -227,17 +240,14 @@ public class GuavaFluentIterableConversionRule extends BaseGuavaTypeConversionRu if (descriptorBase == null) { return FluentIterableConversionUtil.createToCollectionDescriptor(methodName, context); } - if (descriptorBase != null) { - if (needSpecifyType) { - if (conversionType == null) { - PsiMethodCallExpression methodCall = (PsiMethodCallExpression) (context instanceof PsiMethodCallExpression ? context : context.getParent()); - conversionType = GuavaConversionUtil.addTypeParameters(GuavaTypeConversionDescriptor.isIterable(methodCall) ? CommonClassNames.JAVA_LANG_ITERABLE : StreamApiConstants.JAVA_UTIL_STREAM_STREAM, context.getType(), context); - } - descriptorBase.withConversionType(conversionType); + if (needSpecifyType) { + if (conversionType == null) { + PsiMethodCallExpression methodCall = (PsiMethodCallExpression) (context instanceof PsiMethodCallExpression ? context : context.getParent()); + conversionType = GuavaConversionUtil.addTypeParameters(GuavaTypeConversionDescriptor.isIterable(methodCall) ? CommonClassNames.JAVA_LANG_ITERABLE : StreamApiConstants.JAVA_UTIL_STREAM_STREAM, context.getType(), context); } - return descriptorBase; + descriptorBase.withConversionType(conversionType); } - return null; + return descriptorBase; } @Nullable diff --git a/java/typeMigration/testData/inspections/guava/chainedFluentIterable_after.java b/java/typeMigration/testData/inspections/guava/chainedFluentIterable_after.java index 0cfd483d065f..5f78996981a6 100644 --- a/java/typeMigration/testData/inspections/guava/chainedFluentIterable_after.java +++ b/java/typeMigration/testData/inspections/guava/chainedFluentIterable_after.java @@ -10,6 +10,6 @@ class A { List booleans = it.map(String::isEmpty).collect(Collectors.toList()); - boolean empty = it.map(s -> s.trim()).map(input -> input.toCharArray()).skip(777).filter(input -> input.length != 10).findAny().isPresent(); + boolean empty = !it.map(s -> s.trim()).map(input -> input.toCharArray()).skip(777).filter(input -> input.length != 10).findAny().isPresent(); } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/DoubleNegationInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/DoubleNegationInspection.java index ff4d3e38b50e..ce1bcfca1174 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/DoubleNegationInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/DoubleNegationInspection.java @@ -151,7 +151,7 @@ public class DoubleNegationInspection extends BaseInspection { } } - static boolean isNegation(@Nullable PsiExpression expression) { + public static boolean isNegation(@Nullable PsiExpression expression) { expression = ParenthesesUtils.stripParentheses(expression); if (expression instanceof PsiPrefixExpression) return isNegation((PsiPrefixExpression)expression); if (expression instanceof PsiPolyadicExpression) return isNegation((PsiPolyadicExpression)expression);