Support 'handleException' operator in JVM backend
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
// WITH_RUNTIME
|
||||
class Controller {
|
||||
var exception: Throwable? = null
|
||||
val postponedActions = java.util.ArrayList<() -> Unit>()
|
||||
|
||||
suspend fun suspendWithValue(v: String, x: Continuation<String>) {
|
||||
postponedActions.add {
|
||||
x.resume(v)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun suspendWithException(e: Exception, x: Continuation<String>) {
|
||||
postponedActions.add {
|
||||
x.resumeWithException(e)
|
||||
}
|
||||
}
|
||||
|
||||
operator fun handleException(t: Throwable, c: Continuation<Nothing>) {
|
||||
exception = t
|
||||
}
|
||||
|
||||
fun run(c: Controller.() -> Continuation<Unit>) {
|
||||
c(this).resume(Unit)
|
||||
while (postponedActions.isNotEmpty()) {
|
||||
postponedActions[0]()
|
||||
postponedActions.removeAt(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun builder(coroutine c: Controller.() -> Continuation<Unit>) {
|
||||
val controller = Controller()
|
||||
controller.run(c)
|
||||
|
||||
if (controller.exception?.message != "OK") {
|
||||
throw RuntimeException("Unexpected result: ${controller.exception?.message}")
|
||||
}
|
||||
}
|
||||
|
||||
fun commonThrow(t: Throwable) {
|
||||
throw t
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
builder {
|
||||
throw RuntimeException("OK")
|
||||
}
|
||||
|
||||
builder {
|
||||
commonThrow(RuntimeException("OK"))
|
||||
}
|
||||
|
||||
builder {
|
||||
suspendWithException(RuntimeException("OK"))
|
||||
}
|
||||
|
||||
builder {
|
||||
try {
|
||||
suspendWithException(RuntimeException("fail 1"))
|
||||
} catch (e: RuntimeException) {
|
||||
suspendWithException(RuntimeException("OK"))
|
||||
}
|
||||
}
|
||||
|
||||
builder {
|
||||
try {
|
||||
suspendWithException(Exception("OK"))
|
||||
} catch (e: RuntimeException) {
|
||||
suspendWithException(RuntimeException("fail 3"))
|
||||
throw RuntimeException("fail 4")
|
||||
}
|
||||
}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+20
-11
@@ -25,7 +25,21 @@ fun box(): String {
|
||||
|
||||
java.lang.Thread.sleep(1000)
|
||||
|
||||
return result
|
||||
if (result != "OK") return "fail notOk"
|
||||
|
||||
val future2 = async<String>() {
|
||||
await(exception("OK"))
|
||||
"fail"
|
||||
}
|
||||
|
||||
try {
|
||||
future2.get()
|
||||
} catch (e: Exception) {
|
||||
if (e.cause!!.message != "OK") return "fail message: ${e.cause!!.message}"
|
||||
return "OK"
|
||||
}
|
||||
|
||||
return "No exception"
|
||||
}
|
||||
|
||||
fun <T> async(coroutine c: FutureController<T>.() -> Continuation<Unit>): CompletableFuture<T> {
|
||||
@@ -37,17 +51,12 @@ fun <T> async(coroutine c: FutureController<T>.() -> Continuation<Unit>): Comple
|
||||
class FutureController<T> {
|
||||
val future = CompletableFuture<T>()
|
||||
|
||||
|
||||
suspend fun <V> await(f: CompletableFuture<V>, machine: Continuation<V>) {
|
||||
f.whenComplete { value, throwable ->
|
||||
try {
|
||||
if (throwable == null)
|
||||
machine.resume(value)
|
||||
else
|
||||
machine.resumeWithException(throwable)
|
||||
} catch (e: Exception) {
|
||||
future.completeExceptionally(e)
|
||||
}
|
||||
if (throwable == null)
|
||||
machine.resume(value)
|
||||
else
|
||||
machine.resumeWithException(throwable)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +64,7 @@ class FutureController<T> {
|
||||
future.complete(value)
|
||||
}
|
||||
|
||||
fun handleException(t: Throwable, c: Continuation<Nothing>) {
|
||||
operator fun handleException(t: Throwable, c: Continuation<Nothing>) {
|
||||
future.completeExceptionally(t)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user