From 6fbd744430751b103fd21e8a2186bc2f4d946830 Mon Sep 17 00:00:00 2001 From: "Andrey.Cherkasov" Date: Fri, 25 Sep 2020 14:16:22 +0300 Subject: [PATCH] RedundantUnmodifiableInspection created: IDEA-202309 GitOrigin-RevId: d5a5e1f45ba0f6e0af786ca588caaa192cd4b554 --- java/java-impl/src/META-INF/JavaPlugin.xml | 6 ++ .../RedundantUnmodifiableInspection.java | 97 +++++++++++++++++++ .../RedundantUnmodifiable.html | 14 +++ .../afterIntermediateMethod.java | 35 +++++++ .../afterIntermediateVar.java | 29 ++++++ .../afterUnmodifiableArg.java | 20 ++++ .../afterUnmodifiableMethod.java | 20 ++++ .../afterWithComments.java | 44 +++++++++ .../afterWithParentheses.java | 20 ++++ .../beforeIntermediateMethod.java | 35 +++++++ .../beforeIntermediateVar.java | 29 ++++++ .../beforeUnmodifiableArg.java | 20 ++++ .../beforeUnmodifiableMethod.java | 20 ++++ .../beforeWithComments.java | 20 ++++ .../beforeWithParentheses.java | 20 ++++ .../RedundantUnmodifiableInspectionTest.java | 22 +++++ .../resources/messages/JavaBundle.properties | 3 + 17 files changed, 454 insertions(+) create mode 100644 java/java-impl/src/com/intellij/codeInspection/RedundantUnmodifiableInspection.java create mode 100644 java/java-impl/src/inspectionDescriptions/RedundantUnmodifiable.html create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/afterIntermediateMethod.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/afterIntermediateVar.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/afterUnmodifiableArg.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/afterUnmodifiableMethod.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/afterWithComments.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/afterWithParentheses.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/beforeIntermediateMethod.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/beforeIntermediateVar.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/beforeUnmodifiableArg.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/beforeUnmodifiableMethod.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/beforeWithComments.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/beforeWithParentheses.java create mode 100644 java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/quickFix/RedundantUnmodifiableInspectionTest.java diff --git a/java/java-impl/src/META-INF/JavaPlugin.xml b/java/java-impl/src/META-INF/JavaPlugin.xml index b64def8b5a11..5d56fdba1415 100644 --- a/java/java-impl/src/META-INF/JavaPlugin.xml +++ b/java/java-impl/src/META-INF/JavaPlugin.xml @@ -1389,6 +1389,12 @@ bundle="messages.JavaBundle" key="inspection.redundant.file.creation.display.name" implementationClass="com.intellij.codeInspection.RedundantFileCreationInspection"/> + + +Reports redundant calls to unmodifiable collection factories within the Collections class. +If the argument that is passed to an unmodifiable collection factory is already immutable, such wrapping becomes pointless. +

Example:

+
+Collections.unmodifiableList(Collections.singletonList("abc"));
+
+
+In order to detect the methods that return unmodifiable collections, the inspection uses the @Unmodifiable annotation. Use this annotation if you want to extend the inspection to your own unmodifiable collection factories. + +

New in 2020.3

+ + diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/afterIntermediateMethod.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/afterIntermediateMethod.java new file mode 100644 index 000000000000..7783129d01eb --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/afterIntermediateMethod.java @@ -0,0 +1,35 @@ +// "Fix all 'Redundant usage of unmodifiable collection factories' problems in file" "true" + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; + +class Main { + + public static void main(String[] args) { + getEmptyList(); + + getEmptyList(); + getEmptySet(); + getEmptyMap(); + + getEmptySet(); + getEmptyMap(); + + getEmptySet(); + getEmptyMap(); + } + + static List getEmptyList() { + return Collections.emptyList(); + } + + static Set getEmptySet() { + return Collections.emptySet(); + } + + static Map getEmptyMap() { + return Collections.emptyMap(); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/afterIntermediateVar.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/afterIntermediateVar.java new file mode 100644 index 000000000000..37a2f02ab44d --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/afterIntermediateVar.java @@ -0,0 +1,29 @@ +// "Fix all 'Redundant usage of unmodifiable collection factories' problems in file" "true" + +import java.util.*; + +class Main { + + public static void main(String[] args) { + List list = new ArrayList(); + list = Collections.emptyList(); + + Set set = new HashSet(); + set = Collections.emptySet(); + + Map map = new HashMap(); + map = Collections.emptyMap(); + + list; + + list; + set; + map; + + set; + map; + + set; + map; + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/afterUnmodifiableArg.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/afterUnmodifiableArg.java new file mode 100644 index 000000000000..faf3371326e0 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/afterUnmodifiableArg.java @@ -0,0 +1,20 @@ +// "Fix all 'Redundant usage of unmodifiable collection factories' problems in file" "true" + +import java.util.Collections; + +class Main { + + public static void main(String[] args) { + Collections.EMPTY_LIST; + + Collections.EMPTY_LIST; + Collections.EMPTY_SET; + Collections.EMPTY_MAP; + + Collections.EMPTY_SET; + Collections.EMPTY_MAP; + + Collections.EMPTY_SET; + Collections.EMPTY_MAP; + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/afterUnmodifiableMethod.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/afterUnmodifiableMethod.java new file mode 100644 index 000000000000..ab3a85409e4c --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/afterUnmodifiableMethod.java @@ -0,0 +1,20 @@ +// "Fix all 'Redundant usage of unmodifiable collection factories' problems in file" "true" + +import java.util.Collections; + +class Main { + + public static void main(String[] args) { + Collections.emptyList(); + + Collections.emptyList(); + Collections.emptySet(); + Collections.emptyMap(); + + Collections.emptySet(); + Collections.emptyMap(); + + Collections.emptySet(); + Collections.emptyMap(); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/afterWithComments.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/afterWithComments.java new file mode 100644 index 000000000000..2b6b99bf5c50 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/afterWithComments.java @@ -0,0 +1,44 @@ +// "Fix all 'Redundant usage of unmodifiable collection factories' problems in file" "true" + +import java.util.Collections; + +class Main { + + public static void main(String[] args) { + /*empty*/ + /*empty too*/ + /*blah blah blah*/ + Collections.emptyList(); + + /*empty*/ + /*empty too*/ + /*blah blah blah*/ + Collections.emptyList(); + /*empty*/ + /*empty too*/ + /*blah blah blah*/ + Collections.emptySet(); + /*empty*/ + /*empty too*/ + /*blah blah blah*/ + Collections.emptyMap(); + + /*empty*/ + /*empty too*/ + /*blah blah blah*/ + Collections.emptySet(); + /*empty*/ + /*empty too*/ + /*blah blah blah*/ + Collections.emptyMap(); + + /*empty*/ + /*empty too*/ + /*blah blah blah*/ + Collections.emptySet(); + /*empty*/ + /*empty too*/ + /*blah blah blah*/ + Collections.emptyMap(); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/afterWithParentheses.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/afterWithParentheses.java new file mode 100644 index 000000000000..4e6f3fdf0480 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/afterWithParentheses.java @@ -0,0 +1,20 @@ +// "Fix all 'Redundant usage of unmodifiable collection factories' problems in file" "true" + +import java.util.Collections; + +class Main { + + public static void main(String[] args) { + ((Collections.emptyList())); + + ((Collections.emptyList())); + ((Collections.emptySet())); + ((Collections.emptyMap())); + + ((Collections.emptySet())); + ((Collections.emptyMap())); + + ((Collections.emptySet())); + ((Collections.emptyMap())); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/beforeIntermediateMethod.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/beforeIntermediateMethod.java new file mode 100644 index 000000000000..9f634802385c --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/beforeIntermediateMethod.java @@ -0,0 +1,35 @@ +// "Fix all 'Redundant usage of unmodifiable collection factories' problems in file" "true" + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; + +class Main { + + public static void main(String[] args) { + Collections.unmodifiableCollection(getEmptyList()); + + Collections.unmodifiableList(getEmptyList()); + Collections.unmodifiableSet(getEmptySet()); + Collections.unmodifiableMap(getEmptyMap()); + + Collections.unmodifiableSortedSet(getEmptySet()); + Collections.unmodifiableSortedMap(getEmptyMap()); + + Collections.unmodifiableNavigableSet(getEmptySet()); + Collections.unmodifiableNavigableMap(getEmptyMap()); + } + + static List getEmptyList() { + return Collections.emptyList(); + } + + static Set getEmptySet() { + return Collections.emptySet(); + } + + static Map getEmptyMap() { + return Collections.emptyMap(); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/beforeIntermediateVar.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/beforeIntermediateVar.java new file mode 100644 index 000000000000..85c3dff60bfe --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/beforeIntermediateVar.java @@ -0,0 +1,29 @@ +// "Fix all 'Redundant usage of unmodifiable collection factories' problems in file" "true" + +import java.util.*; + +class Main { + + public static void main(String[] args) { + List list = new ArrayList(); + list = Collections.emptyList(); + + Set set = new HashSet(); + set = Collections.emptySet(); + + Map map = new HashMap(); + map = Collections.emptyMap(); + + Collections.unmodifiableCollection(list); + + Collections.unmodifiableList(list); + Collections.unmodifiableSet(set); + Collections.unmodifiableMap(map); + + Collections.unmodifiableSortedSet(set); + Collections.unmodifiableSortedMap(map); + + Collections.unmodifiableNavigableSet(set); + Collections.unmodifiableNavigableMap(map); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/beforeUnmodifiableArg.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/beforeUnmodifiableArg.java new file mode 100644 index 000000000000..d95aa91d6857 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/beforeUnmodifiableArg.java @@ -0,0 +1,20 @@ +// "Fix all 'Redundant usage of unmodifiable collection factories' problems in file" "true" + +import java.util.Collections; + +class Main { + + public static void main(String[] args) { + Collections.unmodifiableCollection(Collections.EMPTY_LIST); + + Collections.unmodifiableList(Collections.EMPTY_LIST); + Collections.unmodifiableSet(Collections.EMPTY_SET); + Collections.unmodifiableMap(Collections.EMPTY_MAP); + + Collections.unmodifiableSortedSet(Collections.EMPTY_SET); + Collections.unmodifiableSortedMap(Collections.EMPTY_MAP); + + Collections.unmodifiableNavigableSet(Collections.EMPTY_SET); + Collections.unmodifiableNavigableMap(Collections.EMPTY_MAP); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/beforeUnmodifiableMethod.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/beforeUnmodifiableMethod.java new file mode 100644 index 000000000000..861c863d209a --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/beforeUnmodifiableMethod.java @@ -0,0 +1,20 @@ +// "Fix all 'Redundant usage of unmodifiable collection factories' problems in file" "true" + +import java.util.Collections; + +class Main { + + public static void main(String[] args) { + Collections.unmodifiableCollection(Collections.emptyList()); + + Collections.unmodifiableList(Collections.emptyList()); + Collections.unmodifiableSet(Collections.emptySet()); + Collections.unmodifiableMap(Collections.emptyMap()); + + Collections.unmodifiableSortedSet(Collections.emptySet()); + Collections.unmodifiableSortedMap(Collections.emptyMap()); + + Collections.unmodifiableNavigableSet(Collections.emptySet()); + Collections.unmodifiableNavigableMap(Collections.emptyMap()); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/beforeWithComments.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/beforeWithComments.java new file mode 100644 index 000000000000..7f7c8dbfce8f --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/beforeWithComments.java @@ -0,0 +1,20 @@ +// "Fix all 'Redundant usage of unmodifiable collection factories' problems in file" "true" + +import java.util.Collections; + +class Main { + + public static void main(String[] args) { + Collections/*empty*/./*empty too*/unmodifiableCollection/*blah blah blah*/(Collections.emptyList()); + + Collections/*empty*/./*empty too*/unmodifiableList/*blah blah blah*/(Collections.emptyList()); + Collections/*empty*/./*empty too*/unmodifiableSet/*blah blah blah*/(Collections.emptySet()); + Collections/*empty*/./*empty too*/unmodifiableMap/*blah blah blah*/(Collections.emptyMap()); + + Collections/*empty*/./*empty too*/unmodifiableSortedSet/*blah blah blah*/(Collections.emptySet()); + Collections/*empty*/./*empty too*/unmodifiableSortedMap/*blah blah blah*/(Collections.emptyMap()); + + Collections/*empty*/./*empty too*/unmodifiableNavigableSet/*blah blah blah*/(Collections.emptySet()); + Collections/*empty*/./*empty too*/unmodifiableNavigableMap/*blah blah blah*/(Collections.emptyMap()); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/beforeWithParentheses.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/beforeWithParentheses.java new file mode 100644 index 000000000000..462309df66c7 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable/beforeWithParentheses.java @@ -0,0 +1,20 @@ +// "Fix all 'Redundant usage of unmodifiable collection factories' problems in file" "true" + +import java.util.Collections; + +class Main { + + public static void main(String[] args) { + Collections.unmodifiableCollection(((Collections.emptyList()))); + + Collections.unmodifiableList(((Collections.emptyList()))); + Collections.unmodifiableSet(((Collections.emptySet()))); + Collections.unmodifiableMap(((Collections.emptyMap()))); + + Collections.unmodifiableSortedSet(((Collections.emptySet()))); + Collections.unmodifiableSortedMap(((Collections.emptyMap()))); + + Collections.unmodifiableNavigableSet(((Collections.emptySet()))); + Collections.unmodifiableNavigableMap(((Collections.emptyMap()))); + } +} diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/quickFix/RedundantUnmodifiableInspectionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/quickFix/RedundantUnmodifiableInspectionTest.java new file mode 100644 index 000000000000..ae7ef70be61b --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/quickFix/RedundantUnmodifiableInspectionTest.java @@ -0,0 +1,22 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.java.codeInsight.daemon.quickFix; + +import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase; +import com.intellij.codeInspection.LocalInspectionTool; +import com.intellij.codeInspection.RedundantUnmodifiableInspection; +import org.jetbrains.annotations.NotNull; + + +public class RedundantUnmodifiableInspectionTest extends LightQuickFixParameterizedTestCase { + @Override + protected LocalInspectionTool @NotNull [] configureLocalInspectionTools() { + return new LocalInspectionTool[]{ + new RedundantUnmodifiableInspection() + }; + } + + @Override + protected String getBasePath() { + return "/codeInsight/daemonCodeAnalyzer/quickFix/redundantUnmodifiable"; + } +} diff --git a/java/openapi/resources/messages/JavaBundle.properties b/java/openapi/resources/messages/JavaBundle.properties index b19d786989ab..dc75fbf2e1d1 100644 --- a/java/openapi/resources/messages/JavaBundle.properties +++ b/java/openapi/resources/messages/JavaBundle.properties @@ -1551,3 +1551,6 @@ postfix.template.condition.boolean.name=boolean postfix.template.condition.number.name=number postfix.template.condition.not.primitive.type.name=not primitive type postfix.template.condition.array.name=array +inspection.redundant.unmodifiable.call.display.name=Redundant usage of the ''{0}'' factory +inspection.redundant.unmodifiable.call.description=Redundant usage of unmodifiable collection factories +inspection.redundant.unmodifiable.call.replace.with.arg.quickfix=Unwrap argument