From abd7ed5c70b48ba3e63d95dfde5ad9e830bd7b90 Mon Sep 17 00:00:00 2001 From: Natalia Ukhorskaya Date: Wed, 16 Dec 2015 14:58:43 +0300 Subject: [PATCH] Fix intention for when: insert '||' instead of ',' --- .../branchedTransformationUtils.kt | 60 ++++++++++++------- .../EliminateWhenSubjectIntention.kt | 2 +- .../intentions/IfToWhenIntention.kt | 2 +- .../ifToWhen/ifWithMultiConditions.kt.after | 2 +- .../ifWhen/whenToIf/wrongIsAndInNoSubject.kt | 1 + .../whenToIf/wrongIsAndInNoSubject.kt.after | 1 + ...nWithRangeTestsAndMultiConditions.kt.after | 8 +-- 7 files changed, 46 insertions(+), 30 deletions(-) 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 785ceaa82ee..4417f12a241 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/branchedTransformationUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/branchedTransformationUtils.kt @@ -83,6 +83,11 @@ private fun KtExpression?.getWhenConditionSubjectCandidate(): KtExpression? { when (op) { KtTokens.IN_KEYWORD, KtTokens.NOT_IN -> lhs KtTokens.EQEQ -> lhs as? KtNameReferenceExpression ?: getRight() + KtTokens.OROR -> { + val leftCandidate = lhs.getWhenConditionSubjectCandidate() + val rightCandidate = right.getWhenConditionSubjectCandidate() + if (leftCandidate.matches(rightCandidate)) leftCandidate else null + } else -> null } @@ -109,29 +114,7 @@ public fun KtWhenExpression.introduceSubject(): KtWhenExpression { if (i > 0) appendFixedText(",") val conditionExpression = (condition as KtWhenConditionWithExpression).getExpression() - when (conditionExpression) { - is KtIsExpression -> { - if (conditionExpression.isNegated()) { - appendFixedText("!") - } - appendFixedText("is ") - appendNonFormattedText(conditionExpression.getTypeReference()?.getText() ?: "") - } - - is KtBinaryExpression -> { - val lhs = conditionExpression.getLeft() - val rhs = conditionExpression.getRight() - val op = conditionExpression.getOperationToken() - when (op) { - KtTokens.IN_KEYWORD -> appendFixedText("in ").appendExpression(rhs) - KtTokens.NOT_IN -> appendFixedText("!in ").appendExpression(rhs) - KtTokens.EQEQ -> appendExpression(if (subject.matches(lhs)) rhs else lhs) - else -> throw IllegalStateException() - } - } - - else -> throw IllegalStateException() - } + appendConditionWithSubjectRemoved(conditionExpression, subject) } } appendFixedText("->") @@ -146,6 +129,37 @@ public fun KtWhenExpression.introduceSubject(): KtWhenExpression { return replaced(whenExpression) } +private fun BuilderByPattern.appendConditionWithSubjectRemoved(conditionExpression: KtExpression?, subject: KtExpression) { + when (conditionExpression) { + is KtIsExpression -> { + if (conditionExpression.isNegated()) { + appendFixedText("!") + } + appendFixedText("is ") + appendNonFormattedText(conditionExpression.getTypeReference()?.getText() ?: "") + } + + is KtBinaryExpression -> { + val lhs = conditionExpression.getLeft() + val rhs = conditionExpression.getRight() + val op = conditionExpression.getOperationToken() + when (op) { + KtTokens.IN_KEYWORD -> appendFixedText("in ").appendExpression(rhs) + KtTokens.NOT_IN -> appendFixedText("!in ").appendExpression(rhs) + KtTokens.EQEQ -> appendExpression(if (subject.matches(lhs)) rhs else lhs) + KtTokens.OROR -> { + appendConditionWithSubjectRemoved(lhs, subject) + appendFixedText(", ") + appendConditionWithSubjectRemoved(rhs, subject) + } + else -> throw IllegalStateException() + } + } + + else -> throw IllegalStateException() + } +} + fun KtPsiFactory.combineWhenConditions(conditions: Array, subject: KtExpression?): KtExpression? { when (conditions.size) { 0 -> return null diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/EliminateWhenSubjectIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/EliminateWhenSubjectIntention.kt index f6d6f78974e..80a0cb58150 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/EliminateWhenSubjectIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/EliminateWhenSubjectIntention.kt @@ -46,7 +46,7 @@ public class EliminateWhenSubjectIntention : SelfTargetingIntention") 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 08a7ba22141..70eb428af08 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 @@ -43,7 +43,7 @@ public class IfToWhenIntention : SelfTargetingRangeIntention(jav orBranches.addOrBranches(condition) } - appendExpressions(orBranches) + appendExpressions(orBranches, separator = "||") appendFixedText("->") diff --git a/idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithMultiConditions.kt.after b/idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithMultiConditions.kt.after index c734c5f8f3b..4d8a090f190 100644 --- a/idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithMultiConditions.kt.after +++ b/idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithMultiConditions.kt.after @@ -1,6 +1,6 @@ fun test(n: Int): String { return when { - n < 0, n > 1000 -> "unknown" + n < 0 || n > 1000 -> "unknown" n <= 10 -> "small" n <= 100 -> "average" else -> "big" diff --git a/idea/testData/intentions/branched/ifWhen/whenToIf/wrongIsAndInNoSubject.kt b/idea/testData/intentions/branched/ifWhen/whenToIf/wrongIsAndInNoSubject.kt index 250b8f5a7c3..0802860f773 100644 --- a/idea/testData/intentions/branched/ifWhen/whenToIf/wrongIsAndInNoSubject.kt +++ b/idea/testData/intentions/branched/ifWhen/whenToIf/wrongIsAndInNoSubject.kt @@ -1,5 +1,6 @@ // ERROR: Expected condition of type kotlin.Boolean // ERROR: Expected condition of type kotlin.Boolean +// SKIP_ERRORS_AFTER fun test(n: Int): String { return when { diff --git a/idea/testData/intentions/branched/ifWhen/whenToIf/wrongIsAndInNoSubject.kt.after b/idea/testData/intentions/branched/ifWhen/whenToIf/wrongIsAndInNoSubject.kt.after index e5de39e3fec..edb6bccf9d3 100644 --- a/idea/testData/intentions/branched/ifWhen/whenToIf/wrongIsAndInNoSubject.kt.after +++ b/idea/testData/intentions/branched/ifWhen/whenToIf/wrongIsAndInNoSubject.kt.after @@ -1,5 +1,6 @@ // ERROR: Expected condition of type kotlin.Boolean // ERROR: Expected condition of type kotlin.Boolean +// SKIP_ERRORS_AFTER fun test(n: Int): String { return if (_ is String) "String" diff --git a/idea/testData/intentions/branched/when/eliminateSubject/whenWithRangeTestsAndMultiConditions.kt.after b/idea/testData/intentions/branched/when/eliminateSubject/whenWithRangeTestsAndMultiConditions.kt.after index aa84b8524a0..8aa49b2f347 100644 --- a/idea/testData/intentions/branched/when/eliminateSubject/whenWithRangeTestsAndMultiConditions.kt.after +++ b/idea/testData/intentions/branched/when/eliminateSubject/whenWithRangeTestsAndMultiConditions.kt.after @@ -1,8 +1,8 @@ fun test(n: Int): String { - return when { - n in 0..5, n in 5..10 -> "small" - n in 10..50, n in 50..100 -> "average" - n in 100..500, n in 500..1000 -> "big" + return when { + n in 0..5 || n in 5..10 -> "small" + n in 10..50 || n in 50..100 -> "average" + n in 100..500 || n in 500..1000 -> "big" else -> "unknown" } } \ No newline at end of file