diff --git a/idea/resources/inspectionDescriptions/FoldInitializerAndIfToElvis.html b/idea/resources/inspectionDescriptions/FoldInitializerAndIfToElvis.html
new file mode 100644
index 00000000000..5035e8fba27
--- /dev/null
+++ b/idea/resources/inspectionDescriptions/FoldInitializerAndIfToElvis.html
@@ -0,0 +1,5 @@
+
+
+This inspection reports an if expression checking variable being null or not of a type right after initializing it that can be converted into an elvis operator in the initializer
+
+
diff --git a/idea/resources/inspectionDescriptions/IfNullToElvis.html b/idea/resources/inspectionDescriptions/IfNullToElvis.html
deleted file mode 100644
index 630afdfe18e..00000000000
--- a/idea/resources/inspectionDescriptions/IfNullToElvis.html
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-This inspection reports an if expression checking variable being null right after initializing it that can be converted into an elvis operator in the initializer
-
-
diff --git a/idea/resources/intentionDescriptions/IfNullToElvisIntention/after.kt.template b/idea/resources/intentionDescriptions/FoldInitializerAndIfToElvisIntention/after.kt.template
similarity index 100%
rename from idea/resources/intentionDescriptions/IfNullToElvisIntention/after.kt.template
rename to idea/resources/intentionDescriptions/FoldInitializerAndIfToElvisIntention/after.kt.template
diff --git a/idea/resources/intentionDescriptions/IfNullToElvisIntention/before.kt.template b/idea/resources/intentionDescriptions/FoldInitializerAndIfToElvisIntention/before.kt.template
similarity index 100%
rename from idea/resources/intentionDescriptions/IfNullToElvisIntention/before.kt.template
rename to idea/resources/intentionDescriptions/FoldInitializerAndIfToElvisIntention/before.kt.template
diff --git a/idea/resources/intentionDescriptions/FoldInitializerAndIfToElvisIntention/description.html b/idea/resources/intentionDescriptions/FoldInitializerAndIfToElvisIntention/description.html
new file mode 100644
index 00000000000..5937182819d
--- /dev/null
+++ b/idea/resources/intentionDescriptions/FoldInitializerAndIfToElvisIntention/description.html
@@ -0,0 +1,5 @@
+
+
+ Converts an if expression checking variable being null or not of a type right after initializing it to an elvis operator in the initializer (if applicable)
+
+
diff --git a/idea/resources/intentionDescriptions/IfNullToElvisIntention/description.html b/idea/resources/intentionDescriptions/IfNullToElvisIntention/description.html
deleted file mode 100644
index d4cd9342ff0..00000000000
--- a/idea/resources/intentionDescriptions/IfNullToElvisIntention/description.html
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
- Converts an if expression checking variable being null right after initializing it to an elvis operator in the initializer (if applicable)
-
-
diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml
index fd99c671ab8..f1b77fa7ce9 100644
--- a/idea/src/META-INF/plugin.xml
+++ b/idea/src/META-INF/plugin.xml
@@ -731,7 +731,7 @@
- org.jetbrains.kotlin.idea.intentions.IfNullToElvisIntention
+ org.jetbrains.kotlin.idea.intentions.FoldInitializerAndIfToElvisIntention
Kotlin
@@ -1451,7 +1451,7 @@
language="kotlin"
/>
- (IfNullToElvisIntention::class)
+class FoldInitializerAndIfToElvisInspection : IntentionBasedInspection(FoldInitializerAndIfToElvisIntention::class)
-class IfNullToElvisIntention : SelfTargetingRangeIntention(KtIfExpression::class.java, "Replace 'if' with elvis operator"){
+class FoldInitializerAndIfToElvisIntention : SelfTargetingRangeIntention(KtIfExpression::class.java, "Replace 'if' with elvis operator"){
override fun applicabilityRange(element: KtIfExpression): TextRange? {
val data = calcData(element) ?: return null
@@ -49,7 +49,7 @@ class IfNullToElvisIntention : SelfTargetingRangeIntention(KtIfE
}
override fun applyTo(element: KtIfExpression, editor: Editor?) {
- val (initializer, declaration, ifNullExpr) = calcData(element)!!
+ val (initializer, declaration, ifNullExpr, typeReference) = calcData(element)!!
val factory = KtPsiFactory(element)
val explicitTypeToSet = when {
@@ -67,6 +67,9 @@ class IfNullToElvisIntention : SelfTargetingRangeIntention(KtIfE
val childRangeAfter = childRangeBefore.withoutLastStatement()
val elvis = factory.createExpressionByPattern("$0 ?: $1", initializer, ifNullExpr) as KtBinaryExpression
+ if (typeReference != null) {
+ elvis.left!!.replace(factory.createExpressionByPattern("$0 as? $1", initializer, typeReference))
+ }
val newElvis = initializer.replaced(elvis)
element.delete()
@@ -82,15 +85,25 @@ class IfNullToElvisIntention : SelfTargetingRangeIntention(KtIfE
private data class Data(
val initializer: KtExpression,
val declaration: KtVariableDeclaration,
- val ifNullExpression: KtExpression
+ val ifNullExpression: KtExpression,
+ val typeChecked: KtTypeReference? = null
)
private fun calcData(ifExpression: KtIfExpression): Data? {
if (ifExpression.`else` != null) return null
- val binaryExpression = ifExpression.condition as? KtBinaryExpression ?: return null
- if (binaryExpression.operationToken != KtTokens.EQEQ) return null
- val value = binaryExpression.expressionComparedToNull() as? KtNameReferenceExpression ?: return null
+ val operationExpression = ifExpression.condition as? KtOperationExpression ?: return null
+ val value = when (operationExpression) {
+ is KtBinaryExpression -> {
+ if (operationExpression.operationToken != KtTokens.EQEQ) return null
+ operationExpression.expressionComparedToNull()
+ }
+ is KtIsExpression -> {
+ if (!operationExpression.isNegated) return null
+ operationExpression.leftHandSide
+ }
+ else -> return null
+ } as? KtNameReferenceExpression ?: return null
if (ifExpression.parent !is KtBlockExpression) return null
val prevStatement = ifExpression.siblings(forward = false, withItself = false)
@@ -99,13 +112,14 @@ class IfNullToElvisIntention : SelfTargetingRangeIntention(KtIfE
if (prevStatement.nameAsName != value.getReferencedNameAsName()) return null
val initializer = prevStatement.initializer ?: return null
val then = ifExpression.then ?: return null
+ val typeReference = (operationExpression as? KtIsExpression)?.typeReference
if (then is KtBlockExpression) {
val statement = then.statements.singleOrNull() ?: return null
- return Data(initializer, prevStatement, statement)
+ return Data(initializer, prevStatement, statement, typeReference)
}
else {
- return Data(initializer, prevStatement, then)
+ return Data(initializer, prevStatement, then, typeReference)
}
}
diff --git a/idea/src/org/jetbrains/kotlin/idea/j2k/J2kPostProcessings.kt b/idea/src/org/jetbrains/kotlin/idea/j2k/J2kPostProcessings.kt
index b55560a5663..3338fa266ba 100644
--- a/idea/src/org/jetbrains/kotlin/idea/j2k/J2kPostProcessings.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/j2k/J2kPostProcessings.kt
@@ -61,7 +61,7 @@ object J2KPostProcessingRegistrar {
registerIntentionBasedProcessing(ConvertToExpressionBodyIntention(convertEmptyToUnit = false)) { it is KtPropertyAccessor }
registerIntentionBasedProcessing(IfThenToSafeAccessIntention())
registerIntentionBasedProcessing(IfThenToElvisIntention())
- registerIntentionBasedProcessing(IfNullToElvisIntention())
+ registerIntentionBasedProcessing(FoldInitializerAndIfToElvisIntention())
registerIntentionBasedProcessing(SimplifyNegatedBinaryExpressionIntention())
registerIntentionBasedProcessing(ReplaceGetOrSetIntention(), additionalChecker = ReplaceGetOrSetInspection.additionalChecker)
registerIntentionBasedProcessing(AddOperatorModifierIntention())
diff --git a/idea/testData/intentions/ifNullToElvis/.intention b/idea/testData/intentions/ifNullToElvis/.intention
index f7463a9e35f..d15cccdf88e 100644
--- a/idea/testData/intentions/ifNullToElvis/.intention
+++ b/idea/testData/intentions/ifNullToElvis/.intention
@@ -1 +1 @@
-org.jetbrains.kotlin.idea.intentions.IfNullToElvisIntention
+org.jetbrains.kotlin.idea.intentions.FoldInitializerAndIfToElvisIntention
diff --git a/idea/testData/intentions/ifNullToElvis/NotIs.kt b/idea/testData/intentions/ifNullToElvis/NotIs.kt
new file mode 100644
index 00000000000..f47f4882e18
--- /dev/null
+++ b/idea/testData/intentions/ifNullToElvis/NotIs.kt
@@ -0,0 +1,4 @@
+fun foo(arg: Any?) {
+ val n = arg
+ if (n !is Int) return
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/ifNullToElvis/NotIs.kt.after b/idea/testData/intentions/ifNullToElvis/NotIs.kt.after
new file mode 100644
index 00000000000..4c479960b6c
--- /dev/null
+++ b/idea/testData/intentions/ifNullToElvis/NotIs.kt.after
@@ -0,0 +1,3 @@
+fun foo(arg: Any?) {
+ val n = arg as? Int ?: return
+}
\ No newline at end of file
diff --git a/idea/testData/quickfix/suppress/inspections/ifNullToElvis.kt b/idea/testData/quickfix/suppress/inspections/ifNullToElvis.kt
index 695bf9e0800..5ced09b4b38 100644
--- a/idea/testData/quickfix/suppress/inspections/ifNullToElvis.kt
+++ b/idea/testData/quickfix/suppress/inspections/ifNullToElvis.kt
@@ -1,4 +1,4 @@
-// "Suppress 'IfNullToElvis' for fun foo" "true"
+// "Suppress 'FoldInitializerAndIfToElvis' for fun foo" "true"
fun foo(p: List, b: Boolean) {
var v = p[0]
@@ -6,4 +6,4 @@ fun foo(p: List, b: Boolean) {
if (b) v = null
}
-// TOOL: org.jetbrains.kotlin.idea.intentions.IfNullToElvisInspection
\ No newline at end of file
+// TOOL: org.jetbrains.kotlin.idea.intentions.FoldInitializerAndIfToElvisInspection
\ No newline at end of file
diff --git a/idea/testData/quickfix/suppress/inspections/ifNullToElvis.kt.after b/idea/testData/quickfix/suppress/inspections/ifNullToElvis.kt.after
index c3589d6d13c..8f623d98b2b 100644
--- a/idea/testData/quickfix/suppress/inspections/ifNullToElvis.kt.after
+++ b/idea/testData/quickfix/suppress/inspections/ifNullToElvis.kt.after
@@ -1,10 +1,10 @@
-// "Suppress 'IfNullToElvis' for fun foo" "true"
+// "Suppress 'FoldInitializerAndIfToElvis' for fun foo" "true"
-@Suppress("IfNullToElvis")
+@Suppress("FoldInitializerAndIfToElvis")
fun foo(p: List, b: Boolean) {
var v = p[0]
if (v == null) return
if (b) v = null
}
-// TOOL: org.jetbrains.kotlin.idea.intentions.IfNullToElvisInspection
\ No newline at end of file
+// TOOL: org.jetbrains.kotlin.idea.intentions.FoldInitializerAndIfToElvisInspection
\ No newline at end of file
diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java
index 166083bad22..0b0775d7eec 100644
--- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java
+++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java
@@ -6463,6 +6463,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
doTest(fileName);
}
+ @TestMetadata("NotIs.kt")
+ public void testNotIs() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/ifNullToElvis/NotIs.kt");
+ doTest(fileName);
+ }
+
@TestMetadata("OtherVar1.kt")
public void testOtherVar1() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/ifNullToElvis/OtherVar1.kt");