[Native] Support suspend functions as supertypes

^KT-46777
This commit is contained in:
Dmitriy Dolovov
2021-05-07 18:49:12 +03:00
parent 9fe503eeb3
commit 896929cb21
4 changed files with 284 additions and 40 deletions
@@ -4,28 +4,170 @@
import kotlin.coroutines.*
var res = "FAIL"
var failure: String? = "FAIL ILLEGAL STATE"
class C: suspend () -> Unit {
override suspend fun invoke() {
res = "OK"
class TopLevel1: suspend () -> Int {
override suspend fun invoke(): Int {
failure = null
return 42
}
}
fun box(): String {
val o: suspend () -> Unit = object : suspend () -> Unit {
override suspend fun invoke() {
res = "OK"
class TopLevel2: suspend (String) -> Int {
override suspend fun invoke(p: String): Int {
failure = null
return p.length
}
}
class Outer {
class Nested1: suspend () -> Int {
override suspend fun invoke(): Int {
failure = null
return 42
}
}
o.startCoroutine(Continuation(EmptyCoroutineContext) {
it.getOrThrow()
})
if (res != "OK") return "FAIL 1: $res"
res = "FAIL 2"
C().startCoroutine(Continuation(EmptyCoroutineContext) {
it.getOrThrow()
})
return res
}
class Nested2: suspend (String) -> Int {
override suspend fun invoke(p: String): Int {
failure = null
return p.length
}
}
}
interface I : suspend (String) -> Int
abstract class Abstract1 : suspend (String) -> Int
abstract class Abstract2 : suspend (String) -> Int {
override suspend fun invoke(p: String): Int {
failure = null
return p.length
}
}
fun objectLiteral1(): String? {
failure = "FAIL OBJECT LITERAL 1"
val o: suspend () -> Int = object : suspend () -> Int {
override suspend fun invoke(): Int {
failure = null
return 42
}
}
o.startCoroutine(Continuation(EmptyCoroutineContext) { it.getOrThrow() })
return failure
}
fun objectLiteral2(): String? {
failure = "FAIL OBJECT LITERAL 2"
val o: suspend (String) -> Int = object : suspend (String) -> Int {
override suspend fun invoke(p: String): Int {
failure = null
return p.length
}
}
o.startCoroutine("Hello", Continuation(EmptyCoroutineContext) { it.getOrThrow() })
return failure
}
fun topLevelClass1(): String? {
failure = "FAIL TOP LEVEL CLASS 1"
TopLevel1().startCoroutine(Continuation(EmptyCoroutineContext) { it.getOrThrow() })
return failure
}
fun topLevelClass2(): String? {
failure = "FAIL TOP LEVEL CLASS 2"
TopLevel2().startCoroutine("Hello", Continuation(EmptyCoroutineContext) { it.getOrThrow() })
return failure
}
fun nestedClass1(): String? {
failure = "FAIL NESTED CLASS 1"
Outer.Nested1().startCoroutine(Continuation(EmptyCoroutineContext) { it.getOrThrow() })
return failure
}
fun nestedClass2(): String? {
failure = "FAIL NESTED CLASS 2"
Outer.Nested2().startCoroutine("Hello", Continuation(EmptyCoroutineContext) { it.getOrThrow() })
return failure
}
fun localClass1(): String? {
failure = "FAIL LOCAL CLASS 1"
class Local : suspend () -> Int {
override suspend fun invoke(): Int {
failure = null
return 42
}
}
Local().startCoroutine(Continuation(EmptyCoroutineContext) { it.getOrThrow() })
return failure
}
fun localClass2(): String? {
fun foo(): String? {
fun bar(): String? {
failure = "FAIL LOCAL CLASS 2"
class Local : suspend (String) -> Int {
override suspend fun invoke(p: String): Int {
failure = null
return p.length
}
}
Local().startCoroutine("Hello", Continuation(EmptyCoroutineContext) { it.getOrThrow() })
return failure
}
return bar()
}
return foo()
}
fun inherited1(): String? {
failure = "FAIL INHERITED 1"
val o = object : I {
override suspend fun invoke(p: String): Int {
failure = null
return p.length
}
}
o.startCoroutine("Hello", Continuation(EmptyCoroutineContext) { it.getOrThrow() })
return failure
}
fun inherited2(): String? {
failure = "FAIL INHERITED 2"
val o = object : I, Abstract1() {
override suspend fun invoke(p: String): Int {
failure = null
return p.length
}
}
o.startCoroutine("Hello", Continuation(EmptyCoroutineContext) { it.getOrThrow() })
return failure
}
fun inherited3(): String? {
failure = "FAIL INHERITED 3"
val o = object : I, Abstract2() {}
o.startCoroutine("Hello", Continuation(EmptyCoroutineContext) { it.getOrThrow() })
return failure
}
fun box(): String {
val failures = listOfNotNull(
objectLiteral1(),
objectLiteral2(),
topLevelClass1(),
topLevelClass2(),
nestedClass1(),
nestedClass2(),
localClass1(),
localClass2(),
inherited1(),
inherited2(),
inherited3()
)
return if (failures.isNotEmpty()) failures.joinToString("\n") else "OK"
}