From 47b1ea7fa45a49d3e95c5f5dd898171fa7077fad Mon Sep 17 00:00:00 2001 From: Toshiaki Kameyama Date: Mon, 8 Apr 2019 18:14:25 +0900 Subject: [PATCH] SimplifiableCallChainInspection: replace `.sorted().first()` with `.min()` #KT-30725 Fixed --- .../collections/AbstractCallChainChecker.kt | 3 +- .../SimplifiableCallChainInspection.kt | 8 ++++ .../collections/SimplifyCallChainFix.kt | 5 ++- .../sortedByDescendingFirst.kt | 2 + .../sortedByDescendingFirst.kt.after | 2 + .../sortedByDescendingLast.kt | 2 + .../sortedByDescendingLast.kt.after | 2 + .../simplifiableCallChain/sortedByFirst.kt | 2 + .../sortedByFirst.kt.after | 2 + .../simplifiableCallChain/sortedByLast.kt | 2 + .../sortedByLast.kt.after | 2 + .../sortedDescendingFirst.kt | 2 + .../sortedDescendingFirst.kt.after | 2 + .../sortedDescendingLast.kt | 2 + .../sortedDescendingLast.kt.after | 2 + .../simplifiableCallChain/sortedFirst.kt | 2 + .../sortedFirst.kt.after | 2 + .../simplifiableCallChain/sortedLast.kt | 2 + .../simplifiableCallChain/sortedLast.kt.after | 2 + .../LocalInspectionTestGenerated.java | 40 +++++++++++++++++++ 20 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByDescendingFirst.kt create mode 100644 idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByDescendingFirst.kt.after create mode 100644 idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByDescendingLast.kt create mode 100644 idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByDescendingLast.kt.after create mode 100644 idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByFirst.kt create mode 100644 idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByFirst.kt.after create mode 100644 idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByLast.kt create mode 100644 idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByLast.kt.after create mode 100644 idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedDescendingFirst.kt create mode 100644 idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedDescendingFirst.kt.after create mode 100644 idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedDescendingLast.kt create mode 100644 idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedDescendingLast.kt.after create mode 100644 idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedFirst.kt create mode 100644 idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedFirst.kt.after create mode 100644 idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedLast.kt create mode 100644 idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedLast.kt.after diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/collections/AbstractCallChainChecker.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/collections/AbstractCallChainChecker.kt index c7c2038e13e..5cc012760b0 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/collections/AbstractCallChainChecker.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/collections/AbstractCallChainChecker.kt @@ -66,7 +66,8 @@ abstract class AbstractCallChainChecker : AbstractKotlinInspection() { val firstFqName: String, val secondFqName: String, val replacement: String, - val additionalArgument: String? = null + val additionalArgument: String? = null, + val withNotNullAssertion: Boolean = false ) { private fun String.convertToShort() = takeLastWhile { it != '.' } diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/collections/SimplifiableCallChainInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/collections/SimplifiableCallChainInspection.kt index 9c8d8e6a6e2..f3f94d5d515 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/collections/SimplifiableCallChainInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/collections/SimplifiableCallChainInspection.kt @@ -80,6 +80,14 @@ class SimplifiableCallChainInspection : AbstractCallChainChecker() { Conversion("kotlin.collections.sortedBy", "kotlin.collections.lastOrNull", "maxBy"), Conversion("kotlin.collections.sortedByDescending", "kotlin.collections.firstOrNull", "maxBy"), Conversion("kotlin.collections.sortedByDescending", "kotlin.collections.lastOrNull", "minBy"), + Conversion("kotlin.collections.sorted", "kotlin.collections.first", "min", withNotNullAssertion = true), + Conversion("kotlin.collections.sorted", "kotlin.collections.last", "max", withNotNullAssertion = true), + Conversion("kotlin.collections.sortedDescending", "kotlin.collections.first", "max", withNotNullAssertion = true), + Conversion("kotlin.collections.sortedDescending", "kotlin.collections.last", "min", withNotNullAssertion = true), + Conversion("kotlin.collections.sortedBy", "kotlin.collections.first", "minBy", withNotNullAssertion = true), + Conversion("kotlin.collections.sortedBy", "kotlin.collections.last", "maxBy", withNotNullAssertion = true), + Conversion("kotlin.collections.sortedByDescending", "kotlin.collections.first", "maxBy", withNotNullAssertion = true), + Conversion("kotlin.collections.sortedByDescending", "kotlin.collections.last", "minBy", withNotNullAssertion = true), Conversion("kotlin.text.filter", "kotlin.text.first", "first"), Conversion("kotlin.text.filter", "kotlin.text.firstOrNull", "firstOrNull"), diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/collections/SimplifyCallChainFix.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/collections/SimplifyCallChainFix.kt index 787d40728d4..7627ec6089e 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/collections/SimplifyCallChainFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/collections/SimplifyCallChainFix.kt @@ -86,7 +86,7 @@ class SimplifyCallChainFix( val project = qualifiedExpression.project val file = qualifiedExpression.containingKtFile - val result = qualifiedExpression.replaced(newQualifiedOrCallExpression) + var result = qualifiedExpression.replaced(newQualifiedOrCallExpression) if (!firstCallHasArguments && !secondCallHasArguments) { commentSaver.restore(result) @@ -99,6 +99,9 @@ class SimplifyCallChainFix( } callExpression?.moveFunctionLiteralOutsideParentheses() } + if (conversion.withNotNullAssertion) { + result = result.replaced(factory.createExpressionByPattern("$0!!", result)) + } result.containingKtFile.commitAndUnblockDocument() val reformatted = CodeStyleManager.getInstance(project).reformat(result) diff --git a/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByDescendingFirst.kt b/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByDescendingFirst.kt new file mode 100644 index 00000000000..5969a41a245 --- /dev/null +++ b/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByDescendingFirst.kt @@ -0,0 +1,2 @@ +// WITH_RUNTIME +val x: Pair = listOf("a" to 1, "c" to 3, "b" to 2).sortedByDescending { it.second }.first() \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByDescendingFirst.kt.after b/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByDescendingFirst.kt.after new file mode 100644 index 00000000000..61f13e55369 --- /dev/null +++ b/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByDescendingFirst.kt.after @@ -0,0 +1,2 @@ +// WITH_RUNTIME +val x: Pair = listOf("a" to 1, "c" to 3, "b" to 2).maxBy { it.second }!! \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByDescendingLast.kt b/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByDescendingLast.kt new file mode 100644 index 00000000000..208ff22c831 --- /dev/null +++ b/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByDescendingLast.kt @@ -0,0 +1,2 @@ +// WITH_RUNTIME +val x: Pair = listOf("a" to 1, "c" to 3, "b" to 2).sortedByDescending { it.second }.last() \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByDescendingLast.kt.after b/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByDescendingLast.kt.after new file mode 100644 index 00000000000..4da94078adf --- /dev/null +++ b/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByDescendingLast.kt.after @@ -0,0 +1,2 @@ +// WITH_RUNTIME +val x: Pair = listOf("a" to 1, "c" to 3, "b" to 2).minBy { it.second }!! \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByFirst.kt b/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByFirst.kt new file mode 100644 index 00000000000..dcd64d1fb2a --- /dev/null +++ b/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByFirst.kt @@ -0,0 +1,2 @@ +// WITH_RUNTIME +val x: Pair = listOf("a" to 1, "c" to 3, "b" to 2).sortedBy { it.second }.first() \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByFirst.kt.after b/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByFirst.kt.after new file mode 100644 index 00000000000..4da94078adf --- /dev/null +++ b/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByFirst.kt.after @@ -0,0 +1,2 @@ +// WITH_RUNTIME +val x: Pair = listOf("a" to 1, "c" to 3, "b" to 2).minBy { it.second }!! \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByLast.kt b/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByLast.kt new file mode 100644 index 00000000000..477f8433388 --- /dev/null +++ b/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByLast.kt @@ -0,0 +1,2 @@ +// WITH_RUNTIME +val x: Pair = listOf("a" to 1, "c" to 3, "b" to 2).sortedBy { it.second }.last() \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByLast.kt.after b/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByLast.kt.after new file mode 100644 index 00000000000..61f13e55369 --- /dev/null +++ b/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByLast.kt.after @@ -0,0 +1,2 @@ +// WITH_RUNTIME +val x: Pair = listOf("a" to 1, "c" to 3, "b" to 2).maxBy { it.second }!! \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedDescendingFirst.kt b/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedDescendingFirst.kt new file mode 100644 index 00000000000..d1956ced99a --- /dev/null +++ b/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedDescendingFirst.kt @@ -0,0 +1,2 @@ +// WITH_RUNTIME +val x: Int = listOf(1, 3, 2).sortedDescending().first() \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedDescendingFirst.kt.after b/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedDescendingFirst.kt.after new file mode 100644 index 00000000000..97d688a29ab --- /dev/null +++ b/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedDescendingFirst.kt.after @@ -0,0 +1,2 @@ +// WITH_RUNTIME +val x: Int = listOf(1, 3, 2).max()!! \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedDescendingLast.kt b/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedDescendingLast.kt new file mode 100644 index 00000000000..21a1759d1ea --- /dev/null +++ b/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedDescendingLast.kt @@ -0,0 +1,2 @@ +// WITH_RUNTIME +val x: Int = listOf(1, 3, 2).sortedDescending().last() \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedDescendingLast.kt.after b/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedDescendingLast.kt.after new file mode 100644 index 00000000000..3e18063c187 --- /dev/null +++ b/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedDescendingLast.kt.after @@ -0,0 +1,2 @@ +// WITH_RUNTIME +val x: Int = listOf(1, 3, 2).min()!! \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedFirst.kt b/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedFirst.kt new file mode 100644 index 00000000000..67bb71c9d08 --- /dev/null +++ b/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedFirst.kt @@ -0,0 +1,2 @@ +// WITH_RUNTIME +val x: Int = listOf(1, 3, 2).sorted().first() \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedFirst.kt.after b/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedFirst.kt.after new file mode 100644 index 00000000000..3e18063c187 --- /dev/null +++ b/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedFirst.kt.after @@ -0,0 +1,2 @@ +// WITH_RUNTIME +val x: Int = listOf(1, 3, 2).min()!! \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedLast.kt b/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedLast.kt new file mode 100644 index 00000000000..bde4030adec --- /dev/null +++ b/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedLast.kt @@ -0,0 +1,2 @@ +// WITH_RUNTIME +val x: Int = listOf(1, 3, 2).sorted().last() \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedLast.kt.after b/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedLast.kt.after new file mode 100644 index 00000000000..97d688a29ab --- /dev/null +++ b/idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedLast.kt.after @@ -0,0 +1,2 @@ +// WITH_RUNTIME +val x: Int = listOf(1, 3, 2).max()!! \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java index 6d286b4f8c7..31db75ce9ca 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java @@ -1291,41 +1291,81 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest { runTest("idea/testData/inspectionsLocal/collections/simplifiableCallChain/saveComment3.kt"); } + @TestMetadata("sortedByDescendingFirst.kt") + public void testSortedByDescendingFirst() throws Exception { + runTest("idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByDescendingFirst.kt"); + } + @TestMetadata("sortedByDescendingFirstOrNull.kt") public void testSortedByDescendingFirstOrNull() throws Exception { runTest("idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByDescendingFirstOrNull.kt"); } + @TestMetadata("sortedByDescendingLast.kt") + public void testSortedByDescendingLast() throws Exception { + runTest("idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByDescendingLast.kt"); + } + @TestMetadata("sortedByDescendingLastOrNull.kt") public void testSortedByDescendingLastOrNull() throws Exception { runTest("idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByDescendingLastOrNull.kt"); } + @TestMetadata("sortedByFirst.kt") + public void testSortedByFirst() throws Exception { + runTest("idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByFirst.kt"); + } + @TestMetadata("sortedByFirstOrNull.kt") public void testSortedByFirstOrNull() throws Exception { runTest("idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByFirstOrNull.kt"); } + @TestMetadata("sortedByLast.kt") + public void testSortedByLast() throws Exception { + runTest("idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByLast.kt"); + } + @TestMetadata("sortedByLastOrNull.kt") public void testSortedByLastOrNull() throws Exception { runTest("idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedByLastOrNull.kt"); } + @TestMetadata("sortedDescendingFirst.kt") + public void testSortedDescendingFirst() throws Exception { + runTest("idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedDescendingFirst.kt"); + } + @TestMetadata("sortedDescendingFirstOrNull.kt") public void testSortedDescendingFirstOrNull() throws Exception { runTest("idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedDescendingFirstOrNull.kt"); } + @TestMetadata("sortedDescendingLast.kt") + public void testSortedDescendingLast() throws Exception { + runTest("idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedDescendingLast.kt"); + } + @TestMetadata("sortedDescendingLastOrNull.kt") public void testSortedDescendingLastOrNull() throws Exception { runTest("idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedDescendingLastOrNull.kt"); } + @TestMetadata("sortedFirst.kt") + public void testSortedFirst() throws Exception { + runTest("idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedFirst.kt"); + } + @TestMetadata("sortedFirstOrNull.kt") public void testSortedFirstOrNull() throws Exception { runTest("idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedFirstOrNull.kt"); } + @TestMetadata("sortedLast.kt") + public void testSortedLast() throws Exception { + runTest("idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedLast.kt"); + } + @TestMetadata("sortedLastOrNull.kt") public void testSortedLastOrNull() throws Exception { runTest("idea/testData/inspectionsLocal/collections/simplifiableCallChain/sortedLastOrNull.kt");