Effects: annotate functions in stdlib with contracts
build.xml was also changed to incorporate contracts in mock-runtime-for-tests.jar, because it is using Standard.kt, which, in turn, has contract-annotated functions. ========== Introduction of EffectSystem: 17/18
This commit is contained in:
@@ -1022,6 +1022,9 @@
|
|||||||
<copy file="${basedir}/libraries/stdlib/src/kotlin/jvm/JvmVersion.kt" todir="${output}/mock-runtime-src"/>
|
<copy file="${basedir}/libraries/stdlib/src/kotlin/jvm/JvmVersion.kt" todir="${output}/mock-runtime-src"/>
|
||||||
<copy file="${basedir}/libraries/stdlib/src/kotlin/util/Standard.kt" todir="${output}/mock-runtime-src"/>
|
<copy file="${basedir}/libraries/stdlib/src/kotlin/util/Standard.kt" todir="${output}/mock-runtime-src"/>
|
||||||
<copy file="${basedir}/libraries/stdlib/src/kotlin/internal/Annotations.kt" todir="${output}/mock-runtime-src"/>
|
<copy file="${basedir}/libraries/stdlib/src/kotlin/internal/Annotations.kt" todir="${output}/mock-runtime-src"/>
|
||||||
|
<!-- Contracts -->
|
||||||
|
<copy file="${basedir}/libraries/stdlib/src/kotlin/internal/contracts/ContractBuilder.kt" todir="${output}/mock-runtime-src"/>
|
||||||
|
<copy file="${basedir}/libraries/stdlib/src/kotlin/internal/contracts/Effect.kt" todir="${output}/mock-runtime-src"/>
|
||||||
|
|
||||||
<new-kotlinc output="${output}/classes/mock-runtime" moduleName="kotlin-stdlib">
|
<new-kotlinc output="${output}/classes/mock-runtime" moduleName="kotlin-stdlib">
|
||||||
<src>
|
<src>
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
package kotlin.test
|
package kotlin.test
|
||||||
|
|
||||||
import kotlin.internal.*
|
import kotlin.internal.*
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
import kotlin.reflect.KClass
|
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]. */
|
/** Asserts that the expression is `true` with an optional [message]. */
|
||||||
fun assertTrue(actual: Boolean, message: String? = null) {
|
fun assertTrue(actual: Boolean, message: String? = null) {
|
||||||
|
contract { returns() implies actual }
|
||||||
return asserter.assertTrue(message ?: "Expected value to be true.", 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]. */
|
/** Asserts that the expression is `false` with an optional [message]. */
|
||||||
fun assertFalse(actual: Boolean, message: String? = null) {
|
fun assertFalse(actual: Boolean, message: String? = null) {
|
||||||
|
contract { returns() implies (!actual) }
|
||||||
return asserter.assertTrue(message ?: "Expected value to be false.", !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]. */
|
/** Asserts that the [actual] value is not `null`, with an optional [message]. */
|
||||||
fun <T : Any> assertNotNull(actual: T?, message: String? = null): T {
|
fun <T : Any> assertNotNull(actual: T?, message: String? = null): T {
|
||||||
|
contract { returns() implies (actual != null) }
|
||||||
asserter.assertNotNull(message, actual)
|
asserter.assertNotNull(message, actual)
|
||||||
return 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. */
|
/** Asserts that the [actual] value is not `null`, with an optional [message] and a function [block] to process the not-null value. */
|
||||||
fun <T : Any, R> assertNotNull(actual: T?, message: String? = null, block: (T) -> R) {
|
fun <T : Any, R> assertNotNull(actual: T?, message: String? = null, block: (T) -> R) {
|
||||||
|
contract { returns() implies (actual != null) }
|
||||||
asserter.assertNotNull(message, actual)
|
asserter.assertNotNull(message, actual)
|
||||||
if (actual != null) {
|
if (actual != null) {
|
||||||
block(actual)
|
block(actual)
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
package kotlin.text
|
package kotlin.text
|
||||||
|
|
||||||
import kotlin.comparisons.*
|
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.
|
* Returns `true` if this nullable char sequence is either `null` or empty.
|
||||||
*/
|
*/
|
||||||
@kotlin.internal.InlineOnly
|
@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).
|
* 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.
|
* Returns `true` if this nullable char sequence is either `null` or empty or consists solely of whitespace characters.
|
||||||
*/
|
*/
|
||||||
@kotlin.internal.InlineOnly
|
@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.
|
* Iterator for characters of the given char sequence.
|
||||||
|
|||||||
@@ -2,13 +2,20 @@
|
|||||||
@file:kotlin.jvm.JvmName("PreconditionsKt")
|
@file:kotlin.jvm.JvmName("PreconditionsKt")
|
||||||
package kotlin
|
package kotlin
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Throws an [IllegalArgumentException] if the [value] is false.
|
* Throws an [IllegalArgumentException] if the [value] is false.
|
||||||
*
|
*
|
||||||
* @sample samples.misc.Preconditions.failRequireWithLazyMessage
|
* @sample samples.misc.Preconditions.failRequireWithLazyMessage
|
||||||
*/
|
*/
|
||||||
@kotlin.internal.InlineOnly
|
@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.
|
* 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
|
@kotlin.internal.InlineOnly
|
||||||
public inline fun require(value: Boolean, lazyMessage: () -> Any): Unit {
|
public inline fun require(value: Boolean, lazyMessage: () -> Any): Unit {
|
||||||
|
contract {
|
||||||
|
returns() implies value
|
||||||
|
}
|
||||||
if (!value) {
|
if (!value) {
|
||||||
val message = lazyMessage()
|
val message = lazyMessage()
|
||||||
throw IllegalArgumentException(message.toString())
|
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.
|
* Throws an [IllegalArgumentException] if the [value] is null. Otherwise returns the not null value.
|
||||||
*/
|
*/
|
||||||
@kotlin.internal.InlineOnly
|
@kotlin.internal.InlineOnly
|
||||||
public inline fun <T:Any> requireNotNull(value: T?): T = requireNotNull(value) { "Required value was null." }
|
public inline fun <T:Any> 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
|
* Throws an [IllegalArgumentException] with the result of calling [lazyMessage] if the [value] is null. Otherwise
|
||||||
@@ -37,6 +52,10 @@ public inline fun <T:Any> requireNotNull(value: T?): T = requireNotNull(value) {
|
|||||||
*/
|
*/
|
||||||
@kotlin.internal.InlineOnly
|
@kotlin.internal.InlineOnly
|
||||||
public inline fun <T:Any> requireNotNull(value: T?, lazyMessage: () -> Any): T {
|
public inline fun <T:Any> requireNotNull(value: T?, lazyMessage: () -> Any): T {
|
||||||
|
contract {
|
||||||
|
returns() implies (value != null)
|
||||||
|
}
|
||||||
|
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
val message = lazyMessage()
|
val message = lazyMessage()
|
||||||
throw IllegalArgumentException(message.toString())
|
throw IllegalArgumentException(message.toString())
|
||||||
@@ -51,7 +70,12 @@ public inline fun <T:Any> requireNotNull(value: T?, lazyMessage: () -> Any): T {
|
|||||||
* @sample samples.misc.Preconditions.failCheckWithLazyMessage
|
* @sample samples.misc.Preconditions.failCheckWithLazyMessage
|
||||||
*/
|
*/
|
||||||
@kotlin.internal.InlineOnly
|
@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.
|
* 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
|
@kotlin.internal.InlineOnly
|
||||||
public inline fun check(value: Boolean, lazyMessage: () -> Any): Unit {
|
public inline fun check(value: Boolean, lazyMessage: () -> Any): Unit {
|
||||||
|
contract {
|
||||||
|
returns() implies value
|
||||||
|
}
|
||||||
if (!value) {
|
if (!value) {
|
||||||
val message = lazyMessage()
|
val message = lazyMessage()
|
||||||
throw IllegalStateException(message.toString())
|
throw IllegalStateException(message.toString())
|
||||||
@@ -83,6 +110,10 @@ public inline fun <T:Any> checkNotNull(value: T?): T = checkNotNull(value) { "Re
|
|||||||
*/
|
*/
|
||||||
@kotlin.internal.InlineOnly
|
@kotlin.internal.InlineOnly
|
||||||
public inline fun <T:Any> checkNotNull(value: T?, lazyMessage: () -> Any): T {
|
public inline fun <T:Any> checkNotNull(value: T?, lazyMessage: () -> Any): T {
|
||||||
|
contract {
|
||||||
|
returns() implies (value != null)
|
||||||
|
}
|
||||||
|
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
val message = lazyMessage()
|
val message = lazyMessage()
|
||||||
throw IllegalStateException(message.toString())
|
throw IllegalStateException(message.toString())
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
@file:kotlin.jvm.JvmName("StandardKt")
|
@file:kotlin.jvm.JvmName("StandardKt")
|
||||||
package kotlin
|
package kotlin
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An exception is thrown to indicate that a method body remains to be implemented.
|
* 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.
|
* Calls the specified function [block] and returns its result.
|
||||||
*/
|
*/
|
||||||
@kotlin.internal.InlineOnly
|
@kotlin.internal.InlineOnly
|
||||||
public inline fun <R> run(block: () -> R): R = block()
|
public inline fun <R> 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.
|
* Calls the specified function [block] with `this` value as its receiver and returns its result.
|
||||||
*/
|
*/
|
||||||
@kotlin.internal.InlineOnly
|
@kotlin.internal.InlineOnly
|
||||||
public inline fun <T, R> T.run(block: T.() -> R): R = block()
|
public inline fun <T, R> 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.
|
* Calls the specified function [block] with the given [receiver] as its receiver and returns its result.
|
||||||
*/
|
*/
|
||||||
@kotlin.internal.InlineOnly
|
@kotlin.internal.InlineOnly
|
||||||
public inline fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block()
|
public inline fun <T, R> 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.
|
* Calls the specified function [block] with `this` value as its receiver and returns `this` value.
|
||||||
*/
|
*/
|
||||||
@kotlin.internal.InlineOnly
|
@kotlin.internal.InlineOnly
|
||||||
public inline fun <T> T.apply(block: T.() -> Unit): T { block(); return this }
|
public inline fun <T> 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.
|
* Calls the specified function [block] with `this` value as its argument and returns `this` value.
|
||||||
*/
|
*/
|
||||||
@kotlin.internal.InlineOnly
|
@kotlin.internal.InlineOnly
|
||||||
@SinceKotlin("1.1")
|
@SinceKotlin("1.1")
|
||||||
public inline fun <T> T.also(block: (T) -> Unit): T { block(this); return this }
|
public inline fun <T> 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.
|
* Calls the specified function [block] with `this` value as its argument and returns its result.
|
||||||
*/
|
*/
|
||||||
@kotlin.internal.InlineOnly
|
@kotlin.internal.InlineOnly
|
||||||
public inline fun <T, R> T.let(block: (T) -> R): R = block(this)
|
public inline fun <T, R> 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.
|
* Returns `this` value if it satisfies the given [predicate] or `null`, if it doesn't.
|
||||||
*/
|
*/
|
||||||
@kotlin.internal.InlineOnly
|
@kotlin.internal.InlineOnly
|
||||||
@SinceKotlin("1.1")
|
@SinceKotlin("1.1")
|
||||||
public inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? = if (predicate(this)) this else null
|
public inline fun <T> 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.
|
* Returns `this` value if it _does not_ satisfy the given [predicate] or `null`, if it does.
|
||||||
*/
|
*/
|
||||||
@kotlin.internal.InlineOnly
|
@kotlin.internal.InlineOnly
|
||||||
@SinceKotlin("1.1")
|
@SinceKotlin("1.1")
|
||||||
public inline fun <T> T.takeUnless(predicate: (T) -> Boolean): T? = if (!predicate(this)) this else null
|
public inline fun <T> T.takeUnless(predicate: (T) -> Boolean): T? {
|
||||||
|
return if (!predicate(this)) this else null
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the given function [action] specified number of [times].
|
* Executes the given function [action] specified number of [times].
|
||||||
@@ -82,7 +123,9 @@ public inline fun <T> T.takeUnless(predicate: (T) -> Boolean): T? = if (!predica
|
|||||||
*/
|
*/
|
||||||
@kotlin.internal.InlineOnly
|
@kotlin.internal.InlineOnly
|
||||||
public inline fun repeat(times: Int, action: (Int) -> Unit) {
|
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)
|
action(index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,9 @@ val copySources by task<Copy> {
|
|||||||
.include("kotlin/collections/TypeAliases.kt",
|
.include("kotlin/collections/TypeAliases.kt",
|
||||||
"kotlin/jvm/JvmVersion.kt",
|
"kotlin/jvm/JvmVersion.kt",
|
||||||
"kotlin/util/Standard.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"))
|
into(File(buildDir, "src"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user