Supported forEach
This commit is contained in:
@@ -101,7 +101,8 @@ data class MatchingState(
|
|||||||
* Matchers can assume that indexVariable is null if it's not used in the rest of the loop
|
* Matchers can assume that indexVariable is null if it's not used in the rest of the loop
|
||||||
*/
|
*/
|
||||||
val indexVariable: KtCallableDeclaration?,
|
val indexVariable: KtCallableDeclaration?,
|
||||||
val initializationStatementsToDelete: Collection<KtExpression> = emptyList()
|
val initializationStatementsToDelete: Collection<KtExpression> = emptyList(),
|
||||||
|
val previousTransformations: List<SequenceTransformation>
|
||||||
)
|
)
|
||||||
|
|
||||||
interface TransformationMatcher {
|
interface TransformationMatcher {
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
|||||||
import org.jetbrains.kotlin.idea.intentions.loopToCallChain.result.AddToCollectionTransformation
|
import org.jetbrains.kotlin.idea.intentions.loopToCallChain.result.AddToCollectionTransformation
|
||||||
import org.jetbrains.kotlin.idea.intentions.loopToCallChain.result.CountTransformation
|
import org.jetbrains.kotlin.idea.intentions.loopToCallChain.result.CountTransformation
|
||||||
import org.jetbrains.kotlin.idea.intentions.loopToCallChain.result.FindTransformationMatcher
|
import org.jetbrains.kotlin.idea.intentions.loopToCallChain.result.FindTransformationMatcher
|
||||||
|
import org.jetbrains.kotlin.idea.intentions.loopToCallChain.result.ForEachTransformation
|
||||||
import org.jetbrains.kotlin.idea.intentions.loopToCallChain.sequence.FilterTransformation
|
import org.jetbrains.kotlin.idea.intentions.loopToCallChain.sequence.FilterTransformation
|
||||||
import org.jetbrains.kotlin.idea.intentions.loopToCallChain.sequence.FlatMapTransformation
|
import org.jetbrains.kotlin.idea.intentions.loopToCallChain.sequence.FlatMapTransformation
|
||||||
import org.jetbrains.kotlin.idea.intentions.loopToCallChain.sequence.IntroduceIndexMatcher
|
import org.jetbrains.kotlin.idea.intentions.loopToCallChain.sequence.IntroduceIndexMatcher
|
||||||
@@ -52,7 +53,8 @@ object MatcherRegistrar {
|
|||||||
IntroduceIndexMatcher,
|
IntroduceIndexMatcher,
|
||||||
FilterTransformation.Matcher,
|
FilterTransformation.Matcher,
|
||||||
MapTransformation.Matcher,
|
MapTransformation.Matcher,
|
||||||
FlatMapTransformation.Matcher
|
FlatMapTransformation.Matcher,
|
||||||
|
ForEachTransformation.Matcher
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,7 +76,8 @@ fun match(loop: KtForExpression): MatchResult? {
|
|||||||
innerLoop = loop,
|
innerLoop = loop,
|
||||||
statements = listOf(loop.body ?: return null),
|
statements = listOf(loop.body ?: return null),
|
||||||
inputVariable = inputVariable,
|
inputVariable = inputVariable,
|
||||||
indexVariable = indexVariable
|
indexVariable = indexVariable,
|
||||||
|
previousTransformations = sequenceTransformations
|
||||||
)
|
)
|
||||||
|
|
||||||
MatchLoop@
|
MatchLoop@
|
||||||
|
|||||||
+57
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.intentions.loopToCallChain.result
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.idea.intentions.loopToCallChain.*
|
||||||
|
import org.jetbrains.kotlin.psi.KtCallableDeclaration
|
||||||
|
import org.jetbrains.kotlin.psi.KtExpression
|
||||||
|
import org.jetbrains.kotlin.psi.KtForExpression
|
||||||
|
|
||||||
|
class ForEachTransformation(
|
||||||
|
loop: KtForExpression,
|
||||||
|
private val inputVariable: KtCallableDeclaration,
|
||||||
|
private val statement: KtExpression
|
||||||
|
) : ReplaceLoopResultTransformation(loop) {
|
||||||
|
|
||||||
|
override val presentation: String
|
||||||
|
get() = "forEach{}"
|
||||||
|
|
||||||
|
override fun generateCode(chainedCallGenerator: ChainedCallGenerator): KtExpression {
|
||||||
|
val lambda = generateLambda(inputVariable, statement)
|
||||||
|
return chainedCallGenerator.generate("forEach $0:'{}'", lambda)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Matches:
|
||||||
|
* for (...) {
|
||||||
|
* ...
|
||||||
|
* <statement>
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
object Matcher : TransformationMatcher {
|
||||||
|
override val indexVariableAllowed: Boolean
|
||||||
|
get() = false //TODO: support forEachIndexed
|
||||||
|
|
||||||
|
override fun match(state: MatchingState): TransformationMatch.Result? {
|
||||||
|
if (state.previousTransformations.isEmpty()) return null // do not suggest conversion to just ".forEach{}"
|
||||||
|
|
||||||
|
val statement = state.statements.singleOrNull() ?: return null
|
||||||
|
val transformation = ForEachTransformation(state.outerLoop, state.inputVariable, statement)
|
||||||
|
return TransformationMatch.Result(transformation)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// IS_APPLICABLE: false
|
|
||||||
fun foo(list: List<String?>): String? {
|
fun foo(list: List<String?>): String? {
|
||||||
<caret>for (s in list) {
|
<caret>for (s in list) {
|
||||||
if (s == null || s.isNotEmpty()) {
|
if (s == null || s.isNotEmpty()) {
|
||||||
|
|||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
fun foo(list: List<String?>): String? {
|
||||||
|
list
|
||||||
|
.filter { it == null || it.isNotEmpty() }
|
||||||
|
.forEach { return it }
|
||||||
|
return ""
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// INTENTION_TEXT: "Replace with 'filter{}.forEach{}'"
|
||||||
|
fun foo(list: List<String>) {
|
||||||
|
<caret>for (s in list) {
|
||||||
|
if (s.isNotBlank()) {
|
||||||
|
println(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// INTENTION_TEXT: "Replace with 'filter{}.forEach{}'"
|
||||||
|
fun foo(list: List<String>) {
|
||||||
|
list
|
||||||
|
.filter { it.isNotBlank() }
|
||||||
|
.forEach { println(it) }
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// IS_APPLICABLE: false
|
||||||
|
fun foo(list: List<String>) {
|
||||||
|
<caret>for (s in list) {
|
||||||
|
println(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// IS_APPLICABLE: false
|
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
|
|
||||||
fun foo(list: List<String>): List<Int> {
|
fun foo(list: List<String>): List<Int> {
|
||||||
|
|||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
import java.util.ArrayList
|
||||||
|
|
||||||
|
fun foo(list: List<String>): List<Int> {
|
||||||
|
val result = ArrayList<Int>()
|
||||||
|
list
|
||||||
|
.filter { it.length > result.size }
|
||||||
|
.forEach { result.add(it.hashCode()) }
|
||||||
|
return result
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user