Added safeAccessToIfThen intention
This commit is contained in:
committed by
Zalim Bashorov
parent
1ca4bb0e79
commit
1f720c8559
@@ -349,6 +349,7 @@ fun main(args: Array<String>) {
|
|||||||
testClass(javaClass<AbstractCodeTransformationTest>()) {
|
testClass(javaClass<AbstractCodeTransformationTest>()) {
|
||||||
model("intentions/branched/elvisToIfThen", testMethod = "doTestElvisToIfThen")
|
model("intentions/branched/elvisToIfThen", testMethod = "doTestElvisToIfThen")
|
||||||
model("intentions/branched/ifThenToElvis", testMethod = "doTestIfThenToElvis")
|
model("intentions/branched/ifThenToElvis", testMethod = "doTestIfThenToElvis")
|
||||||
|
model("intentions/branched/safeAccessToIfThen", testMethod = "doTestSafeAccessToIfThen")
|
||||||
model("intentions/branched/folding/ifToAssignment", testMethod = "doTestFoldIfToAssignment")
|
model("intentions/branched/folding/ifToAssignment", testMethod = "doTestFoldIfToAssignment")
|
||||||
model("intentions/branched/folding/ifToReturn", testMethod = "doTestFoldIfToReturn")
|
model("intentions/branched/folding/ifToReturn", testMethod = "doTestFoldIfToReturn")
|
||||||
model("intentions/branched/folding/ifToReturnAsymmetrically", testMethod = "doTestFoldIfToReturnAsymmetrically")
|
model("intentions/branched/folding/ifToReturnAsymmetrically", testMethod = "doTestFoldIfToReturnAsymmetrically")
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
val result = if (maybeSomething != null) maybeSomething.perform(something) else null
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
val result = maybeSomething?.perform(something)
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
Converts an expression that uses an safe-access operator to an if-then expression
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -484,6 +484,11 @@
|
|||||||
<category>Kotlin</category>
|
<category>Kotlin</category>
|
||||||
</intentionAction>
|
</intentionAction>
|
||||||
|
|
||||||
|
<intentionAction>
|
||||||
|
<className>org.jetbrains.jet.plugin.intentions.branchedTransformations.intentions.SafeAccessToIfThenIntention</className>
|
||||||
|
<category>Kotlin</category>
|
||||||
|
</intentionAction>
|
||||||
|
|
||||||
<intentionAction>
|
<intentionAction>
|
||||||
<className>org.jetbrains.jet.plugin.intentions.branchedTransformations.intentions.IfToWhenIntention</className>
|
<className>org.jetbrains.jet.plugin.intentions.branchedTransformations.intentions.IfToWhenIntention</className>
|
||||||
<category>Kotlin</category>
|
<category>Kotlin</category>
|
||||||
|
|||||||
@@ -222,11 +222,9 @@ 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=Replace elvis expression with 'if' expression
|
||||||
elvis.to.if.then.family=Replace Elvis Expression With 'if' Expression
|
elvis.to.if.then.family=Replace Elvis Expression With 'if' Expression
|
||||||
if.then.to.elvis=Replace 'if' expression with elvis expression
|
if.then.to.elvis=Replace 'if' expression with elvis expression
|
||||||
if.then.to.elvis.family=Replace 'if' Expression With Elvis Expression
|
if.then.to.elvis.family=Replace 'if' expression With Elvis Expression
|
||||||
safe.access.to.if.then=Replace safe access expression with 'if' expression
|
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
|
safe.access.to.if.then.family=Replace Safe Access Expression With 'if' Expression
|
||||||
if.then.to.safe.access=Replace 'if' expression with safe access expression
|
|
||||||
if.then.to.safe.access.family=Replace 'if' Expression with Safe Access Expression
|
|
||||||
if.to.when=Replace 'if' with 'when'
|
if.to.when=Replace 'if' with 'when'
|
||||||
if.to.when.family=Replace 'if' with 'when'
|
if.to.when.family=Replace 'if' with 'when'
|
||||||
when.to.if=Replace 'when' with 'if'
|
when.to.if=Replace 'when' with 'if'
|
||||||
|
|||||||
+53
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* 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.JetSafeQualifiedExpression
|
||||||
|
import org.jetbrains.jet.plugin.intentions.JetSelfTargetingIntention
|
||||||
|
import com.intellij.openapi.editor.Editor
|
||||||
|
import org.jetbrains.jet.lang.psi.JetPsiFactory
|
||||||
|
import org.jetbrains.jet.lang.psi.JetPsiUtil
|
||||||
|
import org.jetbrains.jet.lang.psi.JetBinaryExpression
|
||||||
|
import org.jetbrains.jet.plugin.intentions.branchedTransformations.convertToIfNotNullExpression
|
||||||
|
import org.jetbrains.jet.plugin.intentions.branchedTransformations.introduceValueForCondition
|
||||||
|
import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression
|
||||||
|
import org.jetbrains.jet.plugin.intentions.branchedTransformations.isStatement
|
||||||
|
import org.jetbrains.jet.plugin.intentions.branchedTransformations.isStableVariable
|
||||||
|
|
||||||
|
public class SafeAccessToIfThenIntention : JetSelfTargetingIntention<JetSafeQualifiedExpression>("safe.access.to.if.then", javaClass()) {
|
||||||
|
override fun isApplicableTo(element: JetSafeQualifiedExpression): Boolean = true
|
||||||
|
|
||||||
|
override fun applyTo(element: JetSafeQualifiedExpression, editor: Editor) {
|
||||||
|
val receiver = JetPsiUtil.deparenthesize(element.getReceiverExpression())!!
|
||||||
|
val selector = JetPsiUtil.deparenthesize(element.getSelectorExpression())
|
||||||
|
|
||||||
|
val receiverIsStable = receiver.isStableVariable()
|
||||||
|
|
||||||
|
val receiverTemplate = if (receiver is JetBinaryExpression) "(%s)" else "%s"
|
||||||
|
val receiverAsString = receiverTemplate.format(receiver.getText())
|
||||||
|
val dotQualifiedExpression = JetPsiFactory.createExpression(element.getProject(), "${receiverAsString}.${selector!!.getText()}")
|
||||||
|
|
||||||
|
val elseClause = if (element.isStatement()) null else JetPsiFactory.createExpression(element.getProject(), "null")
|
||||||
|
val ifExpression = element.convertToIfNotNullExpression(receiver, dotQualifiedExpression, elseClause)
|
||||||
|
|
||||||
|
if (!receiverIsStable) {
|
||||||
|
val valueToExtract = (ifExpression.getThen() as JetDotQualifiedExpression).getReceiverExpression()
|
||||||
|
ifExpression.introduceValueForCondition(valueToExtract, editor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
val x: String? = null
|
||||||
|
val y: String? = "Hello"
|
||||||
|
val z = (x ?: y)?.<caret>length
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
val x: String? = null
|
||||||
|
val y: String? = "Hello"
|
||||||
|
val s = x ?: y
|
||||||
|
val z = if (s != null) s.length else null
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
fun foo(): String? = "foo"
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
foo()?.<caret>length()
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
fun foo(): String? = "foo"
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val s = foo()
|
||||||
|
if (s != null) s.length()
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
fun foo(): String? = "foo"
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
(foo())?.<caret>length()
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
fun foo(): String? = "foo"
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val s = foo()
|
||||||
|
if (s != null) s.length()
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
class Foo {
|
||||||
|
val b: String?
|
||||||
|
get() {
|
||||||
|
print("I have side effects")
|
||||||
|
return "Foo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val a = Foo()
|
||||||
|
println(a.b?.<caret>length)
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
class Foo {
|
||||||
|
val b: String?
|
||||||
|
get() {
|
||||||
|
print("I have side effects")
|
||||||
|
return "Foo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val a = Foo()
|
||||||
|
val s = a.b
|
||||||
|
println(if (s != null) s.length else null)
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
val x: String? = "abc"
|
||||||
|
x?.<caret>length
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
val x: String? = "abc"
|
||||||
|
if (x != null) x.length
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
val a: String? = "A"
|
||||||
|
println(a?.<caret>length)
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
val a: String? = "A"
|
||||||
|
println(if (a != null) a.length else null)
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
var a: String? = "A"
|
||||||
|
println(a?.<caret>length)
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
var a: String? = "A"
|
||||||
|
val s = a
|
||||||
|
println(if (s != null) s.length else null)
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
val x: String? = "abc"
|
||||||
|
val y = x?.<caret>length
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
val x: String? = "abc"
|
||||||
|
val y = if (x != null) x.length else null
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fun f(s: Int?) {
|
||||||
|
println(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val x: String? = "foo"
|
||||||
|
f(x?.<caret>length)
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
fun f(s: Int?) {
|
||||||
|
println(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val x: String? = "foo"
|
||||||
|
f(if (x != null) x.length else null)
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
val foo: String? = "foo"
|
||||||
|
foo?.<caret>length()
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
val foo: String? = "foo"
|
||||||
|
if (foo != null) foo.length()
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
val foo: String? = "foo"
|
||||||
|
(foo)?.<caret>length()
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
val foo: String? = "foo"
|
||||||
|
if (foo != null) foo.length()
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
class B {
|
||||||
|
val c = "ab"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val a: B? = B()
|
||||||
|
val x = a?.<caret>c
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
class B {
|
||||||
|
val c = "ab"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val a: B? = B()
|
||||||
|
val x = if (a != null) a.c else null
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
class B {
|
||||||
|
val c = C()
|
||||||
|
}
|
||||||
|
|
||||||
|
class C {
|
||||||
|
val d = "bc"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val a: B? = B()
|
||||||
|
val x = a<caret>?.c?.d
|
||||||
|
}
|
||||||
|
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
class B {
|
||||||
|
val c = C()
|
||||||
|
}
|
||||||
|
|
||||||
|
class C {
|
||||||
|
val d = "bc"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val a: B? = B()
|
||||||
|
val x = (if (a != null) a.c else null)?.d
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
class B {
|
||||||
|
val c = C()
|
||||||
|
}
|
||||||
|
|
||||||
|
class C {
|
||||||
|
val d = "bc"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val a: B? = B()
|
||||||
|
val x = a?.c?.<caret>d
|
||||||
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
class B {
|
||||||
|
val c = C()
|
||||||
|
}
|
||||||
|
|
||||||
|
class C {
|
||||||
|
val d = "bc"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val a: B? = B()
|
||||||
|
val x = if (a?.c != null) a?.c.d else null
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
val a: String? = "A"
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
println(a?.<caret>length)
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
val a: String? = "A"
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
println(if (a != null) a.length else null)
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
val a: String?
|
||||||
|
get() = ""
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
println(a?.<caret>length)
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
val a: String?
|
||||||
|
get() = ""
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val s = a
|
||||||
|
println(if (s != null) s.length else null)
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
var a: String? = "A"
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
a<caret>?.length
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
var a: String? = "A"
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val s = a
|
||||||
|
if (s != null) s.length
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
var a: String?
|
||||||
|
get() = ""
|
||||||
|
set(v) {}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
a?.<caret>length
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
var a: String?
|
||||||
|
get() = ""
|
||||||
|
set(v) {}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val s = a
|
||||||
|
if (s != null) s.length
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
fun foo(arg: String?): Int? = arg?.<caret>length
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
foo("bar")
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
fun foo(arg: String?): Int? = if (arg != null) arg.length else null
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
foo("bar")
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
val foo: String? = "foo"
|
||||||
|
val y = if (true) foo?.<caret>length() else null
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
val foo: String? = "foo"
|
||||||
|
val y = if (true) if (foo != null) foo.length() else null else null
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fun doSth(): String? {
|
||||||
|
val x?: String = "abc"
|
||||||
|
return x?.<caret>reverse()
|
||||||
|
}
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val y = doSth()
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fun doSth(): String? {
|
||||||
|
val x?: String = "abc"
|
||||||
|
return if (x != null) x.reverse() else null
|
||||||
|
}
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val y = doSth()
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
val foo: String? = "foo"
|
||||||
|
if (true) {
|
||||||
|
foo?.<caret>length()
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
val foo: String? = "foo"
|
||||||
|
if (true) {
|
||||||
|
if (foo != null) foo.length()
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
-1
@@ -1,6 +1,9 @@
|
|||||||
// "class com.intellij.codeInsight.daemon.impl.quickfix.ImportClassFixBase" "false"
|
// "class com.intellij.codeInsight.daemon.impl.quickfix.ImportClassFixBase" "false"
|
||||||
// ERROR: Unresolved reference: SomeTest
|
// ERROR: Unresolved reference: SomeTest
|
||||||
|
// ACTION: Edit intention settings
|
||||||
|
// ACTION: Replace safe access expression with 'if' expression
|
||||||
|
// ACTION: Disable 'Replace Safe Access Expression With 'if' Expression'
|
||||||
|
|
||||||
package testing
|
package testing
|
||||||
|
|
||||||
val x = testing?.<caret>SomeTest()
|
val x = testing?.<caret>SomeTest()
|
||||||
|
|||||||
@@ -39,6 +39,10 @@ public abstract class AbstractCodeTransformationTest extends LightCodeInsightTes
|
|||||||
doTestIntention(path, new IfThenToElvisIntention());
|
doTestIntention(path, new IfThenToElvisIntention());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void doTestSafeAccessToIfThen(@NotNull String path) throws Exception {
|
||||||
|
doTestIntention(path, new SafeAccessToIfThenIntention());
|
||||||
|
}
|
||||||
|
|
||||||
public void doTestFoldIfToAssignment(@NotNull String path) throws Exception {
|
public void doTestFoldIfToAssignment(@NotNull String path) throws Exception {
|
||||||
doTestIntention(path, new FoldIfToAssignmentIntention());
|
doTestIntention(path, new FoldIfToAssignmentIntention());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user