JS: coroutines: fix handling of throw statement inside try/catch block when controller has handleSuspend function

This commit is contained in:
Alexey Andreev
2016-11-21 17:47:43 +03:00
parent e44edf12e0
commit dc8e90809c
6 changed files with 63 additions and 3 deletions
@@ -0,0 +1,37 @@
// WITH_RUNTIME
class Controller {
var result = ""
suspend fun <T> suspendAndLog(value: T, c: Continuation<T>) {
result += "suspend($value);"
c.resume(value)
}
operator fun handleException(exception: Throwable, c: Continuation<Nothing>) {
result += "ignoreCaught(${exception.message});"
}
}
fun builder(coroutine c: Controller.() -> Continuation<Unit>): String {
val controller = Controller()
c(controller).resume(Unit)
return controller.result
}
fun box(): String {
val value = builder {
try {
suspendAndLog("before")
throw RuntimeException("foo")
} catch (e: RuntimeException) {
result += "caught(${e.message});"
}
suspendAndLog("after")
}
if (value != "suspend(before);caught(foo);suspend(after);") {
return "fail: $value"
}
return "OK"
}
@@ -4774,6 +4774,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
doTest(fileName);
}
@TestMetadata("throwInTryWithHandleResult.kt")
public void testThrowInTryWithHandleResult() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/throwInTryWithHandleResult.kt");
doTest(fileName);
}
@TestMetadata("whileStatement.kt")
public void testWhileStatement() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/whileStatement.kt");
@@ -332,6 +332,12 @@ public class AdditionalCoroutineBlackBoxCodegenTestGenerated extends AbstractAdd
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/controlFlow"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
}
@TestMetadata("throwInTryWithHandleResult.kt")
public void testThrowInTryWithHandleResult() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/throwInTryWithHandleResult.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/codegen/box/coroutines/intLikeVarSpilling")
@@ -4774,6 +4774,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
doTest(fileName);
}
@TestMetadata("throwInTryWithHandleResult.kt")
public void testThrowInTryWithHandleResult() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/throwInTryWithHandleResult.kt");
doTest(fileName);
}
@TestMetadata("whileStatement.kt")
public void testWhileStatement() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/whileStatement.kt");
@@ -73,7 +73,7 @@ class CoroutineBodyTransformer(
val thenEntryBlock = CoroutineBlock()
currentBlock = thenEntryBlock
x.thenStatement?.accept(this)
x.thenStatement.accept(this)
val thenExitBlock = currentBlock
val elseEntryBlock = CoroutineBlock()
@@ -322,8 +322,7 @@ class CoroutineBodyTransformer(
}
override fun visitThrow(x: JsThrow) {
if (throwFunctionName != null) {
// TODO: what if we catch exception in coroutine?
if (throwFunctionName != null && tryStack.isEmpty()) {
val methodRef = JsNameRef(throwFunctionName, JsNameRef(context.controllerFieldName, JsLiteral.THIS))
val invocation = JsInvocation(methodRef, x.expression).apply {
source = x.source
@@ -5591,6 +5591,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
doTest(fileName);
}
@TestMetadata("throwInTryWithHandleResult.kt")
public void testThrowInTryWithHandleResult() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/throwInTryWithHandleResult.kt");
doTest(fileName);
}
@TestMetadata("whileStatement.kt")
public void testWhileStatement() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/whileStatement.kt");