diff --git a/idea/resources/intentionDescriptions/RemoveLabeledReturnInLambdaIntention/after.kt.template b/idea/resources/intentionDescriptions/RemoveLabeledReturnInLambdaIntention/after.kt.template
new file mode 100644
index 00000000000..51551a0d780
--- /dev/null
+++ b/idea/resources/intentionDescriptions/RemoveLabeledReturnInLambdaIntention/after.kt.template
@@ -0,0 +1,5 @@
+fun foo() {
+ listOf(1,2,3).find {
+ true
+ }
+}
\ No newline at end of file
diff --git a/idea/resources/intentionDescriptions/RemoveLabeledReturnInLambdaIntention/before.kt.template b/idea/resources/intentionDescriptions/RemoveLabeledReturnInLambdaIntention/before.kt.template
new file mode 100644
index 00000000000..f0f1216fc33
--- /dev/null
+++ b/idea/resources/intentionDescriptions/RemoveLabeledReturnInLambdaIntention/before.kt.template
@@ -0,0 +1,5 @@
+fun foo() {
+ listOf(1,2,3).find {
+ return@find true
+ }
+}
\ No newline at end of file
diff --git a/idea/resources/intentionDescriptions/RemoveLabeledReturnInLambdaIntention/description.html b/idea/resources/intentionDescriptions/RemoveLabeledReturnInLambdaIntention/description.html
new file mode 100644
index 00000000000..9d0ed638425
--- /dev/null
+++ b/idea/resources/intentionDescriptions/RemoveLabeledReturnInLambdaIntention/description.html
@@ -0,0 +1,5 @@
+
+
+This intention removes labeled return from last expression in a lambda.
+
+
diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml
index 80eb3a14b39..0b0e7b16f81 100644
--- a/idea/src/META-INF/plugin.xml
+++ b/idea/src/META-INF/plugin.xml
@@ -1557,6 +1557,11 @@
Kotlin
+
+ org.jetbrains.kotlin.idea.intentions.RemoveLabeledReturnInLambdaIntention
+ Kotlin
+
+
(
+ KtReturnExpression::class.java,
+ "Remove labeled return from last expression in a lambda"
+), LowPriorityAction {
+ override fun isApplicableTo(element: KtReturnExpression, caretOffset: Int): Boolean {
+ val labelName = element.getLabelName() ?: return false
+ val block = element.getStrictParentOfType() ?: return false
+ if (block.statements.lastOrNull() != element) return false
+ val callExpression = block.getStrictParentOfType() ?: return false
+ val lambdaArgument = callExpression.lambdaArguments.firstOrNull {
+ val argumentExpression = it.getArgumentExpression()
+ val lambda = when (argumentExpression) {
+ is KtLambdaExpression -> argumentExpression
+ is KtLabeledExpression -> argumentExpression.baseExpression as? KtLambdaExpression
+ else -> null
+ }
+ lambda?.bodyExpression === block
+ } ?: return false
+ val callName = (lambdaArgument.getArgumentExpression() as? KtLabeledExpression)?.getLabelName()
+ ?: callExpression.getCallNameExpression()?.text ?: return false
+ if (labelName != callName) return false
+ text = "Remove return@$labelName"
+ return true
+ }
+
+ override fun applyTo(element: KtReturnExpression, editor: Editor?) {
+ val returnedExpression = element.returnedExpression
+ if (returnedExpression == null) {
+ element.delete()
+ } else {
+ element.replace(returnedExpression)
+ }
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/removeLabeledReturnInLambda/.intention b/idea/testData/intentions/removeLabeledReturnInLambda/.intention
new file mode 100644
index 00000000000..58b806f80fc
--- /dev/null
+++ b/idea/testData/intentions/removeLabeledReturnInLambda/.intention
@@ -0,0 +1 @@
+org.jetbrains.kotlin.idea.intentions.RemoveLabeledReturnInLambdaIntention
\ No newline at end of file
diff --git a/idea/testData/intentions/removeLabeledReturnInLambda/labeledLambda.kt b/idea/testData/intentions/removeLabeledReturnInLambda/labeledLambda.kt
new file mode 100644
index 00000000000..4adb08a05d7
--- /dev/null
+++ b/idea/testData/intentions/removeLabeledReturnInLambda/labeledLambda.kt
@@ -0,0 +1,8 @@
+// WITH_RUNTIME
+// INTENTION_TEXT: "Remove return@label"
+
+fun foo() {
+ listOf(1,2,3).find label@{
+ return@label true
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/removeLabeledReturnInLambda/labeledLambda.kt.after b/idea/testData/intentions/removeLabeledReturnInLambda/labeledLambda.kt.after
new file mode 100644
index 00000000000..9e38c36ca9c
--- /dev/null
+++ b/idea/testData/intentions/removeLabeledReturnInLambda/labeledLambda.kt.after
@@ -0,0 +1,8 @@
+// WITH_RUNTIME
+// INTENTION_TEXT: "Remove return@label"
+
+fun foo() {
+ listOf(1,2,3).find label@{
+ true
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/removeLabeledReturnInLambda/normal.kt b/idea/testData/intentions/removeLabeledReturnInLambda/normal.kt
new file mode 100644
index 00000000000..4770218534f
--- /dev/null
+++ b/idea/testData/intentions/removeLabeledReturnInLambda/normal.kt
@@ -0,0 +1,8 @@
+// WITH_RUNTIME
+// INTENTION_TEXT: "Remove return@find"
+
+fun foo() {
+ listOf(1,2,3).find {
+ return@find true
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/removeLabeledReturnInLambda/normal.kt.after b/idea/testData/intentions/removeLabeledReturnInLambda/normal.kt.after
new file mode 100644
index 00000000000..864641b8452
--- /dev/null
+++ b/idea/testData/intentions/removeLabeledReturnInLambda/normal.kt.after
@@ -0,0 +1,8 @@
+// WITH_RUNTIME
+// INTENTION_TEXT: "Remove return@find"
+
+fun foo() {
+ listOf(1,2,3).find {
+ true
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/removeLabeledReturnInLambda/notInsideLabeled.kt b/idea/testData/intentions/removeLabeledReturnInLambda/notInsideLabeled.kt
new file mode 100644
index 00000000000..910445d4134
--- /dev/null
+++ b/idea/testData/intentions/removeLabeledReturnInLambda/notInsideLabeled.kt
@@ -0,0 +1,6 @@
+// WITH_RUNTIME
+// IS_APPLICABLE: FALSE
+
+fun foo(): Boolean {
+ return@foo true
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/removeLabeledReturnInLambda/notLabeled.kt b/idea/testData/intentions/removeLabeledReturnInLambda/notLabeled.kt
new file mode 100644
index 00000000000..b98d5aa2ba4
--- /dev/null
+++ b/idea/testData/intentions/removeLabeledReturnInLambda/notLabeled.kt
@@ -0,0 +1,9 @@
+// WITH_RUNTIME
+// IS_APPLICABLE: FALSE
+
+fun foo(): Boolean {
+ listOf(1,2,3).find {
+ return true
+ }
+ return false
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/removeLabeledReturnInLambda/notLastLine.kt b/idea/testData/intentions/removeLabeledReturnInLambda/notLastLine.kt
new file mode 100644
index 00000000000..8f4c1d7b098
--- /dev/null
+++ b/idea/testData/intentions/removeLabeledReturnInLambda/notLastLine.kt
@@ -0,0 +1,9 @@
+// WITH_RUNTIME
+// IS_APPLICABLE: FALSE
+
+fun foo() {
+ listOf(1,2,3).find {
+ 1
+ return@find true
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/removeLabeledReturnInLambda/outerLambda.kt b/idea/testData/intentions/removeLabeledReturnInLambda/outerLambda.kt
new file mode 100644
index 00000000000..47beb1f1d36
--- /dev/null
+++ b/idea/testData/intentions/removeLabeledReturnInLambda/outerLambda.kt
@@ -0,0 +1,10 @@
+// WITH_RUNTIME
+// IS_APPLICABLE: FALSE
+
+fun foo() {
+ listOf(1,2,3).forEach {
+ listOf(1,2,3).find {
+ return@forEach
+ }
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/removeLabeledReturnInLambda/unit.kt b/idea/testData/intentions/removeLabeledReturnInLambda/unit.kt
new file mode 100644
index 00000000000..6db30593a83
--- /dev/null
+++ b/idea/testData/intentions/removeLabeledReturnInLambda/unit.kt
@@ -0,0 +1,8 @@
+// WITH_RUNTIME
+// INTENTION_TEXT: "Remove return@forEach"
+
+fun foo() {
+ listOf(1,2,3).forEach {
+ return@forEach
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/removeLabeledReturnInLambda/unit.kt.after b/idea/testData/intentions/removeLabeledReturnInLambda/unit.kt.after
new file mode 100644
index 00000000000..c419f84bf89
--- /dev/null
+++ b/idea/testData/intentions/removeLabeledReturnInLambda/unit.kt.after
@@ -0,0 +1,7 @@
+// WITH_RUNTIME
+// INTENTION_TEXT: "Remove return@forEach"
+
+fun foo() {
+ listOf(1,2,3).forEach {
+ }
+}
\ No newline at end of file
diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java
index 08e4e7d94cc..286e30e6b0d 100644
--- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java
+++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java
@@ -13216,6 +13216,57 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
}
}
+ @TestMetadata("idea/testData/intentions/removeLabeledReturnInLambda")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class RemoveLabeledReturnInLambda extends AbstractIntentionTest {
+ public void testAllFilesPresentInRemoveLabeledReturnInLambda() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/removeLabeledReturnInLambda"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
+ }
+
+ @TestMetadata("labeledLambda.kt")
+ public void testLabeledLambda() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeLabeledReturnInLambda/labeledLambda.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("normal.kt")
+ public void testNormal() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeLabeledReturnInLambda/normal.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("notInsideLabeled.kt")
+ public void testNotInsideLabeled() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeLabeledReturnInLambda/notInsideLabeled.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("notLabeled.kt")
+ public void testNotLabeled() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeLabeledReturnInLambda/notLabeled.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("notLastLine.kt")
+ public void testNotLastLine() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeLabeledReturnInLambda/notLastLine.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("outerLambda.kt")
+ public void testOuterLambda() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeLabeledReturnInLambda/outerLambda.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("unit.kt")
+ public void testUnit() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeLabeledReturnInLambda/unit.kt");
+ doTest(fileName);
+ }
+ }
+
@TestMetadata("idea/testData/intentions/removeRedundantCallsOfConversionMethods")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)