JVM_IR indy-lambdas: initial implementation and tests

KT-44278 KT-26060 KT-42621
This commit is contained in:
Dmitry Petrov
2021-01-29 16:39:42 +03:00
committed by TeamCityServer
parent 0bc386cb08
commit d94912ed62
41 changed files with 733 additions and 37 deletions
@@ -0,0 +1,9 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// LAMBDAS: INDY
class C(val x: String) {
fun test() = { x }
}
fun box() = C("OK").test()()
@@ -0,0 +1,9 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// LAMBDAS: INDY
class C(val x: String)
fun C.test() = { x }
fun box() = C("OK").test()()
@@ -0,0 +1,8 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// LAMBDAS: INDY
fun box(): String {
val ok = "OK"
return { ok }()
}
@@ -0,0 +1,9 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// LAMBDAS: INDY
fun box(): String {
var ok = "Failed"
{ ok = "OK" }()
return ok
}
@@ -0,0 +1,12 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// LAMBDAS: INDY
class C(val x: String)
fun boxLambda(lambda: C.() -> String) = lambda
fun box(): String {
val ext = boxLambda { x }
return C("OK").ext()
}
@@ -0,0 +1,16 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// LAMBDAS: INDY
// FILE: 1.kt
inline fun cross(crossinline fn: () -> String) : Any =
object {
override fun toString(): String = fn()
}
fun foo(fn: () -> String) = fn()
// FILE: 2.kt
fun box() =
cross {
foo { "OK" }
}.toString()
@@ -0,0 +1,22 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// LAMBDAS: INDY
// FILE: 1.kt
class C {
fun test() =
cross {
foo { "OK" }
}.toString()
}
inline fun cross(crossinline fn: () -> String) : Any =
object {
override fun toString(): String = fn()
}
fun foo(fn: () -> String) = fn()
// FILE: 2.kt
fun box() =
C().test()
@@ -0,0 +1,16 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// LAMBDAS: INDY
// WITH_RUNTIME
// FILE: 2.kt
import a.*
fun box() = test { k -> "O" + k }
// FILE: 1.kt
package a
fun fooK(fn: (String) -> String) = fn("K")
inline fun test(crossinline lambda: (String) -> String) =
fooK { k -> lambda(k) }
@@ -0,0 +1,24 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// LAMBDAS: INDY
// WITH_RUNTIME
// FILE: 1.kt
fun foo(fn: () -> Unit) = fn()
inline fun twice(fn: () -> Unit) {
fn()
fn()
}
// FILE: 2.kt
fun box(): String {
var test = 0
twice {
foo { test += 1 }
}
if (test != 2)
return "Failed: test=$test"
return "OK"
}
@@ -0,0 +1,15 @@
// TARGET_BACKEND: JVM
// IGNORE_LIGHT_ANALYSIS
// JVM_TARGET: 1.8
// LAMBDAS: INDY
inline class Z(val value: Any)
fun foo1(fs: (Z) -> Z) = fs(Z(1))
fun box(): String {
val t = foo1 { Z((it.value as Int) + 41) }
if (t.value != 42) return "Failed: t=$t"
return "OK"
}
@@ -0,0 +1,16 @@
// TARGET_BACKEND: JVM
// IGNORE_BACKEND: JVM
// IGNORE_LIGHT_ANALYSIS
// JVM_TARGET: 1.8
// LAMBDAS: INDY
inline class Z(val value: Int)
fun foo1(fs: (Z) -> Z) = fs(Z(1))
fun box(): String {
val t = foo1 { Z(it.value + 41) }
if (t.value != 42) return "Failed: t=$t"
return "OK"
}
@@ -0,0 +1,16 @@
// TARGET_BACKEND: JVM
// IGNORE_BACKEND: JVM
// IGNORE_LIGHT_ANALYSIS
// JVM_TARGET: 1.8
// LAMBDAS: INDY
inline class Z(val value: Any?)
fun foo1(fs: (Z) -> Z) = fs(Z(1))
fun box(): String {
val t = foo1 { Z((it.value as Int) + 41) }
if (t.value != 42) return "Failed: t=$t"
return "OK"
}
@@ -0,0 +1,16 @@
// TARGET_BACKEND: JVM
// IGNORE_BACKEND: JVM
// IGNORE_LIGHT_ANALYSIS
// JVM_TARGET: 1.8
// LAMBDAS: INDY
inline class Z(val value: Int?)
fun foo1(fs: (Z) -> Z) = fs(Z(1))
fun box(): String {
val t = foo1 { Z(it.value!! + 41) }
if (t.value != 42) return "Failed: t=$t"
return "OK"
}
@@ -0,0 +1,16 @@
// TARGET_BACKEND: JVM
// IGNORE_BACKEND: JVM
// IGNORE_LIGHT_ANALYSIS
// JVM_TARGET: 1.8
// LAMBDAS: INDY
inline class Z(val value: String?)
fun foo1(fs: (Z) -> Z) = fs(Z("O"))
fun box(): String {
val t = foo1 { Z(it.value!! + "K") }
if (t.value != "OK") return "Failed: t=$t"
return "OK"
}
@@ -0,0 +1,16 @@
// TARGET_BACKEND: JVM
// IGNORE_BACKEND: JVM
// IGNORE_LIGHT_ANALYSIS
// JVM_TARGET: 1.8
// LAMBDAS: INDY
inline class Z(val value: String)
fun foo1(fs: (Z) -> Z) = fs(Z("O"))
fun box(): String {
val t = foo1 { Z(it.value + "K") }
if (t.value != "OK") return "Failed: t=$t"
return "OK"
}
@@ -0,0 +1,5 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// LAMBDAS: INDY
fun box() = { { "O" }() + { "K" }() }()
@@ -0,0 +1,10 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// LAMBDAS: INDY
fun box(): String {
val test = { i: Int -> i + 40 }(2)
if (test != 42) return "Failed: test=$test"
return "OK"
}
@@ -0,0 +1,5 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// LAMBDAS: INDY
fun box() = { "OK" }()
@@ -0,0 +1,35 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// LAMBDAS: INDY
// WITH_RUNTIME
// WITH_COROUTINES
import kotlin.coroutines.*
var c: Continuation<Unit>? = null
suspend fun suspendMe() = suspendCoroutine<Unit> { continuation ->
c = continuation
}
fun builder(c: suspend () -> Unit) {
c.startCoroutine(object: Continuation<Unit> {
override val context = EmptyCoroutineContext
override fun resumeWith(result: Result<Unit>) {
result.getOrThrow()
}
})
}
fun box(): String {
var test = ""
builder {
suspendMe()
test += "O"
suspendMe()
test += "K"
}
c?.resume(Unit)
c?.resume(Unit)
return test
}
@@ -0,0 +1,10 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// LAMBDAS: INDY
var ok = "Failed"
fun box(): String {
{ ok = "OK" }()
return ok
}
@@ -0,0 +1,16 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// LAMBDAS: INDY
fun interface IFoo<T> {
fun foo(): T
}
fun <T> foo(iFoo: IFoo<T>) = iFoo.foo()
var ok = "Failed"
fun box(): String {
foo { ok = "OK" }
return ok
}