#KT-26965 Add inspection + quickfix for replacing Collection<T>.count() with .size

This commit is contained in:
Dereck Bridie
2019-02-28 11:33:10 +01:00
committed by Dmitry Gridin
parent 240ff08069
commit 4156a76129
12 changed files with 138 additions and 0 deletions
@@ -1753,6 +1753,14 @@
level="WEAK WARNING"
language="kotlin"
/>
<localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.ReplaceCollectionCountWithSizeInspection"
displayName="Collection count can be converted to size"
groupPath="Kotlin"
groupName="Style issues"
enabledByDefault="false"
level="WEAK WARNING"
language="kotlin"
/>
<localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.DeprecatedCallableAddReplaceWithInspection"
displayName="@Deprecated annotation without 'replaceWith' argument"
@@ -0,0 +1,5 @@
<html>
<body>
This intention replaces <code>count()</code> function calls with <code>size</code>.
</body>
</html>
@@ -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)
}
@@ -0,0 +1 @@
org.jetbrains.kotlin.idea.inspections.ReplaceCollectionCountWithSizeInspection
@@ -0,0 +1,6 @@
// WITH_RUNTIME
fun foo() {
var array = arrayOf(1,2,3)
array.<caret>count()
}
@@ -0,0 +1,6 @@
// WITH_RUNTIME
fun foo() {
var array = arrayOf(1,2,3)
array.size
}
@@ -0,0 +1,7 @@
// PROBLEM: none
// WITH_RUNTIME
fun foo() {
var array = arrayOf(1,2,3)
array.<caret>count { i -> i == 1 }
}
@@ -0,0 +1,6 @@
// WITH_RUNTIME
fun foo() {
var list = listOf(1,2,3)
list.<caret>count()
}
@@ -0,0 +1,6 @@
// WITH_RUNTIME
fun foo() {
var list = listOf(1,2,3)
list.size
}
@@ -0,0 +1,6 @@
// WITH_RUNTIME
fun foo() {
var map = mapOf(1 to true)
map.<caret>count()
}
@@ -0,0 +1,6 @@
// WITH_RUNTIME
fun foo() {
var map = mapOf(1 to true)
map.size
}
@@ -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)