From 4156a76129a5f785d85ea93e9076b0e8ff88f383 Mon Sep 17 00:00:00 2001 From: Dereck Bridie Date: Thu, 28 Feb 2019 11:33:10 +0100 Subject: [PATCH] #KT-26965 Add inspection + quickfix for replacing Collection.count() with .size --- idea/resources/META-INF/plugin-common.xml | 8 ++++ .../ReplaceCollectionCountWithSize.html | 5 ++ ...eplaceCollectionCountWithSizeInspection.kt | 48 +++++++++++++++++++ .../.inspection | 1 + .../countOfArray.kt | 6 +++ .../countOfArray.kt.after | 6 +++ .../countOfArrayWithPredicate.kt | 7 +++ .../countOfCollection.kt | 6 +++ .../countOfCollection.kt.after | 6 +++ .../countOfMap.kt | 6 +++ .../countOfMap.kt.after | 6 +++ .../LocalInspectionTestGenerated.java | 33 +++++++++++++ 12 files changed, 138 insertions(+) create mode 100644 idea/resources/inspectionDescriptions/ReplaceCollectionCountWithSize.html create mode 100644 idea/src/org/jetbrains/kotlin/idea/inspections/ReplaceCollectionCountWithSizeInspection.kt create mode 100644 idea/testData/inspectionsLocal/replaceCollectionCountWithSize/.inspection create mode 100644 idea/testData/inspectionsLocal/replaceCollectionCountWithSize/countOfArray.kt create mode 100644 idea/testData/inspectionsLocal/replaceCollectionCountWithSize/countOfArray.kt.after create mode 100644 idea/testData/inspectionsLocal/replaceCollectionCountWithSize/countOfArrayWithPredicate.kt create mode 100644 idea/testData/inspectionsLocal/replaceCollectionCountWithSize/countOfCollection.kt create mode 100644 idea/testData/inspectionsLocal/replaceCollectionCountWithSize/countOfCollection.kt.after create mode 100644 idea/testData/inspectionsLocal/replaceCollectionCountWithSize/countOfMap.kt create mode 100644 idea/testData/inspectionsLocal/replaceCollectionCountWithSize/countOfMap.kt.after diff --git a/idea/resources/META-INF/plugin-common.xml b/idea/resources/META-INF/plugin-common.xml index 9b6d21b7680..8f0a714d190 100644 --- a/idea/resources/META-INF/plugin-common.xml +++ b/idea/resources/META-INF/plugin-common.xml @@ -1753,6 +1753,14 @@ level="WEAK WARNING" language="kotlin" /> + + +This intention replaces count() function calls with size. + + diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/ReplaceCollectionCountWithSizeInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/ReplaceCollectionCountWithSizeInspection.kt new file mode 100644 index 00000000000..0621dcac275 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/ReplaceCollectionCountWithSizeInspection.kt @@ -0,0 +1,48 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. 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 + +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 com.intellij.psi.PsiElementVisitor +import org.jetbrains.kotlin.idea.inspections.collections.isCalling +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.psi.KtCallExpression +import org.jetbrains.kotlin.psi.KtPsiFactory +import org.jetbrains.kotlin.psi.callExpressionVisitor + +class ReplaceCollectionCountWithSizeInspection : AbstractKotlinInspection() { + override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { + return callExpressionVisitor { callExpression -> + if (callExpression.isCount()) { + holder.registerProblem( + callExpression, + "Replace 'count' with 'size'", + ProblemHighlightType.GENERIC_ERROR_OR_WARNING, + ReplaceCollectionCountWithSizeQuickFix() + ) + } + } + } +} + +class ReplaceCollectionCountWithSizeQuickFix : LocalQuickFix { + override fun getName() = "Replace 'count' with 'size'" + + override fun getFamilyName() = name + + override fun applyFix(project: Project, descriptor: ProblemDescriptor) { + val element = descriptor.psiElement as KtCallExpression + element.replace(KtPsiFactory(element).createExpression("size")) + } +} + +private fun KtCallExpression.isCount(): Boolean { + return isCalling(FqName("kotlin.collections.count")) && (this.valueArguments.size == 0) +} diff --git a/idea/testData/inspectionsLocal/replaceCollectionCountWithSize/.inspection b/idea/testData/inspectionsLocal/replaceCollectionCountWithSize/.inspection new file mode 100644 index 00000000000..d42784b8348 --- /dev/null +++ b/idea/testData/inspectionsLocal/replaceCollectionCountWithSize/.inspection @@ -0,0 +1 @@ +org.jetbrains.kotlin.idea.inspections.ReplaceCollectionCountWithSizeInspection diff --git a/idea/testData/inspectionsLocal/replaceCollectionCountWithSize/countOfArray.kt b/idea/testData/inspectionsLocal/replaceCollectionCountWithSize/countOfArray.kt new file mode 100644 index 00000000000..857f59db7ca --- /dev/null +++ b/idea/testData/inspectionsLocal/replaceCollectionCountWithSize/countOfArray.kt @@ -0,0 +1,6 @@ +// WITH_RUNTIME + +fun foo() { + var array = arrayOf(1,2,3) + array.count() +} diff --git a/idea/testData/inspectionsLocal/replaceCollectionCountWithSize/countOfArray.kt.after b/idea/testData/inspectionsLocal/replaceCollectionCountWithSize/countOfArray.kt.after new file mode 100644 index 00000000000..049e3a85395 --- /dev/null +++ b/idea/testData/inspectionsLocal/replaceCollectionCountWithSize/countOfArray.kt.after @@ -0,0 +1,6 @@ +// WITH_RUNTIME + +fun foo() { + var array = arrayOf(1,2,3) + array.size +} diff --git a/idea/testData/inspectionsLocal/replaceCollectionCountWithSize/countOfArrayWithPredicate.kt b/idea/testData/inspectionsLocal/replaceCollectionCountWithSize/countOfArrayWithPredicate.kt new file mode 100644 index 00000000000..ed9dc4dc2ff --- /dev/null +++ b/idea/testData/inspectionsLocal/replaceCollectionCountWithSize/countOfArrayWithPredicate.kt @@ -0,0 +1,7 @@ +// PROBLEM: none +// WITH_RUNTIME + +fun foo() { + var array = arrayOf(1,2,3) + array.count { i -> i == 1 } +} diff --git a/idea/testData/inspectionsLocal/replaceCollectionCountWithSize/countOfCollection.kt b/idea/testData/inspectionsLocal/replaceCollectionCountWithSize/countOfCollection.kt new file mode 100644 index 00000000000..68eaff9c2fb --- /dev/null +++ b/idea/testData/inspectionsLocal/replaceCollectionCountWithSize/countOfCollection.kt @@ -0,0 +1,6 @@ +// WITH_RUNTIME + +fun foo() { + var list = listOf(1,2,3) + list.count() +} diff --git a/idea/testData/inspectionsLocal/replaceCollectionCountWithSize/countOfCollection.kt.after b/idea/testData/inspectionsLocal/replaceCollectionCountWithSize/countOfCollection.kt.after new file mode 100644 index 00000000000..d88f2d6e3b2 --- /dev/null +++ b/idea/testData/inspectionsLocal/replaceCollectionCountWithSize/countOfCollection.kt.after @@ -0,0 +1,6 @@ +// WITH_RUNTIME + +fun foo() { + var list = listOf(1,2,3) + list.size +} diff --git a/idea/testData/inspectionsLocal/replaceCollectionCountWithSize/countOfMap.kt b/idea/testData/inspectionsLocal/replaceCollectionCountWithSize/countOfMap.kt new file mode 100644 index 00000000000..cb0305a882c --- /dev/null +++ b/idea/testData/inspectionsLocal/replaceCollectionCountWithSize/countOfMap.kt @@ -0,0 +1,6 @@ +// WITH_RUNTIME + +fun foo() { + var map = mapOf(1 to true) + map.count() +} diff --git a/idea/testData/inspectionsLocal/replaceCollectionCountWithSize/countOfMap.kt.after b/idea/testData/inspectionsLocal/replaceCollectionCountWithSize/countOfMap.kt.after new file mode 100644 index 00000000000..a57d271ca4d --- /dev/null +++ b/idea/testData/inspectionsLocal/replaceCollectionCountWithSize/countOfMap.kt.after @@ -0,0 +1,6 @@ +// WITH_RUNTIME + +fun foo() { + var map = mapOf(1 to true) + map.size +} diff --git a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java index c417d569bf9..ebc0e96be06 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java @@ -6569,6 +6569,39 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest { } } + @TestMetadata("idea/testData/inspectionsLocal/replaceCollectionCountWithSize") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ReplaceCollectionCountWithSize extends AbstractLocalInspectionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInReplaceCollectionCountWithSize() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/replaceCollectionCountWithSize"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true); + } + + @TestMetadata("countOfArray.kt") + public void testCountOfArray() throws Exception { + runTest("idea/testData/inspectionsLocal/replaceCollectionCountWithSize/countOfArray.kt"); + } + + @TestMetadata("countOfArrayWithPredicate.kt") + public void testCountOfArrayWithPredicate() throws Exception { + runTest("idea/testData/inspectionsLocal/replaceCollectionCountWithSize/countOfArrayWithPredicate.kt"); + } + + @TestMetadata("countOfCollection.kt") + public void testCountOfCollection() throws Exception { + runTest("idea/testData/inspectionsLocal/replaceCollectionCountWithSize/countOfCollection.kt"); + } + + @TestMetadata("countOfMap.kt") + public void testCountOfMap() throws Exception { + runTest("idea/testData/inspectionsLocal/replaceCollectionCountWithSize/countOfMap.kt"); + } + } + @TestMetadata("idea/testData/inspectionsLocal/replaceNegatedIsEmptyWithIsNotEmpty") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)