SimplifiableCallChainInspection: replace .sorted().first() with .min()

#KT-30725 Fixed
This commit is contained in:
Toshiaki Kameyama
2019-04-08 18:14:25 +09:00
committed by Mikhail Glukhikh
parent e4b10a156e
commit 47b1ea7fa4
20 changed files with 86 additions and 2 deletions
@@ -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 != '.' }
@@ -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"),
@@ -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)
@@ -0,0 +1,2 @@
// WITH_RUNTIME
val x: Pair<String, Int> = listOf("a" to 1, "c" to 3, "b" to 2).<caret>sortedByDescending { it.second }.first()
@@ -0,0 +1,2 @@
// WITH_RUNTIME
val x: Pair<String, Int> = listOf("a" to 1, "c" to 3, "b" to 2).maxBy { it.second }!!
@@ -0,0 +1,2 @@
// WITH_RUNTIME
val x: Pair<String, Int> = listOf("a" to 1, "c" to 3, "b" to 2).<caret>sortedByDescending { it.second }.last()
@@ -0,0 +1,2 @@
// WITH_RUNTIME
val x: Pair<String, Int> = listOf("a" to 1, "c" to 3, "b" to 2).minBy { it.second }!!
@@ -0,0 +1,2 @@
// WITH_RUNTIME
val x: Pair<String, Int> = listOf("a" to 1, "c" to 3, "b" to 2).<caret>sortedBy { it.second }.first()
@@ -0,0 +1,2 @@
// WITH_RUNTIME
val x: Pair<String, Int> = listOf("a" to 1, "c" to 3, "b" to 2).minBy { it.second }!!
@@ -0,0 +1,2 @@
// WITH_RUNTIME
val x: Pair<String, Int> = listOf("a" to 1, "c" to 3, "b" to 2).<caret>sortedBy { it.second }.last()
@@ -0,0 +1,2 @@
// WITH_RUNTIME
val x: Pair<String, Int> = listOf("a" to 1, "c" to 3, "b" to 2).maxBy { it.second }!!
@@ -0,0 +1,2 @@
// WITH_RUNTIME
val x: Int = listOf(1, 3, 2).<caret>sortedDescending().first()
@@ -0,0 +1,2 @@
// WITH_RUNTIME
val x: Int = listOf(1, 3, 2).max()!!
@@ -0,0 +1,2 @@
// WITH_RUNTIME
val x: Int = listOf(1, 3, 2).<caret>sortedDescending().last()
@@ -0,0 +1,2 @@
// WITH_RUNTIME
val x: Int = listOf(1, 3, 2).min()!!
@@ -0,0 +1,2 @@
// WITH_RUNTIME
val x: Int = listOf(1, 3, 2).<caret>sorted().first()
@@ -0,0 +1,2 @@
// WITH_RUNTIME
val x: Int = listOf(1, 3, 2).min()!!
@@ -0,0 +1,2 @@
// WITH_RUNTIME
val x: Int = listOf(1, 3, 2).<caret>sorted().last()
@@ -0,0 +1,2 @@
// WITH_RUNTIME
val x: Int = listOf(1, 3, 2).max()!!
@@ -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");