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.ReferenceAccess
|
||||||
import org.jetbrains.kotlin.idea.references.mainReference
|
import org.jetbrains.kotlin.idea.references.mainReference
|
||||||
import org.jetbrains.kotlin.idea.references.readWriteAccess
|
import org.jetbrains.kotlin.idea.references.readWriteAccess
|
||||||
import org.jetbrains.kotlin.psi.KtCallableDeclaration
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.KtExpression
|
|
||||||
import org.jetbrains.kotlin.psi.KtForExpression
|
|
||||||
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
|
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelector
|
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{}"
|
if (state.previousTransformations.isEmpty()) return null // do not suggest conversion to just ".forEach{}" or ".forEachIndexed{}"
|
||||||
|
|
||||||
val statement = state.statements.singleOrNull() ?: return null
|
val statement = state.statements.singleOrNull() ?: return null
|
||||||
|
if (statement is KtReturnExpression) return null
|
||||||
|
|
||||||
if (!state.lazySequence) {
|
if (!state.lazySequence) {
|
||||||
// check if it changes any variable that has other usages in the loop - then only lazy sequence is correct
|
// 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
|
// WITH_RUNTIME
|
||||||
// INTENTION_TEXT: "Replace with 'filter{}.forEach{}'"
|
// IS_APPLICABLE: false
|
||||||
// INTENTION_TEXT_2: "Replace with 'asSequence().filter{}.forEach{}'"
|
// IS_APPLICABLE_2: 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()) {
|
||||||
|
|||||||
-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);
|
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")
|
@TestMetadata("notAvailable.kt")
|
||||||
public void testNotAvailable() throws Exception {
|
public void testNotAvailable() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/forEach/notAvailable.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/forEach/notAvailable.kt");
|
||||||
|
|||||||
@@ -10771,6 +10771,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("notAvailable.kt")
|
||||||
public void testNotAvailable() throws Exception {
|
public void testNotAvailable() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/forEach/notAvailable.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/forEach/notAvailable.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user