From aa6240a0c50c14da9e60512ceac17b7e98d8cf67 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Fri, 22 Apr 2016 12:56:25 +0300 Subject: [PATCH] Do not generate redundant .toList() --- .../result/AddToCollectionTransformation.kt | 2 +- .../sequence/FilterTransformation.kt | 25 ++++++++++++++++--- .../loopToCallChain/assignFilterIndexed.kt | 13 ++++++++++ .../assignFilterIndexed.kt.after | 8 ++++++ .../loopToCallChain/assignFilterNotNull.kt | 13 ++++++++++ .../assignFilterNotNull.kt.after | 8 ++++++ .../intentions/loopToCallChain/assignMap2.kt | 14 +++++++++++ .../loopToCallChain/assignMap2.kt.after | 10 ++++++++ 8 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 idea/testData/intentions/loopToCallChain/assignFilterIndexed.kt create mode 100644 idea/testData/intentions/loopToCallChain/assignFilterIndexed.kt.after create mode 100644 idea/testData/intentions/loopToCallChain/assignFilterNotNull.kt create mode 100644 idea/testData/intentions/loopToCallChain/assignFilterNotNull.kt.after create mode 100644 idea/testData/intentions/loopToCallChain/assignMap2.kt create mode 100644 idea/testData/intentions/loopToCallChain/assignMap2.kt.after diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/result/AddToCollectionTransformation.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/result/AddToCollectionTransformation.kt index 5eeeab60db0..e9cbf9f954c 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/result/AddToCollectionTransformation.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/result/AddToCollectionTransformation.kt @@ -378,7 +378,7 @@ class AssignToListTransformation( get() = "toList()" override fun mergeWithPrevious(previousTransformation: SequenceTransformation): ResultTransformation? { - if (previousTransformation !is FilterTransformation) return null + //TODO: can be any SequenceTransformation's that return not List? Also this code needs to be changed when .asSequence() used return AssignSequenceTransformationResultTransformation(previousTransformation, initialization) } 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 03354af1d86..220ef6443d5 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 @@ -76,6 +76,22 @@ class FilterTransformation( */ object Matcher : SequenceTransformationMatcher { override fun match(state: MatchingState): SequenceTransformationMatch? { + var (transformation, currentState) = matchOneTransformation(state, takeWhileAllowed = true) ?: return null + +/* + if (transformation is FilterTransformation || transformation is FilterIndexedTransformation) { + while (true) { + val (nextTransformation, nextState) = matchOneTransformation(currentState, takeWhileAllowed = false) ?: break + if (nextTransformation !is FilterTransformation && nextTransformation !is FilterIndexedTransformation) break + + } + } +*/ + + return SequenceTransformationMatch(transformation, currentState) + } + + private fun matchOneTransformation(state: MatchingState, takeWhileAllowed: Boolean): Pair? { val ifStatement = state.statements.firstOrNull() as? KtIfExpression ?: return null if (ifStatement.`else` != null) return null val condition = ifStatement.condition ?: return null @@ -84,7 +100,7 @@ class FilterTransformation( if (state.statements.size == 1) { val transformation = createFilterTransformation(state.outerLoop, state.inputVariable, state.indexVariable, condition, isInverse = false) val newState = state.copy(statements = listOf(then)) - return SequenceTransformationMatch(transformation, newState) + return transformation to newState } else { val statement = then.blockExpressionsOrSingle().singleOrNull() ?: return null @@ -93,14 +109,15 @@ class FilterTransformation( if (statement.targetLoop() != state.innerLoop) return null val transformation = createFilterTransformation(state.outerLoop, state.inputVariable, state.indexVariable, condition, isInverse = true) val newState = state.copy(statements = state.statements.drop(1)) - return SequenceTransformationMatch(transformation, newState) + return transformation to newState } is KtBreakExpression -> { + if (!takeWhileAllowed) return null if (statement.targetLoop() != state.outerLoop) return null val transformation = TakeWhileTransformation(state.outerLoop, state.inputVariable, condition.negate()) val newState = state.copy(statements = state.statements.drop(1)) - return SequenceTransformationMatch(transformation, newState) + return transformation to newState } else -> return null @@ -108,6 +125,8 @@ class FilterTransformation( } } +// private fun mergeFilterTransformations(transformation1: ) + //TODO: choose filter or filterNot depending on condition private fun createFilterTransformation( loop: KtForExpression, diff --git a/idea/testData/intentions/loopToCallChain/assignFilterIndexed.kt b/idea/testData/intentions/loopToCallChain/assignFilterIndexed.kt new file mode 100644 index 00000000000..76cce2dce41 --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/assignFilterIndexed.kt @@ -0,0 +1,13 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'filterIndexed{}'" +import java.util.* + +fun foo(list: List): List { + val result = ArrayList() + for ((index, s) in list.withIndex()) { + if (s.length > index) { + result.add(s) + } + } + return result +} \ No newline at end of file diff --git a/idea/testData/intentions/loopToCallChain/assignFilterIndexed.kt.after b/idea/testData/intentions/loopToCallChain/assignFilterIndexed.kt.after new file mode 100644 index 00000000000..dd48aea7ed4 --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/assignFilterIndexed.kt.after @@ -0,0 +1,8 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'filterIndexed{}'" +import java.util.* + +fun foo(list: List): List { + val result = list.filterIndexed { index, s -> s.length > index } + return result +} \ No newline at end of file diff --git a/idea/testData/intentions/loopToCallChain/assignFilterNotNull.kt b/idea/testData/intentions/loopToCallChain/assignFilterNotNull.kt new file mode 100644 index 00000000000..d91c9a99081 --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/assignFilterNotNull.kt @@ -0,0 +1,13 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'filterNotNull()'" +import java.util.ArrayList + +fun foo(list: List): List { + val result = ArrayList() + for (s in list) { + if (s != null) { + result.add(s) + } + } + return result +} \ No newline at end of file diff --git a/idea/testData/intentions/loopToCallChain/assignFilterNotNull.kt.after b/idea/testData/intentions/loopToCallChain/assignFilterNotNull.kt.after new file mode 100644 index 00000000000..109da40f98c --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/assignFilterNotNull.kt.after @@ -0,0 +1,8 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'filterNotNull()'" +import java.util.ArrayList + +fun foo(list: List): List { + val result = list.filterNotNull() + return result +} \ No newline at end of file diff --git a/idea/testData/intentions/loopToCallChain/assignMap2.kt b/idea/testData/intentions/loopToCallChain/assignMap2.kt new file mode 100644 index 00000000000..742c1638eab --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/assignMap2.kt @@ -0,0 +1,14 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'filter{}.map{}'" +import java.util.ArrayList + +fun foo(list: List): List { + val result = ArrayList() + for (s in list) { + if (s.length > 0) { + val h = s.hashCode() + result.add(h) + } + } + return result +} \ No newline at end of file diff --git a/idea/testData/intentions/loopToCallChain/assignMap2.kt.after b/idea/testData/intentions/loopToCallChain/assignMap2.kt.after new file mode 100644 index 00000000000..6caa3c1905a --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/assignMap2.kt.after @@ -0,0 +1,10 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'filter{}.map{}'" +import java.util.ArrayList + +fun foo(list: List): List { + val result = list + .filter { it.length > 0 } + .map { it.hashCode() } + return result +} \ No newline at end of file