From f625bb942d341365f103cdd1c3e0c72cb92cb607 Mon Sep 17 00:00:00 2001 From: "Andrey.Cherkasov" Date: Mon, 6 Sep 2021 17:11:35 +0300 Subject: [PATCH] [java-inspections] 'map.putAll(Map.of("key", "value"))' could be simplified to 'map.put("key", "value")' IDEA-271418 GitOrigin-RevId: 05ac65c6ba692b3af70189cb4e1b173d31ea7268 --- .../afterPutAllMapOf.java | 8 +++ .../beforePutAllMapOf.java | 8 +++ ...dantCollectionOperationInspectionTest.java | 8 +++ ...edundantCollectionOperationInspection.java | 51 ++++++++++--------- 4 files changed, 50 insertions(+), 25 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantCollectionOperation/afterPutAllMapOf.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantCollectionOperation/beforePutAllMapOf.java diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantCollectionOperation/afterPutAllMapOf.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantCollectionOperation/afterPutAllMapOf.java new file mode 100644 index 000000000000..23e9281b2d92 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantCollectionOperation/afterPutAllMapOf.java @@ -0,0 +1,8 @@ +// "Replace with 'put()'" "true" +import java.util.*; + +class Test { + void test(Map map) { + map.put(1, "one"); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantCollectionOperation/beforePutAllMapOf.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantCollectionOperation/beforePutAllMapOf.java new file mode 100644 index 000000000000..4669fb9062d0 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantCollectionOperation/beforePutAllMapOf.java @@ -0,0 +1,8 @@ +// "Replace with 'put()'" "true" +import java.util.*; + +class Test { + void test(Map map) { + map.putAll(Map.of(1, "one")); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/quickFix/RedundantCollectionOperationInspectionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/quickFix/RedundantCollectionOperationInspectionTest.java index 2e1a5954bb79..75d01b56f981 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/quickFix/RedundantCollectionOperationInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/quickFix/RedundantCollectionOperationInspectionTest.java @@ -3,9 +3,11 @@ package com.intellij.java.codeInsight.daemon.quickFix; import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase; import com.intellij.codeInspection.LocalInspectionTool; +import com.intellij.testFramework.LightProjectDescriptor; import com.siyeh.ig.redundancy.RedundantCollectionOperationInspection; import org.jetbrains.annotations.NotNull; +import static com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase.JAVA_9; public class RedundantCollectionOperationInspectionTest extends LightQuickFixParameterizedTestCase { @Override @@ -19,4 +21,10 @@ public class RedundantCollectionOperationInspectionTest extends LightQuickFixPar protected String getBasePath() { return "/codeInsight/daemonCodeAnalyzer/quickFix/redundantCollectionOperation"; } + + @NotNull + @Override + protected LightProjectDescriptor getProjectDescriptor() { + return JAVA_9; + } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/redundancy/RedundantCollectionOperationInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/redundancy/RedundantCollectionOperationInspection.java index 53679cce5319..817c2dac4c64 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/redundancy/RedundantCollectionOperationInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/redundancy/RedundantCollectionOperationInspection.java @@ -67,18 +67,21 @@ public class RedundantCollectionOperationInspection extends AbstractBaseJavaLoca private static final CallMatcher ITERABLE_ITERATOR = instanceCall(CommonClassNames.JAVA_LANG_ITERABLE, "iterator").parameterCount(0); private static final CallMatcher MAP_KEY_SET = instanceCall(CommonClassNames.JAVA_UTIL_MAP, "keySet").parameterCount(0); private static final CallMatcher MAP_VALUES = instanceCall(CommonClassNames.JAVA_UTIL_MAP, "values").parameterCount(0); + private static final CallMatcher MAP_PUT_ALL = instanceCall(CommonClassNames.JAVA_UTIL_MAP, "putAll").parameterCount(1); + private static final CallMatcher MAP_OF = staticCall(CommonClassNames.JAVA_UTIL_MAP, "of").parameterCount(2); private static final CallMapper HANDLERS = new CallMapper() .register(TO_ARRAY, AsListToArrayHandler::handler) - .register(CONTAINS_ALL, ContainsAllSingletonHandler::handler) + .register(CONTAINS_ALL, call -> createHandler(call, SINGLETON, "contains")) .register(CONTAINS, SingletonContainsHandler::handler) .register(CONTAINS, MapKeySetContainsHandler::handler) .register(anyOf(CONTAINS, CONTAINS_KEY), ContainsBeforeAddRemoveHandler::handler) .register(REMOVE_BY_INDEX, RedundantIndexOfHandler::handler) .register(AS_LIST, RedundantAsListForIterationHandler::handler) .register(AS_LIST, RedundantSortAsListHandler::handler) - .register(ITERABLE_ITERATOR, RedundantEmptyIteratorHandler::handler); + .register(ITERABLE_ITERATOR, RedundantEmptyIteratorHandler::handler) + .register(MAP_PUT_ALL, call -> createHandler(call, MAP_OF, "put")); @NotNull @Override @@ -365,30 +368,28 @@ public class RedundantCollectionOperationInspection extends AbstractBaseJavaLoca } } - private static class ContainsAllSingletonHandler implements RedundantCollectionOperationHandler { - @Override - public @NotNull @NlsSafe String getReplacement() { - return "contains()"; - } + private static RedundantCollectionOperationHandler createHandler(PsiMethodCallExpression call, + CallMatcher matcher, + String replacementMethod) { + PsiExpression arg = call.getArgumentList().getExpressions()[0]; + PsiMethodCallExpression argCall = tryCast(PsiUtil.skipParenthesizedExprDown(arg), PsiMethodCallExpression.class); + if (!matcher.test(argCall)) return null; + return new RedundantCollectionOperationHandler() { + @Override + public @NotNull @NlsSafe String getReplacement() { + return replacementMethod + "()"; + } - @Override - public void performFix(@NotNull Project project, @NotNull PsiMethodCallExpression call) { - PsiExpression arg = ArrayUtil.getFirstElement(call.getArgumentList().getExpressions()); - if (arg == null) return; - PsiMethodCallExpression singleton = tryCast(PsiUtil.skipParenthesizedExprDown(arg), PsiMethodCallExpression.class); - if (singleton == null) return; - PsiExpression singletonArg = ArrayUtil.getFirstElement(singleton.getArgumentList().getExpressions()); - if (singletonArg == null) return; - ExpressionUtils.bindCallTo(call, "contains"); - new CommentTracker().replaceAndRestoreComments(arg, singletonArg); - } - - public static RedundantCollectionOperationHandler handler(PsiMethodCallExpression call) { - PsiExpression containsAllArg = call.getArgumentList().getExpressions()[0]; - PsiMethodCallExpression maybeSingleton = tryCast(PsiUtil.skipParenthesizedExprDown(containsAllArg), PsiMethodCallExpression.class); - if (!SINGLETON.test(maybeSingleton)) return null; - return new ContainsAllSingletonHandler(); - } + @Override + public void performFix(@NotNull Project project, @NotNull PsiMethodCallExpression call) { + PsiExpression arg = ArrayUtil.getFirstElement(call.getArgumentList().getExpressions()); + if (arg == null) return; + PsiMethodCallExpression argCall = tryCast(PsiUtil.skipParenthesizedExprDown(arg), PsiMethodCallExpression.class); + if (argCall == null) return; + ExpressionUtils.bindCallTo(call, replacementMethod); + new CommentTracker().replaceAndRestoreComments(call.getArgumentList(), argCall.getArgumentList()); + } + }; } private static class SingletonContainsHandler implements RedundantCollectionOperationHandler {