Replace return with 'if'/'when': don't drop return label

#KT-30414 Fixed
This commit is contained in:
Toshiaki Kameyama
2019-03-16 21:41:10 +09:00
committed by Mikhail Glukhikh
parent 9a2178d96b
commit 39016594b1
7 changed files with 63 additions and 5 deletions
@@ -50,16 +50,23 @@ class UnfoldReturnToIfIntention : LowPriorityAction, SelfTargetingRangeIntention
val psiFactory = KtPsiFactory(element)
val context = element.analyze()
newThenExpr.replace(createReturnExpression(thenExpr, psiFactory, context))
newElseExpr.replace(createReturnExpression(elseExpr, psiFactory, context))
val labelName = element.getLabelName()
newThenExpr.replace(createReturnExpression(thenExpr, labelName, psiFactory, context))
newElseExpr.replace(createReturnExpression(elseExpr, labelName, psiFactory, context))
element.replace(newIfExpression)
}
companion object {
fun createReturnExpression(expr: KtExpression, psiFactory: KtPsiFactory, context: BindingContext): KtExpression {
fun createReturnExpression(
expr: KtExpression,
labelName: String?,
psiFactory: KtPsiFactory,
context: BindingContext
): KtExpression {
val label = labelName?.let { "@$it" } ?: ""
val returnText = when (expr) {
is KtBreakExpression, is KtContinueExpression, is KtReturnExpression, is KtThrowExpression -> ""
else -> if (expr.getResolvedCall(context)?.resultingDescriptor?.returnType?.isNothing() == true) "" else "return "
else -> if (expr.getResolvedCall(context)?.resultingDescriptor?.returnType?.isNothing() == true) "" else "return$label "
}
return psiFactory.createExpressionByPattern("$returnText$0", expr)
}
@@ -44,10 +44,11 @@ class UnfoldReturnToWhenIntention : LowPriorityAction, SelfTargetingRangeIntenti
val whenExpression = element.returnedExpression as KtWhenExpression
val newWhenExpression = whenExpression.copied()
val labelName = element.getLabelName()
whenExpression.entries.zip(newWhenExpression.entries).forEach { (entry, newEntry) ->
val expr = entry.expression!!.lastBlockStatementOrThis()
val newExpr = newEntry.expression!!.lastBlockStatementOrThis()
newExpr.replace(UnfoldReturnToIfIntention.createReturnExpression(expr, psiFactory, context))
newExpr.replace(UnfoldReturnToIfIntention.createReturnExpression(expr, labelName, psiFactory, context))
}
element.replace(newWhenExpression)
}
@@ -0,0 +1,10 @@
// WITH_RUNTIME
fun main() {
run label@{
<caret>return@label if (true) {
42
} else {
42
}
}
}
@@ -0,0 +1,10 @@
// WITH_RUNTIME
fun main() {
run label@{
<caret>if (true) {
return@label 42
} else {
return@label 42
}
}
}
@@ -0,0 +1,10 @@
// WITH_RUNTIME
fun main() {
run label@{
<caret>return@label when {
true ->
42
else -> 42
}
}
}
@@ -0,0 +1,10 @@
// WITH_RUNTIME
fun main() {
run label@{
<caret>when {
true ->
return@label 42
else -> return@label 42
}
}
}
@@ -3416,6 +3416,11 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
runTest("idea/testData/intentions/branched/unfolding/returnToIf/innerIfTransformed.kt");
}
@TestMetadata("labeledReturn.kt")
public void testLabeledReturn() throws Exception {
runTest("idea/testData/intentions/branched/unfolding/returnToIf/labeledReturn.kt");
}
@TestMetadata("simpleIf.kt")
public void testSimpleIf() throws Exception {
runTest("idea/testData/intentions/branched/unfolding/returnToIf/simpleIf.kt");
@@ -3444,6 +3449,11 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
runTest("idea/testData/intentions/branched/unfolding/returnToWhen/innerWhenTransformed.kt");
}
@TestMetadata("labeledReturn.kt")
public void testLabeledReturn() throws Exception {
runTest("idea/testData/intentions/branched/unfolding/returnToWhen/labeledReturn.kt");
}
@TestMetadata("simpleWhen.kt")
public void testSimpleWhen() throws Exception {
runTest("idea/testData/intentions/branched/unfolding/returnToWhen/simpleWhen.kt");