diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt index 2f8008b59da..2ab621e7eb6 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt @@ -619,7 +619,14 @@ abstract class FirDataFlowAnalyzer( lastNode.flow, argumentVariable, functionCallVariable, - filter = { it.condition.operation == value.toOperation() } + filter = { it.condition.operation == Operation.EqTrue }, + transform = { + when (value) { + ConeBooleanConstantReference.TRUE -> it + ConeBooleanConstantReference.FALSE -> it.invertCondition() + else -> throw IllegalStateException() + } + } ) } diff --git a/compiler/fir/resolve/testData/resolveWithStdlib/contracts/notIsNullOrEmpty.kt b/compiler/fir/resolve/testData/resolveWithStdlib/contracts/notIsNullOrEmpty.kt new file mode 100644 index 00000000000..4a615ff5aa3 --- /dev/null +++ b/compiler/fir/resolve/testData/resolveWithStdlib/contracts/notIsNullOrEmpty.kt @@ -0,0 +1,14 @@ +fun test_1(s: String?) { + when { + !s.isNullOrEmpty() -> s.length // Should be OK + } +} + +fun test_2(s: String?) { + // contracts related + if (s.isNullOrEmpty()) { + s.length // Should be bad + } else { + s.length // Should be OK + } +} diff --git a/compiler/fir/resolve/testData/resolveWithStdlib/contracts/notIsNullOrEmpty.txt b/compiler/fir/resolve/testData/resolveWithStdlib/contracts/notIsNullOrEmpty.txt new file mode 100644 index 00000000000..0f5bdfb67c4 --- /dev/null +++ b/compiler/fir/resolve/testData/resolveWithStdlib/contracts/notIsNullOrEmpty.txt @@ -0,0 +1,20 @@ +FILE: notIsNullOrEmpty.kt + public final fun test_1(s: R|kotlin/String?|): R|kotlin/Unit| { + when () { + R|/s|.R|kotlin/text/isNullOrEmpty|().R|kotlin/Boolean.not|() -> { + R|/s|.R|kotlin/String.length| + } + } + + } + public final fun test_2(s: R|kotlin/String?|): R|kotlin/Unit| { + when () { + R|/s|.R|kotlin/text/isNullOrEmpty|() -> { + R|/s|.# + } + else -> { + R|/s|.R|kotlin/String.length| + } + } + + } diff --git a/compiler/fir/resolve/testData/resolveWithStdlib/problems/complexSmartCasts.kt b/compiler/fir/resolve/testData/resolveWithStdlib/problems/complexSmartCasts.kt index feeb5f29c34..c77ab4db826 100644 --- a/compiler/fir/resolve/testData/resolveWithStdlib/problems/complexSmartCasts.kt +++ b/compiler/fir/resolve/testData/resolveWithStdlib/problems/complexSmartCasts.kt @@ -1,10 +1,3 @@ -fun test_1(s: String?) { - // contracts related - when { - !s.isNullOrEmpty() -> s.length // Should be OK - } -} - fun test_2(s: String?) { s?.let { takeString(it) // Should be OK diff --git a/compiler/fir/resolve/testData/resolveWithStdlib/problems/complexSmartCasts.txt b/compiler/fir/resolve/testData/resolveWithStdlib/problems/complexSmartCasts.txt index 326bda59e4d..7d089d28cb7 100644 --- a/compiler/fir/resolve/testData/resolveWithStdlib/problems/complexSmartCasts.txt +++ b/compiler/fir/resolve/testData/resolveWithStdlib/problems/complexSmartCasts.txt @@ -1,12 +1,4 @@ FILE: complexSmartCasts.kt - public final fun test_1(s: R|kotlin/String?|): R|kotlin/Unit| { - when () { - R|/s|.R|kotlin/text/isNullOrEmpty|().R|kotlin/Boolean.not|() -> { - R|/s|.# - } - } - - } public final fun test_2(s: R|kotlin/String?|): R|kotlin/Unit| { R|/s|?.R|kotlin/let|( = let@fun (it: R|kotlin/String|): R|kotlin/Unit| { R|/takeString|(R|/it|) diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java index e3a93393d4e..94c422e8628 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java @@ -475,6 +475,11 @@ public class FirDiagnosticsWithStdlibTestGenerated extends AbstractFirDiagnostic public void testConditionalEffects() throws Exception { runTest("compiler/fir/resolve/testData/resolveWithStdlib/contracts/conditionalEffects.kt"); } + + @TestMetadata("notIsNullOrEmpty.kt") + public void testNotIsNullOrEmpty() throws Exception { + runTest("compiler/fir/resolve/testData/resolveWithStdlib/contracts/notIsNullOrEmpty.kt"); + } } @TestMetadata("compiler/fir/resolve/testData/resolveWithStdlib/inference") diff --git a/compiler/testData/diagnostics/testsWithStdLib/contracts/fromStdlib/isNullOrBlank.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/contracts/fromStdlib/isNullOrBlank.fir.kt index 40960b5b21e..443bdf08694 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/contracts/fromStdlib/isNullOrBlank.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/contracts/fromStdlib/isNullOrBlank.fir.kt @@ -6,13 +6,13 @@ fun testIsNullOrBlank(x: String?) { x.length } else { - x.length + x.length } } fun testIsNotNullOrBlank(x: String?) { if (!x.isNullOrBlank()) { - x.length + x.length } x.length diff --git a/compiler/testData/diagnostics/testsWithStdLib/contracts/fromStdlib/isNullOrEmpty.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/contracts/fromStdlib/isNullOrEmpty.fir.kt index f33d9520b95..c096243d0a9 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/contracts/fromStdlib/isNullOrEmpty.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/contracts/fromStdlib/isNullOrEmpty.fir.kt @@ -6,13 +6,13 @@ fun testIsNullOrEmpty(x: String?) { x.length } else { - x.length + x.length } } fun testIsNotNullOrEmpty(x: String?) { if (!x.isNullOrEmpty()) { - x.length + x.length } x.length