IfToWhenIntention - smaller range and code refactoring

This commit is contained in:
Valentin Kipyatkov
2015-05-05 23:41:15 +03:00
parent 50f2c13cac
commit 47c613c477
3 changed files with 60 additions and 77 deletions
@@ -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
@@ -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<JetExpression> {
val branches = ArrayList<JetExpression>()
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<JetIfExpression> = object: Iterator<JetIfExpression> {
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<JetWhenCondition>, subject: JetExpression?): String {
return when (conditions.size) {
@@ -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<JetIfExpression>("if.to.when", javaClass()) {
override fun isApplicableTo(element: JetIfExpression): Boolean = element.canTransformToWhen()
public class IfToWhenIntention : JetSelfTargetingIntention<JetIfExpression>(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<JetExpression>()
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<JetExpression>.addOrBranches(expression: JetExpression): List<JetExpression> {
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
}
}