Add few tests for contracts
- Contracts in getter/setter (unexpected behaviour) - Check smartcasts when non-null assertion for a contract function is used - Check work of contracts when type parameter of the callsInPlace is specify explicitly - Check smartcasts working if type checking for contract function is used
This commit is contained in:
+58
@@ -0,0 +1,58 @@
|
||||
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect
|
||||
// !WITH_CONTRACT_FUNCTIONS
|
||||
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
|
||||
|
||||
/*
|
||||
KOTLIN DIAGNOSTICS NOT LINKED SPEC TEST (NEGATIVE)
|
||||
|
||||
SECTION: contracts
|
||||
CATEGORIES: analysis, smartcasts
|
||||
NUMBER: 15
|
||||
DESCRIPTION: Check smartcasts working if type checking for contract function is used
|
||||
UNEXPECTED BEHAVIOUR
|
||||
ISSUES: KT-27241
|
||||
*/
|
||||
|
||||
// FILE: contracts.kt
|
||||
|
||||
package contracts
|
||||
|
||||
import kotlin.contracts.*
|
||||
|
||||
fun case_1_1(cond: Boolean): Any {
|
||||
contract { returns(true) implies cond }
|
||||
return cond
|
||||
}
|
||||
|
||||
fun case_1_2(value: Any): Boolean {
|
||||
contract { returns(true) implies (value is Boolean) }
|
||||
return value is Boolean
|
||||
}
|
||||
|
||||
fun case_2(cond: Boolean): Any {
|
||||
contract { returns(true) implies cond }
|
||||
return cond
|
||||
}
|
||||
|
||||
// FILE: usages.kt
|
||||
|
||||
import contracts.*
|
||||
|
||||
fun case_1(value: Any) {
|
||||
if (contracts.case_1_2(contracts.case_1_1(value is Char))) {
|
||||
println(<!DEBUG_INFO_SMARTCAST!>value<!>.category)
|
||||
}
|
||||
}
|
||||
|
||||
fun case_2(value: Any) {
|
||||
if (contracts.case_2(value is Char) is Boolean) {
|
||||
println(<!DEBUG_INFO_SMARTCAST!>value<!>.category)
|
||||
}
|
||||
}
|
||||
|
||||
fun case_3(value: String?) {
|
||||
if (<!USELESS_IS_CHECK!>!value.isNullOrEmpty() is Boolean<!>) {
|
||||
<!DEBUG_INFO_SMARTCAST!>value<!>.length
|
||||
}
|
||||
}
|
||||
Vendored
+124
@@ -0,0 +1,124 @@
|
||||
package
|
||||
|
||||
public fun case_1(/*0*/ value: kotlin.Any): kotlin.Unit
|
||||
public fun case_2(/*0*/ value: kotlin.Any): kotlin.Unit
|
||||
public fun case_3(/*0*/ value: kotlin.String?): kotlin.Unit
|
||||
public inline fun </*0*/ T> funWithAtLeastOnceCallsInPlace(/*0*/ block: () -> T): T
|
||||
CallsInPlace(block, AT_LEAST_ONCE)
|
||||
|
||||
public inline fun funWithAtLeastOnceCallsInPlace(/*0*/ block: () -> kotlin.Unit): kotlin.Unit
|
||||
CallsInPlace(block, AT_LEAST_ONCE)
|
||||
|
||||
public inline fun funWithAtMostOnceCallsInPlace(/*0*/ block: () -> kotlin.Unit): kotlin.Unit
|
||||
CallsInPlace(block, AT_MOST_ONCE)
|
||||
|
||||
public inline fun </*0*/ T> funWithExactlyOnceCallsInPlace(/*0*/ block: () -> T): T
|
||||
CallsInPlace(block, EXACTLY_ONCE)
|
||||
|
||||
public inline fun funWithExactlyOnceCallsInPlace(/*0*/ block: () -> kotlin.Unit): kotlin.Unit
|
||||
CallsInPlace(block, EXACTLY_ONCE)
|
||||
|
||||
public fun funWithReturns(/*0*/ cond: kotlin.Boolean): kotlin.Unit
|
||||
Returns(WILDCARD) -> cond
|
||||
|
||||
public fun funWithReturnsAndInvertCondition(/*0*/ cond: kotlin.Boolean): kotlin.Unit
|
||||
Returns(WILDCARD) -> !cond
|
||||
|
||||
public fun funWithReturnsAndInvertTypeCheck(/*0*/ value_1: kotlin.Any?): kotlin.Unit
|
||||
Returns(WILDCARD) -> value_1 !is String
|
||||
|
||||
public fun funWithReturnsAndNotNullCheck(/*0*/ value_1: kotlin.Any?): kotlin.Unit
|
||||
Returns(WILDCARD) -> value_1 != null
|
||||
|
||||
public fun funWithReturnsAndNullCheck(/*0*/ value_1: kotlin.Any?): kotlin.Unit
|
||||
Returns(WILDCARD) -> value_1 == null
|
||||
|
||||
public fun funWithReturnsAndTypeCheck(/*0*/ value_1: kotlin.Any?): kotlin.Unit
|
||||
Returns(WILDCARD) -> value_1 is String
|
||||
|
||||
public fun funWithReturnsFalse(/*0*/ cond: kotlin.Boolean): kotlin.Boolean
|
||||
Returns(FALSE) -> cond
|
||||
|
||||
public fun funWithReturnsFalseAndInvertCondition(/*0*/ cond: kotlin.Boolean): kotlin.Boolean
|
||||
Returns(FALSE) -> !cond
|
||||
|
||||
public fun funWithReturnsFalseAndInvertTypeCheck(/*0*/ value_1: kotlin.Any?): kotlin.Boolean
|
||||
Returns(FALSE) -> value_1 !is String
|
||||
|
||||
public fun funWithReturnsFalseAndNotNullCheck(/*0*/ value_1: kotlin.Number?): kotlin.Boolean
|
||||
Returns(FALSE) -> value_1 != null
|
||||
|
||||
public fun funWithReturnsFalseAndNullCheck(/*0*/ value_1: kotlin.Number?): kotlin.Boolean
|
||||
Returns(FALSE) -> value_1 == null
|
||||
|
||||
public fun funWithReturnsFalseAndTypeCheck(/*0*/ value_1: kotlin.Any?): kotlin.Boolean
|
||||
Returns(FALSE) -> value_1 is String
|
||||
|
||||
public fun funWithReturnsNotNull(/*0*/ cond: kotlin.Boolean): kotlin.Boolean?
|
||||
Returns(NOT_NULL) -> cond
|
||||
|
||||
public fun funWithReturnsNotNullAndInvertCondition(/*0*/ cond: kotlin.Boolean): kotlin.Boolean?
|
||||
Returns(NOT_NULL) -> !cond
|
||||
|
||||
public fun funWithReturnsNotNullAndInvertTypeCheck(/*0*/ value_1: kotlin.Any?): kotlin.Boolean?
|
||||
Returns(NOT_NULL) -> value_1 !is String
|
||||
|
||||
public fun funWithReturnsNotNullAndNotNullCheck(/*0*/ value_1: kotlin.Number?): kotlin.Boolean?
|
||||
Returns(NOT_NULL) -> value_1 != null
|
||||
|
||||
public fun funWithReturnsNotNullAndNullCheck(/*0*/ value_1: kotlin.Number?): kotlin.Boolean?
|
||||
Returns(NOT_NULL) -> value_1 == null
|
||||
|
||||
public fun funWithReturnsNotNullAndTypeCheck(/*0*/ value_1: kotlin.Any?): kotlin.Boolean?
|
||||
Returns(NOT_NULL) -> value_1 is String
|
||||
|
||||
public fun funWithReturnsNull(/*0*/ cond: kotlin.Boolean): kotlin.Boolean?
|
||||
Returns(NULL) -> cond
|
||||
|
||||
public fun funWithReturnsNullAndInvertCondition(/*0*/ cond: kotlin.Boolean): kotlin.Boolean?
|
||||
Returns(NULL) -> !cond
|
||||
|
||||
public fun funWithReturnsNullAndInvertTypeCheck(/*0*/ value_1: kotlin.Any?): kotlin.Boolean?
|
||||
Returns(NULL) -> value_1 !is String
|
||||
|
||||
public fun funWithReturnsNullAndNotNullCheck(/*0*/ value_1: kotlin.Number?): kotlin.Boolean?
|
||||
Returns(NULL) -> value_1 != null
|
||||
|
||||
public fun funWithReturnsNullAndNullCheck(/*0*/ value_1: kotlin.Number?): kotlin.Boolean?
|
||||
Returns(NULL) -> value_1 == null
|
||||
|
||||
public fun funWithReturnsNullAndTypeCheck(/*0*/ value_1: kotlin.Any?): kotlin.Boolean?
|
||||
Returns(NULL) -> value_1 is String
|
||||
|
||||
public fun funWithReturnsTrue(/*0*/ cond: kotlin.Boolean): kotlin.Boolean
|
||||
Returns(TRUE) -> cond
|
||||
|
||||
public fun funWithReturnsTrueAndInvertCondition(/*0*/ cond: kotlin.Boolean): kotlin.Boolean
|
||||
Returns(TRUE) -> !cond
|
||||
|
||||
public fun funWithReturnsTrueAndInvertTypeCheck(/*0*/ value_1: kotlin.Any?): kotlin.Boolean
|
||||
Returns(TRUE) -> value_1 !is String
|
||||
|
||||
public fun funWithReturnsTrueAndNotNullCheck(/*0*/ value_1: kotlin.Any?): kotlin.Boolean
|
||||
Returns(TRUE) -> value_1 != null
|
||||
|
||||
public fun funWithReturnsTrueAndNullCheck(/*0*/ value_1: kotlin.Any?): kotlin.Boolean
|
||||
Returns(TRUE) -> value_1 == null
|
||||
|
||||
public fun funWithReturnsTrueAndTypeCheck(/*0*/ value_1: kotlin.Any?): kotlin.Boolean
|
||||
Returns(TRUE) -> value_1 is String
|
||||
|
||||
public inline fun funWithUnknownCallsInPlace(/*0*/ block: () -> kotlin.Unit): kotlin.Unit
|
||||
CallsInPlace(block, UNKNOWN)
|
||||
|
||||
package contracts {
|
||||
public fun case_1_1(/*0*/ cond: kotlin.Boolean): kotlin.Any
|
||||
Returns(TRUE) -> cond
|
||||
|
||||
public fun case_1_2(/*0*/ value: kotlin.Any): kotlin.Boolean
|
||||
Returns(TRUE) -> value is Boolean
|
||||
|
||||
public fun case_2(/*0*/ cond: kotlin.Boolean): kotlin.Any
|
||||
Returns(TRUE) -> cond
|
||||
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
// !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect
|
||||
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
|
||||
|
||||
/*
|
||||
KOTLIN DIAGNOSTICS NOT LINKED SPEC TEST (POSITIVE)
|
||||
|
||||
SECTION: contracts
|
||||
CATEGORIES: analysis, smartcasts
|
||||
NUMBER: 14
|
||||
DESCRIPTION: Check smartcast with non-null assertion for a contract function.
|
||||
UNEXPECTED BEHAVIOUR
|
||||
ISSUES: KT-26856
|
||||
*/
|
||||
|
||||
// FILE: contracts.kt
|
||||
|
||||
package contracts
|
||||
|
||||
import kotlin.contracts.*
|
||||
|
||||
fun case_1(value_1: Int?): Boolean? {
|
||||
contract {
|
||||
returns(true) implies (value_1 != null)
|
||||
}
|
||||
|
||||
return value_1 != null
|
||||
}
|
||||
|
||||
fun case_2(value_1: Int?): Boolean {
|
||||
contract {
|
||||
returns(false) implies (value_1 != null)
|
||||
}
|
||||
|
||||
return value_1 != null
|
||||
}
|
||||
|
||||
fun case_3(value_1: Int?): Boolean? {
|
||||
contract {
|
||||
returnsNotNull() implies (value_1 != null)
|
||||
}
|
||||
|
||||
return value_1 != null
|
||||
}
|
||||
|
||||
fun case_4(value_1: Any?): Boolean {
|
||||
contract {
|
||||
returnsNotNull() implies (value_1 is Number)
|
||||
}
|
||||
|
||||
return value_1 is Number
|
||||
}
|
||||
|
||||
// FILE: usages.kt
|
||||
|
||||
import contracts.*
|
||||
|
||||
fun case_1(value_1: Int?) {
|
||||
if (contracts.case_1(value_1)!!) {
|
||||
value_1<!UNSAFE_CALL!>.<!>inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun case_2(value_1: Int?) {
|
||||
if (!contracts.case_2(value_1)<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>) {
|
||||
value_1<!UNSAFE_CALL!>.<!>inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun case_3(value_1: Int?) {
|
||||
if (contracts.case_3(value_1)!!) {
|
||||
value_1<!UNSAFE_CALL!>.<!>inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun case_4(value_1: Any?) {
|
||||
if (<!SENSELESS_COMPARISON!>contracts.case_4(value_1) != null<!>) {
|
||||
<!DEBUG_INFO_SMARTCAST!>value_1<!>.toByte()
|
||||
}
|
||||
}
|
||||
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
package
|
||||
|
||||
public fun case_1(/*0*/ value_1: kotlin.Int?): kotlin.Unit
|
||||
public fun case_2(/*0*/ value_1: kotlin.Int?): kotlin.Unit
|
||||
public fun case_3(/*0*/ value_1: kotlin.Int?): kotlin.Unit
|
||||
public fun case_4(/*0*/ value_1: kotlin.Any?): kotlin.Unit
|
||||
|
||||
package contracts {
|
||||
public fun case_1(/*0*/ value_1: kotlin.Int?): kotlin.Boolean?
|
||||
Returns(TRUE) -> value_1 != null
|
||||
|
||||
public fun case_2(/*0*/ value_1: kotlin.Int?): kotlin.Boolean
|
||||
Returns(FALSE) -> value_1 != null
|
||||
|
||||
public fun case_3(/*0*/ value_1: kotlin.Int?): kotlin.Boolean?
|
||||
Returns(NOT_NULL) -> value_1 != null
|
||||
|
||||
public fun case_4(/*0*/ value_1: kotlin.Any?): kotlin.Boolean
|
||||
Returns(NOT_NULL) -> value_1 is Number
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user