From 45c5454e3969fef69506173d5ce410c34098970f Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Wed, 6 May 2015 12:30:39 +0300 Subject: [PATCH] Refactored IntroduceWhenSubjectIntention --- .../kotlin/idea/JetBundle.properties | 2 - .../branchedTransformationUtils.kt | 61 ++++++++----------- .../intentions/IfToWhenIntention.kt | 4 +- .../IntroduceWhenSubjectIntention.kt | 10 ++- 4 files changed, 35 insertions(+), 42 deletions(-) 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 2366ef3ed9e..e674fb6905c 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/JetBundle.properties +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/JetBundle.properties @@ -250,8 +250,6 @@ 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 merge.when=Merge 'when' expressions merge.when.family=Merge 'when' Expression -introduce.when.subject=Introduce argument to 'when' -introduce.when.subject.family=Introduce Argument to 'when' transform.if.statement.with.assignments.to.expression=Transform 'if' statement with assignments to expression transform.assignment.with.if.expression.to.statement=Transform assignment with 'if' expression to statement transform.if.statement.with.assignments.to.expression.family=Transform 'if' Statement with Assignments to 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 cc02be25348..5ff2a57a6c5 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/branchedTransformationUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/branchedTransformationUtils.kt @@ -26,8 +26,6 @@ import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.psi.typeRefHelpers.getTypeReference -public val TRANSFORM_WITHOUT_CHECK: String = "Expression must be checked before applying transformation" - fun JetWhenCondition.toExpression(subject: JetExpression?): JetExpression { val factory = JetPsiFactory(this) when (this) { @@ -54,29 +52,7 @@ fun JetWhenCondition.toExpression(subject: JetExpression?): JetExpression { } } -fun JetWhenExpression.getSubjectCandidate(): JetExpression? { - fun JetExpression?.getWhenConditionSubjectCandidate(): JetExpression? { - return when(this) { - is JetIsExpression -> getLeftHandSide() - is JetBinaryExpression -> { - val lhs = getLeft() - val op = getOperationToken() - when (op) { - JetTokens.IN_KEYWORD, JetTokens.NOT_IN -> lhs - JetTokens.EQEQ -> { - if (lhs is JetSimpleNameExpression) - lhs - else - getRight() - } - else -> null - } - - } - else -> null - } - } - +public fun JetWhenExpression.getSubjectToIntroduce(): JetExpression? { if (getSubjectExpression() != null) return null var lastCandidate: JetExpression? = null @@ -87,13 +63,14 @@ fun JetWhenExpression.getSubjectCandidate(): JetExpression? { for (condition in conditions) { if (condition !is JetWhenConditionWithExpression) return null - val currCandidate = condition.getExpression().getWhenConditionSubjectCandidate() - if (currCandidate !is JetSimpleNameExpression) return null + val candidate = condition.getExpression()?.getWhenConditionSubjectCandidate() as? JetSimpleNameExpression ?: return null if (lastCandidate == null) { - lastCandidate = currCandidate + lastCandidate = candidate + } + else if (!lastCandidate.matches(candidate)) { + return null } - else if (!lastCandidate.matches(currCandidate)) return null } } @@ -101,12 +78,27 @@ fun JetWhenExpression.getSubjectCandidate(): JetExpression? { return lastCandidate } -public fun JetWhenExpression.canIntroduceSubject(): Boolean { - return getSubjectCandidate() != null +private fun JetExpression?.getWhenConditionSubjectCandidate(): JetExpression? { + return when(this) { + is JetIsExpression -> getLeftHandSide() + + is JetBinaryExpression -> { + val lhs = getLeft() + val op = getOperationToken() + when (op) { + JetTokens.IN_KEYWORD, JetTokens.NOT_IN -> lhs + JetTokens.EQEQ -> lhs as? JetSimpleNameExpression ?: getRight() + else -> null + } + + } + + else -> null + } } public fun JetWhenExpression.introduceSubject(): JetWhenExpression { - val subject = getSubjectCandidate()!! + val subject = getSubjectToIntroduce()!! val whenExpression = JetPsiFactory(this).buildExpression { appendFixedText("when(").appendExpression(subject).appendFixedText("){\n") @@ -120,7 +112,6 @@ public fun JetWhenExpression.introduceSubject(): JetWhenExpression { else { for ((i, condition) in entry.getConditions().withIndex()) { if (i > 0) appendFixedText(",") - assert(condition is JetWhenConditionWithExpression, TRANSFORM_WITHOUT_CHECK) val conditionExpression = (condition as JetWhenConditionWithExpression).getExpression() when (conditionExpression) { @@ -140,11 +131,11 @@ public fun JetWhenExpression.introduceSubject(): JetWhenExpression { JetTokens.IN_KEYWORD -> appendFixedText("in ").appendExpression(rhs) JetTokens.NOT_IN -> appendFixedText("!in ").appendExpression(rhs) JetTokens.EQEQ -> appendExpression(if (subject.matches(lhs)) rhs else lhs) - else -> error(TRANSFORM_WITHOUT_CHECK) + else -> throw IllegalStateException() } } - else -> error(TRANSFORM_WITHOUT_CHECK) + else -> throw IllegalStateException() } } } 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 428db3832ce..b3e1a954234 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 @@ -18,7 +18,7 @@ package org.jetbrains.kotlin.idea.intentions.branchedTransformations.intentions import com.intellij.openapi.editor.Editor import org.jetbrains.kotlin.idea.intentions.JetSelfTargetingIntention -import org.jetbrains.kotlin.idea.intentions.branchedTransformations.canIntroduceSubject +import org.jetbrains.kotlin.idea.intentions.branchedTransformations.getSubjectToIntroduce import org.jetbrains.kotlin.idea.intentions.branchedTransformations.introduceSubject import org.jetbrains.kotlin.lexer.JetTokens import org.jetbrains.kotlin.psi.* @@ -68,7 +68,7 @@ public class IfToWhenIntention : JetSelfTargetingIntention(java } as JetWhenExpression - if (whenExpression.canIntroduceSubject()) { + if (whenExpression.getSubjectToIntroduce() != null) { whenExpression = whenExpression.introduceSubject() } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/IntroduceWhenSubjectIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/IntroduceWhenSubjectIntention.kt index 10700f1b126..9f4511bc12e 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/IntroduceWhenSubjectIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/IntroduceWhenSubjectIntention.kt @@ -18,12 +18,16 @@ 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.canIntroduceSubject +import org.jetbrains.kotlin.idea.intentions.branchedTransformations.getSubjectToIntroduce import org.jetbrains.kotlin.idea.intentions.branchedTransformations.introduceSubject import org.jetbrains.kotlin.psi.JetWhenExpression -public class IntroduceWhenSubjectIntention : JetSelfTargetingOffsetIndependentIntention("introduce.when.subject", javaClass()) { - override fun isApplicableTo(element: JetWhenExpression): Boolean = element.canIntroduceSubject() +public class IntroduceWhenSubjectIntention : JetSelfTargetingOffsetIndependentIntention(javaClass(), "Introduce argument to 'when'") { + override fun isApplicableTo(element: JetWhenExpression): Boolean { + val subject = element.getSubjectToIntroduce() ?: return false + setText("Introduce '$subject' as argument to 'when'") + return true + } override fun applyTo(element: JetWhenExpression, editor: Editor) { element.introduceSubject()