From 4a5cbe0443b19a9cdde47ba6652ec16630827182 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Mon, 6 May 2019 11:46:56 +0300 Subject: [PATCH] Replace "flatMap -> flatten" inspection with abstract "simplifiable call" Related to KT-30501 --- idea/resources/META-INF/plugin-common.xml | 4 +- .../ConvertFlatMapToFlatten.html | 5 -- .../SimplifiableCall.html | 6 ++ .../ConvertFlatMapToFlattenInspection.kt | 51 -------------- .../collections/SimplifiableCallInspection.kt | 66 +++++++++++++++++++ .../convertFlatMapToFlatten/.inspection | 1 - .../collections/simplifiableCall/.inspection | 1 + .../explicitLambdaParameter.kt | 0 .../explicitLambdaParameter.kt.after | 0 .../notOnlyReference.kt | 0 .../set.kt | 0 .../set.kt.after | 0 .../simple.kt | 0 .../simple.kt.after | 0 .../simple2.kt | 0 .../simple2.kt.after | 0 .../LocalInspectionTestGenerated.java | 18 ++--- 17 files changed, 84 insertions(+), 68 deletions(-) delete mode 100644 idea/resources/inspectionDescriptions/ConvertFlatMapToFlatten.html create mode 100644 idea/resources/inspectionDescriptions/SimplifiableCall.html delete mode 100644 idea/src/org/jetbrains/kotlin/idea/inspections/collections/ConvertFlatMapToFlattenInspection.kt create mode 100644 idea/src/org/jetbrains/kotlin/idea/inspections/collections/SimplifiableCallInspection.kt delete mode 100644 idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten/.inspection create mode 100644 idea/testData/inspectionsLocal/collections/simplifiableCall/.inspection rename idea/testData/inspectionsLocal/collections/{convertFlatMapToFlatten => simplifiableCall}/explicitLambdaParameter.kt (100%) rename idea/testData/inspectionsLocal/collections/{convertFlatMapToFlatten => simplifiableCall}/explicitLambdaParameter.kt.after (100%) rename idea/testData/inspectionsLocal/collections/{convertFlatMapToFlatten => simplifiableCall}/notOnlyReference.kt (100%) rename idea/testData/inspectionsLocal/collections/{convertFlatMapToFlatten => simplifiableCall}/set.kt (100%) rename idea/testData/inspectionsLocal/collections/{convertFlatMapToFlatten => simplifiableCall}/set.kt.after (100%) rename idea/testData/inspectionsLocal/collections/{convertFlatMapToFlatten => simplifiableCall}/simple.kt (100%) rename idea/testData/inspectionsLocal/collections/{convertFlatMapToFlatten => simplifiableCall}/simple.kt.after (100%) rename idea/testData/inspectionsLocal/collections/{convertFlatMapToFlatten => simplifiableCall}/simple2.kt (100%) rename idea/testData/inspectionsLocal/collections/{convertFlatMapToFlatten => simplifiableCall}/simple2.kt.after (100%) diff --git a/idea/resources/META-INF/plugin-common.xml b/idea/resources/META-INF/plugin-common.xml index 76cdc5a02a0..fbd9e63a18a 100644 --- a/idea/resources/META-INF/plugin-common.xml +++ b/idea/resources/META-INF/plugin-common.xml @@ -3144,8 +3144,8 @@ language="kotlin" /> - - -This inspection reports flatMap call should be simplified to flatten(), e.g. flatMap { it } to flatten(). - - diff --git a/idea/resources/inspectionDescriptions/SimplifiableCall.html b/idea/resources/inspectionDescriptions/SimplifiableCall.html new file mode 100644 index 00000000000..069b7c54619 --- /dev/null +++ b/idea/resources/inspectionDescriptions/SimplifiableCall.html @@ -0,0 +1,6 @@ + + +This inspection reports library function calls which could be replaced by simplified one, +e.g. flatMap { it } call could be simplified to flatten(). + + diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/collections/ConvertFlatMapToFlattenInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/collections/ConvertFlatMapToFlattenInspection.kt deleted file mode 100644 index 115f3ad460d..00000000000 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/collections/ConvertFlatMapToFlattenInspection.kt +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.idea.inspections.collections - -import com.intellij.codeInspection.LocalQuickFix -import com.intellij.codeInspection.ProblemDescriptor -import com.intellij.codeInspection.ProblemHighlightType -import com.intellij.codeInspection.ProblemsHolder -import com.intellij.openapi.project.Project -import org.jetbrains.kotlin.idea.inspections.AbstractKotlinInspection -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.psi.* - -class ConvertFlatMapToFlattenInspection : AbstractKotlinInspection() { - override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean) = - qualifiedExpressionVisitor(fun(expression) { - val callExpression = expression.selectorExpression as? KtCallExpression ?: return - val calleeExpression = callExpression.calleeExpression ?: return - if (!callExpression.isCalling(FqName("kotlin.collections.flatMap"))) return - - val argument = callExpression.valueArguments.singleOrNull() ?: return - val lambdaExpression = (argument as? KtLambdaArgument)?.getLambdaExpression() - ?: argument.getArgumentExpression() as? KtLambdaExpression - ?: return - val reference = lambdaExpression.bodyExpression?.statements?.singleOrNull() as? KtNameReferenceExpression ?: return - val lambdaParameters = lambdaExpression.valueParameters - val lambdaParameterName = if (lambdaParameters.isNotEmpty()) lambdaParameters.singleOrNull()?.name else "it" - if (reference.text != lambdaParameterName) return - - holder.registerProblem( - calleeExpression, - "flatMap call should be simplified to flatten()", - ProblemHighlightType.GENERIC_ERROR_OR_WARNING, - ConvertFlatMapToFlattenFix() - ) - }) -} - -private class ConvertFlatMapToFlattenFix : LocalQuickFix { - override fun getName() = "Convert flatMap to flatten" - - override fun getFamilyName() = name - - override fun applyFix(project: Project, descriptor: ProblemDescriptor) { - val callExpression = descriptor.psiElement.parent as? KtCallExpression ?: return - callExpression.replace(KtPsiFactory(callExpression).createExpression("flatten()")) - } -} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/collections/SimplifiableCallInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/collections/SimplifiableCallInspection.kt new file mode 100644 index 00000000000..00cdb965937 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/collections/SimplifiableCallInspection.kt @@ -0,0 +1,66 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.inspections.collections + +import com.intellij.codeInspection.LocalQuickFix +import com.intellij.codeInspection.ProblemDescriptor +import com.intellij.codeInspection.ProblemHighlightType +import com.intellij.codeInspection.ProblemsHolder +import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.idea.inspections.AbstractKotlinInspection +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.psi.* + +class SimplifiableCallInspection : AbstractKotlinInspection() { + override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean) = + qualifiedExpressionVisitor(fun(expression) { + val callExpression = expression.selectorExpression as? KtCallExpression ?: return + val calleeExpression = callExpression.calleeExpression ?: return + val conversion = callExpression.findConversion() ?: return + val conversionSuffix = conversion.analyzer(callExpression) ?: return + + holder.registerProblem( + calleeExpression, + "${conversion.fqName.shortName()} call could be simplified to ${conversion.replacement}$conversionSuffix", + ProblemHighlightType.GENERIC_ERROR_OR_WARNING, + SimplifyCallFix(conversion, conversionSuffix) + ) + }) + + private fun KtCallExpression.findConversion(): Conversion? = conversions.firstOrNull { isCalling(it.fqName) } + + private data class Conversion(val callFqName: String, val replacement: String, val analyzer: (KtCallExpression) -> String?) { + val fqName = FqName(callFqName) + } + + companion object { + private val conversions = listOf( + Conversion("kotlin.collections.flatMap", "flatten", fun(callExpression: KtCallExpression): String? { + val argument = callExpression.valueArguments.singleOrNull() ?: return null + val lambdaExpression = (argument as? KtLambdaArgument)?.getLambdaExpression() + ?: argument.getArgumentExpression() as? KtLambdaExpression + ?: return null + val reference = lambdaExpression.bodyExpression?.statements?.singleOrNull() as? KtNameReferenceExpression ?: return null + val lambdaParameters = lambdaExpression.valueParameters + val lambdaParameterName = if (lambdaParameters.isNotEmpty()) lambdaParameters.singleOrNull()?.name else "it" + if (reference.text != lambdaParameterName) return null + return "()" + }) + ) + } + + private class SimplifyCallFix(val conversion: Conversion, val conversionSuffix: String) : LocalQuickFix { + override fun getName() = "Convert '${conversion.fqName.shortName()}' call to '${conversion.replacement}$conversionSuffix'" + + override fun getFamilyName() = name + + override fun applyFix(project: Project, descriptor: ProblemDescriptor) { + val callExpression = descriptor.psiElement.parent as? KtCallExpression ?: return + callExpression.replace(KtPsiFactory(callExpression).createExpression("${conversion.replacement}$conversionSuffix")) + } + } +} + diff --git a/idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten/.inspection b/idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten/.inspection deleted file mode 100644 index 9803885df1a..00000000000 --- a/idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten/.inspection +++ /dev/null @@ -1 +0,0 @@ -org.jetbrains.kotlin.idea.inspections.collections.ConvertFlatMapToFlattenInspection \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/collections/simplifiableCall/.inspection b/idea/testData/inspectionsLocal/collections/simplifiableCall/.inspection new file mode 100644 index 00000000000..69050eba7a3 --- /dev/null +++ b/idea/testData/inspectionsLocal/collections/simplifiableCall/.inspection @@ -0,0 +1 @@ +org.jetbrains.kotlin.idea.inspections.collections.SimplifiableCallInspection \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten/explicitLambdaParameter.kt b/idea/testData/inspectionsLocal/collections/simplifiableCall/explicitLambdaParameter.kt similarity index 100% rename from idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten/explicitLambdaParameter.kt rename to idea/testData/inspectionsLocal/collections/simplifiableCall/explicitLambdaParameter.kt diff --git a/idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten/explicitLambdaParameter.kt.after b/idea/testData/inspectionsLocal/collections/simplifiableCall/explicitLambdaParameter.kt.after similarity index 100% rename from idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten/explicitLambdaParameter.kt.after rename to idea/testData/inspectionsLocal/collections/simplifiableCall/explicitLambdaParameter.kt.after diff --git a/idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten/notOnlyReference.kt b/idea/testData/inspectionsLocal/collections/simplifiableCall/notOnlyReference.kt similarity index 100% rename from idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten/notOnlyReference.kt rename to idea/testData/inspectionsLocal/collections/simplifiableCall/notOnlyReference.kt diff --git a/idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten/set.kt b/idea/testData/inspectionsLocal/collections/simplifiableCall/set.kt similarity index 100% rename from idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten/set.kt rename to idea/testData/inspectionsLocal/collections/simplifiableCall/set.kt diff --git a/idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten/set.kt.after b/idea/testData/inspectionsLocal/collections/simplifiableCall/set.kt.after similarity index 100% rename from idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten/set.kt.after rename to idea/testData/inspectionsLocal/collections/simplifiableCall/set.kt.after diff --git a/idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten/simple.kt b/idea/testData/inspectionsLocal/collections/simplifiableCall/simple.kt similarity index 100% rename from idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten/simple.kt rename to idea/testData/inspectionsLocal/collections/simplifiableCall/simple.kt diff --git a/idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten/simple.kt.after b/idea/testData/inspectionsLocal/collections/simplifiableCall/simple.kt.after similarity index 100% rename from idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten/simple.kt.after rename to idea/testData/inspectionsLocal/collections/simplifiableCall/simple.kt.after diff --git a/idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten/simple2.kt b/idea/testData/inspectionsLocal/collections/simplifiableCall/simple2.kt similarity index 100% rename from idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten/simple2.kt rename to idea/testData/inspectionsLocal/collections/simplifiableCall/simple2.kt diff --git a/idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten/simple2.kt.after b/idea/testData/inspectionsLocal/collections/simplifiableCall/simple2.kt.after similarity index 100% rename from idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten/simple2.kt.after rename to idea/testData/inspectionsLocal/collections/simplifiableCall/simple2.kt.after diff --git a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java index 7f86367ea35..5b3650b9157 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java @@ -1091,41 +1091,41 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest { } } - @TestMetadata("idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten") + @TestMetadata("idea/testData/inspectionsLocal/collections/simplifiableCall") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) - public static class ConvertFlatMapToFlatten extends AbstractLocalInspectionTest { + public static class SimplifiableCall extends AbstractLocalInspectionTest { private void runTest(String testDataFilePath) throws Exception { KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); } - public void testAllFilesPresentInConvertFlatMapToFlatten() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true); + public void testAllFilesPresentInSimplifiableCall() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/collections/simplifiableCall"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true); } @TestMetadata("explicitLambdaParameter.kt") public void testExplicitLambdaParameter() throws Exception { - runTest("idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten/explicitLambdaParameter.kt"); + runTest("idea/testData/inspectionsLocal/collections/simplifiableCall/explicitLambdaParameter.kt"); } @TestMetadata("notOnlyReference.kt") public void testNotOnlyReference() throws Exception { - runTest("idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten/notOnlyReference.kt"); + runTest("idea/testData/inspectionsLocal/collections/simplifiableCall/notOnlyReference.kt"); } @TestMetadata("set.kt") public void testSet() throws Exception { - runTest("idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten/set.kt"); + runTest("idea/testData/inspectionsLocal/collections/simplifiableCall/set.kt"); } @TestMetadata("simple.kt") public void testSimple() throws Exception { - runTest("idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten/simple.kt"); + runTest("idea/testData/inspectionsLocal/collections/simplifiableCall/simple.kt"); } @TestMetadata("simple2.kt") public void testSimple2() throws Exception { - runTest("idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten/simple2.kt"); + runTest("idea/testData/inspectionsLocal/collections/simplifiableCall/simple2.kt"); } }