JS: add coroutines tests
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
class Controller {
|
||||
var result = ""
|
||||
|
||||
suspend fun <T> suspendWithResult(value: T, c: Continuation<T>) {
|
||||
c.resume(value)
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
outer@for (x in listOf("A", "B")) {
|
||||
try {
|
||||
result += suspendWithResult(x)
|
||||
for (y in listOf("C", "D")) {
|
||||
try {
|
||||
result += suspendWithResult(y)
|
||||
if (y == "D") {
|
||||
break@outer
|
||||
}
|
||||
}
|
||||
finally {
|
||||
result += "!"
|
||||
}
|
||||
result += "E"
|
||||
}
|
||||
}
|
||||
finally {
|
||||
result += "@"
|
||||
}
|
||||
result += "ignore"
|
||||
}
|
||||
}
|
||||
finally {
|
||||
result += "finally"
|
||||
}
|
||||
result += "."
|
||||
}
|
||||
if (value != "AC!ED!@finally.") return "fail: $value"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
class Controller {
|
||||
var result = ""
|
||||
|
||||
suspend fun <T> suspendWithResult(value: T, c: Continuation<T>) {
|
||||
c.resume(value)
|
||||
}
|
||||
}
|
||||
|
||||
fun builder(coroutine c: Controller.() -> Continuation<Unit>): String {
|
||||
val controller = Controller()
|
||||
c(controller).resume(Unit)
|
||||
return controller.result
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var value = builder {
|
||||
outer@for (x in listOf("O", "K")) {
|
||||
result += suspendWithResult(x)
|
||||
for (y in listOf("Q", "W")) {
|
||||
result += suspendWithResult(y)
|
||||
if (y == "W") {
|
||||
break@outer
|
||||
}
|
||||
}
|
||||
}
|
||||
result += "."
|
||||
}
|
||||
if (value != "OQW.") return "fail: break outer loop: $value"
|
||||
|
||||
value = builder {
|
||||
for (x in listOf("O", "K")) {
|
||||
result += suspendWithResult(x)
|
||||
for (y in listOf("Q", "W")) {
|
||||
if (y == "W") {
|
||||
break
|
||||
}
|
||||
result += suspendWithResult(y)
|
||||
}
|
||||
}
|
||||
result += "."
|
||||
}
|
||||
if (value != "OQKQ.") return "fail: break inner loop: $value"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
class Controller {
|
||||
var result = ""
|
||||
|
||||
suspend fun <T> suspendWithResult(value: T, c: Continuation<T>) {
|
||||
c.resume(value)
|
||||
}
|
||||
}
|
||||
|
||||
fun builder(coroutine c: Controller.() -> Continuation<Unit>): String {
|
||||
val controller = Controller()
|
||||
c(controller).resume(Unit)
|
||||
return controller.result
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var value = builder {
|
||||
var x = 1
|
||||
do {
|
||||
result += x
|
||||
} while (suspendWithResult(x++) < 3)
|
||||
result += "."
|
||||
}
|
||||
if (value != "123.") return "fail: suspend as do..while condition: $value"
|
||||
|
||||
value = builder {
|
||||
var x = 1
|
||||
do {
|
||||
result += suspendWithResult(x)
|
||||
result += ";"
|
||||
} while (x++ < 3)
|
||||
result += "."
|
||||
}
|
||||
if (value != "1;2;3;.") return "fail: suspend in do..while body: $value"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
class Controller {
|
||||
var result = ""
|
||||
|
||||
suspend fun <T> suspendWithResult(value: T, c: Continuation<T>) {
|
||||
c.resume(value)
|
||||
}
|
||||
}
|
||||
|
||||
fun builder(coroutine c: Controller.() -> Continuation<Unit>): String {
|
||||
val controller = Controller()
|
||||
c(controller).resume(Unit)
|
||||
return controller.result
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val value = builder {
|
||||
for (x in listOf("O", "K")) {
|
||||
result += suspendWithResult(x)
|
||||
}
|
||||
result += "."
|
||||
}
|
||||
if (value != "OK.") return "fail: suspend in for body: $value"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
class Controller {
|
||||
var result = ""
|
||||
|
||||
suspend fun <T> suspendWithResult(value: T, c: Continuation<T>) {
|
||||
c.resume(value)
|
||||
}
|
||||
}
|
||||
|
||||
fun builder(coroutine c: Controller.() -> Continuation<Unit>): String {
|
||||
val controller = Controller()
|
||||
c(controller).resume(Unit)
|
||||
return controller.result
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var value = builder {
|
||||
if (suspendWithResult(true)) {
|
||||
result = "OK"
|
||||
}
|
||||
}
|
||||
if (value != "OK") return "fail: suspend as if condition: $value"
|
||||
|
||||
value = builder {
|
||||
for (x in listOf(true, false)) {
|
||||
if (x) {
|
||||
result += suspendWithResult("O")
|
||||
}
|
||||
else {
|
||||
result += "K"
|
||||
}
|
||||
}
|
||||
}
|
||||
if (value != "OK") return "fail: suspend in then branch: $value"
|
||||
|
||||
value = builder {
|
||||
for (x in listOf(true, false)) {
|
||||
if (x) {
|
||||
result += "O"
|
||||
}
|
||||
else {
|
||||
result += suspendWithResult("K")
|
||||
}
|
||||
}
|
||||
}
|
||||
if (value != "OK") return "fail: suspend in else branch: $value"
|
||||
|
||||
value = builder {
|
||||
for (x in listOf(true, false)) {
|
||||
if (x) {
|
||||
result += suspendWithResult("O")
|
||||
}
|
||||
else {
|
||||
result += suspendWithResult("K")
|
||||
}
|
||||
}
|
||||
}
|
||||
if (value != "OK") return "fail: suspend in both branches: $value"
|
||||
|
||||
value = builder {
|
||||
for (x in listOf(true, false)) {
|
||||
if (x) {
|
||||
result += suspendWithResult("O")
|
||||
}
|
||||
result += ";"
|
||||
}
|
||||
}
|
||||
if (value != "O;;") return "fail: suspend in then branch without else: $value"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
class Controller {
|
||||
var result = ""
|
||||
|
||||
suspend fun <T> suspendAndLog(value: T, c: Continuation<T>) {
|
||||
result += "suspend($value);"
|
||||
c.resume(value)
|
||||
}
|
||||
|
||||
operator fun handleResult(value: String, c: Continuation<Nothing>) {
|
||||
result += "return($value);"
|
||||
}
|
||||
}
|
||||
|
||||
fun builder(coroutine c: Controller.() -> Continuation<Unit>): String {
|
||||
val controller = Controller()
|
||||
c(controller).resume(Unit)
|
||||
return controller.result
|
||||
}
|
||||
|
||||
fun <T> id(value: T) = value
|
||||
|
||||
fun box(): String {
|
||||
val value = builder {
|
||||
try {
|
||||
if (id(23) == 23) {
|
||||
return@builder suspendAndLog("OK")
|
||||
}
|
||||
}
|
||||
finally {
|
||||
result += "finally;"
|
||||
}
|
||||
result += "afterFinally;"
|
||||
"shouldNotReach"
|
||||
}
|
||||
if (value != "suspend(OK);finally;return(OK);") return "fail: $value"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
class Controller {
|
||||
var result = ""
|
||||
|
||||
suspend fun <T> suspendWithResult(value: T, c: Continuation<T>) {
|
||||
c.resume(value)
|
||||
}
|
||||
}
|
||||
|
||||
fun builder(coroutine c: Controller.() -> Continuation<Unit>): String {
|
||||
val controller = Controller()
|
||||
c(controller).resume(Unit)
|
||||
return controller.result
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var value = builder {
|
||||
var x = 1
|
||||
while (suspendWithResult(x) <= 3) {
|
||||
result += x++
|
||||
}
|
||||
result += "."
|
||||
}
|
||||
if (value != "123.") return "fail: suspend as while condition: $value"
|
||||
|
||||
value = builder {
|
||||
var x = 1
|
||||
while (x <= 3) {
|
||||
result += suspendWithResult(x++)
|
||||
result += ";"
|
||||
}
|
||||
result += "."
|
||||
}
|
||||
if (value != "1;2;3;.") return "fail: suspend in while body: $value"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
class Controller {
|
||||
var log = ""
|
||||
|
||||
suspend fun <T> suspendAndLog(value: T, x: Continuation<T>) {
|
||||
log += "suspend($value);"
|
||||
x.resume(value)
|
||||
}
|
||||
|
||||
operator fun handleResult(value: String, y: Continuation<Nothing>) {
|
||||
log += "return($value);"
|
||||
}
|
||||
}
|
||||
|
||||
fun builder(coroutine c: Controller.() -> Continuation<Unit>): String {
|
||||
val controller = Controller()
|
||||
c(controller).resume(Unit)
|
||||
return controller.log
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val result = builder { suspendAndLog("OK") }
|
||||
|
||||
if (result != "suspend(OK);return(OK);") return "fail: $result"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// MODULE: controller
|
||||
// FILE: controller.kt
|
||||
package lib
|
||||
|
||||
class Controller {
|
||||
suspend fun suspendHere(x: Continuation<String>) {
|
||||
x.resume("OK")
|
||||
}
|
||||
}
|
||||
|
||||
// MODULE: main(controller)
|
||||
// FILE: main.kt
|
||||
import lib.*
|
||||
|
||||
fun builder(coroutine c: Controller.() -> Continuation<Unit>) {
|
||||
c(Controller()).resume(Unit)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var result = ""
|
||||
|
||||
builder {
|
||||
result = suspendHere()
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
// MODULE: controller
|
||||
// FILE: controller.kt
|
||||
package lib
|
||||
|
||||
@AllowSuspendExtensions
|
||||
class Controller {
|
||||
suspend fun String.suspendHere(x: Continuation<String>) {
|
||||
x.resume(this)
|
||||
}
|
||||
|
||||
inline suspend fun String.inlineSuspendHere(x: Continuation<String>) {
|
||||
suspendHere(x)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun Controller.suspendExtension(v: String, x: Continuation<String>) {
|
||||
v.suspendHere(x)
|
||||
}
|
||||
|
||||
inline suspend fun Controller.inlineSuspendExtension(v: String, x: Continuation<String>) {
|
||||
v.inlineSuspendHere(x)
|
||||
}
|
||||
|
||||
// MODULE: main(controller)
|
||||
// FILE: main.kt
|
||||
import lib.*
|
||||
|
||||
suspend fun Controller.localSuspendExtension(v: String, x: Continuation<String>) {
|
||||
v.suspendHere(x)
|
||||
}
|
||||
|
||||
inline suspend fun Controller.localInlineSuspendExtension(v: String, x: Continuation<String>) {
|
||||
v.inlineSuspendHere(x)
|
||||
}
|
||||
|
||||
fun builder(coroutine c: Controller.() -> Continuation<Unit>) {
|
||||
c(Controller()).resume(Unit)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var result = ""
|
||||
|
||||
builder {
|
||||
if ("56".suspendHere() != "56") throw RuntimeException("fail 1")
|
||||
if ("28".inlineSuspendHere() != "28") throw RuntimeException("fail 2")
|
||||
|
||||
if (suspendExtension("123") != "123") throw RuntimeException("fail 3")
|
||||
if (inlineSuspendExtension("234") != "234") throw RuntimeException("fail 4")
|
||||
|
||||
if (localSuspendExtension("9123") != "9123") throw RuntimeException("fail 5")
|
||||
if (localInlineSuspendExtension("9234") != "9234") throw RuntimeException("fail 6")
|
||||
|
||||
result = "OK"
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
+78
@@ -4490,6 +4490,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("handleResultSuspended.kt")
|
||||
public void testHandleResultSuspended() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/handleResultSuspended.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("illegalState.kt")
|
||||
public void testIllegalState() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/illegalState.kt");
|
||||
@@ -4706,6 +4712,57 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/coroutines/controlFlow")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ControlFlow extends AbstractIrBlackBoxCodegenTest {
|
||||
public void testAllFilesPresentInControlFlow() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/controlFlow"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("breakFinally.kt")
|
||||
public void testBreakFinally() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/breakFinally.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("breakStatement.kt")
|
||||
public void testBreakStatement() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/breakStatement.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("doWhileStatement.kt")
|
||||
public void testDoWhileStatement() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/doWhileStatement.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("forStatement.kt")
|
||||
public void testForStatement() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/forStatement.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ifStatement.kt")
|
||||
public void testIfStatement() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/ifStatement.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("returnFromFinally.kt")
|
||||
public void testReturnFromFinally() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/returnFromFinally.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("whileStatement.kt")
|
||||
public void testWhileStatement() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/whileStatement.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/coroutines/intLikeVarSpilling")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@@ -4774,6 +4831,27 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/coroutines/multiModule")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class MultiModule extends AbstractIrBlackBoxCodegenTest {
|
||||
public void testAllFilesPresentInMultiModule() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/multiModule"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/multiModule/simple.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("suspendExtension.kt")
|
||||
public void testSuspendExtension() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/multiModule/suspendExtension.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/dataClasses")
|
||||
|
||||
@@ -4490,6 +4490,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("handleResultSuspended.kt")
|
||||
public void testHandleResultSuspended() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/handleResultSuspended.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("illegalState.kt")
|
||||
public void testIllegalState() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/illegalState.kt");
|
||||
@@ -4706,6 +4712,57 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/coroutines/controlFlow")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ControlFlow extends AbstractBlackBoxCodegenTest {
|
||||
public void testAllFilesPresentInControlFlow() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/controlFlow"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("breakFinally.kt")
|
||||
public void testBreakFinally() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/breakFinally.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("breakStatement.kt")
|
||||
public void testBreakStatement() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/breakStatement.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("doWhileStatement.kt")
|
||||
public void testDoWhileStatement() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/doWhileStatement.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("forStatement.kt")
|
||||
public void testForStatement() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/forStatement.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ifStatement.kt")
|
||||
public void testIfStatement() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/ifStatement.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("returnFromFinally.kt")
|
||||
public void testReturnFromFinally() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/returnFromFinally.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("whileStatement.kt")
|
||||
public void testWhileStatement() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/whileStatement.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/coroutines/intLikeVarSpilling")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@@ -4774,6 +4831,27 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/coroutines/multiModule")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class MultiModule extends AbstractBlackBoxCodegenTest {
|
||||
public void testAllFilesPresentInMultiModule() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/multiModule"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/multiModule/simple.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("suspendExtension.kt")
|
||||
public void testSuspendExtension() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/multiModule/suspendExtension.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/dataClasses")
|
||||
|
||||
@@ -50,7 +50,8 @@ class CoroutineBodyTransformer(val program: JsProgram, val scope: JsScope, val t
|
||||
get
|
||||
private set
|
||||
|
||||
private val currentTryDepth = tryStack.lastIndex
|
||||
private val currentTryDepth: Int
|
||||
get() = tryStack.lastIndex
|
||||
|
||||
fun preProcess(node: JsNode) {
|
||||
val nodes = mutableSetOf<JsNode>()
|
||||
@@ -323,7 +324,7 @@ class CoroutineBodyTransformer(val program: JsProgram, val scope: JsScope, val t
|
||||
|
||||
val targetBlock = breakBlocks[targetStatement]!!
|
||||
referencedBlocks += targetBlock
|
||||
jumpWithFinally(targetTryDepth, targetBlock)
|
||||
jumpWithFinally(targetTryDepth + 1, targetBlock)
|
||||
currentStatements += jump()
|
||||
}
|
||||
|
||||
@@ -339,15 +340,15 @@ class CoroutineBodyTransformer(val program: JsProgram, val scope: JsScope, val t
|
||||
val targetBlock = continueBlocks[targetStatement]!!
|
||||
referencedBlocks += targetBlock
|
||||
|
||||
jumpWithFinally(targetTryDepth, targetBlock)
|
||||
jumpWithFinally(targetTryDepth + 1, targetBlock)
|
||||
currentStatements += jump()
|
||||
}
|
||||
|
||||
private fun jumpWithFinally(targetTryDepth: Int, successor: CoroutineBlock) {
|
||||
if (targetTryDepth == tryStack.size) return
|
||||
|
||||
val tryBlock = tryStack[targetTryDepth]
|
||||
currentStatements += exceptionState(tryBlock.catchBlock)
|
||||
if (targetTryDepth < tryStack.size) {
|
||||
val tryBlock = tryStack[targetTryDepth]
|
||||
currentStatements += exceptionState(tryBlock.catchBlock)
|
||||
}
|
||||
|
||||
val relativeFinallyPath = relativeFinallyPath(targetTryDepth)
|
||||
val fullPath = relativeFinallyPath + successor
|
||||
@@ -593,7 +594,10 @@ class CoroutineBodyTransformer(val program: JsProgram, val scope: JsScope, val t
|
||||
}
|
||||
}
|
||||
|
||||
private fun relativeFinallyPath(targetTryDepth: Int) = tryStack.subList(targetTryDepth, tryStack.size).mapNotNull { it.finallyBlock }
|
||||
private fun relativeFinallyPath(targetTryDepth: Int) = tryStack
|
||||
.subList(targetTryDepth, tryStack.size)
|
||||
.mapNotNull { it.finallyBlock }
|
||||
.reversed()
|
||||
|
||||
private fun hasEnclosingFinallyBlock() = tryStack.any { it.finallyBlock != null }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user