diff --git a/plugins/kotlin/code-insight/impl-base/src/org/jetbrains/kotlin/idea/codeInsight/IfThenTransformationUtils.kt b/plugins/kotlin/code-insight/impl-base/src/org/jetbrains/kotlin/idea/codeInsight/IfThenTransformationUtils.kt index e1c44a729181..2f9a45e467cf 100644 --- a/plugins/kotlin/code-insight/impl-base/src/org/jetbrains/kotlin/idea/codeInsight/IfThenTransformationUtils.kt +++ b/plugins/kotlin/code-insight/impl-base/src/org/jetbrains/kotlin/idea/codeInsight/IfThenTransformationUtils.kt @@ -205,7 +205,7 @@ object IfThenTransformationUtils { context(KaSession) fun prepareIfThenToElvisInspectionData(element: KtIfExpression): IfThenToElvisInspectionData? { - val transformationData = IfThenTransformationUtils.buildTransformationData(element) ?: return null + val transformationData = buildTransformationData(element) ?: return null val transformationStrategy = IfThenTransformationStrategy.create(transformationData) ?: return null if (element.expressionType?.isUnitType != false) return null @@ -234,7 +234,7 @@ object IfThenTransformationUtils { private fun KaSession.clausesReplaceableByElvis(data: IfThenTransformationData): Boolean = when { - data.negatedClause == null || data.negatedClause?.isNullOrBlockExpression() == true -> + data.negatedClause == null || data.negatedClause.isNullOrBlockExpression() == true -> false (data.negatedClause as? KtThrowExpression)?.let { throwsNullPointerExceptionWithNoArguments(it) } == true -> false @@ -245,7 +245,8 @@ object IfThenTransformationUtils { data.baseClause.anyArgumentEvaluatesTo(data.checkedExpression) -> true hasImplicitReceiverReplaceableBySafeCall(data) || data.baseClause.hasFirstReceiverOf(data.checkedExpression) -> - data.baseClause.expressionType?.canBeNull == false + generateSequence(data.baseClause) { (it as? KtDotQualifiedExpression)?.receiverExpression }.toList() + .all { it.expressionType?.canBeNull == false || it.smartCastInfo?.smartCastType?.canBeNull == false } else -> false } diff --git a/plugins/kotlin/code-insight/inspections-k2/tests/test/org/jetbrains/kotlin/idea/k2/inspections/tests/K2LocalInspectionTestGenerated.java b/plugins/kotlin/code-insight/inspections-k2/tests/test/org/jetbrains/kotlin/idea/k2/inspections/tests/K2LocalInspectionTestGenerated.java index 0a246db179b6..54eefb9f0a2e 100644 --- a/plugins/kotlin/code-insight/inspections-k2/tests/test/org/jetbrains/kotlin/idea/k2/inspections/tests/K2LocalInspectionTestGenerated.java +++ b/plugins/kotlin/code-insight/inspections-k2/tests/test/org/jetbrains/kotlin/idea/k2/inspections/tests/K2LocalInspectionTestGenerated.java @@ -742,6 +742,16 @@ public abstract class K2LocalInspectionTestGenerated extends AbstractK2LocalInsp runTest("../../../idea/tests/testData/inspectionsLocal/branched/ifThenToElvis/nullCheckWithSelectorCallChain.kt"); } + @TestMetadata("nullabilityInReceiversOfBaseCause.kt") + public void testNullabilityInReceiversOfBaseCause() throws Exception { + runTest("../../../idea/tests/testData/inspectionsLocal/branched/ifThenToElvis/nullabilityInReceiversOfBaseCause.kt"); + } + + @TestMetadata("nullabilityInReceiversOfBaseCause1.kt") + public void testNullabilityInReceiversOfBaseCause1() throws Exception { + runTest("../../../idea/tests/testData/inspectionsLocal/branched/ifThenToElvis/nullabilityInReceiversOfBaseCause1.kt"); + } + @TestMetadata("nullableResultWithImplicitReceiver.kt") public void testNullableResultWithImplicitReceiver() throws Exception { runTest("../../../idea/tests/testData/inspectionsLocal/branched/ifThenToElvis/nullableResultWithImplicitReceiver.kt"); diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java index 5d3af246a0af..8ef6cd473624 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java @@ -453,6 +453,16 @@ public abstract class LocalInspectionTestGenerated extends AbstractLocalInspecti runTest("testData/inspectionsLocal/branched/ifThenToElvis/nullCheckWithSelectorCallChain.kt"); } + @TestMetadata("nullabilityInReceiversOfBaseCause.kt") + public void testNullabilityInReceiversOfBaseCause() throws Exception { + runTest("testData/inspectionsLocal/branched/ifThenToElvis/nullabilityInReceiversOfBaseCause.kt"); + } + + @TestMetadata("nullabilityInReceiversOfBaseCause1.kt") + public void testNullabilityInReceiversOfBaseCause1() throws Exception { + runTest("testData/inspectionsLocal/branched/ifThenToElvis/nullabilityInReceiversOfBaseCause1.kt"); + } + @TestMetadata("nullableResultWithImplicitReceiver.kt") public void testNullableResultWithImplicitReceiver() throws Exception { runTest("testData/inspectionsLocal/branched/ifThenToElvis/nullableResultWithImplicitReceiver.kt"); diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/branched/ifThenToElvis/nullabilityInReceiversOfBaseCause.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/branched/ifThenToElvis/nullabilityInReceiversOfBaseCause.kt new file mode 100644 index 000000000000..b547fcc9d00c --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/branched/ifThenToElvis/nullabilityInReceiversOfBaseCause.kt @@ -0,0 +1,13 @@ +// WITH_STDLIB +// PROBLEM: none +data class Parent( + val child: Int?, +) + +fun function(parent: Parent?) = if (parent == null) { + "placeholder" +} else { + parent.child?.toString().orEmpty() +} + +// IGNORE_K1 \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/branched/ifThenToElvis/nullabilityInReceiversOfBaseCause1.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/branched/ifThenToElvis/nullabilityInReceiversOfBaseCause1.kt new file mode 100644 index 000000000000..45b8e038bc05 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/branched/ifThenToElvis/nullabilityInReceiversOfBaseCause1.kt @@ -0,0 +1,17 @@ +// PROBLEM: none +data class Sas(val f: Int?) +fun Int?.exampleFun() = when (this) { + null -> "a" + else -> "b" +} + +fun getSas() : Sas? = Sas(null) + +fun main() { + val sas = getSas() + val str = if (sas == null) "null!!!" else sas.f.exampleFun() + + println(str) +} + +// IGNORE_K1 \ No newline at end of file