From 73600a25eab65e5cca78016be9803b6a83066104 Mon Sep 17 00:00:00 2001 From: Olga Klisho Date: Tue, 10 Feb 2026 22:25:32 +0100 Subject: [PATCH] [kotlin] KTIJ-37276 ReplaceManualRangeWithIndicesCallsInspection: refactoring GitOrigin-RevId: 00562c51071dedbf72f12bcc78628c3fef6ecac2 --- .../messages/KotlinBundle.properties | 2 +- .../tests/K2LocalInspectionTestGenerated.java | 5 + ...ceManualRangeWithIndicesCallsInspection.kt | 49 +++- .../shared/utils/RangeInspectionUtils.kt | 22 ++ .../LocalInspectionTestGenerated.java | 214 ------------------ .../elementNameCollision.kt | 1 - .../elementNameCollision.kt.after | 1 - .../elementNameCollisionMultiple.kt | 1 - .../elementNameCollisionMultiple.kt.after | 1 - .../elementNameCollisionNestedLoop.kt | 1 - .../elementNameCollisionNestedLoop.kt.after | 1 - .../elementNameCollisionParameter.kt | 1 - .../elementNameCollisionParameter.kt.after | 1 - .../qualifiedReceiverDifferentCollection.kt | 12 + ...lifiedReceiverDifferentCollection.kt.after | 12 + .../withIndexElementNameCollision.kt | 1 - .../withIndexElementNameCollision.kt.after | 1 - .../fe10/testGenerator/Fe10GenerateTests.kt | 1 + 18 files changed, 95 insertions(+), 232 deletions(-) create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/qualifiedReceiverDifferentCollection.kt create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/qualifiedReceiverDifferentCollection.kt.after diff --git a/plugins/kotlin/base/resources/resources-en/messages/KotlinBundle.properties b/plugins/kotlin/base/resources/resources-en/messages/KotlinBundle.properties index da97aed5af1a..d40abaf98f8c 100644 --- a/plugins/kotlin/base/resources/resources-en/messages/KotlinBundle.properties +++ b/plugins/kotlin/base/resources/resources-en/messages/KotlinBundle.properties @@ -1688,7 +1688,7 @@ replace.index.loop.with.collection.loop.quick.fix.text=Replace with loop over el replace.manual.range.with.indices.call.quick.fix.text=Replace with indices range.could.be.replaced.with.indices.call=Range could be replaced with '.indices' call for.loop.over.indices.could.be.replaced.with.loop.over.elements=For loop over indices could be replaced with loop over elements -for.loop.could.use.withIndex=For loop could use 'withIndex()' +for.loop.could.use.withIndex=Range can be replaced with withIndex() replace.index.loop.with.withIndex.quick.fix.text=Replace with 'withIndex()' replace.negated.0.with.1=Replace negated ''{0}'' with ''{1}'' replace.with.elvis.return.fix.text=Replace with ''?: return{0}'' diff --git a/plugins/kotlin/code-insight/inspections-k2/tests/test/org/jetbrains/kotlin/idea/k2/inspections/tests/K2LocalInspectionTestGenerated.java b/plugins/kotlin/code-insight/inspections-k2/tests/test/org/jetbrains/kotlin/idea/k2/inspections/tests/K2LocalInspectionTestGenerated.java index 5e1fc2d3d382..7a783d3b648f 100644 --- a/plugins/kotlin/code-insight/inspections-k2/tests/test/org/jetbrains/kotlin/idea/k2/inspections/tests/K2LocalInspectionTestGenerated.java +++ b/plugins/kotlin/code-insight/inspections-k2/tests/test/org/jetbrains/kotlin/idea/k2/inspections/tests/K2LocalInspectionTestGenerated.java @@ -9802,6 +9802,11 @@ public abstract class K2LocalInspectionTestGenerated extends AbstractK2LocalInsp runTest("../../../idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/notUsedAsIndex.kt"); } + @TestMetadata("qualifiedReceiverDifferentCollection.kt") + public void testQualifiedReceiverDifferentCollection() throws Exception { + runTest("../../../idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/qualifiedReceiverDifferentCollection.kt"); + } + @TestMetadata("rangeTo.kt") public void testRangeTo() throws Exception { runTest("../../../idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/rangeTo.kt"); diff --git a/plugins/kotlin/code-insight/inspections-shared/src/org/jetbrains/kotlin/idea/codeInsight/inspections/shared/ReplaceManualRangeWithIndicesCallsInspection.kt b/plugins/kotlin/code-insight/inspections-shared/src/org/jetbrains/kotlin/idea/codeInsight/inspections/shared/ReplaceManualRangeWithIndicesCallsInspection.kt index 97ea6fb940c6..85f7c8f53e5b 100644 --- a/plugins/kotlin/code-insight/inspections-shared/src/org/jetbrains/kotlin/idea/codeInsight/inspections/shared/ReplaceManualRangeWithIndicesCallsInspection.kt +++ b/plugins/kotlin/code-insight/inspections-shared/src/org/jetbrains/kotlin/idea/codeInsight/inspections/shared/ReplaceManualRangeWithIndicesCallsInspection.kt @@ -20,13 +20,14 @@ import org.jetbrains.kotlin.analysis.api.types.KaType import org.jetbrains.kotlin.idea.base.codeInsight.KotlinDeclarationNameValidator import org.jetbrains.kotlin.idea.base.codeInsight.KotlinNameSuggester import org.jetbrains.kotlin.idea.base.codeInsight.KotlinNameSuggestionProvider -import org.jetbrains.kotlin.idea.references.mainReference import org.jetbrains.kotlin.idea.base.psi.isAssignmentLHS +import org.jetbrains.kotlin.idea.references.mainReference import org.jetbrains.kotlin.idea.base.psi.replaced import org.jetbrains.kotlin.idea.base.psi.safeDeparenthesize import org.jetbrains.kotlin.idea.base.resources.KotlinBundle import org.jetbrains.kotlin.idea.codeInsight.inspections.shared.AbstractRangeInspection.Companion.rangeExpressionByPsi import org.jetbrains.kotlin.idea.codeInsight.inspections.shared.AbstractRangeInspection.RangeExpression +import org.jetbrains.kotlin.idea.codeInsight.inspections.shared.utils.isPrimitiveRangeType import org.jetbrains.kotlin.idea.codeinsight.api.applicable.inspections.KotlinApplicableInspectionBase import org.jetbrains.kotlin.idea.codeinsight.api.applicable.inspections.KotlinModCommandQuickFix import org.jetbrains.kotlin.idea.codeinsight.utils.ImplicitReceiverInfo @@ -40,7 +41,7 @@ import org.jetbrains.kotlin.idea.codeinsight.utils.RangeKtExpressionType.RANGE_T import org.jetbrains.kotlin.idea.codeinsight.utils.RangeKtExpressionType.RANGE_UNTIL import org.jetbrains.kotlin.idea.codeinsight.utils.RangeKtExpressionType.UNTIL import org.jetbrains.kotlin.lexer.KtTokens -import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.psi.KtArrayAccessExpression import org.jetbrains.kotlin.psi.KtBinaryExpression @@ -101,6 +102,8 @@ class ReplaceManualRangeWithIndicesCallsInspection : KotlinApplicableInspectionB val indexedAccessUsages: List>, // Either KtArrayAccessExpression or KtDotQualifiedExpression ) + private val RANGE_CALLABLE_NAMES = setOf("until", "rangeTo", "rangeUntil", "downTo") + private fun getProblemDescription(context: Context): @InspectionMessage String { return when (context.indexUsagePattern) { IndexUsagePattern.ELEMENT_LOOP -> KotlinBundle.message("for.loop.over.indices.could.be.replaced.with.loop.over.elements") @@ -140,11 +143,25 @@ class ReplaceManualRangeWithIndicesCallsInspection : KotlinApplicableInspectionB */ private fun KaSession.rangeExpressionByAnalyze(expression: KtExpression): RangeExpression? = rangeExpressionByPsi(expression)?.takeIf { - val call = expression.resolveToCall()?.singleFunctionCallOrNull() - val packageName = call?.symbol?.callableId?.packageName - packageName != null && packageName.startsWith(Name.identifier("kotlin")) + val callableId = expression.resolveToCall()?.singleFunctionCallOrNull()?.symbol?.callableId + callableId != null && isStdlibRangeFunction(callableId) } + private fun isStdlibRangeFunction(callableId: CallableId): Boolean { + val callableName = callableId.callableName.asString() + if (callableName !in RANGE_CALLABLE_NAMES) return false + + // Extension functions in kotlin.ranges (until, rangeUntil, downTo, and some rangeTo overloads) + if (callableId.packageName == StandardClassIds.BASE_RANGES_PACKAGE) return true + + // Member functions on primitive types (Int.rangeTo, Int.rangeUntil, etc.) + if (callableName == "rangeTo" || callableName == "rangeUntil") { + return callableId.classId?.isPrimitiveRangeType() == true + } + + return false + } + private fun KaSession.prepareContextForRange(range: RangeExpression): Context? { val (_, right) = range.arguments @@ -305,8 +322,26 @@ class ReplaceManualRangeWithIndicesCallsInspection : KotlinApplicableInspectionB private fun receiversMatch(accessReceiver: KtExpression?, explicitReceiver: KtExpression?): Boolean { if (explicitReceiver == null) return accessReceiver?.safeDeparenthesize() is KtThisExpression if (accessReceiver == null) return false - return (accessReceiver as? KtNameReferenceExpression)?.mainReference?.resolve() == - (explicitReceiver as? KtNameReferenceExpression)?.mainReference?.resolve() + + val access = accessReceiver.safeDeparenthesize() + val explicit = explicitReceiver.safeDeparenthesize() + + return when { + access is KtNameReferenceExpression && explicit is KtNameReferenceExpression -> { + access.mainReference.resolve() == explicit.mainReference.resolve() + } + + access is KtDotQualifiedExpression && explicit is KtDotQualifiedExpression -> { + access.selectorExpression?.text == explicit.selectorExpression?.text && + receiversMatch(access.receiverExpression, explicit.receiverExpression) + } + + access is KtThisExpression && explicit is KtThisExpression -> { + access.labelQualifier?.text == explicit.labelQualifier?.text + } + + else -> false + } } private fun createQuickFixes(context: Context): List> { diff --git a/plugins/kotlin/code-insight/inspections-shared/src/org/jetbrains/kotlin/idea/codeInsight/inspections/shared/utils/RangeInspectionUtils.kt b/plugins/kotlin/code-insight/inspections-shared/src/org/jetbrains/kotlin/idea/codeInsight/inspections/shared/utils/RangeInspectionUtils.kt index 4bd45277a3c9..a896dfa2edda 100644 --- a/plugins/kotlin/code-insight/inspections-shared/src/org/jetbrains/kotlin/idea/codeInsight/inspections/shared/utils/RangeInspectionUtils.kt +++ b/plugins/kotlin/code-insight/inspections-shared/src/org/jetbrains/kotlin/idea/codeInsight/inspections/shared/utils/RangeInspectionUtils.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.idea.codeinsights.impl.base.isOptInSatisfied import org.jetbrains.kotlin.idea.compiler.configuration.IdeKotlinVersion import org.jetbrains.kotlin.idea.compiler.configuration.KotlinJpsPluginSettings import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.psi.KtElement context(_: KaSession) @@ -63,3 +64,24 @@ val KaType.isFloatingPointType: Boolean private val OPEN_END_RANGE_CLASS_ID = ClassId.fromString("kotlin/ranges/OpenEndRange") private val EXPERIMENTAL_STDLIB_API_CLASS_ID = ClassId.fromString("kotlin/ExperimentalStdlibApi") + +/** + * ClassIds of primitive types that support rangeTo/rangeUntil operations. + * These are the types that have member functions like Int.rangeTo(Int). + */ +private val PRIMITIVE_RANGE_TYPE_CLASS_IDS: Set = setOf( + StandardClassIds.Int, + StandardClassIds.Long, + StandardClassIds.Short, + StandardClassIds.Byte, + StandardClassIds.Char, + StandardClassIds.UInt, + StandardClassIds.ULong, + StandardClassIds.UShort, + StandardClassIds.UByte, +) + +/** + * Checks if this ClassId represents a primitive type that supports range operations (rangeTo/rangeUntil). + */ +fun ClassId.isPrimitiveRangeType(): Boolean = this in PRIMITIVE_RANGE_TYPE_CLASS_IDS diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java index baf73835946e..7f57b6ac17a6 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java @@ -14363,220 +14363,6 @@ public abstract class LocalInspectionTestGenerated extends AbstractK1LocalInspec } } - @RunWith(JUnit3RunnerWithInners.class) - @TestMetadata("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls") - public static class ReplaceManualRangeWithIndicesCalls extends AbstractK1LocalInspectionTest { - @java.lang.Override - @org.jetbrains.annotations.NotNull - public final KotlinPluginMode getPluginMode() { - return KotlinPluginMode.K1; - } - - private void runTest(String testDataFilePath) throws Exception { - KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); - } - - @TestMetadata("asReceiver.kt") - public void testAsReceiver() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/asReceiver.kt"); - } - - @TestMetadata("complexReceiver.kt") - public void testComplexReceiver() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/complexReceiver.kt"); - } - - @TestMetadata("elementNameCollision.kt") - public void testElementNameCollision() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollision.kt"); - } - - @TestMetadata("elementNameCollisionMultiple.kt") - public void testElementNameCollisionMultiple() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollisionMultiple.kt"); - } - - @TestMetadata("elementNameCollisionNestedLoop.kt") - public void testElementNameCollisionNestedLoop() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollisionNestedLoop.kt"); - } - - @TestMetadata("elementNameCollisionParameter.kt") - public void testElementNameCollisionParameter() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollisionParameter.kt"); - } - - @TestMetadata("forNotTarget.kt") - public void testForNotTarget() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/forNotTarget.kt"); - } - - @TestMetadata("getMethod.kt") - public void testGetMethod() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/getMethod.kt"); - } - - @TestMetadata("getMethodDifferentArray.kt") - public void testGetMethodDifferentArray() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/getMethodDifferentArray.kt"); - } - - @TestMetadata("implicitReceiver.kt") - public void testImplicitReceiver() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/implicitReceiver.kt"); - } - - @TestMetadata("implicitReceiverFor.kt") - public void testImplicitReceiverFor() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/implicitReceiverFor.kt"); - } - - @TestMetadata("implicitReceiverRangeUntil.kt") - public void testImplicitReceiverRangeUntil() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/implicitReceiverRangeUntil.kt"); - } - - @TestMetadata("implicitReceiverUntil.kt") - public void testImplicitReceiverUntil() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/implicitReceiverUntil.kt"); - } - - @TestMetadata("indexInLvalue.kt") - public void testIndexInLvalue() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/indexInLvalue.kt"); - } - - @TestMetadata("lastIndex.kt") - public void testLastIndex() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/lastIndex.kt"); - } - - @TestMetadata("lengthLiteralConstant.kt") - public void testLengthLiteralConstant() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/lengthLiteralConstant.kt"); - } - - @TestMetadata("lengthVariable.kt") - public void testLengthVariable() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/lengthVariable.kt"); - } - - @TestMetadata("map.kt") - public void testMap() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/map.kt"); - } - - @TestMetadata("multidimensionalArray2.kt") - public void testMultidimensionalArray2() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/multidimensionalArray2.kt"); - } - - @TestMetadata("multipleImplicitReceivers.kt") - public void testMultipleImplicitReceivers() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/multipleImplicitReceivers.kt"); - } - - @TestMetadata("multipleImplicitReceivers2.kt") - public void testMultipleImplicitReceivers2() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/multipleImplicitReceivers2.kt"); - } - - @TestMetadata("notUsedAsIndex.kt") - public void testNotUsedAsIndex() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/notUsedAsIndex.kt"); - } - - @TestMetadata("rangeTo.kt") - public void testRangeTo() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/rangeTo.kt"); - } - - @TestMetadata("simpleExpression.kt") - public void testSimpleExpression() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/simpleExpression.kt"); - } - - @TestMetadata("simpleExpressionRangeUntil.kt") - public void testSimpleExpressionRangeUntil() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/simpleExpressionRangeUntil.kt"); - } - - @TestMetadata("simpleExpressionUntil.kt") - public void testSimpleExpressionUntil() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/simpleExpressionUntil.kt"); - } - - @TestMetadata("simpleFor.kt") - public void testSimpleFor() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/simpleFor.kt"); - } - - @TestMetadata("sizeLabeled.kt") - public void testSizeLabeled() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/sizeLabeled.kt"); - } - - @TestMetadata("sizeLiteralConstant.kt") - public void testSizeLiteralConstant() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/sizeLiteralConstant.kt"); - } - - @TestMetadata("sizeVariable.kt") - public void testSizeVariable() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/sizeVariable.kt"); - } - - @TestMetadata("thisReceiver.kt") - public void testThisReceiver() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/thisReceiver.kt"); - } - - @TestMetadata("thisReceiverFor.kt") - public void testThisReceiverFor() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/thisReceiverFor.kt"); - } - - @TestMetadata("thisReceiverRangeUntil.kt") - public void testThisReceiverRangeUntil() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/thisReceiverRangeUntil.kt"); - } - - @TestMetadata("thisReceiverUntil.kt") - public void testThisReceiverUntil() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/thisReceiverUntil.kt"); - } - - @TestMetadata("typeMismatch.kt") - public void testTypeMismatch() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/typeMismatch.kt"); - } - - @TestMetadata("usedForOtherArray.kt") - public void testUsedForOtherArray() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/usedForOtherArray.kt"); - } - - @TestMetadata("withIndexBasic.kt") - public void testWithIndexBasic() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/withIndexBasic.kt"); - } - - @TestMetadata("withIndexElementNameCollision.kt") - public void testWithIndexElementNameCollision() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/withIndexElementNameCollision.kt"); - } - - @TestMetadata("withIndexMultipleArrayAccess.kt") - public void testWithIndexMultipleArrayAccess() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/withIndexMultipleArrayAccess.kt"); - } - - @TestMetadata("withIndexRangeTo.kt") - public void testWithIndexRangeTo() throws Exception { - runTest("testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/withIndexRangeTo.kt"); - } - } - @RunWith(JUnit3RunnerWithInners.class) @TestMetadata("testData/inspectionsLocal/replaceNegatedIsEmptyWithIsNotEmpty") public static class ReplaceNegatedIsEmptyWithIsNotEmpty extends AbstractK1LocalInspectionTest { diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollision.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollision.kt index 12003f534a42..bcb41b9abe9e 100644 --- a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollision.kt +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollision.kt @@ -1,6 +1,5 @@ // WITH_STDLIB // FIX: Replace with loop over elements -// IGNORE_K1 fun test() { val element = mutableListOf("hello", "world") for (i in 0 until element.size) { diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollision.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollision.kt.after index b0302ff9adf3..6ec27cb530ac 100644 --- a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollision.kt.after +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollision.kt.after @@ -1,6 +1,5 @@ // WITH_STDLIB // FIX: Replace with loop over elements -// IGNORE_K1 fun test() { val element = mutableListOf("hello", "world") for (element1 in element) { diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollisionMultiple.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollisionMultiple.kt index 441f9c135da6..beda47344581 100644 --- a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollisionMultiple.kt +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollisionMultiple.kt @@ -1,6 +1,5 @@ // WITH_STDLIB // FIX: Replace with loop over elements -// IGNORE_K1 fun test() { val element = "first" val element1 = "second" diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollisionMultiple.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollisionMultiple.kt.after index 561f68642c6d..b716fd14761d 100644 --- a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollisionMultiple.kt.after +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollisionMultiple.kt.after @@ -1,6 +1,5 @@ // WITH_STDLIB // FIX: Replace with loop over elements -// IGNORE_K1 fun test() { val element = "first" val element1 = "second" diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollisionNestedLoop.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollisionNestedLoop.kt index 21e8862277e0..91d42ab21957 100644 --- a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollisionNestedLoop.kt +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollisionNestedLoop.kt @@ -1,6 +1,5 @@ // WITH_STDLIB // FIX: Replace with loop over elements -// IGNORE_K1 fun test() { val outer = listOf(listOf("a", "b"), listOf("c", "d")) for (element in outer) { diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollisionNestedLoop.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollisionNestedLoop.kt.after index 94cfc3542eab..ebdbd189a235 100644 --- a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollisionNestedLoop.kt.after +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollisionNestedLoop.kt.after @@ -1,6 +1,5 @@ // WITH_STDLIB // FIX: Replace with loop over elements -// IGNORE_K1 fun test() { val outer = listOf(listOf("a", "b"), listOf("c", "d")) for (element in outer) { diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollisionParameter.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollisionParameter.kt index 0ed400f8b8ab..6161572e54a1 100644 --- a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollisionParameter.kt +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollisionParameter.kt @@ -1,6 +1,5 @@ // WITH_STDLIB // FIX: Replace with loop over elements -// IGNORE_K1 fun test(element: String, list: List) { for (i in 0 until list.size) { list[i].length diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollisionParameter.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollisionParameter.kt.after index 24c5ea1e9af9..8ff550cd89f7 100644 --- a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollisionParameter.kt.after +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/elementNameCollisionParameter.kt.after @@ -1,6 +1,5 @@ // WITH_STDLIB // FIX: Replace with loop over elements -// IGNORE_K1 fun test(element: String, list: List) { for (element1 in list) { element1.length diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/qualifiedReceiverDifferentCollection.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/qualifiedReceiverDifferentCollection.kt new file mode 100644 index 000000000000..425b4d6a9a09 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/qualifiedReceiverDifferentCollection.kt @@ -0,0 +1,12 @@ +// WITH_STDLIB +// FIX: Replace with indices +// NO_FIX: Replace index loop with collection loop +private class RC(val a: List, val b: List) + +fun test() { + val rc = RC(a = listOf(1), b = listOf(2)) + + for (i in 0 until rc.a.size) { + println(rc.a[i] != rc.b[i]) + } +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/qualifiedReceiverDifferentCollection.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/qualifiedReceiverDifferentCollection.kt.after new file mode 100644 index 000000000000..f27fe4620477 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/qualifiedReceiverDifferentCollection.kt.after @@ -0,0 +1,12 @@ +// WITH_STDLIB +// FIX: Replace with indices +// NO_FIX: Replace index loop with collection loop +private class RC(val a: List, val b: List) + +fun test() { + val rc = RC(a = listOf(1), b = listOf(2)) + + for (i in rc.a.indices) { + println(rc.a[i] != rc.b[i]) + } +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/withIndexElementNameCollision.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/withIndexElementNameCollision.kt index 479b9c11f48a..59a7cba4af07 100644 --- a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/withIndexElementNameCollision.kt +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/withIndexElementNameCollision.kt @@ -1,6 +1,5 @@ // WITH_STDLIB // FIX: Replace with 'withIndex()' -// IGNORE_K1 fun test() { val element = "existing" val list = listOf("a", "b", "c") diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/withIndexElementNameCollision.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/withIndexElementNameCollision.kt.after index 05e382c65a55..024f464ebaba 100644 --- a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/withIndexElementNameCollision.kt.after +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceManualRangeWithIndicesCalls/withIndexElementNameCollision.kt.after @@ -1,6 +1,5 @@ // WITH_STDLIB // FIX: Replace with 'withIndex()' -// IGNORE_K1 fun test() { val element = "existing" val list = listOf("a", "b", "c") diff --git a/plugins/kotlin/util/test-generator-fe10/test/org/jetbrains/kotlin/fe10/testGenerator/Fe10GenerateTests.kt b/plugins/kotlin/util/test-generator-fe10/test/org/jetbrains/kotlin/fe10/testGenerator/Fe10GenerateTests.kt index fc11d5733de6..1474e758c26e 100644 --- a/plugins/kotlin/util/test-generator-fe10/test/org/jetbrains/kotlin/fe10/testGenerator/Fe10GenerateTests.kt +++ b/plugins/kotlin/util/test-generator-fe10/test/org/jetbrains/kotlin/fe10/testGenerator/Fe10GenerateTests.kt @@ -836,6 +836,7 @@ private fun assembleWorkspace(): TWorkspace = workspace(KotlinPluginMode.K1) { "convertFromMultiDollarToRegularString", // K2-only "javaCollectionsWithNullableTypes", // K2-only "kdocResolutionResultHasChanged", // K2-only + "replaceManualRangeWithIndicesCalls", // K2-only "convertLongToDuration", // K2-only "customComponentDestructuringMigration", // K2-only )