JS: support SAM conversion
The SAM adapter is generate on declaration site. This is different from the JVM approach. `external fun interface` is banned for now. Reusing interface declaration for the adapter is a hack which reduces code size and makes importing/exporting the adapter effortless.
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
// !LANGUAGE: +NewInference +FunctionalInterfaceConversion +SamConversionPerArgument +SamConversionForKotlinFunctions
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JS
|
||||
// SKIP_DCE_DRIVEN
|
||||
|
||||
fun interface Foo {
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
// !LANGUAGE: +NewInference +FunctionalInterfaceConversion +SamConversionPerArgument +SamConversionForKotlinFunctions
|
||||
|
||||
// IGNORE_BACKEND: JVM, JVM_IR, JS_IR
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// SKIP_DCE_DRIVEN
|
||||
|
||||
fun interface Base {
|
||||
fun doStuff(): String
|
||||
}
|
||||
|
||||
fun interface I : Base
|
||||
|
||||
fun interface Proxy : I {
|
||||
|
||||
override fun doStuff(): String = doStuffInt().toString()
|
||||
|
||||
fun doStuffInt(): Int
|
||||
}
|
||||
|
||||
fun runBase(b: Base) = b.doStuff()
|
||||
|
||||
fun runI(i: I) = i.doStuff()
|
||||
|
||||
fun runProxy(p: Proxy) = p.doStuff()
|
||||
|
||||
fun box(): String {
|
||||
|
||||
if (runI { "i" } != "i") return "fail1"
|
||||
|
||||
if (runProxy { 10 } != "10") return "fail2"
|
||||
|
||||
return runBase { "OK" }
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// !LANGUAGE: +NewInference +FunctionalInterfaceConversion +SamConversionPerArgument +SamConversionForKotlinFunctions
|
||||
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// SKIP_DCE_DRIVEN
|
||||
|
||||
// MODULE: m1
|
||||
// FILE: m1.kt
|
||||
|
||||
fun interface I {
|
||||
fun f(): String
|
||||
}
|
||||
|
||||
fun rn(i: I) = i.f()
|
||||
|
||||
inline fun rnInline(i: I) = i.f()
|
||||
|
||||
// MODULE: m2(m1)
|
||||
// FILE: m2.kt
|
||||
|
||||
fun rn2(f: () -> String) = rn(f)
|
||||
|
||||
inline fun rn2Inline(noinline f: () -> String) = rnInline(f)
|
||||
|
||||
// MODULE: main(m2)
|
||||
// FILE: main.kt
|
||||
|
||||
fun box(): String {
|
||||
|
||||
if (rn2Inline { "inline" } != "inline") return "fail"
|
||||
|
||||
return rn2 { "OK" }
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
// !LANGUAGE: +NewInference +FunctionalInterfaceConversion +SamConversionPerArgument +SamConversionForKotlinFunctions
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JS
|
||||
// WITH_RUNTIME
|
||||
// SKIP_DCE_DRIVEN
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// !LANGUAGE: +NewInference +FunctionalInterfaceConversion +SamConversionPerArgument +SamConversionForKotlinFunctions
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JS
|
||||
// WITH_RUNTIME
|
||||
// SKIP_DCE_DRIVEN
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
// !LANGUAGE: +NewInference +FunctionalInterfaceConversion +SamConversionPerArgument +SamConversionForKotlinFunctions
|
||||
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// SKIP_DCE_DRIVEN
|
||||
|
||||
// This test should check argument coercion between the SAM and the lambda.
|
||||
// For now it checks that Char is boxed in JS
|
||||
|
||||
fun interface CharToAny {
|
||||
fun invoke(c: Char): Any
|
||||
}
|
||||
|
||||
fun foo(c: CharToAny): Any = c.invoke('O')
|
||||
|
||||
fun box(): String {
|
||||
|
||||
if (foo { it } !is Char) return "fail"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
// !LANGUAGE: +NewInference +FunctionalInterfaceConversion +SamConversionPerArgument +SamConversionForKotlinFunctions
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JS
|
||||
// WITH_RUNTIME
|
||||
// SKIP_DCE_DRIVEN
|
||||
|
||||
|
||||
+16
-2
@@ -1,11 +1,11 @@
|
||||
// !LANGUAGE: +NewInference +FunctionalInterfaceConversion +SamConversionPerArgument +SamConversionForKotlinFunctions
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JS, JS_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// WITH_COROUTINES
|
||||
// WITH_RUNTIME
|
||||
|
||||
import helpers.*
|
||||
import kotlin.coroutines.startCoroutine
|
||||
import kotlin.coroutines.*
|
||||
|
||||
fun interface SuspendRunnable {
|
||||
suspend fun invoke()
|
||||
@@ -17,11 +17,25 @@ fun run(r: SuspendRunnable) {
|
||||
|
||||
var result = "initial"
|
||||
|
||||
var resumingCallback: () -> Unit = {}
|
||||
|
||||
suspend fun bar() {
|
||||
// Generate proper state machine
|
||||
suspendCoroutine<Unit> { cont ->
|
||||
resumingCallback = {
|
||||
cont.resume(Unit)
|
||||
}
|
||||
}
|
||||
|
||||
result = "OK"
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
run(::bar)
|
||||
|
||||
if (result != "initial") return "fail"
|
||||
|
||||
resumingCallback()
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user