diff --git a/build.xml b/build.xml
index 0ee4aea0164..585da896cb8 100644
--- a/build.xml
+++ b/build.xml
@@ -1022,6 +1022,9 @@
+
+
+
diff --git a/libraries/kotlin.test/common/src/main/kotlin/kotlin/test/Assertions.kt b/libraries/kotlin.test/common/src/main/kotlin/kotlin/test/Assertions.kt
index 3c104fb9126..b942ff92627 100644
--- a/libraries/kotlin.test/common/src/main/kotlin/kotlin/test/Assertions.kt
+++ b/libraries/kotlin.test/common/src/main/kotlin/kotlin/test/Assertions.kt
@@ -24,6 +24,7 @@
package kotlin.test
import kotlin.internal.*
+import kotlin.internal.contracts.*
import kotlin.reflect.KClass
/**
@@ -40,6 +41,7 @@ fun assertTrue(message: String? = null, block: () -> Boolean): Unit = assertTrue
/** Asserts that the expression is `true` with an optional [message]. */
fun assertTrue(actual: Boolean, message: String? = null) {
+ contract { returns() implies actual }
return asserter.assertTrue(message ?: "Expected value to be true.", actual)
}
@@ -48,6 +50,7 @@ fun assertFalse(message: String? = null, block: () -> Boolean): Unit = assertFal
/** Asserts that the expression is `false` with an optional [message]. */
fun assertFalse(actual: Boolean, message: String? = null) {
+ contract { returns() implies (!actual) }
return asserter.assertTrue(message ?: "Expected value to be false.", !actual)
}
@@ -63,12 +66,14 @@ fun <@OnlyInputTypes T> assertNotEquals(illegal: T, actual: T, message: String?
/** Asserts that the [actual] value is not `null`, with an optional [message]. */
fun assertNotNull(actual: T?, message: String? = null): T {
+ contract { returns() implies (actual != null) }
asserter.assertNotNull(message, actual)
return actual!!
}
/** Asserts that the [actual] value is not `null`, with an optional [message] and a function [block] to process the not-null value. */
fun assertNotNull(actual: T?, message: String? = null, block: (T) -> R) {
+ contract { returns() implies (actual != null) }
asserter.assertNotNull(message, actual)
if (actual != null) {
block(actual)
diff --git a/libraries/stdlib/src/kotlin/text/Strings.kt b/libraries/stdlib/src/kotlin/text/Strings.kt
index 1b8d1f57d34..2a94223f400 100644
--- a/libraries/stdlib/src/kotlin/text/Strings.kt
+++ b/libraries/stdlib/src/kotlin/text/Strings.kt
@@ -21,6 +21,7 @@
package kotlin.text
import kotlin.comparisons.*
+import kotlin.internal.contracts.*
/**
@@ -225,7 +226,13 @@ public fun String.padEnd(length: Int, padChar: Char = ' '): String
* Returns `true` if this nullable char sequence is either `null` or empty.
*/
@kotlin.internal.InlineOnly
-public inline fun CharSequence?.isNullOrEmpty(): Boolean = this == null || this.length == 0
+public inline fun CharSequence?.isNullOrEmpty(): Boolean {
+ contract {
+ returns(false) implies (this@isNullOrEmpty != null)
+ }
+
+ return this == null || this.length == 0
+}
/**
* Returns `true` if this char sequence is empty (contains no characters).
@@ -253,7 +260,13 @@ public inline fun CharSequence.isNotBlank(): Boolean = !isBlank()
* Returns `true` if this nullable char sequence is either `null` or empty or consists solely of whitespace characters.
*/
@kotlin.internal.InlineOnly
-public inline fun CharSequence?.isNullOrBlank(): Boolean = this == null || this.isBlank()
+public inline fun CharSequence?.isNullOrBlank(): Boolean {
+ contract {
+ returns(false) implies (this@isNullOrBlank != null)
+ }
+
+ return this == null || this.isBlank()
+}
/**
* Iterator for characters of the given char sequence.
diff --git a/libraries/stdlib/src/kotlin/util/Preconditions.kt b/libraries/stdlib/src/kotlin/util/Preconditions.kt
index 7ae8d724907..7aabd40aa87 100644
--- a/libraries/stdlib/src/kotlin/util/Preconditions.kt
+++ b/libraries/stdlib/src/kotlin/util/Preconditions.kt
@@ -2,13 +2,20 @@
@file:kotlin.jvm.JvmName("PreconditionsKt")
package kotlin
+import kotlin.internal.contracts.*
+
/**
* Throws an [IllegalArgumentException] if the [value] is false.
*
* @sample samples.misc.Preconditions.failRequireWithLazyMessage
*/
@kotlin.internal.InlineOnly
-public inline fun require(value: Boolean): Unit = require(value) { "Failed requirement." }
+public inline fun require(value: Boolean): Unit {
+ contract {
+ returns() implies value
+ }
+ require(value) { "Failed requirement." }
+}
/**
* Throws an [IllegalArgumentException] with the result of calling [lazyMessage] if the [value] is false.
@@ -17,6 +24,9 @@ public inline fun require(value: Boolean): Unit = require(value) { "Failed requi
*/
@kotlin.internal.InlineOnly
public inline fun require(value: Boolean, lazyMessage: () -> Any): Unit {
+ contract {
+ returns() implies value
+ }
if (!value) {
val message = lazyMessage()
throw IllegalArgumentException(message.toString())
@@ -27,7 +37,12 @@ public inline fun require(value: Boolean, lazyMessage: () -> Any): Unit {
* Throws an [IllegalArgumentException] if the [value] is null. Otherwise returns the not null value.
*/
@kotlin.internal.InlineOnly
-public inline fun requireNotNull(value: T?): T = requireNotNull(value) { "Required value was null." }
+public inline fun requireNotNull(value: T?): T {
+ contract {
+ returns() implies (value != null)
+ }
+ return requireNotNull(value) { "Required value was null." }
+}
/**
* Throws an [IllegalArgumentException] with the result of calling [lazyMessage] if the [value] is null. Otherwise
@@ -37,6 +52,10 @@ public inline fun requireNotNull(value: T?): T = requireNotNull(value) {
*/
@kotlin.internal.InlineOnly
public inline fun requireNotNull(value: T?, lazyMessage: () -> Any): T {
+ contract {
+ returns() implies (value != null)
+ }
+
if (value == null) {
val message = lazyMessage()
throw IllegalArgumentException(message.toString())
@@ -51,7 +70,12 @@ public inline fun requireNotNull(value: T?, lazyMessage: () -> Any): T {
* @sample samples.misc.Preconditions.failCheckWithLazyMessage
*/
@kotlin.internal.InlineOnly
-public inline fun check(value: Boolean): Unit = check(value) { "Check failed." }
+public inline fun check(value: Boolean): Unit {
+ contract {
+ returns() implies value
+ }
+ check(value) { "Check failed." }
+}
/**
* Throws an [IllegalStateException] with the result of calling [lazyMessage] if the [value] is false.
@@ -60,6 +84,9 @@ public inline fun check(value: Boolean): Unit = check(value) { "Check failed." }
*/
@kotlin.internal.InlineOnly
public inline fun check(value: Boolean, lazyMessage: () -> Any): Unit {
+ contract {
+ returns() implies value
+ }
if (!value) {
val message = lazyMessage()
throw IllegalStateException(message.toString())
@@ -83,6 +110,10 @@ public inline fun checkNotNull(value: T?): T = checkNotNull(value) { "Re
*/
@kotlin.internal.InlineOnly
public inline fun checkNotNull(value: T?, lazyMessage: () -> Any): T {
+ contract {
+ returns() implies (value != null)
+ }
+
if (value == null) {
val message = lazyMessage()
throw IllegalStateException(message.toString())
diff --git a/libraries/stdlib/src/kotlin/util/Standard.kt b/libraries/stdlib/src/kotlin/util/Standard.kt
index e524197ebab..98421de1651 100644
--- a/libraries/stdlib/src/kotlin/util/Standard.kt
+++ b/libraries/stdlib/src/kotlin/util/Standard.kt
@@ -2,6 +2,8 @@
@file:kotlin.jvm.JvmName("StandardKt")
package kotlin
+import kotlin.internal.contracts.*
+
/**
* An exception is thrown to indicate that a method body remains to be implemented.
*/
@@ -28,52 +30,91 @@ public inline fun TODO(reason: String): Nothing = throw NotImplementedError("An
* Calls the specified function [block] and returns its result.
*/
@kotlin.internal.InlineOnly
-public inline fun run(block: () -> R): R = block()
+public inline fun run(block: () -> R): R {
+ contract {
+ callsInPlace(block, InvocationKind.EXACTLY_ONCE)
+ }
+ return block()
+}
/**
* Calls the specified function [block] with `this` value as its receiver and returns its result.
*/
@kotlin.internal.InlineOnly
-public inline fun T.run(block: T.() -> R): R = block()
+public inline fun T.run(block: T.() -> R): R {
+ contract {
+ callsInPlace(block, InvocationKind.EXACTLY_ONCE)
+ }
+ return block()
+}
/**
* Calls the specified function [block] with the given [receiver] as its receiver and returns its result.
*/
@kotlin.internal.InlineOnly
-public inline fun with(receiver: T, block: T.() -> R): R = receiver.block()
+public inline fun with(receiver: T, block: T.() -> R): R {
+ contract {
+ callsInPlace(block, InvocationKind.EXACTLY_ONCE)
+ }
+ return receiver.block()
+}
/**
* Calls the specified function [block] with `this` value as its receiver and returns `this` value.
*/
@kotlin.internal.InlineOnly
-public inline fun T.apply(block: T.() -> Unit): T { block(); return this }
+public inline fun T.apply(block: T.() -> Unit): T {
+ contract {
+ callsInPlace(block, InvocationKind.EXACTLY_ONCE)
+ }
+ block()
+ return this
+}
/**
* Calls the specified function [block] with `this` value as its argument and returns `this` value.
*/
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
-public inline fun T.also(block: (T) -> Unit): T { block(this); return this }
+public inline fun T.also(block: (T) -> Unit): T {
+ contract {
+ callsInPlace(block, InvocationKind.EXACTLY_ONCE)
+ }
+ block(this)
+ return this
+}
/**
* Calls the specified function [block] with `this` value as its argument and returns its result.
*/
@kotlin.internal.InlineOnly
-public inline fun T.let(block: (T) -> R): R = block(this)
+public inline fun T.let(block: (T) -> R): R {
+ contract {
+ callsInPlace(block, InvocationKind.EXACTLY_ONCE)
+ }
+ return block(this)
+}
/**
* Returns `this` value if it satisfies the given [predicate] or `null`, if it doesn't.
*/
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
-public inline fun T.takeIf(predicate: (T) -> Boolean): T? = if (predicate(this)) this else null
+public inline fun T.takeIf(predicate: (T) -> Boolean): T? {
+ contract {
+ callsInPlace(predicate, InvocationKind.EXACTLY_ONCE)
+ }
+ return if (predicate(this)) this else null
+}
/**
* Returns `this` value if it _does not_ satisfy the given [predicate] or `null`, if it does.
*/
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
-public inline fun T.takeUnless(predicate: (T) -> Boolean): T? = if (!predicate(this)) this else null
+public inline fun T.takeUnless(predicate: (T) -> Boolean): T? {
+ return if (!predicate(this)) this else null
+}
/**
* Executes the given function [action] specified number of [times].
@@ -82,7 +123,9 @@ public inline fun T.takeUnless(predicate: (T) -> Boolean): T? = if (!predica
*/
@kotlin.internal.InlineOnly
public inline fun repeat(times: Int, action: (Int) -> Unit) {
- for (index in 0 until times) {
+ contract { callsInPlace(action) }
+
+ for (index in 0..times - 1) {
action(index)
}
}
diff --git a/prepare/mock-runtime-for-test/build.gradle.kts b/prepare/mock-runtime-for-test/build.gradle.kts
index 6e4ee448696..d04024e2c40 100644
--- a/prepare/mock-runtime-for-test/build.gradle.kts
+++ b/prepare/mock-runtime-for-test/build.gradle.kts
@@ -36,7 +36,9 @@ val copySources by task {
.include("kotlin/collections/TypeAliases.kt",
"kotlin/jvm/JvmVersion.kt",
"kotlin/util/Standard.kt",
- "kotlin/internal/Annotations.kt")
+ "kotlin/internal/Annotations.kt",
+ "kotlin/internal/contracts/ContractBuilder.kt",
+ "kotlin/internal/contracts/Effect.kt")
into(File(buildDir, "src"))
}