[FIR] Add ReturnsImplies effect analyzer

This commit is contained in:
Oleg Ivanov
2020-08-11 12:41:43 +03:00
parent 3454ae7ca4
commit 21b8679799
37 changed files with 1110 additions and 89 deletions
@@ -53,8 +53,8 @@ fun case_8(value_1: Any?) {
if (!funWithReturnsTrueAndInvertCondition(value_1 !is String)) <!AMBIGUITY!>println<!>(value_1.<!UNRESOLVED_REFERENCE!>length<!>)
if (funWithReturnsFalse(value_1 is String)) <!AMBIGUITY!>println<!>(value_1.<!UNRESOLVED_REFERENCE!>length<!>)
if (funWithReturnsFalseAndInvertCondition(value_1 !is String)) <!AMBIGUITY!>println<!>(value_1.<!UNRESOLVED_REFERENCE!>length<!>)
if (funWithReturnsNotNull(value_1 is String) == null) println(value_1.length)
if (!(funWithReturnsNotNull(value_1 is String) != null)) println(value_1.length)
if (funWithReturnsNotNull(value_1 is String) == null) <!AMBIGUITY!>println<!>(value_1.<!UNRESOLVED_REFERENCE!>length<!>)
if (!(funWithReturnsNotNull(value_1 is String) != null)) <!AMBIGUITY!>println<!>(value_1.<!UNRESOLVED_REFERENCE!>length<!>)
if (!(funWithReturnsNull(value_1 is String) == null)) <!AMBIGUITY!>println<!>(value_1.<!UNRESOLVED_REFERENCE!>length<!>)
if (funWithReturnsNull(value_1 is String) != null) <!AMBIGUITY!>println<!>(value_1.<!UNRESOLVED_REFERENCE!>length<!>)
}
@@ -65,8 +65,8 @@ fun case_9(value_1: String?) {
if (!funWithReturnsTrueAndInvertCondition(value_1 == null)) println(value_1.<!INAPPLICABLE_CANDIDATE!>length<!>)
if (funWithReturnsFalse(value_1 != null)) println(value_1.<!INAPPLICABLE_CANDIDATE!>length<!>)
if (funWithReturnsFalseAndInvertCondition(value_1 == null)) println(value_1.<!INAPPLICABLE_CANDIDATE!>length<!>)
if (funWithReturnsNotNull(value_1 != null) == null) println(value_1.length)
if (funWithReturnsNotNullAndInvertCondition(value_1 == null) == null) println(value_1.length)
if (funWithReturnsNotNull(value_1 != null) == null) println(value_1.<!INAPPLICABLE_CANDIDATE!>length<!>)
if (funWithReturnsNotNullAndInvertCondition(value_1 == null) == null) println(value_1.<!INAPPLICABLE_CANDIDATE!>length<!>)
if (funWithReturnsNull(value_1 != null) != null) println(value_1.<!INAPPLICABLE_CANDIDATE!>length<!>)
if (funWithReturnsNullAndInvertCondition(value_1 == null) != null) println(value_1.<!INAPPLICABLE_CANDIDATE!>length<!>)
}
@@ -75,8 +75,8 @@ fun case_9(value_1: String?) {
fun case_10(value_1: Any?) {
if (!funWithReturnsTrueAndTypeCheck(value_1)) <!AMBIGUITY!>println<!>(value_1.<!UNRESOLVED_REFERENCE!>length<!>)
if (!!funWithReturnsFalseAndTypeCheck(value_1)) <!AMBIGUITY!>println<!>(value_1.<!UNRESOLVED_REFERENCE!>length<!>)
if (!(funWithReturnsNotNullAndTypeCheck(value_1) != null)) println(value_1.length)
if (!!(funWithReturnsNotNullAndTypeCheck(value_1) == null)) println(value_1.length)
if (!(funWithReturnsNotNullAndTypeCheck(value_1) != null)) <!AMBIGUITY!>println<!>(value_1.<!UNRESOLVED_REFERENCE!>length<!>)
if (!!(funWithReturnsNotNullAndTypeCheck(value_1) == null)) <!AMBIGUITY!>println<!>(value_1.<!UNRESOLVED_REFERENCE!>length<!>)
if (!!(funWithReturnsNullAndTypeCheck(value_1) != null)) <!AMBIGUITY!>println<!>(value_1.<!UNRESOLVED_REFERENCE!>length<!>)
if (!(funWithReturnsNullAndTypeCheck(value_1) == null)) <!AMBIGUITY!>println<!>(value_1.<!UNRESOLVED_REFERENCE!>length<!>)
}
@@ -87,8 +87,8 @@ fun case_11(value_1: Number?) {
if (!funWithReturnsTrueAndNullCheck(value_1)) println(value_1)
if (funWithReturnsFalseAndNotNullCheck(value_1)) println(value_1.<!INAPPLICABLE_CANDIDATE!>toByte<!>())
if (funWithReturnsFalseAndNullCheck(value_1)) println(value_1)
if ((funWithReturnsNotNullAndNotNullCheck(value_1) == null)) println(value_1.toByte())
if (!!!(funWithReturnsNotNullAndNotNullCheck(value_1) != null)) println(value_1.toByte())
if ((funWithReturnsNotNullAndNotNullCheck(value_1) == null)) println(value_1.<!INAPPLICABLE_CANDIDATE!>toByte<!>())
if (!!!(funWithReturnsNotNullAndNotNullCheck(value_1) != null)) println(value_1.<!INAPPLICABLE_CANDIDATE!>toByte<!>())
if (!!(funWithReturnsNotNullAndNullCheck(value_1) == null)) println(value_1)
if (!(funWithReturnsNullAndNotNullCheck(value_1) == null)) println(value_1.<!INAPPLICABLE_CANDIDATE!>toByte<!>())
if (!!(funWithReturnsNullAndNotNullCheck(value_1) != null)) println(value_1.<!INAPPLICABLE_CANDIDATE!>toByte<!>())
@@ -9,45 +9,45 @@ import kotlin.contracts.*
// TESTCASE NUMBER: 3
fun <T> T?.case_3(value_1: Int?, value_2: Boolean): Boolean {
contract {
<!WRONG_IMPLIES_CONDITION!>contract {
returns(true) implies (value_1 != null)
returns(false) implies (value_1 == null && !value_2)
returns(null) implies (value_1 == null && value_2)
}
}<!>
return value_1 == null
}
// TESTCASE NUMBER: 4
fun case_4(value_1: Number, block: (() -> Unit)?): Boolean? {
contract {
<!WRONG_IMPLIES_CONDITION, WRONG_IMPLIES_CONDITION!>contract {
returns(true) implies (block != null)
returns(false) implies (value_1 is Int)
returns(null) implies (block == null)
}
}<!>
return value_1 == null
}
// TESTCASE NUMBER: 5
fun String?.case_5(value_1: Number?): Boolean? {
contract {
<!WRONG_IMPLIES_CONDITION!>contract {
returns(true) implies (value_1 == null)
returns(false) implies (this@case_5 == null)
returnsNotNull() implies (value_1 is Int)
}
}<!>
return value_1 == null
}
// TESTCASE NUMBER: 6
fun <T> T?.case_6(value_1: Number, value_2: String?): Boolean? {
contract {
<!WRONG_IMPLIES_CONDITION!>contract {
returns(true) implies (this@case_6 == null)
returns(false) implies (value_1 is Int)
returns(null) implies (this@case_6 is String)
returnsNotNull() implies (value_2 == null)
}
}<!>
return value_1 == null
}
@@ -62,7 +62,7 @@ fun case_1(value_1: Any?) {
<!AMBIGUITY!>println<!>(value_1?.<!UNRESOLVED_REFERENCE!>toByte<!>())
if (funWithReturnsTrue(value_1 !is Number)) {
<!AMBIGUITY!>println<!>(value_1.<!UNRESOLVED_REFERENCE!>toByte<!>())
if (funWithReturnsNotNull(value_1 is Int) == null) println(value_1.inv())
if (funWithReturnsNotNull(value_1 is Int) == null) <!AMBIGUITY!>println<!>(value_1.inv())
}
}
@@ -52,8 +52,8 @@ fun case_8(value_1: Any?) {
if (funWithReturnsTrueAndInvertCondition(value_1 !is String)) println(value_1.length)
if (!funWithReturnsFalse(value_1 is String)) println(value_1.length)
if (!funWithReturnsFalseAndInvertCondition(value_1 !is String)) println(value_1.length)
if (funWithReturnsNotNull(value_1 is String) != null) <!AMBIGUITY!>println<!>(value_1.<!UNRESOLVED_REFERENCE!>length<!>)
if (!(funWithReturnsNotNull(value_1 is String) == null)) <!AMBIGUITY!>println<!>(value_1.<!UNRESOLVED_REFERENCE!>length<!>)
if (funWithReturnsNotNull(value_1 is String) != null) println(value_1.length)
if (!(funWithReturnsNotNull(value_1 is String) == null)) println(value_1.length)
}
// TESTCASE NUMBER: 9
@@ -62,17 +62,17 @@ fun case_9(value_1: String?) {
if (funWithReturnsTrueAndInvertCondition(value_1 == null)) println(value_1.length)
if (!funWithReturnsFalse(value_1 != null)) println(value_1.length)
if (!funWithReturnsFalseAndInvertCondition(value_1 == null)) println(value_1.length)
if (funWithReturnsNotNull(value_1 != null) != null) println(value_1.<!INAPPLICABLE_CANDIDATE!>length<!>)
if (!(funWithReturnsNotNull(value_1 != null) == null)) println(value_1.<!INAPPLICABLE_CANDIDATE!>length<!>)
if (!(funWithReturnsNotNullAndInvertCondition(value_1 == null) == null)) println(value_1.<!INAPPLICABLE_CANDIDATE!>length<!>)
if (funWithReturnsNotNull(value_1 != null) != null) println(value_1.length)
if (!(funWithReturnsNotNull(value_1 != null) == null)) println(value_1.length)
if (!(funWithReturnsNotNullAndInvertCondition(value_1 == null) == null)) println(value_1.length)
}
// TESTCASE NUMBER: 10
fun case_10(value_1: Any?) {
if (funWithReturnsTrueAndTypeCheck(value_1)) println(value_1.length)
if (!funWithReturnsFalseAndTypeCheck(value_1)) println(value_1.length)
if (funWithReturnsNotNullAndTypeCheck(value_1) != null) <!AMBIGUITY!>println<!>(value_1.<!UNRESOLVED_REFERENCE!>length<!>)
if (!(funWithReturnsNotNullAndTypeCheck(value_1) == null)) <!AMBIGUITY!>println<!>(value_1.<!UNRESOLVED_REFERENCE!>length<!>)
if (funWithReturnsNotNullAndTypeCheck(value_1) != null) println(value_1.length)
if (!(funWithReturnsNotNullAndTypeCheck(value_1) == null)) println(value_1.length)
}
// TESTCASE NUMBER: 11
@@ -82,7 +82,7 @@ fun case_11(value_1: Number?, value_2: Int?) {
if (!funWithReturnsFalseAndNotNullCheck(value_2)) value_2.inc()
if (!funWithReturnsFalseAndNotNullCheck(value_1)) println(value_1.toByte())
if (!funWithReturnsFalseAndNullCheck(value_1)) println(value_1)
if (!(funWithReturnsNotNullAndNotNullCheck(value_1) == null)) println(value_1.<!INAPPLICABLE_CANDIDATE!>toByte<!>())
if (funWithReturnsNotNullAndNotNullCheck(value_1) != null) println(value_1.<!INAPPLICABLE_CANDIDATE!>toByte<!>())
if (!(funWithReturnsNotNullAndNotNullCheck(value_1) == null)) println(value_1.toByte())
if (funWithReturnsNotNullAndNotNullCheck(value_1) != null) println(value_1.toByte())
if (funWithReturnsNotNullAndNullCheck(value_1) != null) println(value_1)
}
@@ -15,7 +15,7 @@ fun case_1(value_1: Int?, value_2: Int? = 10): Boolean {
// TESTCASE NUMBER: 2
fun case_2(value_1: Int? = 10, value_2: Int? = 10, value_3: Int? = 10): Boolean {
contract { returns(true) implies (value_2 != null) }
<!WRONG_IMPLIES_CONDITION!>contract { returns(true) implies (value_2 != null) }<!>
return value_1 != null
}
@@ -17,27 +17,27 @@ fun case_1(value_1: Int?): Boolean? {
// TESTCASE NUMBER: 2
fun case_2(value_1: Int?): Boolean {
contract {
<!WRONG_IMPLIES_CONDITION!>contract {
returns(false) implies (value_1 != null)
}
}<!>
return value_1 != null
}
// TESTCASE NUMBER: 3
fun case_3(value_1: Int?): Boolean? {
contract {
<!WRONG_IMPLIES_CONDITION!>contract {
returnsNotNull() implies (value_1 != null)
}
}<!>
return value_1 != null
}
// TESTCASE NUMBER: 4
fun case_4(value_1: Any?): Boolean {
contract {
<!WRONG_IMPLIES_CONDITION!>contract {
returnsNotNull() implies (value_1 is Number)
}
}<!>
return value_1 is Number
}
@@ -70,6 +70,6 @@ fun case_3(value_1: Int?) {
// TESTCASE NUMBER: 4
fun case_4(value_1: Any?) {
if (contracts.case_4(value_1) != null) {
value_1.<!UNRESOLVED_REFERENCE!>toByte<!>()
value_1.toByte()
}
}
@@ -20,34 +20,34 @@ fun <T> T?.case_3(value_1: Int?, value_2: Boolean): Boolean {
// TESTCASE NUMBER: 4
fun case_4(value_1: Number, block: (() -> Unit)?): Boolean? {
contract {
<!WRONG_IMPLIES_CONDITION!>contract {
returns(true) implies (value_1 is Int)
returns(false) implies (block == null)
returns(null) implies (block != null)
}
}<!>
return value_1 == null
}
// TESTCASE NUMBER: 5
fun String?.case_5(value_1: Number?): Boolean? {
contract {
<!WRONG_IMPLIES_CONDITION, WRONG_IMPLIES_CONDITION, WRONG_IMPLIES_CONDITION!>contract {
returns(true) implies (value_1 != null)
returns(false) implies (value_1 is Int)
returnsNotNull() implies (this@case_5 != null)
}
}<!>
return value_1 == null
}
// TESTCASE NUMBER: 6
fun <T> T?.case_6(value_1: Number, value_2: String?): Boolean? {
contract {
<!WRONG_IMPLIES_CONDITION, WRONG_IMPLIES_CONDITION, WRONG_IMPLIES_CONDITION!>contract {
returns(true) implies (this@case_6 != null)
returns(false) implies (this@case_6 is String)
returns(null) implies (value_1 is Int)
returnsNotNull() implies (value_2 != null)
}
}<!>
return value_1 == null
}
@@ -62,7 +62,7 @@ fun case_1(value_1: Any?) {
println(value_1?.toByte())
if (funWithReturnsTrue(value_1 is Number)) {
println(value_1.toByte())
if (funWithReturnsNotNull(value_1 is Int) != null) <!AMBIGUITY!>println<!>(value_1.inv())
if (funWithReturnsNotNull(value_1 is Int) != null) println(value_1.inv())
}
}