diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetPsiFactory.kt b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetPsiFactory.kt index 2ca36229e5c..550fb9950a7 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetPsiFactory.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetPsiFactory.kt @@ -502,10 +502,6 @@ public class JetPsiFactory(private val project: Project) { } } - public fun WhenBuilder(): WhenBuilder { - return WhenBuilder(null: String?) - } - public fun WhenBuilder(subject: JetExpression?): WhenBuilder { return WhenBuilder(subject?.getText()) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/createByPattern.kt b/compiler/frontend/src/org/jetbrains/kotlin/psi/createByPattern.kt index 88d2f34efef..42eef2b80f2 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/createByPattern.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/createByPattern.kt @@ -198,7 +198,7 @@ public class ExpressionBuilder { return this } - public fun appendExpression(expression: JetExpression): ExpressionBuilder { + public fun appendExpression(expression: JetExpression?): ExpressionBuilder { patternBuilder.append("$" + arguments.size()) arguments.add(expression) return this diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/psiUtil/jetPsiUtil.kt b/compiler/frontend/src/org/jetbrains/kotlin/psi/psiUtil/jetPsiUtil.kt index c322f1011bc..bf8981448a7 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/psiUtil/jetPsiUtil.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/psiUtil/jetPsiUtil.kt @@ -126,8 +126,8 @@ public fun PsiElement.replaced(newElement: T): T = replace(newEl [suppress("UNCHECKED_CAST")] public fun T.copied(): T = copy() as T -public fun JetElement.blockExpressionsOrSingle(): Stream = - if (this is JetBlockExpression) getStatements().stream() else listOf(this).stream() +public fun JetElement.blockExpressionsOrSingle(): Sequence = + if (this is JetBlockExpression) getStatements().asSequence() else sequenceOf(this) public fun JetElement.outermostLastBlockElement(predicate: (JetElement) -> Boolean = { true }): JetElement? { return JetPsiUtil.getOutermostLastBlockElement(this) { e -> e != null && predicate(e) } 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 74c388f15e3..9adf800e38c 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/branchedTransformationUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/branchedTransformationUtils.kt @@ -102,7 +102,7 @@ fun JetWhenExpression.getSubjectCandidate(): JetExpression? { var lastCandidate: JetExpression? = null for (entry in getEntries()) { val conditions = entry.getConditions() - if (!entry.isElse() && conditions.size == 0) return null + if (!entry.isElse() && conditions.isEmpty()) return null for (condition in conditions) { if (condition !is JetWhenConditionWithExpression) return null @@ -152,54 +152,69 @@ public fun JetWhenExpression.flatten(): JetWhenExpression { public fun JetWhenExpression.introduceSubject(): JetWhenExpression { val subject = getSubjectCandidate()!! - val builder = JetPsiFactory(this).WhenBuilder(subject) - for (entry in getEntries()) { - val branchExpression = entry.getExpression() - if (entry.isElse()) { - builder.elseEntry(branchExpression) - continue - } + val whenExpression = JetPsiFactory(this).buildExpression { + appendFixedText("when(").appendExpression(subject).appendFixedText("){\n") - for (condition in entry.getConditions()) { - assert(condition is JetWhenConditionWithExpression, TRANSFORM_WITHOUT_CHECK) + for (entry in getEntries()) { + val branchExpression = entry.getExpression() - val conditionExpression = ((condition as JetWhenConditionWithExpression)).getExpression() - when (conditionExpression) { - is JetIsExpression -> { - builder.pattern(conditionExpression.getTypeReference(), conditionExpression.isNegated()) - } - is JetBinaryExpression -> { - val lhs = conditionExpression.getLeft() - val rhs = conditionExpression.getRight() - val op = conditionExpression.getOperationToken() - when (op) { - JetTokens.IN_KEYWORD -> builder.range(rhs, false) - JetTokens.NOT_IN -> builder.range(rhs, true) - JetTokens.EQEQ -> builder.condition(if (subject.matches(lhs)) rhs else lhs) - else -> assert(false, TRANSFORM_WITHOUT_CHECK) + if (entry.isElse()) { + appendFixedText("else") + } + 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) { + is JetIsExpression -> { + if (conditionExpression.isNegated()) { + appendFixedText("!") + } + appendFixedText("is ") + appendNonFormattedText(conditionExpression.getTypeReference()?.getText() ?: "") + } + + is JetBinaryExpression -> { + val lhs = conditionExpression.getLeft() + val rhs = conditionExpression.getRight() + val op = conditionExpression.getOperationToken() + when (op) { + 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 -> error(TRANSFORM_WITHOUT_CHECK) } } - else -> assert(false, TRANSFORM_WITHOUT_CHECK) } + appendFixedText("->") + appendExpression(branchExpression) + appendFixedText("\n") } - builder.branchExpression(branchExpression) - } - return replaced(builder.toExpression()) + appendFixedText("}") + } as JetWhenExpression + + return replaced(whenExpression) } public fun JetWhenExpression.canTransformToIf(): Boolean = !getEntries().isEmpty() public fun JetWhenExpression.transformToIf() { fun combineWhenConditions(conditions: Array, subject: JetExpression?): String { - return when (conditions.size) { + return when (conditions.size()) { 0 -> "" 1 -> conditions[0].toExpressionText(subject) else -> { conditions .map { condition -> parenthesizeTextIfNeeded(condition.toExpressionText(subject)) } - .makeString(separator = " || ") + .joinToString(separator = " || ") } } } @@ -227,8 +242,8 @@ public fun JetWhenExpression.canMergeWithNext(): Boolean { fun JetWhenEntry.declarationNames(): Set = getExpression()?.blockExpressionsOrSingle() ?.filter { it is JetNamedDeclaration } - ?.map { decl -> decl.getName() } - ?.filterNotNull()?.toSet() ?: Collections.emptySet() + ?.map { it.getName() } + ?.filterNotNull()?.toSet() ?: emptySet() fun checkBodies(e1: JetWhenEntry, e2: JetWhenEntry): Boolean { if (ContainerUtil.intersects(e1.declarationNames(), e2.declarationNames())) return false @@ -246,7 +261,7 @@ public fun JetWhenExpression.canMergeWithNext(): Boolean { val entries1 = getEntries() val entries2 = sibling.getEntries() - return entries1.size == entries2.size && (entries1 zip entries2).all { pair -> + return entries1.size() == entries2.size() && (entries1 zip entries2).all { pair -> checkConditions(pair.first, pair.second) && checkBodies(pair.first, pair.second) } } 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 1bef17160c7..d4ad435b7c0 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 @@ -51,9 +51,7 @@ public class EliminateWhenSubjectIntention : JetSelfTargetingIntention") - if (branchExpression != null) { - appendExpression(branchExpression) - } + appendExpression(branchExpression) appendFixedText("\n") } 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 3856845f6f1..428db3832ce 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 @@ -49,9 +49,7 @@ public class IfToWhenIntention : JetSelfTargetingIntention(java appendFixedText("->") val thenBranch = ifExpression.getThen() - if (thenBranch != null) { - appendExpression(thenBranch) - } + appendExpression(thenBranch) appendFixedText("\n") val elseBranch = ifExpression.getElse() ?: break