Replace "flatMap -> flatten" inspection with abstract "simplifiable call"
Related to KT-30501
This commit is contained in:
@@ -3144,8 +3144,8 @@
|
|||||||
language="kotlin"
|
language="kotlin"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.collections.ConvertFlatMapToFlattenInspection"
|
<localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.collections.SimplifiableCallInspection"
|
||||||
displayName="flatMap call should be simplified to flatten()"
|
displayName="Library function call could be simplified"
|
||||||
groupPath="Kotlin"
|
groupPath="Kotlin"
|
||||||
groupName="Style issues"
|
groupName="Style issues"
|
||||||
enabledByDefault="true"
|
enabledByDefault="true"
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
<html>
|
|
||||||
<body>
|
|
||||||
This inspection reports <b>flatMap</b> call should be simplified to <b>flatten()<b>, e.g. <b>flatMap { it }</b> to <b>flatten()</b>.
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
This inspection reports library function calls which could be replaced by simplified one,
|
||||||
|
e.g. <b>flatMap { it }</b> call could be simplified to <b>flatten()</b>.
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
-51
@@ -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()"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+66
@@ -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"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
org.jetbrains.kotlin.idea.inspections.collections.ConvertFlatMapToFlattenInspection
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
org.jetbrains.kotlin.idea.inspections.collections.SimplifiableCallInspection
|
||||||
+9
-9
@@ -1091,41 +1091,41 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten")
|
@TestMetadata("idea/testData/inspectionsLocal/collections/simplifiableCall")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class ConvertFlatMapToFlatten extends AbstractLocalInspectionTest {
|
public static class SimplifiableCall extends AbstractLocalInspectionTest {
|
||||||
private void runTest(String testDataFilePath) throws Exception {
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testAllFilesPresentInConvertFlatMapToFlatten() throws Exception {
|
public void testAllFilesPresentInSimplifiableCall() throws Exception {
|
||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/collections/simplifiableCall"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("explicitLambdaParameter.kt")
|
@TestMetadata("explicitLambdaParameter.kt")
|
||||||
public void testExplicitLambdaParameter() throws Exception {
|
public void testExplicitLambdaParameter() throws Exception {
|
||||||
runTest("idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten/explicitLambdaParameter.kt");
|
runTest("idea/testData/inspectionsLocal/collections/simplifiableCall/explicitLambdaParameter.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("notOnlyReference.kt")
|
@TestMetadata("notOnlyReference.kt")
|
||||||
public void testNotOnlyReference() throws Exception {
|
public void testNotOnlyReference() throws Exception {
|
||||||
runTest("idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten/notOnlyReference.kt");
|
runTest("idea/testData/inspectionsLocal/collections/simplifiableCall/notOnlyReference.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("set.kt")
|
@TestMetadata("set.kt")
|
||||||
public void testSet() throws Exception {
|
public void testSet() throws Exception {
|
||||||
runTest("idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten/set.kt");
|
runTest("idea/testData/inspectionsLocal/collections/simplifiableCall/set.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("simple.kt")
|
@TestMetadata("simple.kt")
|
||||||
public void testSimple() throws Exception {
|
public void testSimple() throws Exception {
|
||||||
runTest("idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten/simple.kt");
|
runTest("idea/testData/inspectionsLocal/collections/simplifiableCall/simple.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("simple2.kt")
|
@TestMetadata("simple2.kt")
|
||||||
public void testSimple2() throws Exception {
|
public void testSimple2() throws Exception {
|
||||||
runTest("idea/testData/inspectionsLocal/collections/convertFlatMapToFlatten/simple2.kt");
|
runTest("idea/testData/inspectionsLocal/collections/simplifiableCall/simple2.kt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user