Use of expressions instead of plain text when converting when's
This commit is contained in:
@@ -63,7 +63,7 @@ public class JetPsiFactory(private val project: Project) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public fun createExpression(text: String): JetExpression {
|
public fun createExpression(text: String): JetExpression {
|
||||||
return createProperty("val x = $text").getInitializer()!!
|
return createProperty("val x = $text").getInitializer() ?: error("Failed to create expression from text: '$text'")
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun createClassLiteral(className: String): JetClassLiteralExpression =
|
public fun createClassLiteral(className: String): JetClassLiteralExpression =
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.psi;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
public class JetPsiUnparsingUtils {
|
|
||||||
private JetPsiUnparsingUtils() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public static String toBinaryExpression(@Nullable JetExpression left, @NotNull String op, @Nullable JetElement right) {
|
|
||||||
return toBinaryExpression(JetPsiUtil.getText(left), op, JetPsiUtil.getText(right));
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public static String toBinaryExpression(@NotNull String left, @NotNull String op, @NotNull String right) {
|
|
||||||
return left + " " + op + " " + right;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public static String parenthesizeIfNeeded(@Nullable JetExpression expression) {
|
|
||||||
String text = JetPsiUtil.getText(expression);
|
|
||||||
|
|
||||||
return (expression instanceof JetParenthesizedExpression ||
|
|
||||||
expression instanceof JetConstantExpression ||
|
|
||||||
expression instanceof JetSimpleNameExpression ||
|
|
||||||
expression instanceof JetDotQualifiedExpression)
|
|
||||||
? text : "(" + text + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public static String parenthesizeTextIfNeeded(@NotNull String expressionText) {
|
|
||||||
return (expressionText.startsWith("(") && expressionText.endsWith(")")) ? expressionText : "(" + expressionText + ")";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -52,6 +52,7 @@ public class JetWhenConditionInRange extends JetWhenCondition {
|
|||||||
return visitor.visitWhenConditionInRange(this, data);
|
return visitor.visitWhenConditionInRange(this, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
public JetSimpleNameExpression getOperationReference() {
|
public JetSimpleNameExpression getOperationReference() {
|
||||||
return (JetSimpleNameExpression) findChildByType(JetNodeTypes.OPERATION_REFERENCE);
|
return (JetSimpleNameExpression) findChildByType(JetNodeTypes.OPERATION_REFERENCE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ public fun JetPsiFactory.createExpressionByPattern(pattern: String, vararg args:
|
|||||||
.filter { args[it.getKey()] is String }
|
.filter { args[it.getKey()] is String }
|
||||||
.flatMap { it.getValue() }
|
.flatMap { it.getValue() }
|
||||||
.map { it.range }
|
.map { it.range }
|
||||||
|
.filterNot { it.isEmpty() }
|
||||||
.sortBy { -it.getStartOffset() }
|
.sortBy { -it.getStartOffset() }
|
||||||
|
|
||||||
// reformat whole text except for String arguments (as they can contain user's formatting to be preserved)
|
// reformat whole text except for String arguments (as they can contain user's formatting to be preserved)
|
||||||
|
|||||||
+16
-23
@@ -23,41 +23,34 @@ import org.jetbrains.kotlin.idea.util.psi.patternMatching.matches
|
|||||||
import org.jetbrains.kotlin.idea.util.psi.patternMatching.toRange
|
import org.jetbrains.kotlin.idea.util.psi.patternMatching.toRange
|
||||||
import org.jetbrains.kotlin.lexer.JetTokens
|
import org.jetbrains.kotlin.lexer.JetTokens
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.JetPsiUnparsingUtils.parenthesizeIfNeeded
|
|
||||||
import org.jetbrains.kotlin.psi.JetPsiUnparsingUtils.toBinaryExpression
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
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"
|
public val TRANSFORM_WITHOUT_CHECK: String = "Expression must be checked before applying transformation"
|
||||||
|
|
||||||
fun JetWhenCondition.toExpressionText(subject: JetExpression?): String {
|
fun JetWhenCondition.toExpression(subject: JetExpression?): JetExpression {
|
||||||
return when (this) {
|
val factory = JetPsiFactory(this)
|
||||||
|
when (this) {
|
||||||
is JetWhenConditionIsPattern -> {
|
is JetWhenConditionIsPattern -> {
|
||||||
val op = if (isNegated()) "!is" else "is"
|
val op = if (isNegated()) "!is" else "is"
|
||||||
toBinaryExpression(subject, op, getTypeReference())
|
return factory.createExpressionByPattern("$0 $op $1", subject ?: "_", getTypeReference() ?: "")
|
||||||
}
|
}
|
||||||
is JetWhenConditionInRange -> {
|
|
||||||
toBinaryExpression(subject, getOperationReference()!!.getText()!!, getRangeExpression())
|
|
||||||
}
|
|
||||||
is JetWhenConditionWithExpression -> {
|
|
||||||
val conditionExpression = getExpression()
|
|
||||||
if (subject != null) {
|
|
||||||
toBinaryExpression(parenthesizeIfNeeded(subject), "==", parenthesizeIfNeeded(conditionExpression))
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
JetPsiUtil.getText(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
assert(this is JetWhenConditionWithExpression, TRANSFORM_WITHOUT_CHECK)
|
|
||||||
|
|
||||||
val conditionExpression = (this as JetWhenConditionWithExpression).getExpression()
|
is JetWhenConditionInRange -> {
|
||||||
if (subject != null) {
|
val op = getOperationReference().getText()
|
||||||
toBinaryExpression(parenthesizeIfNeeded(subject), "==", parenthesizeIfNeeded(conditionExpression))
|
return factory.createExpressionByPattern("$0 $op $1", subject ?: "_", getRangeExpression() ?: "")
|
||||||
|
}
|
||||||
|
|
||||||
|
is JetWhenConditionWithExpression -> {
|
||||||
|
return if (subject != null) {
|
||||||
|
factory.createExpressionByPattern("$0 == $1", subject, getExpression() ?: "")
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
JetPsiUtil.getText(this)
|
getExpression()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else -> throw IllegalArgumentException("Unknown JetWhenCondition type: $this")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.idea.intentions.branchedTransformations.intentions
|
|||||||
|
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import org.jetbrains.kotlin.idea.intentions.JetSelfTargetingIntention
|
import org.jetbrains.kotlin.idea.intentions.JetSelfTargetingIntention
|
||||||
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.toExpressionText
|
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.toExpression
|
||||||
import org.jetbrains.kotlin.psi.JetPsiFactory
|
import org.jetbrains.kotlin.psi.JetPsiFactory
|
||||||
import org.jetbrains.kotlin.psi.JetSimpleNameExpression
|
import org.jetbrains.kotlin.psi.JetSimpleNameExpression
|
||||||
import org.jetbrains.kotlin.psi.JetWhenExpression
|
import org.jetbrains.kotlin.psi.JetWhenExpression
|
||||||
@@ -46,7 +46,7 @@ public class EliminateWhenSubjectIntention : JetSelfTargetingIntention<JetWhenEx
|
|||||||
else {
|
else {
|
||||||
for ((i, condition) in entry.getConditions().withIndex()) {
|
for ((i, condition) in entry.getConditions().withIndex()) {
|
||||||
if (i > 0) appendFixedText(",")
|
if (i > 0) appendFixedText(",")
|
||||||
appendNonFormattedText(condition.toExpressionText(subject))
|
appendExpression(condition.toExpression(subject))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
appendFixedText("->")
|
appendFixedText("->")
|
||||||
|
|||||||
+17
-11
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.idea.intentions.branchedTransformations.intentions
|
|||||||
|
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import org.jetbrains.kotlin.idea.intentions.JetSelfTargetingIntention
|
import org.jetbrains.kotlin.idea.intentions.JetSelfTargetingIntention
|
||||||
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.toExpressionText
|
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.toExpression
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
|
||||||
public class WhenToIfIntention : JetSelfTargetingIntention<JetWhenExpression>(javaClass(), "Replace 'when' with 'if'") {
|
public class WhenToIfIntention : JetSelfTargetingIntention<JetWhenExpression>(javaClass(), "Replace 'when' with 'if'") {
|
||||||
@@ -32,7 +32,8 @@ public class WhenToIfIntention : JetSelfTargetingIntention<JetWhenExpression>(ja
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun applyTo(element: JetWhenExpression, editor: Editor) {
|
override fun applyTo(element: JetWhenExpression, editor: Editor) {
|
||||||
val ifExpression = JetPsiFactory(element).buildExpression {
|
val factory = JetPsiFactory(element)
|
||||||
|
val ifExpression = factory.buildExpression {
|
||||||
for ((i, entry) in element.getEntries().withIndex()) {
|
for ((i, entry) in element.getEntries().withIndex()) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
appendFixedText("else ")
|
appendFixedText("else ")
|
||||||
@@ -43,9 +44,9 @@ public class WhenToIfIntention : JetSelfTargetingIntention<JetWhenExpression>(ja
|
|||||||
appendFixedText("\n")
|
appendFixedText("\n")
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
val branchConditionText = combineWhenConditions(entry.getConditions(), element.getSubjectExpression())
|
val condition = factory.combineWhenConditions(entry.getConditions(), element.getSubjectExpression())
|
||||||
appendFixedText("if (")
|
appendFixedText("if (")
|
||||||
appendNonFormattedText(branchConditionText)
|
appendExpression(condition)
|
||||||
appendFixedText(")")
|
appendFixedText(")")
|
||||||
appendExpression(branch)
|
appendExpression(branch)
|
||||||
appendFixedText("\n")
|
appendFixedText("\n")
|
||||||
@@ -56,14 +57,19 @@ public class WhenToIfIntention : JetSelfTargetingIntention<JetWhenExpression>(ja
|
|||||||
element.replace(ifExpression)
|
element.replace(ifExpression)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun combineWhenConditions(conditions: Array<JetWhenCondition>, subject: JetExpression?): String {
|
private fun JetPsiFactory.combineWhenConditions(conditions: Array<JetWhenCondition>, subject: JetExpression?): JetExpression? {
|
||||||
return when (conditions.size()) {
|
when (conditions.size()) {
|
||||||
0 -> ""
|
0 -> return null
|
||||||
1 -> conditions[0].toExpressionText(subject)
|
|
||||||
|
1 -> return conditions[0].toExpression(subject)
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
conditions
|
return buildExpression {
|
||||||
.map { condition -> JetPsiUnparsingUtils.parenthesizeTextIfNeeded(condition.toExpressionText(subject)) }
|
for ((i, condition) in conditions.withIndex()) {
|
||||||
.joinToString(separator = " || ")
|
if (i > 0) appendFixedText("||")
|
||||||
|
appendExpression(condition.toExpression(subject))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
fun test(n: Int): String {
|
fun test(n: Int): String {
|
||||||
return <caret>if ((n < 0) || (n > 1000)) "unknown"
|
return <caret>if (n < 0 || n > 1000) "unknown"
|
||||||
else if (n <= 10) "small"
|
else if (n <= 10) "small"
|
||||||
else if (n <= 100) "average"
|
else if (n <= 100) "average"
|
||||||
else "big"
|
else "big"
|
||||||
|
|||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
fun test(n: Int): String {
|
fun test(n: Int): String {
|
||||||
return <caret>if ((n in 0..5) || (n in 5..10)) "small"
|
return <caret>if (n in 0..5 || n in 5..10) "small"
|
||||||
else if ((n in 10..50) || (n in 50..100)) "average"
|
else if (n in 10..50 || n in 50..100) "average"
|
||||||
else if ((n in 100..500) || (n in 500..1000)) "big"
|
else if (n in 100..500 || n in 500..1000) "big"
|
||||||
else "unknown"
|
else "unknown"
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fun test(n: Int): String {
|
||||||
|
return <caret>when (n) {
|
||||||
|
is -> "String"
|
||||||
|
in -> "1..10"
|
||||||
|
else -> "unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
fun test(n: Int): String {
|
||||||
|
return if (n is ) "String"
|
||||||
|
else if (n in) "1..10"
|
||||||
|
else "unknown"
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// ERROR: Expected condition of type kotlin.Boolean
|
||||||
|
// ERROR: Expected condition of type kotlin.Boolean
|
||||||
|
|
||||||
|
fun test(n: Int): String {
|
||||||
|
return <caret>when {
|
||||||
|
is String -> "String"
|
||||||
|
in 1..10 -> "1..10"
|
||||||
|
else -> "unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// ERROR: Expected condition of type kotlin.Boolean
|
||||||
|
// ERROR: Expected condition of type kotlin.Boolean
|
||||||
|
|
||||||
|
fun test(n: Int): String {
|
||||||
|
return if (_ is String) "String"
|
||||||
|
else if (_ in 1..10) "1..10"
|
||||||
|
else "unknown"
|
||||||
|
}
|
||||||
@@ -1732,6 +1732,18 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
|||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/branched/ifWhen/whenToIf/whenWithoutSubject.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/branched/ifWhen/whenToIf/whenWithoutSubject.kt");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("wrongIsAndInNoEnd.kt")
|
||||||
|
public void testWrongIsAndInNoEnd() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/branched/ifWhen/whenToIf/wrongIsAndInNoEnd.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("wrongIsAndInNoSubject.kt")
|
||||||
|
public void testWrongIsAndInNoSubject() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/branched/ifWhen/whenToIf/wrongIsAndInNoSubject.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user