JS: coroutines: fix handling of throw statement inside try/catch block when controller has handleSuspend function
This commit is contained in:
+37
@@ -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"
|
||||
}
|
||||
+6
@@ -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");
|
||||
|
||||
+6
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user