diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/JetBundle.properties b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/JetBundle.properties index 8f66a2692c4..7c5dbe5a153 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/JetBundle.properties +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/JetBundle.properties @@ -248,8 +248,6 @@ elvis.to.if.then=Replace elvis expression with 'if' expression elvis.to.if.then.family=Replace Elvis Expression with 'if' Expression safe.access.to.if.then=Replace safe access expression with 'if' expression safe.access.to.if.then.family=Replace Safe Access Expression with 'if' Expression -if.to.when=Replace 'if' with 'when' -if.to.when.family=Replace 'if' with 'when' when.to.if=Replace 'when' with 'if' when.to.if.family=Replace 'when' with 'if' flatten.when=Flatten 'when' expression diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/branchedTransformationUtils.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/branchedTransformationUtils.kt index d0e7500879d..74c388f15e3 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/branchedTransformationUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/branchedTransformationUtils.kt @@ -189,76 +189,8 @@ public fun JetWhenExpression.introduceSubject(): JetWhenExpression { return replaced(builder.toExpression()) } -public fun JetIfExpression.canTransformToWhen(): Boolean = getThen() != null - public fun JetWhenExpression.canTransformToIf(): Boolean = !getEntries().isEmpty() -public fun JetIfExpression.transformToWhen() { - fun JetExpression.splitToOrBranches(): List { - val branches = ArrayList() - accept( - object : JetVisitorVoid() { - public override fun visitBinaryExpression(expression: JetBinaryExpression) { - if (expression.getOperationToken() == JetTokens.OROR) { - expression.getLeft()?.accept(this) - expression.getRight()?.accept(this) - } - else { - visitExpression(expression) - } - } - - public override fun visitParenthesizedExpression(expression: JetParenthesizedExpression) { - expression.getExpression()?.accept(this) - } - - public override fun visitExpression(expression: JetExpression) { - branches.add(expression) - } - } - ) - return branches - } - - fun branchIterator(ifExpression: JetIfExpression): Iterator = object: Iterator { - private var expression: JetIfExpression? = ifExpression - - override fun next(): JetIfExpression { - val current = expression!! - expression = current.getElse()?.let { next -> if (next is JetIfExpression) next else null } - return current - } - - override fun hasNext(): Boolean = expression != null - } - - val builder = JetPsiFactory(this).WhenBuilder() - branchIterator(this).forEach { ifExpression -> - ifExpression.getCondition()?.let { condition -> - val orBranches = condition.splitToOrBranches() - if (orBranches.isEmpty()) { - builder.condition("") - } - else { - orBranches.forEach { branch -> builder.condition(branch) } - } - } - - builder.branchExpression(ifExpression.getThen()) - - ifExpression.getElse()?.let { elseBranch -> - if (elseBranch !is JetIfExpression) { - builder.elseEntry(elseBranch) - } - } - } - - val whenExpression = builder.toExpression().let { whenExpression -> - if (whenExpression.canIntroduceSubject()) whenExpression.introduceSubject() else whenExpression - } - replace(whenExpression) -} - public fun JetWhenExpression.transformToIf() { fun combineWhenConditions(conditions: Array, subject: JetExpression?): String { return when (conditions.size) { diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/IfToWhenIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/IfToWhenIntention.kt index 3ad95f35a5c..720436b3190 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/IfToWhenIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/IfToWhenIntention.kt @@ -17,15 +17,68 @@ package org.jetbrains.kotlin.idea.intentions.branchedTransformations.intentions import com.intellij.openapi.editor.Editor -import org.jetbrains.kotlin.idea.intentions.JetSelfTargetingOffsetIndependentIntention -import org.jetbrains.kotlin.idea.intentions.branchedTransformations.canTransformToWhen -import org.jetbrains.kotlin.idea.intentions.branchedTransformations.transformToWhen -import org.jetbrains.kotlin.psi.JetIfExpression +import org.jetbrains.kotlin.idea.intentions.JetSelfTargetingIntention +import org.jetbrains.kotlin.idea.intentions.branchedTransformations.canIntroduceSubject +import org.jetbrains.kotlin.idea.intentions.branchedTransformations.introduceSubject +import org.jetbrains.kotlin.lexer.JetTokens +import org.jetbrains.kotlin.psi.* +import java.util.ArrayList -public class IfToWhenIntention : JetSelfTargetingOffsetIndependentIntention("if.to.when", javaClass()) { - override fun isApplicableTo(element: JetIfExpression): Boolean = element.canTransformToWhen() +public class IfToWhenIntention : JetSelfTargetingIntention(javaClass(), "Replace 'if' with 'when'") { + override fun isApplicableTo(element: JetIfExpression, caretOffset: Int): Boolean { + if (element.getThen() == null) return false + return element.getIfKeyword().getTextRange().containsOffset(caretOffset) + } override fun applyTo(element: JetIfExpression, editor: Editor) { - element.transformToWhen() + val builder = JetPsiFactory(element).WhenBuilder() + + var ifExpression = element + while (true) { + val condition = ifExpression.getCondition() + val orBranches = ArrayList() + if (condition != null) { + orBranches.addOrBranches(condition) + } + if (orBranches.isNotEmpty()) { + orBranches.forEach { builder.condition(it) } + } + else { + builder.condition(null) + } + + builder.branchExpression(ifExpression.getThen()) + + val elseBranch = ifExpression.getElse() ?: break + if (elseBranch is JetIfExpression) { + ifExpression = elseBranch + } + else { + builder.elseEntry(elseBranch) + break + } + } + + var whenExpression = builder.toExpression() + if (whenExpression.canIntroduceSubject()) { + whenExpression = whenExpression.introduceSubject() + } + + element.replace(whenExpression) + } + + private fun MutableList.addOrBranches(expression: JetExpression): List { + if (expression is JetBinaryExpression && expression.getOperationToken() == JetTokens.OROR) { + val left = expression.getLeft() + val right = expression.getRight() + if (left != null && right != null) { + addOrBranches(left) + addOrBranches(right) + return this + } + } + + add(JetPsiUtil.safeDeparenthesize(expression)) + return this } }