Files
kotlin/compiler/testData/codegen/java8/box/async.kt
2016-06-08 18:53:16 +03:00

82 lines
2.0 KiB
Kotlin
Vendored

// WITH_RUNTIME
// FULL_JDK
import java.util.concurrent.CompletableFuture
fun foo(): CompletableFuture<String> = CompletableFuture.supplyAsync { "foo" }
fun bar(v: String): CompletableFuture<String> = CompletableFuture.supplyAsync { "bar with $v" }
fun exception(v: String): CompletableFuture<String> = CompletableFuture.supplyAsync { throw RuntimeException(v) }
fun foobar(x: String, y: String) = x + y
fun box(): String {
var result = ""
fun log(x: String) {
synchronized(result) {
if (result.isNotEmpty()) result += "\n"
result += x
}
}
val future = async<String> {
log("start")
val x = await(foo())
log("got '$x'")
val y = foobar("123 ", await(bar(x)))
log("got '$y' after '$x'")
y
}
future.whenComplete { value, t ->
log("completed with '$value'")
}
future.join()
java.lang.Thread.sleep(1000)
val readResult = synchronized(result) {
result
}
val expectedResult =
"""
|start
|got 'foo'
|got '123 bar with foo' after 'foo'
|completed with '123 bar with foo'""".trimMargin().trim('\n', ' ')
if (expectedResult != readResult) return readResult
return "OK"
}
// LIBRARY CODE
fun <T> async(coroutine c: FutureController<T>.() -> Continuation<Unit>): CompletableFuture<T> {
val controller = FutureController<T>()
c(controller).resume(Unit)
return controller.future
}
class FutureController<T> {
val future = CompletableFuture<T>()
suspend fun <V> await(f: CompletableFuture<V>, machine: Continuation<V>) {
f.whenComplete { value, throwable ->
if (throwable == null)
machine.resume(value)
else
machine.resumeWithException(throwable)
}
}
operator fun handleResult(value: T, c: Continuation<Nothing>) {
future.complete(value)
}
fun handleException(t: Throwable, c: Continuation<Nothing>) {
future.completeExceptionally(t)
}
}