[FIR] Fix passing flow from contracts with form returns(false) ...

This commit is contained in:
Dmitriy Novozhilov
2020-02-12 17:44:07 +03:00
parent 643a4b9c3b
commit a4b53b4a20
8 changed files with 51 additions and 20 deletions
@@ -619,7 +619,14 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
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()
}
}
)
}
@@ -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.<!INAPPLICABLE_CANDIDATE!>length<!> // Should be bad
} else {
s.length // Should be OK
}
}
@@ -0,0 +1,20 @@
FILE: notIsNullOrEmpty.kt
public final fun test_1(s: R|kotlin/String?|): R|kotlin/Unit| {
when () {
R|<local>/s|.R|kotlin/text/isNullOrEmpty|().R|kotlin/Boolean.not|() -> {
R|<local>/s|.R|kotlin/String.length|
}
}
}
public final fun test_2(s: R|kotlin/String?|): R|kotlin/Unit| {
when () {
R|<local>/s|.R|kotlin/text/isNullOrEmpty|() -> {
R|<local>/s|.<Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#
}
else -> {
R|<local>/s|.R|kotlin/String.length|
}
}
}
@@ -1,10 +1,3 @@
fun test_1(s: String?) {
// contracts related
when {
!s.isNullOrEmpty() -> s.<!INAPPLICABLE_CANDIDATE!>length<!> // Should be OK
}
}
fun test_2(s: String?) {
s?.let {
takeString(it) // Should be OK
@@ -1,12 +1,4 @@
FILE: complexSmartCasts.kt
public final fun test_1(s: R|kotlin/String?|): R|kotlin/Unit| {
when () {
R|<local>/s|.R|kotlin/text/isNullOrEmpty|().R|kotlin/Boolean.not|() -> {
R|<local>/s|.<Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#
}
}
}
public final fun test_2(s: R|kotlin/String?|): R|kotlin/Unit| {
R|<local>/s|?.R|kotlin/let|<R|kotlin/String|, R|kotlin/Unit|>(<L> = let@fun <anonymous>(it: R|kotlin/String|): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
R|/takeString|(R|<local>/it|)
@@ -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")
@@ -6,13 +6,13 @@ fun testIsNullOrBlank(x: String?) {
x.<!INAPPLICABLE_CANDIDATE!>length<!>
}
else {
x.<!INAPPLICABLE_CANDIDATE!>length<!>
x.length
}
}
fun testIsNotNullOrBlank(x: String?) {
if (!x.isNullOrBlank()) {
x.<!INAPPLICABLE_CANDIDATE!>length<!>
x.length
}
x.<!INAPPLICABLE_CANDIDATE!>length<!>
@@ -6,13 +6,13 @@ fun testIsNullOrEmpty(x: String?) {
x.<!INAPPLICABLE_CANDIDATE!>length<!>
}
else {
x.<!INAPPLICABLE_CANDIDATE!>length<!>
x.length
}
}
fun testIsNotNullOrEmpty(x: String?) {
if (!x.isNullOrEmpty()) {
x.<!INAPPLICABLE_CANDIDATE!>length<!>
x.length
}
x.<!INAPPLICABLE_CANDIDATE!>length<!>