Implement callable references to suspend functions

In FE they have type KSuspendFunctionN
In BE they are treated like normal callable references with additional
parameter in invoke function.
This commit is contained in:
Ilmir Usmanov
2018-05-29 13:17:53 +03:00
parent 5869274ff1
commit f94b579d19
82 changed files with 5393 additions and 41 deletions
@@ -0,0 +1,26 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
class A {
companion object {
suspend fun ok() = "OK"
}
}
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
fun box(): String {
var res = "FAIL"
builder {
res = (A.Companion::ok)()
}
return res
}
@@ -0,0 +1,16 @@
// IGNORE_BACKEND: JS
// SKIP_SOURCEMAP_REMAPPING
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import COROUTINES_PACKAGE.*
fun box(): String {
val name = ::coroutineContext.name
if (name != "coroutineContext") return "Fail 1: $name"
return "OK"
}
@@ -0,0 +1,97 @@
// IGNORE_BACKEND: JS
// LANGUAGE_VERSION: 1.2
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import kotlin.coroutines.experimental.*
var result = ""
class A {
suspend fun memberFunction() {
result += "A.mf,"
}
suspend fun aMemberFunction() {
result += "A.amf,"
}
suspend fun test(): String {
(::memberFunction)()
(::aExtensionFunction)()
return result
}
inner class B {
suspend fun memberFunction() {
result += "B.mf,"
}
suspend fun test(): String {
(::aMemberFunction)()
(::aExtensionFunction)()
(::memberFunction)()
(::bExtensionFunction)()
return result
}
}
}
suspend fun A.aExtensionFunction() {
result += "A.ef,"
}
suspend fun A.B.bExtensionFunction() {
result += "B.ef,"
}
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
fun box(): String {
var a = "FAIL 1"
builder {
a = A().test()
}
if (a != "A.mf,A.ef,") return "Fail $a"
result = ""
var b = "FAIL 2"
builder {
b = A().B().test()
}
if (b != "A.amf,A.ef,B.mf,B.ef,") return "Fail $b"
result = ""
builder {
with(A()) {
(::memberFunction)()
(::aExtensionFunction)()
}
}
if (result != "A.mf,A.ef,") return "Fail $result"
result = ""
builder {
with(A()) {
with(B()) {
(::aMemberFunction)()
(::aExtensionFunction)()
(::memberFunction)()
(::bExtensionFunction)()
}
}
}
if (result != "A.amf,A.ef,B.mf,B.ef,") return "Fail $result"
return "OK"
}
@@ -0,0 +1,31 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
enum class E {
A, B;
suspend fun foo() = this.name
}
fun box(): String {
val f = E.A::foo
val ef = E::foo
var res = ""
builder {
if (f() != "A") res = "Fail 1: ${f()}"
else if (f == E.B::foo) res = "Fail 2"
else if (ef != E::foo) res = "Fail 3"
}
return "OK"
}
@@ -0,0 +1,25 @@
// TODO: investigate should it be ran for JS or not
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_REFLECT
class A
val a = A()
val aa = A()
suspend fun A?.foo() {}
val aFoo = a::foo
val A_foo = A::foo
val nullFoo = null::foo
fun box(): String =
when {
nullFoo != null::foo -> "Bound extension refs with same receiver SHOULD be equal"
nullFoo == aFoo -> "Bound extension refs with different receivers SHOULD NOT be equal"
nullFoo == A_foo -> "Bound extension ref with receiver 'null' SHOULD NOT be equal to free ref"
else -> "OK"
}
@@ -0,0 +1,29 @@
// TODO: investigate should it be ran for JS or not
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
package test
class A {
suspend fun foo() {}
suspend fun bar() {}
}
val a = A()
val aa = A()
val aFoo = a::foo
val aBar = a::bar
val aaFoo = aa::foo
val A_foo = A::foo
fun box(): String =
when {
aFoo != a::foo -> "Bound refs with same receiver SHOULD be equal"
aFoo == aBar -> "Bound refs to different members SHOULD NOT be equal"
aFoo == aaFoo -> "Bound refs with different receiver SHOULD NOT be equal"
aFoo == A_foo -> "Bound ref SHOULD NOT be equal to free ref"
else -> "OK"
}
@@ -0,0 +1,27 @@
// TODO: investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
// COMMON_COROUTINES_TEST
// WITH_REFLECT
import kotlin.reflect.full.*
class C {
suspend fun foo() {}
}
val C_fooReflect = C::class.functions.find { it.name == "foo" }!!
val C_foo = C::foo
val cFoo = C()::foo
val Any.className: String
get() = this::class.qualifiedName!!
fun box(): String =
when {
C_fooReflect != C_foo -> "C_fooReflect != C_foo, ${C_fooReflect.className}"
C_foo != C_fooReflect -> "C_foo != C_fooReflect, ${C_foo.className}"
C_fooReflect == cFoo -> "C_fooReflect == cFoo, ${C_fooReflect.className}"
cFoo == C_fooReflect -> "cFoo == C_fooReflect, ${cFoo.className}"
else -> "OK"
}
@@ -0,0 +1,24 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
inline suspend fun foo(x: suspend () -> String) = x()
suspend fun String.id() = this
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
fun box(): String {
var res = ""
builder {
res = foo("OK"::id)
}
return res
}
@@ -0,0 +1,25 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
inline suspend fun go(f: suspend () -> String) = f()
suspend fun String.id(): String = this
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
fun box(): String {
val x = "OK"
var res = "FAIL"
builder {
res = go(x::id)
}
return res
}
@@ -0,0 +1,20 @@
// TARGET_BACKEND: JVM
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
fun box(): String {
suspend fun foo(): Unit {}
builder {
assert(Unit.javaClass.equals(foo().javaClass))
assert(Unit.javaClass.equals(foo()::class.java))
}
return "OK"
}
@@ -0,0 +1,66 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
class A(var v: Int) {
suspend fun f(x: Int) = x * v
}
suspend fun A.g(x: Int) = x * f(x);
var A.w: Int
get() = 1000 * v
set(c: Int) {
v = c + 10
}
object F {
var u = 0
}
fun box(): String {
builder {
val a = A(5)
val av = a::v
if (av() != 5) throw RuntimeException("fail1: ${av()}")
if (av.get() != 5) throw RuntimeException("fail2: ${av.get()}")
av.set(7)
if (a.v != 7) throw RuntimeException("fail3: ${a.v}")
val af = a::f
if (af(10) != 70) throw RuntimeException("fail4: ${af(10)}")
val ag = a::g
if (ag(10) != 700) throw RuntimeException("fail5: ${ag(10)}")
val aw = a::w
if (aw() != 7000) throw RuntimeException("fail6: ${aw()}")
if (aw.get() != 7000) throw RuntimeException("fail7: ${aw.get()}")
aw.set(5)
if (a.v != 15) throw RuntimeException("fail8: ${a.v}")
val fu = F::u
if (fu() != 0) throw RuntimeException("fail9: ${fu()}")
if (fu.get() != 0) throw RuntimeException("fail10: ${fu.get()}")
fu.set(8)
if (F.u != 8) throw RuntimeException("fail11: ${F.u}")
val x = 100
fun A.lf() = v * x;
val alf = a::lf
if (alf() != 1500) throw RuntimeException("fail9: ${alf()}")
}
return "OK"
}
@@ -0,0 +1,22 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
suspend fun String?.ok() = "OK"
fun box(): String {
var res = "FAIL"
builder {
res = (null::ok)()
}
return res
}
@@ -0,0 +1,24 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
object Singleton {
suspend fun ok() = "OK"
}
fun box(): String {
var res = "FAIL"
builder {
res = (Singleton::ok)()
}
return res
}
@@ -0,0 +1,41 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
suspend fun Boolean.foo() = 1
suspend fun Byte.foo() = 2
suspend fun Short.foo() = 3
suspend fun Int.foo() = 4
suspend fun Long.foo() = 5
suspend fun Char.foo() = 6
suspend fun Float.foo() = 7
suspend fun Double.foo() = 8
fun testRef(name: String, f: suspend () -> Int, expected: Int) {
builder {
val actual = f()
if (actual != expected) throw AssertionError("$name: $actual != $expected")
}
}
fun box(): String {
testRef("Boolean", true::foo, 1)
testRef("Byte", 1.toByte()::foo, 2)
testRef("Short", 1.toShort()::foo, 3)
testRef("Int", 1::foo, 4)
testRef("Long", 1L::foo, 5)
testRef("Char", '1'::foo, 6)
testRef("Float", 1.0F::foo, 7)
testRef("Double", 1.0::foo, 8)
return "OK"
}
@@ -0,0 +1,30 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
class B
suspend fun B.magic() {
}
suspend fun suspendRun(c: suspend() -> Unit) = c()
fun boom(a: Any) {
when (a) {
is B -> builder { suspendRun(a::magic) }
}
}
fun box(): String {
boom(B())
return "OK"
}
@@ -0,0 +1,26 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
abstract class A {
abstract suspend fun foo(): String
}
class B : A() {
override suspend fun foo() = "OK"
}
fun box(): String {
var res = "FAIL"
builder { res = (A::foo)(B()) }
return res
}
@@ -0,0 +1,25 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
class A {
suspend fun foo(k: Int) = k
suspend fun result() = (A::foo)(this, 111)
}
fun box(): String {
var result = 0
builder { result = A().result() }
if (result != 111) return "Fail $result"
return "OK"
}
@@ -0,0 +1,26 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
class A {
suspend fun o() = 111
suspend fun k(k: Int) = k
}
suspend fun A.foo() = (A::o)(this) + (A::k)(this, 222)
fun box(): String {
var result = 0
builder { result = A().foo() }
if (result != 333) return "Fail $result"
return "OK"
}
@@ -0,0 +1,25 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
class A {
suspend fun foo() = "OK"
}
fun box(): String {
val x = A::foo
var res = "FAIL"
builder {
res = x(A())
}
return res
}
@@ -0,0 +1,25 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
class A {
suspend fun foo(result: String) = result
}
fun box(): String {
val x = A::foo
var res = "FAIL"
builder {
res = x(A(), "OK")
}
return res
}
@@ -0,0 +1,27 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
class A {
var result = "Fail"
suspend fun foo() {
result = "OK"
}
}
fun box(): String {
val a = A()
val x = A::foo
builder { x(a) }
return a.result
}
@@ -0,0 +1,27 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
class A {
var result = "Fail"
suspend fun foo(newResult: String) {
result = newResult
}
}
fun box(): String {
val a = A()
val x = A::foo
builder { x(a, "OK") }
return a.result
}
@@ -0,0 +1,24 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
class A {
suspend fun result() = (A::foo)(this, "OK")
}
suspend fun A.foo(x: String) = x
fun box(): String {
var res = "FAIL"
builder { res = A().result() }
return res
}
@@ -0,0 +1,26 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
class A
suspend fun A.foo() = (A::bar)(this, "OK")
suspend fun A.bar(x: String) = x
fun box(): String {
var res = "FAIL"
builder {
res = A().foo()
}
return res
}
@@ -0,0 +1,23 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
class A
suspend fun A.foo() = "OK"
fun box(): String {
val x = A::foo
var res = "FAIL"
builder { res = x(A()) }
return res
}
@@ -0,0 +1,23 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
class A
suspend fun A.foo(result: String) = result
fun box(): String {
val x = A::foo
var res = "FAIL"
builder { res = x(A(), "OK") }
return res
}
@@ -0,0 +1,27 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
class A {
var result = "Fail"
}
suspend fun A.foo() {
result = "OK"
}
fun box(): String {
val a = A()
val x = A::foo
builder { x(a) }
return a.result
}
@@ -0,0 +1,27 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
class A {
var result = "Fail"
}
suspend fun A.foo(newResult: String) {
result = newResult
}
fun box(): String {
val a = A()
val x = A::foo
builder { x(a, "OK") }
return a.result
}
@@ -0,0 +1,41 @@
// IGNORE_BACKEND: JS, NATIVE
// WITH_REFLECT
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import kotlin.test.assertEquals
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
suspend fun <T, R> foo(x: T): R = TODO()
suspend fun <T> fooReturnInt(x: T): Int = 1
suspend fun Int.suspendToString(): String = toString()
suspend inline fun <reified T, reified R> check(x: T, y: R, f: suspend (T) -> R, tType: String, rType: String) {
assertEquals(tType, T::class.simpleName)
assertEquals(rType, R::class.simpleName)
}
suspend inline fun <reified T, reified R> check(f: suspend (T) -> R, g: suspend (T) -> R, tType: String, rType: String) {
assertEquals(tType, T::class.simpleName)
assertEquals(rType, R::class.simpleName)
}
fun box(): String {
builder {
check("", 1, ::foo, "String", "Int")
check("", 1, ::fooReturnInt, "String", "Int")
check("", "", ::fooReturnInt, "String", "Any")
check(Int::suspendToString, ::foo, "Int", "String")
}
return "OK"
}
@@ -0,0 +1,41 @@
// IGNORE_BACKEND: JS, NATIVE
// WITH_REFLECT
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import kotlin.test.assertEquals
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
suspend fun <T, R> foo(x: T): R = TODO()
suspend inline fun <reified T, reified R> bar(x: T, y: R, f: suspend (T) -> R, tType: String, rType: String): Pair<T, R?> {
assertEquals(tType, T::class.simpleName)
assertEquals(rType, R::class.simpleName)
return Pair(x, y)
}
data class Pair<A, B>(val a: A, val b: B)
fun box(): String {
builder {
bar(1, "", ::foo, "Int", "String")
val s1: Pair<Int, String?> = bar(1, "", ::foo, "Int", "String")
val (a: Int, b: String?) = bar(1, "", ::foo, "Int", "String")
val ns: String? = null
bar(ns, ns, ::foo, "String", "String")
val s2: Pair<Int?, String?> = bar(null, null, ::foo, "Int", "String")
}
return "OK"
}
@@ -0,0 +1,33 @@
// IGNORE_BACKEND: JS, NATIVE
// WITH_REFLECT
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
import kotlin.test.assertEquals
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
suspend fun foo(x: Int?) {}
suspend fun foo(y: String?) {}
suspend fun foo(z: Boolean) {}
suspend inline fun <reified T> bar(f: suspend (T) -> Unit, tType: String): T? {
assertEquals(tType, T::class.simpleName)
return null
}
fun box(): String {
builder {
val a1: Int? = bar(::foo, "Int")
val a2: String? = bar(::foo, "String")
val a3: Boolean? = bar<Boolean>(::foo, "Boolean")
}
return "OK"
}
@@ -0,0 +1,24 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
class A<T>(val t: T) {
suspend fun foo(): T = t
}
fun box(): String {
var res = "FAIL"
builder {
res = (A<String>::foo)(A("OK"))
}
return res
}
@@ -0,0 +1,45 @@
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
// IGNORE_LIGHT_ANALYSIS
// LANGUAGE_VERSION: 1.2
// WITH_RUNTIME
// WITH_COROUTINES
import kotlin.test.assertEquals
import kotlin.jvm.internal.FunctionBase
import helpers.*
import kotlin.coroutines.experimental.*
suspend fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
fun test(f: Function<*>, arity: Int) {
assertEquals(arity, (f as FunctionBase).getArity())
}
suspend fun foo(s: String, i: Int) {}
class A {
suspend fun bar(s: String, i: Int) {}
}
suspend fun Double.baz(s: String, i: Int) {}
fun box(): String {
test(::foo, 2 + 1)
test(A::bar, 3 + 1)
test(Double::baz, 3 + 1)
test(::box, 0)
suspend fun local(x: Int) {}
test(::local, 1 + 1)
// TODO: Uncomment when `suspend fun` will be supported
// test(suspend fun(s: String) = s, 1)
// test(suspend fun(){}, 0)
test(suspend {}, 1)
return "OK"
}
@@ -0,0 +1,27 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
class Outer {
val result = "OK"
inner class Inner {
suspend fun foo() = result
}
}
fun box(): String {
val f = Outer.Inner::foo
var res = "FAIL"
builder { res = f(Outer().Inner()) }
return res
}
@@ -0,0 +1,23 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
fun box(): String {
class Local {
suspend fun foo() = "OK"
}
val ref = Local::foo
var res = "FAIL"
builder { res = ref(Local()) }
return res
}
@@ -0,0 +1,22 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
fun box(): String {
var result = "Fail"
suspend fun changeToOK() { result = "OK" }
val ok = ::changeToOK
builder { ok() }
return result
}
@@ -0,0 +1,26 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
interface Named {
suspend fun name() = "OK"
}
enum class E : Named {
OK
}
fun box(): String {
var res = "FAIL"
builder { res = E.OK.name }
return res
}
@@ -0,0 +1,14 @@
// IGNORE_BACKEND: JS, NATIVE
// COMMON_COROUTINES_TEST
fun box(): String {
suspend fun bar() {}
suspend fun baz() {}
if (!::bar.equals(::bar)) return "Fail 1"
if (::bar.hashCode() != ::bar.hashCode()) return "Fail 2"
if (::bar == ::baz) return "Fail 3"
return "OK"
}
@@ -0,0 +1,21 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
class A
fun box(): String {
suspend fun A.foo() = "OK"
var res = "FAIL"
builder { res = (A::foo)(A()) }
return res
}
@@ -0,0 +1,20 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
fun box(): String {
class A
suspend fun A.foo() = "OK"
var res = "FAIL"
builder { res = (A::foo)((::A)()) }
return res
}
@@ -0,0 +1,19 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
fun box(): String {
suspend fun Int.is42With(that: Int) = this + 2 * that == 42
var res = ""
builder { res = if ((Int::is42With)(16, 13)) "OK" else "Fail" }
return res
}
@@ -0,0 +1,24 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
class A
fun box(): String {
var result = "Fail"
suspend fun A.ext() { result = "OK" }
val f = A::ext
builder { f(A()) }
return result
}
@@ -0,0 +1,23 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
fun box(): String {
class Id<T> {
suspend fun invoke(t: T) = t
}
val ref = Id<String>::invoke
var res = "FAIL"
builder { res = ref(Id<String>(), "OK") }
return res
}
@@ -0,0 +1,26 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
fun box(): String {
val result = "OK"
class Local {
suspend fun foo() = result
}
val member = Local::foo
val instance = Local()
var res = "FAIL"
builder { res = member(instance) }
return res
}
@@ -0,0 +1,9 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
fun box(): String {
suspend fun OK() {}
return ::OK.name
}
@@ -0,0 +1,25 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
fun box(): String {
suspend fun foo(): String {
suspend fun bar() = "OK"
val ref = ::bar
return ref()
}
val ref = ::foo
var res = "FAIL"
builder { res = ref() }
return res
}
@@ -0,0 +1,21 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
fun box(): String {
suspend fun foo() = "OK"
var res = "FAIL"
builder {
res = (::foo)()
}
return res
}
@@ -0,0 +1,25 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
fun box(): String {
val result = "OK"
suspend fun foo() = result
var res = "FAIL"
builder {
res = (::foo)()
}
return res
}
@@ -0,0 +1,19 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
fun box(): String {
suspend fun foo(s: String) = s
var res = "FAIL"
builder { res = (::foo)("OK") }
return res
}
@@ -0,0 +1,30 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
var state = 23
fun box(): String {
suspend fun incrementState(inc: Int) {
state += inc
}
val inc = ::incrementState
builder {
inc(12)
inc(-5)
inc(27)
inc(-15)
}
return if (state == 42) "OK" else "Fail $state"
}
@@ -0,0 +1,42 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
suspend fun foo(): String = "foo1"
suspend fun foo(i: Int): String = "foo2"
val f1: suspend () -> String = ::foo
val f2: suspend (Int) -> String = ::foo
suspend fun foo1() {}
suspend fun foo2(i: Int) {}
suspend fun bar(f: suspend () -> Unit): String = "bar1"
suspend fun bar(f: suspend (Int) -> Unit): String = "bar2"
fun box(): String {
builder {
val x1 = f1()
if (x1 != "foo1") throw RuntimeException("Fail 1: $x1")
val x2 = f2(0)
if (x2 != "foo2") throw RuntimeException("Fail 2: $x2")
val y1 = bar(::foo1)
if (y1 != "bar1") throw RuntimeException("Fail 3: $y1")
val y2 = bar(::foo2)
if (y2 != "bar2") throw RuntimeException("Fail 4: $y2")
}
return "OK"
}
@@ -0,0 +1,34 @@
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import kotlin.reflect.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
class A {
val x = 1
suspend fun x(): String = "OK"
}
val f1: KProperty1<A, Int> = A::x
val f2: suspend (A) -> String = A::x
fun box(): String {
val a = A()
val x1 = f1.get(a)
if (x1 != 1) return "Fail 1: $x1"
var res = "FAIL"
builder {
res = f2(a)
}
return res
}
@@ -0,0 +1,26 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
class A {
private suspend fun foo() = "OK"
suspend fun bar() = (A::foo)(this)
}
fun box(): String {
var res = "FAIL"
builder {
res = A().bar()
}
return res
}
@@ -0,0 +1,44 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
suspend fun baz(i: Int) = i
suspend fun <T> bar(x: T): T = x
suspend fun nullableFun(): (suspend (Int) -> Int)? = null
fun box(): String {
builder {
val x1: suspend (Int) -> Int = bar(if (true) ::baz else ::baz)
val x2: suspend (Int) -> Int = bar(nullableFun() ?: ::baz)
val x3: suspend (Int) -> Int = bar(::baz ?: ::baz)
val i = 0
val x4: suspend (Int) -> Int = bar(when (i) {
10 -> ::baz
20 -> ::baz
else -> ::baz
})
val x5: suspend (Int) -> Int = bar(::baz!!)
if (x1(1) != 1) throw RuntimeException("fail 1")
if (x2(1) != 1) throw RuntimeException("fail 2")
if (x3(1) != 1) throw RuntimeException("fail 3")
if (x4(1) != 1) throw RuntimeException("fail 4")
if (x5(1) != 1) throw RuntimeException("fail 5")
if ((if (true) ::baz else ::baz)(1) != 1) throw RuntimeException("fail 6")
}
return "OK"
}
@@ -0,0 +1,25 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
suspend fun foo(o: Int, k: Int) = o + k
class A {
suspend fun bar() = (::foo)(111, 222)
}
fun box(): String {
var result = 0
builder { result = A().bar() }
if (result != 333) return "Fail $result"
return "OK"
}
@@ -0,0 +1,25 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
suspend fun foo(o: Int, k: Int) = o + k
class A
suspend fun A.bar() = (::foo)(111, 222)
fun box(): String {
var result = 0
builder { result = A().bar() }
if (result != 333) return "Fail $result"
return "OK"
}
@@ -0,0 +1,21 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
suspend fun foo() = "OK"
fun box(): String {
val x = ::foo
var res = "FAIL"
builder { res = x() }
return res
}
@@ -0,0 +1,21 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
suspend fun foo(x: String) = x
fun box(): String {
val x = ::foo
var res = "FAIL"
builder { res = x("OK") }
return res
}
@@ -0,0 +1,24 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
var result = "Fail"
suspend fun foo() {
result = "OK"
}
fun box(): String {
val x = ::foo
builder { x() }
return result
}
@@ -0,0 +1,24 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
var result = "Fail"
suspend fun foo(newResult: String) {
result = newResult
}
fun box(): String {
val x = ::foo
builder { x("OK") }
return result
}
@@ -0,0 +1,30 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
interface T {
suspend fun foo() = "OK"
}
class B : T {
inner class C {
suspend fun bar() = (T::foo)(this@B)
}
}
fun box(): String {
var res = "FAIL"
builder {
res = B().C().bar()
}
return res
}
@@ -0,0 +1,28 @@
// IGNORE_BACKEND: JS
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
interface A {
suspend fun foo(): String
}
class B : A {
override suspend fun foo() = "OK"
}
fun box(): String {
var res = "FAIL"
builder {
res = (A::foo)(B())
}
return res
}
@@ -0,0 +1,26 @@
// IGNORE_BACKEND: JS, NATIVE
// WITH_RUNTIME
// COMMON_COROUTINES_TEST
import java.io.*
import kotlin.test.*
class Foo {
suspend fun method() {}
}
fun box(): String {
val baos = ByteArrayOutputStream()
val oos = ObjectOutputStream(baos)
oos.writeObject(Foo::method)
oos.writeObject(::Foo)
oos.close()
val bais = ByteArrayInputStream(baos.toByteArray())
val ois = ObjectInputStream(bais)
assertEquals(Foo::method, ois.readObject())
assertEquals(::Foo, ois.readObject())
ois.close()
return "OK"
}
@@ -0,0 +1,27 @@
// IGNORE_BACKEND: JS, NATIVE
// WITH_REFLECT
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
import java.io.*
import kotlin.test.*
suspend fun bar() {}
fun box(): String {
val baos = ByteArrayOutputStream()
val oos = ObjectOutputStream(baos)
oos.writeObject(::bar)
oos.close()
val bais = ByteArrayInputStream(baos.toByteArray())
val ois = ObjectInputStream(bais)
val o = ois.readObject()
ois.close()
// Test that we don't serialize the reflected view of the reference: it's not needed because it can be restored at runtime
val field = kotlin.jvm.internal.CallableReference::class.java.getDeclaredField("reflected").apply { isAccessible = true }
assertNull(field.get(o))
return "OK"
}
@@ -0,0 +1,27 @@
// IGNORE_BACKEND: JS, NATIVE
// WITH_REFLECT
// COMMON_COROUTINES_TEST
// WITH_RUNTIME
import java.io.*
import kotlin.test.*
class Foo {
suspend fun method() {}
}
fun box(): String {
val baos = ByteArrayOutputStream()
val oos = ObjectOutputStream(baos)
oos.writeObject(Foo::method)
oos.writeObject(::Foo)
oos.close()
val bais = ByteArrayInputStream(baos.toByteArray())
val ois = ObjectInputStream(bais)
assertEquals(Foo::method, ois.readObject())
assertEquals(::Foo, ois.readObject())
ois.close()
return "OK"
}