From 4094d77782028a48ab15ca478387bac65c936d43 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Wed, 11 May 2016 22:52:46 +0300 Subject: [PATCH] Supported forEachIndexed --- .../result/ForEachTransformation.kt | 18 ++++++++++++------ .../loopToCallChain/forEachIndexed.kt | 8 ++++++++ .../loopToCallChain/forEachIndexed.kt.after | 7 +++++++ .../forEachIndexed_nothingElse.kt | 7 +++++++ .../forEachIndexed_nothingElse.kt.after | 5 +++++ .../loopToCallChain/forEach_notIndexed.kt | 8 ++++++++ .../forEach_notIndexed.kt.after | 7 +++++++ 7 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 idea/testData/intentions/loopToCallChain/forEachIndexed.kt create mode 100644 idea/testData/intentions/loopToCallChain/forEachIndexed.kt.after create mode 100644 idea/testData/intentions/loopToCallChain/forEachIndexed_nothingElse.kt create mode 100644 idea/testData/intentions/loopToCallChain/forEachIndexed_nothingElse.kt.after create mode 100644 idea/testData/intentions/loopToCallChain/forEach_notIndexed.kt create mode 100644 idea/testData/intentions/loopToCallChain/forEach_notIndexed.kt.after diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/result/ForEachTransformation.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/result/ForEachTransformation.kt index 53d44301450..bee6fbf43f7 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/result/ForEachTransformation.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/result/ForEachTransformation.kt @@ -24,15 +24,21 @@ import org.jetbrains.kotlin.psi.KtForExpression class ForEachTransformation( loop: KtForExpression, private val inputVariable: KtCallableDeclaration, + private val indexVariable: KtCallableDeclaration?, private val statement: KtExpression ) : ReplaceLoopResultTransformation(loop) { + private val functionName = if (indexVariable != null) "forEachIndexed" else "forEach" + override val presentation: String - get() = "forEach{}" + get() = functionName + "{}" override fun generateCode(chainedCallGenerator: ChainedCallGenerator): KtExpression { - val lambda = generateLambda(inputVariable, statement) - return chainedCallGenerator.generate("forEach $0:'{}'", lambda) + val lambda = if (indexVariable != null) + generateLambda(statement, indexVariable, inputVariable) + else + generateLambda(inputVariable, statement) + return chainedCallGenerator.generate("$functionName $0:'{}'", lambda) } /** @@ -44,13 +50,13 @@ class ForEachTransformation( */ object Matcher : TransformationMatcher { override val indexVariableAllowed: Boolean - get() = false //TODO: support forEachIndexed + get() = true override fun match(state: MatchingState): TransformationMatch.Result? { - if (state.previousTransformations.isEmpty()) return null // do not suggest conversion to just ".forEach{}" + if (state.previousTransformations.isEmpty() && state.indexVariable == null) return null // do not suggest conversion to just ".forEach{}" val statement = state.statements.singleOrNull() ?: return null - val transformation = ForEachTransformation(state.outerLoop, state.inputVariable, statement) + val transformation = ForEachTransformation(state.outerLoop, state.inputVariable, state.indexVariable, statement) return TransformationMatch.Result(transformation) } } diff --git a/idea/testData/intentions/loopToCallChain/forEachIndexed.kt b/idea/testData/intentions/loopToCallChain/forEachIndexed.kt new file mode 100644 index 00000000000..a5b20ba620e --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/forEachIndexed.kt @@ -0,0 +1,8 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'map{}.forEachIndexed{}'" +fun foo(list: List) { + for ((index, s) in list.withIndex()) { + val s1 = s.substring(1) + println(s1.hashCode() * index) + } +} \ No newline at end of file diff --git a/idea/testData/intentions/loopToCallChain/forEachIndexed.kt.after b/idea/testData/intentions/loopToCallChain/forEachIndexed.kt.after new file mode 100644 index 00000000000..2a9320a2ff2 --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/forEachIndexed.kt.after @@ -0,0 +1,7 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'map{}.forEachIndexed{}'" +fun foo(list: List) { + list + .map { it.substring(1) } + .forEachIndexed { index, s1 -> println(s1.hashCode() * index) } +} \ No newline at end of file diff --git a/idea/testData/intentions/loopToCallChain/forEachIndexed_nothingElse.kt b/idea/testData/intentions/loopToCallChain/forEachIndexed_nothingElse.kt new file mode 100644 index 00000000000..0562dc78f1a --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/forEachIndexed_nothingElse.kt @@ -0,0 +1,7 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'forEachIndexed{}'" +fun foo(list: List) { + for ((index, s) in list.withIndex()) { + println(s.hashCode() * index) + } +} \ No newline at end of file diff --git a/idea/testData/intentions/loopToCallChain/forEachIndexed_nothingElse.kt.after b/idea/testData/intentions/loopToCallChain/forEachIndexed_nothingElse.kt.after new file mode 100644 index 00000000000..5c0035f31ff --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/forEachIndexed_nothingElse.kt.after @@ -0,0 +1,5 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'forEachIndexed{}'" +fun foo(list: List) { + list.forEachIndexed { index, s -> println(s.hashCode() * index) } +} \ No newline at end of file diff --git a/idea/testData/intentions/loopToCallChain/forEach_notIndexed.kt b/idea/testData/intentions/loopToCallChain/forEach_notIndexed.kt new file mode 100644 index 00000000000..9c569378d4d --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/forEach_notIndexed.kt @@ -0,0 +1,8 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'mapIndexed{}.forEach{}'" +fun foo(list: List) { + for ((index, s) in list.withIndex()) { + val x = s.length * index + println(x) + } +} \ No newline at end of file diff --git a/idea/testData/intentions/loopToCallChain/forEach_notIndexed.kt.after b/idea/testData/intentions/loopToCallChain/forEach_notIndexed.kt.after new file mode 100644 index 00000000000..37fef4d3e70 --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/forEach_notIndexed.kt.after @@ -0,0 +1,7 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'mapIndexed{}.forEach{}'" +fun foo(list: List) { + list + .mapIndexed { index, s -> s.length * index } + .forEach { println(it) } +} \ No newline at end of file