[JS IR] Introduce the GENERATE_INLINE_ANONYMOUS_FUNCTIONS feature flag
This commit is contained in:
+60
@@ -0,0 +1,60 @@
|
||||
// KT-51133
|
||||
|
||||
package foo
|
||||
|
||||
fun <T, R> myWith(t: T, f: (T) -> R) = f(t)
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: noCapture except=myWith
|
||||
// HAS_NO_CAPTURED_VARS: function=noCapture except=myWith;noCapture$lambda
|
||||
fun noCapture() = myWith(42) { it }
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: captureLocalVariableReadOnly except=myWith IGNORED_BACKENDS=JS
|
||||
// HAS_NO_CAPTURED_VARS: function=captureLocalVariableReadOnly except=myWith IGNORED_BACKENDS=JS
|
||||
fun captureLocalVariableReadOnly(a: Int) = myWith(1) { a + it }
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: captureLocalVariableReadWrite except=myWith IGNORED_BACKENDS=JS
|
||||
// HAS_NO_CAPTURED_VARS: function=captureLocalVariableReadWrite except=myWith IGNORED_BACKENDS=JS
|
||||
fun captureLocalVariableReadWrite(): Int {
|
||||
var a = 41
|
||||
return myWith(1) {
|
||||
a += it
|
||||
a
|
||||
}
|
||||
}
|
||||
|
||||
val thirteen = 13
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: captureGlobalVariable except=myWith
|
||||
// HAS_NO_CAPTURED_VARS: function=captureGlobalVariable except=myWith;captureGlobalVariable$lambda
|
||||
fun captureGlobalVariable() = myWith(2) { thirteen * it }
|
||||
|
||||
class A(val i: Int) {
|
||||
|
||||
fun captureClassField() = myWith(100) { it + i }
|
||||
|
||||
inner class B(val j: Int) {
|
||||
|
||||
inner class C(val k: Int) {
|
||||
fun captureInnerClassField() = myWith(200) { it + i + j + k }
|
||||
|
||||
fun unusedLambda() {
|
||||
{ i + j + k }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun unusedLambda(f: () -> Unit) {
|
||||
{ f() }
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
if (noCapture() != 42) return "fail noCapture()"
|
||||
if (captureLocalVariableReadOnly(41) != 42) return "fail captureLocalVariableReadOnly(41)"
|
||||
if (captureLocalVariableReadWrite() != 42) return "fail captureLocalVariableReadWrite()"
|
||||
if (captureGlobalVariable() != 26) return "fail captureGlobalVariable()"
|
||||
if (A(23).captureClassField() != 123) return "fail A(23).captureClassField()"
|
||||
if (A(300).B(400).C(500).captureInnerClassField() != 1400) return "A(300).B(400).C(500).captureInnerClassField()"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
// KT-4237 With in with
|
||||
|
||||
package foo
|
||||
|
||||
class A {
|
||||
val ok = "OK"
|
||||
}
|
||||
|
||||
class B
|
||||
|
||||
fun <T> with(o: T, body: T.() -> Unit) {
|
||||
o.body()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var o = ""
|
||||
|
||||
with(A()) {
|
||||
with(B()) {
|
||||
o = ok
|
||||
}
|
||||
}
|
||||
|
||||
return o
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
interface A {
|
||||
fun run()
|
||||
}
|
||||
|
||||
inline fun testNested(crossinline f: (String) -> Unit) {
|
||||
object : A {
|
||||
override fun run() {
|
||||
f("OK")
|
||||
}
|
||||
}.run()
|
||||
}
|
||||
|
||||
inline fun test(crossinline f: (String) -> Unit) {
|
||||
testNested { it -> { f(it) }()}
|
||||
}
|
||||
|
||||
// FILE: 2.kt
|
||||
|
||||
import test.*
|
||||
|
||||
fun box(): String {
|
||||
var result = "fail"
|
||||
test { it -> result = it }
|
||||
return result
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
inline fun <T> inlineFun(arg: T, f: (T) -> Unit) {
|
||||
f(arg)
|
||||
}
|
||||
|
||||
// FILE: 2.kt
|
||||
|
||||
import test.*
|
||||
|
||||
fun box(): String {
|
||||
val param = "start"
|
||||
var result = "fail"
|
||||
inlineFun("1") { c ->
|
||||
{
|
||||
inlineFun("2") { a ->
|
||||
{
|
||||
{
|
||||
result = param + c + a
|
||||
}()
|
||||
}()
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
return if (result == "start12") "OK" else "fail: $result"
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
fun <T> bar(x: T, y: (T) -> Boolean): Boolean = y(x) && jsTypeOf(x.asDynamic()) != "number"
|
||||
|
||||
fun typeOf(x: dynamic) = js("typeof x")
|
||||
|
||||
fun box(): String {
|
||||
val f = { x: Char ->
|
||||
val a: Char = x
|
||||
val b: Any = x
|
||||
typeOf(a) == "number" && typeOf(b) == "object"
|
||||
}
|
||||
|
||||
if (!f('Q')) return "fail1"
|
||||
if (!bar('W', f)) return "fail2"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
package foo
|
||||
|
||||
|
||||
fun box(): String {
|
||||
val oneTwo = Array(2) {
|
||||
it + 1
|
||||
}
|
||||
val a = ArrayList<() -> Int>()
|
||||
for (i in oneTwo) {
|
||||
for (l in 1..2) {
|
||||
val j = l
|
||||
a.add({
|
||||
var res = 0
|
||||
for (t in 0..2) {
|
||||
res += i * j
|
||||
}
|
||||
res
|
||||
})
|
||||
}
|
||||
}
|
||||
var sum = 0
|
||||
for (f in a) {
|
||||
sum += f()
|
||||
}
|
||||
|
||||
if (sum != 27) return "fail: $sum"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Vendored
+26
@@ -0,0 +1,26 @@
|
||||
// WITH_STDLIB
|
||||
// WITH_COROUTINES
|
||||
// FILE: 1.kt
|
||||
package test
|
||||
|
||||
inline fun foo(crossinline x: () -> Unit) = suspend {
|
||||
try { } finally {
|
||||
// This object is regenerated twice (normal return & "catch Throwable, execute finally, and rethrow")
|
||||
// It doesn't *need* to be, but this should work regardless.
|
||||
{ x() }()
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: 2.kt
|
||||
import helpers.*
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
import test.*
|
||||
|
||||
var result = "fail"
|
||||
fun box(): String {
|
||||
suspend {
|
||||
foo { result = "OK" }()
|
||||
}.startCoroutine(EmptyContinuation)
|
||||
return result
|
||||
}
|
||||
Reference in New Issue
Block a user