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);
|
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")
|
@TestMetadata("whileStatement.kt")
|
||||||
public void testWhileStatement() throws Exception {
|
public void testWhileStatement() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/whileStatement.kt");
|
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);
|
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")
|
@TestMetadata("compiler/testData/codegen/box/coroutines/intLikeVarSpilling")
|
||||||
|
|||||||
@@ -4774,6 +4774,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("whileStatement.kt")
|
||||||
public void testWhileStatement() throws Exception {
|
public void testWhileStatement() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/whileStatement.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/whileStatement.kt");
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ class CoroutineBodyTransformer(
|
|||||||
|
|
||||||
val thenEntryBlock = CoroutineBlock()
|
val thenEntryBlock = CoroutineBlock()
|
||||||
currentBlock = thenEntryBlock
|
currentBlock = thenEntryBlock
|
||||||
x.thenStatement?.accept(this)
|
x.thenStatement.accept(this)
|
||||||
val thenExitBlock = currentBlock
|
val thenExitBlock = currentBlock
|
||||||
|
|
||||||
val elseEntryBlock = CoroutineBlock()
|
val elseEntryBlock = CoroutineBlock()
|
||||||
@@ -322,8 +322,7 @@ class CoroutineBodyTransformer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitThrow(x: JsThrow) {
|
override fun visitThrow(x: JsThrow) {
|
||||||
if (throwFunctionName != null) {
|
if (throwFunctionName != null && tryStack.isEmpty()) {
|
||||||
// TODO: what if we catch exception in coroutine?
|
|
||||||
val methodRef = JsNameRef(throwFunctionName, JsNameRef(context.controllerFieldName, JsLiteral.THIS))
|
val methodRef = JsNameRef(throwFunctionName, JsNameRef(context.controllerFieldName, JsLiteral.THIS))
|
||||||
val invocation = JsInvocation(methodRef, x.expression).apply {
|
val invocation = JsInvocation(methodRef, x.expression).apply {
|
||||||
source = x.source
|
source = x.source
|
||||||
|
|||||||
@@ -5591,6 +5591,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("whileStatement.kt")
|
||||||
public void testWhileStatement() throws Exception {
|
public void testWhileStatement() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/whileStatement.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/whileStatement.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user