Don't generate .forEach { return } when converting loop to call chain
#KT-17161 Fixed
This commit is contained in:
+2
-4
@@ -20,10 +20,7 @@ import org.jetbrains.kotlin.idea.intentions.loopToCallChain.*
|
||||
import org.jetbrains.kotlin.idea.references.ReferenceAccess
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.idea.references.readWriteAccess
|
||||
import org.jetbrains.kotlin.psi.KtCallableDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtForExpression
|
||||
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelector
|
||||
|
||||
@@ -62,6 +59,7 @@ class ForEachTransformation(
|
||||
if (state.previousTransformations.isEmpty()) return null // do not suggest conversion to just ".forEach{}" or ".forEachIndexed{}"
|
||||
|
||||
val statement = state.statements.singleOrNull() ?: return null
|
||||
if (statement is KtReturnExpression) return null
|
||||
|
||||
if (!state.lazySequence) {
|
||||
// check if it changes any variable that has other usages in the loop - then only lazy sequence is correct
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with 'filter{}.forEach{}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence().filter{}.forEach{}'"
|
||||
// IS_APPLICABLE: false
|
||||
// IS_APPLICABLE_2: false
|
||||
fun foo(list: List<String?>): String? {
|
||||
<caret>for (s in list) {
|
||||
if (s == null || s.isNotEmpty()) {
|
||||
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with 'filter{}.forEach{}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence().filter{}.forEach{}'"
|
||||
fun foo(list: List<String?>): String? {
|
||||
list
|
||||
.filter { it == null || it.isNotEmpty() }
|
||||
.forEach { return it }
|
||||
return ""
|
||||
}
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with 'filter{}.forEach{}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence().filter{}.forEach{}'"
|
||||
fun foo(list: List<String?>): String? {
|
||||
list
|
||||
.asSequence()
|
||||
.filter { it == null || it.isNotEmpty() }
|
||||
.forEach { return it }
|
||||
return ""
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// WITH_RUNTIME
|
||||
// IS_APPLICABLE: false
|
||||
// IS_APPLICABLE_2: false
|
||||
fun foo(l: List<() -> Boolean>) {
|
||||
<caret>for (i in 0 until l.size) {
|
||||
if (l[i]()) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -860,6 +860,12 @@ public class IntentionTest2Generated extends AbstractIntentionTest2 {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("KT21083.kt")
|
||||
public void testKT21083() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/forEach/KT21083.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("notAvailable.kt")
|
||||
public void testNotAvailable() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/forEach/notAvailable.kt");
|
||||
|
||||
@@ -10771,6 +10771,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("KT21083.kt")
|
||||
public void testKT21083() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/forEach/KT21083.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("notAvailable.kt")
|
||||
public void testNotAvailable() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/forEach/notAvailable.kt");
|
||||
|
||||
Reference in New Issue
Block a user