From 673369affefaf1d81ab9ba387a31c5d064216b9c Mon Sep 17 00:00:00 2001 From: Zack Grannan Date: Sun, 2 Mar 2014 17:39:17 -0800 Subject: [PATCH] Added elvisToIfThenIntention --- .../jet/generators/tests/GenerateTests.kt | 1 + .../ElvisToIfThenIntention/after.kt.template | 1 + .../ElvisToIfThenIntention/before.kt.template | 1 + .../ElvisToIfThenIntention/description.html | 5 +++ idea/src/META-INF/plugin.xml | 5 +++ .../jetbrains/jet/plugin/JetBundle.properties | 2 + .../intentions/ElvisToIfThenIntention.kt | 45 +++++++++++++++++++ .../branched/elvisToIfThen/callExpression.kt | 12 +++++ .../elvisToIfThen/callExpression.kt.after | 13 ++++++ .../elvisToIfThen/callExpressionParens.kt | 12 +++++ .../callExpressionParens.kt.after | 13 ++++++ .../elvisToIfThen/elvisAsExpression.kt | 5 +++ .../elvisToIfThen/elvisAsExpression.kt.after | 5 +++ .../branched/elvisToIfThen/localValLhs.kt | 4 ++ .../elvisToIfThen/localValLhs.kt.after | 4 ++ .../branched/elvisToIfThen/localVarLhs.kt | 4 ++ .../elvisToIfThen/localVarLhs.kt.after | 5 +++ .../elvisToIfThen/simpleNameExpression.kt | 5 +++ .../simpleNameExpression.kt.after | 5 +++ .../simpleNameExpressionInParens.kt | 6 +++ .../simpleNameExpressionInParens.kt.after | 6 +++ .../branched/elvisToIfThen/topLevelVal.kt | 4 ++ .../elvisToIfThen/topLevelVal.kt.after | 4 ++ .../elvisToIfThen/topLevelValCustomGetter.kt | 6 +++ .../topLevelValCustomGetter.kt.after | 7 +++ .../branched/elvisToIfThen/topLevelVar.kt | 4 ++ .../elvisToIfThen/topLevelVar.kt.after | 5 +++ .../elvisToIfThen/topLevelVarCustomGetter.kt | 7 +++ .../topLevelVarCustomGetter.kt.after | 8 ++++ .../AbstractCodeTransformationTest.java | 4 ++ 30 files changed, 208 insertions(+) create mode 100644 idea/resources/intentionDescriptions/ElvisToIfThenIntention/after.kt.template create mode 100644 idea/resources/intentionDescriptions/ElvisToIfThenIntention/before.kt.template create mode 100644 idea/resources/intentionDescriptions/ElvisToIfThenIntention/description.html create mode 100644 idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/intentions/ElvisToIfThenIntention.kt create mode 100644 idea/testData/intentions/branched/elvisToIfThen/callExpression.kt create mode 100644 idea/testData/intentions/branched/elvisToIfThen/callExpression.kt.after create mode 100644 idea/testData/intentions/branched/elvisToIfThen/callExpressionParens.kt create mode 100644 idea/testData/intentions/branched/elvisToIfThen/callExpressionParens.kt.after create mode 100644 idea/testData/intentions/branched/elvisToIfThen/elvisAsExpression.kt create mode 100644 idea/testData/intentions/branched/elvisToIfThen/elvisAsExpression.kt.after create mode 100644 idea/testData/intentions/branched/elvisToIfThen/localValLhs.kt create mode 100644 idea/testData/intentions/branched/elvisToIfThen/localValLhs.kt.after create mode 100644 idea/testData/intentions/branched/elvisToIfThen/localVarLhs.kt create mode 100644 idea/testData/intentions/branched/elvisToIfThen/localVarLhs.kt.after create mode 100644 idea/testData/intentions/branched/elvisToIfThen/simpleNameExpression.kt create mode 100644 idea/testData/intentions/branched/elvisToIfThen/simpleNameExpression.kt.after create mode 100644 idea/testData/intentions/branched/elvisToIfThen/simpleNameExpressionInParens.kt create mode 100644 idea/testData/intentions/branched/elvisToIfThen/simpleNameExpressionInParens.kt.after create mode 100644 idea/testData/intentions/branched/elvisToIfThen/topLevelVal.kt create mode 100644 idea/testData/intentions/branched/elvisToIfThen/topLevelVal.kt.after create mode 100644 idea/testData/intentions/branched/elvisToIfThen/topLevelValCustomGetter.kt create mode 100644 idea/testData/intentions/branched/elvisToIfThen/topLevelValCustomGetter.kt.after create mode 100644 idea/testData/intentions/branched/elvisToIfThen/topLevelVar.kt create mode 100644 idea/testData/intentions/branched/elvisToIfThen/topLevelVar.kt.after create mode 100644 idea/testData/intentions/branched/elvisToIfThen/topLevelVarCustomGetter.kt create mode 100644 idea/testData/intentions/branched/elvisToIfThen/topLevelVarCustomGetter.kt.after diff --git a/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt b/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt index 24b3345531b..b7a89555d19 100644 --- a/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt +++ b/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt @@ -347,6 +347,7 @@ fun main(args: Array) { } testClass(javaClass()) { + model("intentions/branched/elvisToIfThen", testMethod = "doTestElvisToIfThen") model("intentions/branched/folding/ifToAssignment", testMethod = "doTestFoldIfToAssignment") model("intentions/branched/folding/ifToReturn", testMethod = "doTestFoldIfToReturn") model("intentions/branched/folding/ifToReturnAsymmetrically", testMethod = "doTestFoldIfToReturnAsymmetrically") diff --git a/idea/resources/intentionDescriptions/ElvisToIfThenIntention/after.kt.template b/idea/resources/intentionDescriptions/ElvisToIfThenIntention/after.kt.template new file mode 100644 index 00000000000..6c64bfdc26d --- /dev/null +++ b/idea/resources/intentionDescriptions/ElvisToIfThenIntention/after.kt.template @@ -0,0 +1 @@ +val result = if (maybeSomething != null) maybeSomething else somethingElse diff --git a/idea/resources/intentionDescriptions/ElvisToIfThenIntention/before.kt.template b/idea/resources/intentionDescriptions/ElvisToIfThenIntention/before.kt.template new file mode 100644 index 00000000000..a37f275650c --- /dev/null +++ b/idea/resources/intentionDescriptions/ElvisToIfThenIntention/before.kt.template @@ -0,0 +1 @@ +val result = maybeSomething ?: somethingElse diff --git a/idea/resources/intentionDescriptions/ElvisToIfThenIntention/description.html b/idea/resources/intentionDescriptions/ElvisToIfThenIntention/description.html new file mode 100644 index 00000000000..d3af5cc92e9 --- /dev/null +++ b/idea/resources/intentionDescriptions/ElvisToIfThenIntention/description.html @@ -0,0 +1,5 @@ + + + Converts an expression that uses an elvis operator to an if-then expression + + diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 5de46d65079..a257d9c6cfd 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -474,6 +474,11 @@ Kotlin + + org.jetbrains.jet.plugin.intentions.branchedTransformations.intentions.ElvisToIfThenIntention + Kotlin + + org.jetbrains.jet.plugin.intentions.branchedTransformations.intentions.IfToWhenIntention Kotlin diff --git a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties index b7b0c7186ec..5ea6e171518 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties +++ b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties @@ -219,6 +219,8 @@ unfold.return.to.when=Replace return with 'when' expression unfold.return.to.when.family=Replace Return with 'when' Expression unfold.call.to.when=Replace method call with 'when' expression unfold.call.to.when.family=Replace Method Call with 'when' Expression +elvis.to.if.then=Replace elvis expression with 'if' expression +elvis.to.if.then.family=Replace Elvis 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' diff --git a/idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/intentions/ElvisToIfThenIntention.kt b/idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/intentions/ElvisToIfThenIntention.kt new file mode 100644 index 00000000000..c618cdc929d --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/intentions/ElvisToIfThenIntention.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2010-2014 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.jet.plugin.intentions.branchedTransformations.intentions + +import org.jetbrains.jet.lang.psi.JetBinaryExpression +import org.jetbrains.jet.plugin.intentions.JetSelfTargetingIntention +import com.intellij.openapi.editor.Editor +import org.jetbrains.jet.lexer.JetTokens +import org.jetbrains.jet.lang.psi.JetPsiUtil +import org.jetbrains.jet.plugin.intentions.branchedTransformations.convertToIfNotNullExpression +import org.jetbrains.jet.plugin.intentions.branchedTransformations.introduceValueForCondition +import org.jetbrains.jet.plugin.intentions.branchedTransformations.isStableVariable + +public class ElvisToIfThenIntention : JetSelfTargetingIntention("elvis.to.if.then", javaClass()) { + override fun isApplicableTo(element: JetBinaryExpression): Boolean = + element.getOperationToken() == JetTokens.ELVIS + + override fun applyTo(element: JetBinaryExpression, editor: Editor) { + val left = checkNotNull(JetPsiUtil.deparenthesize(element.getLeft()), "Left hand side of elvis expression cannot be null") + val right = checkNotNull(JetPsiUtil.deparenthesize(element.getRight()), "Right hand side of elvis expression cannot be null") + + val leftIsStable = left.isStableVariable() + + val ifStatement = element.convertToIfNotNullExpression(left, left, right) + + if (!leftIsStable) { + ifStatement.introduceValueForCondition(ifStatement.getThen()!!, editor) + } + } + +} diff --git a/idea/testData/intentions/branched/elvisToIfThen/callExpression.kt b/idea/testData/intentions/branched/elvisToIfThen/callExpression.kt new file mode 100644 index 00000000000..94374abd14f --- /dev/null +++ b/idea/testData/intentions/branched/elvisToIfThen/callExpression.kt @@ -0,0 +1,12 @@ +fun foo(): String? { + print("foo") + return "foo" +} + +fun bar() { + print("bar") +} + +fun main(args: Array) { + foo() ?: bar() +} diff --git a/idea/testData/intentions/branched/elvisToIfThen/callExpression.kt.after b/idea/testData/intentions/branched/elvisToIfThen/callExpression.kt.after new file mode 100644 index 00000000000..dd319db98b7 --- /dev/null +++ b/idea/testData/intentions/branched/elvisToIfThen/callExpression.kt.after @@ -0,0 +1,13 @@ +fun foo(): String? { + print("foo") + return "foo" +} + +fun bar() { + print("bar") +} + +fun main(args: Array) { + val s = foo() + if (s != null) s else bar() +} diff --git a/idea/testData/intentions/branched/elvisToIfThen/callExpressionParens.kt b/idea/testData/intentions/branched/elvisToIfThen/callExpressionParens.kt new file mode 100644 index 00000000000..62eaa463eb6 --- /dev/null +++ b/idea/testData/intentions/branched/elvisToIfThen/callExpressionParens.kt @@ -0,0 +1,12 @@ +fun foo(): String? { + print("foo") + return "foo" +} + +fun bar() { + print("bar") +} + +fun main(args: Array) { + (foo()) ?: bar() +} diff --git a/idea/testData/intentions/branched/elvisToIfThen/callExpressionParens.kt.after b/idea/testData/intentions/branched/elvisToIfThen/callExpressionParens.kt.after new file mode 100644 index 00000000000..dd319db98b7 --- /dev/null +++ b/idea/testData/intentions/branched/elvisToIfThen/callExpressionParens.kt.after @@ -0,0 +1,13 @@ +fun foo(): String? { + print("foo") + return "foo" +} + +fun bar() { + print("bar") +} + +fun main(args: Array) { + val s = foo() + if (s != null) s else bar() +} diff --git a/idea/testData/intentions/branched/elvisToIfThen/elvisAsExpression.kt b/idea/testData/intentions/branched/elvisToIfThen/elvisAsExpression.kt new file mode 100644 index 00000000000..aafcde69004 --- /dev/null +++ b/idea/testData/intentions/branched/elvisToIfThen/elvisAsExpression.kt @@ -0,0 +1,5 @@ +fun main(args: Array) { + val foo: String? = "foo" + var bar: String = "bar" + val x = foo ?: bar +} diff --git a/idea/testData/intentions/branched/elvisToIfThen/elvisAsExpression.kt.after b/idea/testData/intentions/branched/elvisToIfThen/elvisAsExpression.kt.after new file mode 100644 index 00000000000..afc97f51a98 --- /dev/null +++ b/idea/testData/intentions/branched/elvisToIfThen/elvisAsExpression.kt.after @@ -0,0 +1,5 @@ +fun main(args: Array) { + val foo: String? = "foo" + var bar: String = "bar" + val x = if (foo != null) foo else bar +} diff --git a/idea/testData/intentions/branched/elvisToIfThen/localValLhs.kt b/idea/testData/intentions/branched/elvisToIfThen/localValLhs.kt new file mode 100644 index 00000000000..fc166a03f86 --- /dev/null +++ b/idea/testData/intentions/branched/elvisToIfThen/localValLhs.kt @@ -0,0 +1,4 @@ +fun main(args: Array) { + val a: String? = "A" + a ?: "bar" +} diff --git a/idea/testData/intentions/branched/elvisToIfThen/localValLhs.kt.after b/idea/testData/intentions/branched/elvisToIfThen/localValLhs.kt.after new file mode 100644 index 00000000000..77f7b4ebefb --- /dev/null +++ b/idea/testData/intentions/branched/elvisToIfThen/localValLhs.kt.after @@ -0,0 +1,4 @@ +fun main(args: Array) { + val a: String? = "A" + if (a != null) a else "bar" +} diff --git a/idea/testData/intentions/branched/elvisToIfThen/localVarLhs.kt b/idea/testData/intentions/branched/elvisToIfThen/localVarLhs.kt new file mode 100644 index 00000000000..5d98d31d1f3 --- /dev/null +++ b/idea/testData/intentions/branched/elvisToIfThen/localVarLhs.kt @@ -0,0 +1,4 @@ +fun main(args: Array) { + var a: String? = "A" + a ?: "bar" +} diff --git a/idea/testData/intentions/branched/elvisToIfThen/localVarLhs.kt.after b/idea/testData/intentions/branched/elvisToIfThen/localVarLhs.kt.after new file mode 100644 index 00000000000..c9486b05218 --- /dev/null +++ b/idea/testData/intentions/branched/elvisToIfThen/localVarLhs.kt.after @@ -0,0 +1,5 @@ +fun main(args: Array) { + var a: String? = "A" + val s = a + if (s != null) s else "bar" +} diff --git a/idea/testData/intentions/branched/elvisToIfThen/simpleNameExpression.kt b/idea/testData/intentions/branched/elvisToIfThen/simpleNameExpression.kt new file mode 100644 index 00000000000..1b19decfbe1 --- /dev/null +++ b/idea/testData/intentions/branched/elvisToIfThen/simpleNameExpression.kt @@ -0,0 +1,5 @@ +fun main(args: Array) { + val foo: String? = "foo" + var bar = "bar" + foo ?: bar +} diff --git a/idea/testData/intentions/branched/elvisToIfThen/simpleNameExpression.kt.after b/idea/testData/intentions/branched/elvisToIfThen/simpleNameExpression.kt.after new file mode 100644 index 00000000000..307720dd631 --- /dev/null +++ b/idea/testData/intentions/branched/elvisToIfThen/simpleNameExpression.kt.after @@ -0,0 +1,5 @@ +fun main(args: Array) { + val foo: String? = "foo" + var bar = "bar" + if (foo != null) foo else bar +} diff --git a/idea/testData/intentions/branched/elvisToIfThen/simpleNameExpressionInParens.kt b/idea/testData/intentions/branched/elvisToIfThen/simpleNameExpressionInParens.kt new file mode 100644 index 00000000000..c4ae6fc64d0 --- /dev/null +++ b/idea/testData/intentions/branched/elvisToIfThen/simpleNameExpressionInParens.kt @@ -0,0 +1,6 @@ +fun bar(): String = "bar" + +fun main(args: Array) { + val foo: String? = "foo" + (foo) ?: bar() +} diff --git a/idea/testData/intentions/branched/elvisToIfThen/simpleNameExpressionInParens.kt.after b/idea/testData/intentions/branched/elvisToIfThen/simpleNameExpressionInParens.kt.after new file mode 100644 index 00000000000..c889ef3206a --- /dev/null +++ b/idea/testData/intentions/branched/elvisToIfThen/simpleNameExpressionInParens.kt.after @@ -0,0 +1,6 @@ +fun bar(): String = "bar" + +fun main(args: Array) { + val foo: String? = "foo" + if (foo != null) foo else bar() +} diff --git a/idea/testData/intentions/branched/elvisToIfThen/topLevelVal.kt b/idea/testData/intentions/branched/elvisToIfThen/topLevelVal.kt new file mode 100644 index 00000000000..31e10a4fc51 --- /dev/null +++ b/idea/testData/intentions/branched/elvisToIfThen/topLevelVal.kt @@ -0,0 +1,4 @@ +val a: String? = "A" +fun main(args: Array) { + a ?: "bar" +} diff --git a/idea/testData/intentions/branched/elvisToIfThen/topLevelVal.kt.after b/idea/testData/intentions/branched/elvisToIfThen/topLevelVal.kt.after new file mode 100644 index 00000000000..c34cdd3ec16 --- /dev/null +++ b/idea/testData/intentions/branched/elvisToIfThen/topLevelVal.kt.after @@ -0,0 +1,4 @@ +val a: String? = "A" +fun main(args: Array) { + if (a != null) a else "bar" +} diff --git a/idea/testData/intentions/branched/elvisToIfThen/topLevelValCustomGetter.kt b/idea/testData/intentions/branched/elvisToIfThen/topLevelValCustomGetter.kt new file mode 100644 index 00000000000..58f11faee44 --- /dev/null +++ b/idea/testData/intentions/branched/elvisToIfThen/topLevelValCustomGetter.kt @@ -0,0 +1,6 @@ +val a: String? + get() = "" + +fun main(args: Array) { + a ?: "bar" +} diff --git a/idea/testData/intentions/branched/elvisToIfThen/topLevelValCustomGetter.kt.after b/idea/testData/intentions/branched/elvisToIfThen/topLevelValCustomGetter.kt.after new file mode 100644 index 00000000000..1b11ac0ed61 --- /dev/null +++ b/idea/testData/intentions/branched/elvisToIfThen/topLevelValCustomGetter.kt.after @@ -0,0 +1,7 @@ +val a: String? + get() = "" + +fun main(args: Array) { + val s = a + if (s != null) s else "bar" +} diff --git a/idea/testData/intentions/branched/elvisToIfThen/topLevelVar.kt b/idea/testData/intentions/branched/elvisToIfThen/topLevelVar.kt new file mode 100644 index 00000000000..efac866cc52 --- /dev/null +++ b/idea/testData/intentions/branched/elvisToIfThen/topLevelVar.kt @@ -0,0 +1,4 @@ +var a: String? = "A" +fun main(args: Array) { + a ?: "bar" +} diff --git a/idea/testData/intentions/branched/elvisToIfThen/topLevelVar.kt.after b/idea/testData/intentions/branched/elvisToIfThen/topLevelVar.kt.after new file mode 100644 index 00000000000..e4aceeeef5d --- /dev/null +++ b/idea/testData/intentions/branched/elvisToIfThen/topLevelVar.kt.after @@ -0,0 +1,5 @@ +var a: String? = "A" +fun main(args: Array) { + val s = a + if (s != null) s else "bar" +} diff --git a/idea/testData/intentions/branched/elvisToIfThen/topLevelVarCustomGetter.kt b/idea/testData/intentions/branched/elvisToIfThen/topLevelVarCustomGetter.kt new file mode 100644 index 00000000000..c9eadee1c38 --- /dev/null +++ b/idea/testData/intentions/branched/elvisToIfThen/topLevelVarCustomGetter.kt @@ -0,0 +1,7 @@ +var a: String? + get() = "" + set(v) {} + +fun main(args: Array) { + a ?: "bar" +} diff --git a/idea/testData/intentions/branched/elvisToIfThen/topLevelVarCustomGetter.kt.after b/idea/testData/intentions/branched/elvisToIfThen/topLevelVarCustomGetter.kt.after new file mode 100644 index 00000000000..93d9ada5c3e --- /dev/null +++ b/idea/testData/intentions/branched/elvisToIfThen/topLevelVarCustomGetter.kt.after @@ -0,0 +1,8 @@ +var a: String? + get() = "" + set(v) {} + +fun main(args: Array) { + val s = a + if (s != null) s else "bar" +} diff --git a/idea/tests/org/jetbrains/jet/plugin/intentions/AbstractCodeTransformationTest.java b/idea/tests/org/jetbrains/jet/plugin/intentions/AbstractCodeTransformationTest.java index b8c02f6f57f..47ea545d8b3 100644 --- a/idea/tests/org/jetbrains/jet/plugin/intentions/AbstractCodeTransformationTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/intentions/AbstractCodeTransformationTest.java @@ -31,6 +31,10 @@ import org.junit.Assert; import java.io.File; public abstract class AbstractCodeTransformationTest extends LightCodeInsightTestCase { + public void doTestElvisToIfThen(@NotNull String path) throws Exception { + doTestIntention(path, new ElvisToIfThenIntention()); + } + public void doTestFoldIfToAssignment(@NotNull String path) throws Exception { doTestIntention(path, new FoldIfToAssignmentIntention()); }