diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/sequence/FilterTransformation.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/sequence/FilterTransformation.kt index 430071d8fef..3e9b51d9328 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/sequence/FilterTransformation.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/sequence/FilterTransformation.kt @@ -118,31 +118,39 @@ abstract class FilterTransformationBase : SequenceTransformation { conditions: List, restStatements: List ): List { - //TODO: indexVariable case - if (conditions.size == 1) { return createFilterTransformation(loop, inputVariable, indexVariable, conditions.single()).singletonList() } - val transformations = ArrayList() - for (condition in conditions) { - val transformation = createFilterTransformation(loop, inputVariable, indexVariable, condition) + var transformations = conditions.map { createFilterTransformation(loop, inputVariable, indexVariable, it) } + + val resultTransformations = ArrayList() + + val lastUseOfIndex = transformations.lastOrNull { it.indexVariable != null } + if (lastUseOfIndex != null) { + val index = transformations.indexOf(lastUseOfIndex) + val condition = CompositeCondition.create(conditions.take(index + 1)) + resultTransformations.add(createFilterTransformation(loop, inputVariable, indexVariable, condition)) + transformations = transformations.drop(index + 1) + } + + for ((transformation, condition) in transformations.zip(conditions)) { if (transformation !is FilterTransformation && isSmartCastUsed(inputVariable, restStatements)) { // filterIsInstance of filterNotNull - transformations.add(transformation) + resultTransformations.add(transformation) } else { - val prevFilter = transformations.lastOrNull() as? FilterTransformation + val prevFilter = resultTransformations.lastOrNull() as? FilterTransformation if (prevFilter != null) { val mergedCondition = CompositeCondition.create(prevFilter.effectiveCondition.toAtomicConditions() + transformation.effectiveCondition.toAtomicConditions()) val mergedTransformation = createFilterTransformation(loop, inputVariable, indexVariable, mergedCondition, onlyFilterOrFilterNot = true) - transformations[transformations.lastIndex] = mergedTransformation + resultTransformations[resultTransformations.lastIndex] = mergedTransformation } else { - transformations.add(createFilterTransformation(loop, inputVariable, indexVariable, condition, onlyFilterOrFilterNot = true)) + resultTransformations.add(createFilterTransformation(loop, inputVariable, indexVariable, condition, onlyFilterOrFilterNot = true)) } } } - return transformations + return resultTransformations } private fun matchOneTransformation(state: MatchingState): Pair? { diff --git a/idea/testData/intentions/loopToCallChain/filter/cannotSplitOutFilterIsInstance.kt b/idea/testData/intentions/loopToCallChain/filter/cannotSplitOutFilterIsInstance.kt new file mode 100644 index 00000000000..f64dd30ccad --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/filter/cannotSplitOutFilterIsInstance.kt @@ -0,0 +1,9 @@ +// WITH_RUNTIME +// IS_APPLICABLE: false +// IS_APPLICABLE_2: false +fun foo(list: List, out: MutableList){ + for ((i, any) in list.withIndex()) { + if (any is String && i % 2 == 0) + out.add(any) + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTest2Generated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTest2Generated.java index 7a7d7d31d26..1e820f52af0 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTest2Generated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTest2Generated.java @@ -370,6 +370,12 @@ public class IntentionTest2Generated extends AbstractIntentionTest2 { doTest(fileName); } + @TestMetadata("cannotSplitOutFilterIsInstance.kt") + public void testCannotSplitOutFilterIsInstance() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/filter/cannotSplitOutFilterIsInstance.kt"); + doTest(fileName); + } + @TestMetadata("doNotSplitOutFilterIsInstance.kt") public void testDoNotSplitOutFilterIsInstance() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/filter/doNotSplitOutFilterIsInstance.kt"); diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java index 6e7770f4a53..9fbbd284435 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -8278,6 +8278,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest { doTest(fileName); } + @TestMetadata("cannotSplitOutFilterIsInstance.kt") + public void testCannotSplitOutFilterIsInstance() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/filter/cannotSplitOutFilterIsInstance.kt"); + doTest(fileName); + } + @TestMetadata("doNotSplitOutFilterIsInstance.kt") public void testDoNotSplitOutFilterIsInstance() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/filter/doNotSplitOutFilterIsInstance.kt");