Fix "Replace !! with if-then" inspection in receiver position
#KT-5412 Fixed
This commit is contained in:
committed by
Mikhail Glukhikh
parent
162de77b71
commit
1455451601
+30
-14
@@ -28,18 +28,15 @@ import com.intellij.psi.PsiDocumentManager
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.intentions.ChooseStringExpression
|
||||
import org.jetbrains.kotlin.idea.intentions.SelfTargetingRangeIntention
|
||||
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.convertToIfNotNullExpression
|
||||
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.convertToIfNullExpression
|
||||
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.introduceValueForCondition
|
||||
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.isStableSimpleExpression
|
||||
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.*
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.KtPostfixExpression
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.psi.KtPsiUtil
|
||||
import org.jetbrains.kotlin.psi.KtThrowExpression
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForReceiver
|
||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsStatement
|
||||
|
||||
class DoubleBangToIfThenIntention : SelfTargetingRangeIntention<KtPostfixExpression>(KtPostfixExpression::class.java, "Replace '!!' expression with 'if' expression"), LowPriorityAction {
|
||||
class DoubleBangToIfThenIntention :
|
||||
SelfTargetingRangeIntention<KtPostfixExpression>(KtPostfixExpression::class.java, "Replace '!!' expression with 'if' expression"),
|
||||
LowPriorityAction {
|
||||
override fun applicabilityRange(element: KtPostfixExpression): TextRange? {
|
||||
return if (element.operationToken == KtTokens.EXCLEXCL && element.baseExpression != null)
|
||||
element.operationReference.textRange
|
||||
@@ -60,12 +57,31 @@ class DoubleBangToIfThenIntention : SelfTargetingRangeIntention<KtPostfixExpress
|
||||
|
||||
val ifStatement = if (isStatement)
|
||||
element.convertToIfNullExpression(base, defaultException)
|
||||
else
|
||||
element.convertToIfNotNullExpression(base, base, defaultException)
|
||||
else {
|
||||
val selectorExpression = element.getQualifiedExpressionForReceiver()?.selectorExpression
|
||||
val thenClause = selectorExpression?.let {
|
||||
KtPsiFactory(element).createExpressionByPattern("$0.$1", base, it)
|
||||
} ?: base
|
||||
val hasSelector = thenClause != base
|
||||
|
||||
if (hasSelector) {
|
||||
val prevSibling = selectorExpression?.prevSibling
|
||||
selectorExpression?.delete()
|
||||
prevSibling?.delete()
|
||||
}
|
||||
|
||||
element.convertToIfNotNullExpression(base, thenClause, defaultException).apply {
|
||||
if (hasSelector) {
|
||||
with(parent) {
|
||||
firstChild.delete()
|
||||
lastChild.delete()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val thrownExpression =
|
||||
((if (isStatement) ifStatement.then else ifStatement.`else`) as KtThrowExpression).thrownExpression!!
|
||||
|
||||
((if (isStatement) ifStatement.then else ifStatement.`else`) as KtThrowExpression).thrownExpression!!
|
||||
val message = StringUtil.escapeStringCharacters("Expression '$expressionText' must not be null")
|
||||
val nullPtrExceptionText = "NullPointerException(\"$message\")"
|
||||
val kotlinNullPtrExceptionText = "KotlinNullPointerException()"
|
||||
@@ -79,7 +95,7 @@ class DoubleBangToIfThenIntention : SelfTargetingRangeIntention<KtPostfixExpress
|
||||
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.document)
|
||||
editor.caretModel.moveToOffset(thrownExpression.node!!.startOffset)
|
||||
|
||||
TemplateManager.getInstance(project).startTemplate(editor, builder.buildInlineTemplate(), object: TemplateEditingAdapter() {
|
||||
TemplateManager.getInstance(project).startTemplate(editor, builder.buildInlineTemplate(), object : TemplateEditingAdapter() {
|
||||
override fun templateFinished(template: Template, brokenOff: Boolean) {
|
||||
if (!isStable && !isStatement) {
|
||||
ifStatement.introduceValueForCondition(ifStatement.then!!, editor)
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// WITH_RUNTIME
|
||||
fun foo(): String? {
|
||||
return "foo"
|
||||
}
|
||||
|
||||
class A {
|
||||
fun f(): Int {
|
||||
return 42
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val a: A? = A()
|
||||
a<caret>!!.f()
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// WITH_RUNTIME
|
||||
fun foo(): String? {
|
||||
return "foo"
|
||||
}
|
||||
|
||||
class A {
|
||||
fun f(): Int {
|
||||
return 42
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val a: A? = A()
|
||||
if (a != null) a.f() else throw NullPointerException("Expression 'a' must not be null")
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// WITH_RUNTIME
|
||||
fun foo(): String? {
|
||||
return "foo"
|
||||
}
|
||||
|
||||
class A {
|
||||
val g = 44
|
||||
fun f(): Int {
|
||||
return 42
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val a: A? = A()
|
||||
a<caret>!!.g
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// WITH_RUNTIME
|
||||
fun foo(): String? {
|
||||
return "foo"
|
||||
}
|
||||
|
||||
class A {
|
||||
val g = 44
|
||||
fun f(): Int {
|
||||
return 42
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val a: A? = A()
|
||||
if (a != null) a.g else throw NullPointerException("Expression 'a' must not be null")
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// WITH_RUNTIME
|
||||
fun foo(): String? {
|
||||
return "foo"
|
||||
}
|
||||
|
||||
class A {
|
||||
fun f(): Int {
|
||||
return 42
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val a: A? = A()
|
||||
val b = a<caret>!!.f()
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// WITH_RUNTIME
|
||||
fun foo(): String? {
|
||||
return "foo"
|
||||
}
|
||||
|
||||
class A {
|
||||
fun f(): Int {
|
||||
return 42
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val a: A? = A()
|
||||
val b = if (a != null) a.f() else throw NullPointerException("Expression 'a' must not be null")
|
||||
}
|
||||
@@ -2059,6 +2059,21 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
||||
runTest("idea/testData/intentions/branched/doubleBangToIfThen/localVar.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("replaceParentExpression.kt")
|
||||
public void testReplaceParentExpression() throws Exception {
|
||||
runTest("idea/testData/intentions/branched/doubleBangToIfThen/replaceParentExpression.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("replaceParentExpression2.kt")
|
||||
public void testReplaceParentExpression2() throws Exception {
|
||||
runTest("idea/testData/intentions/branched/doubleBangToIfThen/replaceParentExpression2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("replaceParentExpression3.kt")
|
||||
public void testReplaceParentExpression3() throws Exception {
|
||||
runTest("idea/testData/intentions/branched/doubleBangToIfThen/replaceParentExpression3.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simpleNameExpressionInParens.kt")
|
||||
public void testSimpleNameExpressionInParens() throws Exception {
|
||||
runTest("idea/testData/intentions/branched/doubleBangToIfThen/simpleNameExpressionInParens.kt");
|
||||
|
||||
Reference in New Issue
Block a user