JVM: Make coroutines spilling tests runtime
instead of bytecode text ones. Check the content of continuation object instead of bytecode, since this is less prone to changes during changes in coroutines codegen. #KT-48678
This commit is contained in:
+58
@@ -13163,6 +13163,64 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
public void testSafeCallElvis() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/safeCallElvis.kt");
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/box/coroutines/varSpilling/cleanup")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class Cleanup {
|
||||
@Test
|
||||
public void testAllFilesPresentInCleanup() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/varSpilling/cleanup"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("backEdge.kt")
|
||||
public void testBackEdge() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/backEdge.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("if.kt")
|
||||
public void testIf() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/if.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nullCleanup.kt")
|
||||
public void testNullCleanup() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/nullCleanup.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nullNotSpill.kt")
|
||||
public void testNullNotSpill() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/nullNotSpill.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/simple.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("twoRefs.kt")
|
||||
public void testTwoRefs() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/twoRefs.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("unusedParamNotSpill.kt")
|
||||
public void testUnusedParamNotSpill() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/unusedParamNotSpill.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("when.kt")
|
||||
public void testWhen() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/when.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-58
@@ -1752,64 +1752,6 @@ public class FirBytecodeTextTestGenerated extends AbstractFirBytecodeTextTest {
|
||||
runTest("compiler/testData/codegen/bytecodeText/coroutines/varValueConflictsWithTableSameSort.kt");
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/coroutines/cleanup")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class Cleanup {
|
||||
@Test
|
||||
public void testAllFilesPresentInCleanup() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/coroutines/cleanup"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("backEdge.kt")
|
||||
public void testBackEdge() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/backEdge.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("if.kt")
|
||||
public void testIf() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/if.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nullCleanup.kt")
|
||||
public void testNullCleanup() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/nullCleanup.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nullNotSpill.kt")
|
||||
public void testNullNotSpill() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/nullNotSpill.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/simple.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("twoRefs.kt")
|
||||
public void testTwoRefs() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/twoRefs.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("unusedParamNotSpill.kt")
|
||||
public void testUnusedParamNotSpill() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/unusedParamNotSpill.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("when.kt")
|
||||
public void testWhen() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/when.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/coroutines/debug")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
// WITH_STDLIB
|
||||
// FULL_JDK
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_BACKEND: JVM
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
|
||||
fun blackhole(vararg a: Any?) {}
|
||||
|
||||
val spilledVariables = mutableSetOf<Pair<String, String>>()
|
||||
|
||||
var c: Continuation<Unit>? = null
|
||||
|
||||
suspend fun saveSpilledVariables() = suspendCoroutineUninterceptedOrReturn<Unit> { continuation ->
|
||||
spilledVariables.clear()
|
||||
for (field in continuation.javaClass.declaredFields) {
|
||||
if (field.name != "label" && (field.name.length != 3 || field.name[1] != '$')) continue
|
||||
field.isAccessible = true
|
||||
spilledVariables += field.name to "${field.get(continuation)}"
|
||||
}
|
||||
c = continuation
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
suspend fun test() {
|
||||
for (i in 0..1) {
|
||||
// Should be cleanup, since there is a back edge from the rest of the loop
|
||||
saveSpilledVariables()
|
||||
val a = "a"
|
||||
saveSpilledVariables()
|
||||
blackhole(a)
|
||||
}
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(Continuation(EmptyCoroutineContext) {
|
||||
it.getOrThrow()
|
||||
})
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
builder {
|
||||
test()
|
||||
}
|
||||
if (spilledVariables != setOf("label" to "1", "I$0" to "0", "L$0" to "null")) return "FAIL 1: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "2", "I$0" to "0", "L$0" to "a")) return "FAIL 2: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "1", "I$0" to "1", "L$0" to "null")) return "FAIL 3: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "2", "I$0" to "1", "L$0" to "a")) return "FAIL 4: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "2", "I$0" to "1", "L$0" to "a")) return "FAIL 5: $spilledVariables"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
// WITH_STDLIB
|
||||
// FULL_JDK
|
||||
// TARGET_BACKEND: JVM
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
|
||||
fun blackhole(vararg a: Any?) {}
|
||||
|
||||
val spilledVariables = mutableSetOf<Pair<String, String>>()
|
||||
|
||||
var c: Continuation<Unit>? = null
|
||||
|
||||
suspend fun saveSpilledVariables() = suspendCoroutineUninterceptedOrReturn<Unit> { continuation ->
|
||||
spilledVariables.clear()
|
||||
for (field in continuation.javaClass.declaredFields) {
|
||||
if (field.name != "label" && (field.name.length != 3 || field.name[1] != '$')) continue
|
||||
field.isAccessible = true
|
||||
spilledVariables += field.name to "${field.get(continuation)}"
|
||||
}
|
||||
c = continuation
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
suspend fun test(check: Boolean) {
|
||||
if (check) {
|
||||
val a = "a1"
|
||||
saveSpilledVariables()
|
||||
blackhole(a)
|
||||
} else {
|
||||
val a = "a2"
|
||||
val b = "b2"
|
||||
saveSpilledVariables()
|
||||
blackhole(a, b)
|
||||
}
|
||||
// Cleanup both a and b, since the compiler does not know, which branch is going to executed
|
||||
saveSpilledVariables()
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(Continuation(EmptyCoroutineContext) {
|
||||
it.getOrThrow()
|
||||
})
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
builder {
|
||||
test(true)
|
||||
}
|
||||
if (spilledVariables != setOf("label" to "1", "L$0" to "a1", "L$1" to "null")) return "FAIL 1: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "3", "L$0" to "null", "L$1" to "null")) return "FAIL 2: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "3", "L$0" to "null", "L$1" to "null")) return "FAIL 3: $spilledVariables"
|
||||
|
||||
builder {
|
||||
test(false)
|
||||
}
|
||||
if (spilledVariables != setOf("label" to "2", "L$0" to "a2", "L$1" to "b2")) return "FAIL 4: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "3", "L$0" to "null", "L$1" to "null")) return "FAIL 5: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "3", "L$0" to "null", "L$1" to "null")) return "FAIL 6: $spilledVariables"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
// WITH_STDLIB
|
||||
// FULL_JDK
|
||||
// TARGET_BACKEND: JVM
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
|
||||
fun blackhole(vararg a: Any?) {}
|
||||
|
||||
val spilledVariables = mutableSetOf<Pair<String, String>>()
|
||||
|
||||
var c: Continuation<Unit>? = null
|
||||
|
||||
suspend fun saveSpilledVariables() = suspendCoroutineUninterceptedOrReturn<Unit> { continuation ->
|
||||
spilledVariables.clear()
|
||||
for (field in continuation.javaClass.declaredFields) {
|
||||
if (field.name != "label" && (field.name.length != 3 || field.name[1] != '$')) continue
|
||||
field.isAccessible = true
|
||||
spilledVariables += field.name to "${field.get(continuation)}"
|
||||
}
|
||||
c = continuation
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
suspend fun test() {
|
||||
var a: String? = "a"
|
||||
saveSpilledVariables()
|
||||
blackhole(a)
|
||||
a = null
|
||||
// a is null, known at compile time, do not spill, but cleanup
|
||||
saveSpilledVariables()
|
||||
blackhole(a)
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(Continuation(EmptyCoroutineContext) {
|
||||
it.getOrThrow()
|
||||
})
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
builder {
|
||||
test()
|
||||
}
|
||||
if (spilledVariables != setOf("label" to "1", "L$0" to "a")) return "FAIL 1: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "2", "L$0" to "null")) return "FAIL 2: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "2", "L$0" to "null")) return "FAIL 3: $spilledVariables"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// WITH_STDLIB
|
||||
// FULL_JDK
|
||||
// TARGET_BACKEND: JVM
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
|
||||
fun blackhole(vararg a: Any?) {}
|
||||
|
||||
val spilledVariables = mutableSetOf<Pair<String, String>>()
|
||||
|
||||
var c: Continuation<Unit>? = null
|
||||
|
||||
suspend fun saveSpilledVariables() = suspendCoroutineUninterceptedOrReturn<Unit> { continuation ->
|
||||
spilledVariables.clear()
|
||||
for (field in continuation.javaClass.declaredFields) {
|
||||
if (field.name != "label" && (field.name.length != 3 || field.name[1] != '$')) continue
|
||||
field.isAccessible = true
|
||||
spilledVariables += field.name to "${field.get(continuation)}"
|
||||
}
|
||||
c = continuation
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
suspend fun test() {
|
||||
val a = null
|
||||
// a is null, known at compile time, do not spill
|
||||
saveSpilledVariables()
|
||||
blackhole(a)
|
||||
saveSpilledVariables()
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(Continuation(EmptyCoroutineContext) {
|
||||
it.getOrThrow()
|
||||
})
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
builder {
|
||||
test()
|
||||
}
|
||||
if (spilledVariables != setOf("label" to "1")) return "FAIL 1: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "2")) return "FAIL 2: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "2")) return "FAIL 3: $spilledVariables"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
// WITH_STDLIB
|
||||
// FULL_JDK
|
||||
// TARGET_BACKEND: JVM
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
|
||||
fun blackhole(vararg a: Any?) {}
|
||||
|
||||
val spilledVariables = mutableSetOf<Pair<String, String>>()
|
||||
|
||||
var c: Continuation<Unit>? = null
|
||||
|
||||
suspend fun saveSpilledVariables() = suspendCoroutineUninterceptedOrReturn<Unit> { continuation ->
|
||||
spilledVariables.clear()
|
||||
for (field in continuation.javaClass.declaredFields) {
|
||||
if (field.name != "label" && (field.name.length != 3 || field.name[1] != '$')) continue
|
||||
field.isAccessible = true
|
||||
spilledVariables += field.name to "${field.get(continuation)}"
|
||||
}
|
||||
c = continuation
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
suspend fun test() {
|
||||
val a = "a"
|
||||
saveSpilledVariables()
|
||||
blackhole(a)
|
||||
// a is dead, cleanup
|
||||
saveSpilledVariables()
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(Continuation(EmptyCoroutineContext) {
|
||||
it.getOrThrow()
|
||||
})
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
builder {
|
||||
test()
|
||||
}
|
||||
if (spilledVariables != setOf("label" to "1", "L$0" to "a")) return "FAIL 1: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "2", "L$0" to "null")) return "FAIL 2: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "2", "L$0" to "null")) return "FAIL 3: $spilledVariables"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
fun main() {
|
||||
println(box())
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
// WITH_STDLIB
|
||||
// FULL_JDK
|
||||
// TARGET_BACKEND: JVM
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
|
||||
fun blackhole(vararg a: Any?) {}
|
||||
|
||||
val spilledVariables = mutableSetOf<Pair<String, String>>()
|
||||
|
||||
var c: Continuation<Unit>? = null
|
||||
|
||||
suspend fun saveSpilledVariables() = suspendCoroutineUninterceptedOrReturn<Unit> { continuation ->
|
||||
spilledVariables.clear()
|
||||
for (field in continuation.javaClass.declaredFields) {
|
||||
if (field.name != "label" && (field.name.length != 3 || field.name[1] != '$')) continue
|
||||
field.isAccessible = true
|
||||
spilledVariables += field.name to "${field.get(continuation)}"
|
||||
}
|
||||
c = continuation
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
suspend fun test(a: String, b: String) {
|
||||
saveSpilledVariables()
|
||||
blackhole(a)
|
||||
saveSpilledVariables()
|
||||
blackhole(b)
|
||||
saveSpilledVariables()
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(Continuation(EmptyCoroutineContext) {
|
||||
it.getOrThrow()
|
||||
})
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
builder {
|
||||
test("a", "b")
|
||||
}
|
||||
if (spilledVariables != setOf("label" to "1", "L$0" to "a", "L$1" to "b")) return "FAIL 1: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "2", "L$0" to "b", "L$1" to "null")) return "FAIL 2: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "3", "L$0" to "null", "L$1" to "null")) return "FAIL 3: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "3", "L$0" to "null", "L$1" to "null")) return "FAIL 4: $spilledVariables"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
fun main() {
|
||||
println(box())
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
// WITH_STDLIB
|
||||
// FULL_JDK
|
||||
// TARGET_BACKEND: JVM
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
|
||||
fun blackhole(vararg a: Any?) {}
|
||||
|
||||
val spilledVariables = mutableSetOf<Pair<String, String>>()
|
||||
|
||||
var c: Continuation<Unit>? = null
|
||||
|
||||
suspend fun saveSpilledVariables() = suspendCoroutineUninterceptedOrReturn<Unit> { continuation ->
|
||||
spilledVariables.clear()
|
||||
for (field in continuation.javaClass.declaredFields) {
|
||||
if (field.name != "label" && (field.name.length != 3 || field.name[1] != '$')) continue
|
||||
field.isAccessible = true
|
||||
spilledVariables += field.name to "${field.get(continuation)}"
|
||||
}
|
||||
c = continuation
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
val test: suspend (Int) -> Unit = { unused ->
|
||||
saveSpilledVariables()
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(Continuation(EmptyCoroutineContext) {
|
||||
it.getOrThrow()
|
||||
})
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
builder {
|
||||
test(1)
|
||||
}
|
||||
if (spilledVariables != setOf("label" to "1")) return "FAIL 1: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "1")) return "FAIL 2: $spilledVariables"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
// WITH_STDLIB
|
||||
// FULL_JDK
|
||||
// TARGET_BACKEND: JVM
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
|
||||
fun blackhole(vararg a: Any?) {}
|
||||
|
||||
val spilledVariables = mutableSetOf<Pair<String, String>>()
|
||||
|
||||
var c: Continuation<Unit>? = null
|
||||
|
||||
suspend fun saveSpilledVariables() = suspendCoroutineUninterceptedOrReturn<Unit> { continuation ->
|
||||
spilledVariables.clear()
|
||||
for (field in continuation.javaClass.declaredFields) {
|
||||
if (field.name != "label" && (field.name.length != 3 || field.name[1] != '$')) continue
|
||||
field.isAccessible = true
|
||||
spilledVariables += field.name to "${field.get(continuation)}"
|
||||
}
|
||||
c = continuation
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
suspend fun test(check: Int) {
|
||||
when (check) {
|
||||
0 -> {
|
||||
val a = "a0"
|
||||
saveSpilledVariables()
|
||||
blackhole(a)
|
||||
}
|
||||
1 -> {
|
||||
val a = "a1"
|
||||
val b = "b1"
|
||||
saveSpilledVariables()
|
||||
blackhole(a, b)
|
||||
}
|
||||
else -> {
|
||||
val a = "a2"
|
||||
val b = "b2"
|
||||
val c = 1
|
||||
saveSpilledVariables()
|
||||
blackhole(a, b, c)
|
||||
}
|
||||
}
|
||||
// Cleanup both a and b, but c is primitive, so no need to clean it up
|
||||
saveSpilledVariables()
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(Continuation(EmptyCoroutineContext) {
|
||||
it.getOrThrow()
|
||||
})
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
builder {
|
||||
test(0)
|
||||
}
|
||||
if (spilledVariables != setOf("label" to "1", "I$0" to "0", "L$0" to "a0", "L$1" to "null")) return "FAIL 1: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "4", "I$0" to "0", "L$0" to "null", "L$1" to "null")) return "FAIL 2: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "4", "I$0" to "0", "L$0" to "null", "L$1" to "null")) return "FAIL 3: $spilledVariables"
|
||||
|
||||
builder {
|
||||
test(1)
|
||||
}
|
||||
if (spilledVariables != setOf("label" to "2", "I$0" to "0", "L$0" to "a1", "L$1" to "b1")) return "FAIL 4: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "4", "I$0" to "0", "L$0" to "null", "L$1" to "null")) return "FAIL 5: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "4", "I$0" to "0", "L$0" to "null", "L$1" to "null")) return "FAIL 6: $spilledVariables"
|
||||
|
||||
builder {
|
||||
test(2)
|
||||
}
|
||||
if (spilledVariables != setOf("label" to "3", "I$0" to "1", "L$0" to "a2", "L$1" to "b2")) return "FAIL 7: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "4", "I$0" to "1", "L$0" to "null", "L$1" to "null")) return "FAIL 8: $spilledVariables"
|
||||
c?.resume(Unit)
|
||||
if (spilledVariables != setOf("label" to "4", "I$0" to "1", "L$0" to "null", "L$1" to "null")) return "FAIL 9: $spilledVariables"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
fun blackhole(vararg a: Any?) {}
|
||||
|
||||
suspend fun dummy() {}
|
||||
|
||||
suspend fun test() {
|
||||
for (i in 0..10) {
|
||||
// Should be cleanup, since there is a back edge from the rest of the loop
|
||||
dummy()
|
||||
val a = ""
|
||||
dummy()
|
||||
blackhole(a)
|
||||
}
|
||||
}
|
||||
|
||||
// 1 ACONST_NULL
|
||||
// 2 PUTFIELD .*L\$0 : Ljava/lang/Object;
|
||||
@@ -1,24 +0,0 @@
|
||||
fun blackhole(vararg a: Any?) {}
|
||||
|
||||
suspend fun dummy() {}
|
||||
|
||||
fun check(): Boolean = true
|
||||
|
||||
suspend fun test() {
|
||||
if (check()) {
|
||||
val a = ""
|
||||
dummy()
|
||||
blackhole(a)
|
||||
} else {
|
||||
val a = ""
|
||||
val b = ""
|
||||
dummy()
|
||||
blackhole(a, b)
|
||||
}
|
||||
// Cleanup both a and b, since the compiler does not know, which branch is going to executed
|
||||
dummy()
|
||||
}
|
||||
|
||||
// 2 ACONST_NULL
|
||||
// 3 PUTFIELD .*L\$0 : Ljava/lang/Object;
|
||||
// 2 PUTFIELD .*L\$1 : Ljava/lang/Object;
|
||||
@@ -1,18 +0,0 @@
|
||||
fun blackhole(vararg a: Any?) {}
|
||||
|
||||
suspend fun dummy() {}
|
||||
|
||||
suspend fun test() {
|
||||
var a: String? = ""
|
||||
dummy()
|
||||
blackhole(a)
|
||||
a = null
|
||||
// a is null, known at compile time, do not spill, but cleanup
|
||||
dummy()
|
||||
blackhole(a)
|
||||
}
|
||||
|
||||
// 2 PUTFIELD .*L\$0 : Ljava/lang/Object;
|
||||
|
||||
// two stores to initialize the `a` variable and one null constant to store in the spill slot.
|
||||
// 3 ACONST_NULL
|
||||
@@ -1,15 +0,0 @@
|
||||
fun blackhole(vararg a: Any?) {}
|
||||
|
||||
suspend fun dummy() {}
|
||||
|
||||
suspend fun test() {
|
||||
val a = null
|
||||
// a is null, known at compile time, do not spill
|
||||
dummy()
|
||||
blackhole(a)
|
||||
dummy()
|
||||
}
|
||||
|
||||
// before and after suspension point
|
||||
// 2 ACONST_NULL
|
||||
// 0 PUTFIELD .*L\$0 : Ljava/lang/Object;
|
||||
@@ -1,14 +0,0 @@
|
||||
fun blackhole(vararg a: Any?) {}
|
||||
|
||||
suspend fun dummy() {}
|
||||
|
||||
suspend fun test() {
|
||||
val a = ""
|
||||
dummy()
|
||||
blackhole(a)
|
||||
// a is dead, cleanup
|
||||
dummy()
|
||||
}
|
||||
|
||||
// 1 ACONST_NULL
|
||||
// 2 PUTFIELD .*L\$0 : Ljava/lang/Object;
|
||||
@@ -1,9 +0,0 @@
|
||||
suspend fun blackhole(a: Any?) {}
|
||||
|
||||
suspend fun cleanUpExample(a: String, b: String) {
|
||||
blackhole(a) // 1
|
||||
blackhole(b) // 2
|
||||
}
|
||||
|
||||
// 3 ACONST_NULL
|
||||
// 2 PUTFIELD .*L\$0 : .*;
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
val f: suspend (Int) -> Unit = { unused ->
|
||||
}
|
||||
|
||||
// 0 GETFIELD .*I\$0
|
||||
// 0 PUTFIELD .*I\$0
|
||||
@@ -1,34 +0,0 @@
|
||||
fun blackhole(vararg a: Any?) {}
|
||||
|
||||
suspend fun dummy() {}
|
||||
|
||||
fun check(): Int = 1
|
||||
|
||||
suspend fun test() {
|
||||
when (check()) {
|
||||
0 -> {
|
||||
val a = ""
|
||||
dummy()
|
||||
blackhole(a)
|
||||
}
|
||||
1 -> {
|
||||
val a = ""
|
||||
val b = ""
|
||||
dummy()
|
||||
blackhole(a, b)
|
||||
}
|
||||
else -> {
|
||||
val a = ""
|
||||
val b = ""
|
||||
val c = 1
|
||||
dummy()
|
||||
blackhole(a, b, c)
|
||||
}
|
||||
}
|
||||
// Cleanup both a and b, but c is primitive, so no need to clean it up
|
||||
dummy()
|
||||
}
|
||||
|
||||
// 2 ACONST_NULL
|
||||
// 4 PUTFIELD .*L\$0 : Ljava/lang/Object;
|
||||
// 3 PUTFIELD .*L\$1 : Ljava/lang/Object;
|
||||
+58
@@ -13043,6 +13043,64 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
public void testSafeCallElvis() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/safeCallElvis.kt");
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/box/coroutines/varSpilling/cleanup")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class Cleanup {
|
||||
@Test
|
||||
public void testAllFilesPresentInCleanup() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/varSpilling/cleanup"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("backEdge.kt")
|
||||
public void testBackEdge() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/backEdge.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("if.kt")
|
||||
public void testIf() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/if.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nullCleanup.kt")
|
||||
public void testNullCleanup() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/nullCleanup.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nullNotSpill.kt")
|
||||
public void testNullNotSpill() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/nullNotSpill.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/simple.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("twoRefs.kt")
|
||||
public void testTwoRefs() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/twoRefs.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("unusedParamNotSpill.kt")
|
||||
public void testUnusedParamNotSpill() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/unusedParamNotSpill.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("when.kt")
|
||||
public void testWhen() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/when.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-58
@@ -1716,64 +1716,6 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
||||
runTest("compiler/testData/codegen/bytecodeText/coroutines/varValueConflictsWithTableSameSort.kt");
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/coroutines/cleanup")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class Cleanup {
|
||||
@Test
|
||||
public void testAllFilesPresentInCleanup() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/coroutines/cleanup"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("backEdge.kt")
|
||||
public void testBackEdge() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/backEdge.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("if.kt")
|
||||
public void testIf() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/if.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nullCleanup.kt")
|
||||
public void testNullCleanup() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/nullCleanup.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nullNotSpill.kt")
|
||||
public void testNullNotSpill() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/nullNotSpill.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/simple.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("twoRefs.kt")
|
||||
public void testTwoRefs() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/twoRefs.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("unusedParamNotSpill.kt")
|
||||
public void testUnusedParamNotSpill() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/unusedParamNotSpill.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("when.kt")
|
||||
public void testWhen() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/when.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/coroutines/debug")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
+58
@@ -13163,6 +13163,64 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
public void testSafeCallElvis() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/safeCallElvis.kt");
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/box/coroutines/varSpilling/cleanup")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class Cleanup {
|
||||
@Test
|
||||
public void testAllFilesPresentInCleanup() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/varSpilling/cleanup"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("backEdge.kt")
|
||||
public void testBackEdge() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/backEdge.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("if.kt")
|
||||
public void testIf() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/if.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nullCleanup.kt")
|
||||
public void testNullCleanup() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/nullCleanup.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nullNotSpill.kt")
|
||||
public void testNullNotSpill() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/nullNotSpill.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/simple.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("twoRefs.kt")
|
||||
public void testTwoRefs() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/twoRefs.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("unusedParamNotSpill.kt")
|
||||
public void testUnusedParamNotSpill() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/unusedParamNotSpill.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("when.kt")
|
||||
public void testWhen() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/when.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-58
@@ -1752,64 +1752,6 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
|
||||
runTest("compiler/testData/codegen/bytecodeText/coroutines/varValueConflictsWithTableSameSort.kt");
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/coroutines/cleanup")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class Cleanup {
|
||||
@Test
|
||||
public void testAllFilesPresentInCleanup() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/coroutines/cleanup"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("backEdge.kt")
|
||||
public void testBackEdge() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/backEdge.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("if.kt")
|
||||
public void testIf() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/if.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nullCleanup.kt")
|
||||
public void testNullCleanup() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/nullCleanup.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nullNotSpill.kt")
|
||||
public void testNullNotSpill() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/nullNotSpill.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/simple.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("twoRefs.kt")
|
||||
public void testTwoRefs() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/twoRefs.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("unusedParamNotSpill.kt")
|
||||
public void testUnusedParamNotSpill() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/unusedParamNotSpill.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("when.kt")
|
||||
public void testWhen() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/coroutines/cleanup/when.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/coroutines/debug")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
+53
@@ -10539,6 +10539,59 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
public void testSafeCallElvis() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/safeCallElvis.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/coroutines/varSpilling/cleanup")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Cleanup extends AbstractLightAnalysisModeTest {
|
||||
@TestMetadata("backEdge.kt")
|
||||
public void ignoreBackEdge() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/backEdge.kt");
|
||||
}
|
||||
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInCleanup() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/varSpilling/cleanup"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||
}
|
||||
|
||||
@TestMetadata("if.kt")
|
||||
public void testIf() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/if.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nullCleanup.kt")
|
||||
public void testNullCleanup() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/nullCleanup.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nullNotSpill.kt")
|
||||
public void testNullNotSpill() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/nullNotSpill.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/simple.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("twoRefs.kt")
|
||||
public void testTwoRefs() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/twoRefs.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unusedParamNotSpill.kt")
|
||||
public void testUnusedParamNotSpill() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/unusedParamNotSpill.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("when.kt")
|
||||
public void testWhen() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/cleanup/when.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
@@ -9715,6 +9715,16 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
public void testSafeCallElvis() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/safeCallElvis.kt");
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/box/coroutines/varSpilling/cleanup")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class Cleanup {
|
||||
@Test
|
||||
public void testAllFilesPresentInCleanup() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/varSpilling/cleanup"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
@@ -9757,6 +9757,16 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
public void testSafeCallElvis() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/safeCallElvis.kt");
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/box/coroutines/varSpilling/cleanup")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class Cleanup {
|
||||
@Test
|
||||
public void testAllFilesPresentInCleanup() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/varSpilling/cleanup"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+13
@@ -8624,6 +8624,19 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
||||
public void testSafeCallElvis() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/safeCallElvis.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/coroutines/varSpilling/cleanup")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Cleanup extends AbstractIrCodegenBoxWasmTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest0(this::doTest, TargetBackend.WASM, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInCleanup() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/varSpilling/cleanup"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+12
@@ -10685,6 +10685,18 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest
|
||||
public void testSafeCallElvis() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/safeCallElvis.kt");
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/box/coroutines/varSpilling/cleanup")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@Tag("codegen")
|
||||
@UseExtTestCaseGroupProvider()
|
||||
public class Cleanup {
|
||||
@Test
|
||||
public void testAllFilesPresentInCleanup() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/varSpilling/cleanup"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.NATIVE, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user