KT-11870 "Replace with Elvis" refactoring doesn't change the variable type from T? to T
#KT-11870 Fixed
This commit is contained in:
@@ -30,7 +30,9 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.siblings
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.types.typeUtil.isNothing
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
import java.util.*
|
||||
|
||||
@@ -51,10 +53,15 @@ class IfNullToElvisIntention : SelfTargetingRangeIntention<KtIfExpression>(KtIfE
|
||||
val (initializer, declaration, ifNullExpr) = calcData(element)!!
|
||||
val factory = KtPsiFactory(element)
|
||||
|
||||
val explicitTypeToAdd = if (declaration.isVar && declaration.typeReference == null)
|
||||
initializer.analyze().getType(initializer)
|
||||
else
|
||||
null
|
||||
val explicitTypeToSet = when {
|
||||
// for var with no explicit type, add it so that the actual change won't change
|
||||
declaration.isVar && declaration.typeReference == null -> initializer.analyze(BodyResolveMode.PARTIAL).getType(initializer)
|
||||
|
||||
// for val with explicit type, change it to non-nullable
|
||||
!declaration.isVar && declaration.typeReference != null -> initializer.analyze(BodyResolveMode.PARTIAL).getType(initializer)?.makeNotNullable()
|
||||
|
||||
else -> null
|
||||
}
|
||||
|
||||
// do not loose any comments!
|
||||
val comments = element.extractComments(ifNullExpr)
|
||||
@@ -68,8 +75,8 @@ class IfNullToElvisIntention : SelfTargetingRangeIntention<KtIfExpression>(KtIfE
|
||||
val newElvis = initializer.replaced(elvis)
|
||||
element.delete()
|
||||
|
||||
if (explicitTypeToAdd != null && !explicitTypeToAdd.isError) {
|
||||
declaration.setType(explicitTypeToAdd)
|
||||
if (explicitTypeToSet != null && !explicitTypeToSet.isError) {
|
||||
declaration.setType(explicitTypeToSet)
|
||||
}
|
||||
|
||||
editor?.caretModel?.moveToOffset(newElvis.right!!.textOffset)
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// WITH_RUNTIME
|
||||
fun foo(): String? = null
|
||||
|
||||
fun bar() {
|
||||
val v: String? = foo()
|
||||
<caret>if (v == null) throw Exception()
|
||||
v.length
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// WITH_RUNTIME
|
||||
fun foo(): String? = null
|
||||
|
||||
fun bar() {
|
||||
val v: String = foo() ?: throw Exception()
|
||||
v.length
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun foo(): String? = null
|
||||
|
||||
fun bar() {
|
||||
var v: String? = foo()
|
||||
<caret>if (v == null) throw Exception()
|
||||
v = null
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun foo(): String? = null
|
||||
|
||||
fun bar() {
|
||||
var v: String? = foo() ?: throw Exception()
|
||||
v = null
|
||||
}
|
||||
@@ -5358,6 +5358,18 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ExplicitValType.kt")
|
||||
public void testExplicitValType() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/ifNullToElvis/ExplicitValType.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ExplicitVarType.kt")
|
||||
public void testExplicitVarType() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/ifNullToElvis/ExplicitVarType.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("IfNotNull.kt")
|
||||
public void testIfNotNull() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/ifNullToElvis/IfNotNull.kt");
|
||||
|
||||
Reference in New Issue
Block a user