[IR] Support reflection for MFVC

Signed-off-by: Evgeniy.Zhelenskiy <Evgeniy.Zhelenskiy@jetbrains.com>

#KT-1179
This commit is contained in:
Evgeniy.Zhelenskiy
2023-03-02 01:48:02 +01:00
committed by Space Team
parent 1ff4906880
commit 88f293d4a9
52 changed files with 2910 additions and 172 deletions
@@ -0,0 +1,72 @@
// TARGET_BACKEND: JVM_IR
// WITH_REFLECT
// LANGUAGE: +ValueClasses
import kotlin.test.assertEquals
@JvmInline
value class A(val x: UInt, val y: Int)
fun test1(x: A = A(0U, 1)) = "OK"
fun test32(
arg00: Long = 0L, arg01: Long = 0L, arg02: Long = 0L, arg03: Long = 0L, arg04: Long = 0L,
arg05: Long = 0L, arg06: Long = 0L, arg07: Long = 0L, arg08: Long = 0L, arg09: Long = 0L,
arg10: Long = 0L, arg11: Long = 0L, arg12: Long = 0L, arg13: Long = 0L, arg14: Long = 0L,
arg15: Long = 0L, arg16: Long = 0L, arg17: Long = 0L, arg18: Long = 0L, arg19: Long = 0L,
arg20: Long = 0L, arg21: Long = 0L, arg22: Long = 0L, arg23: Long = 0L, arg24: Long = 0L,
arg25: Long = 0L, arg26: Long = 0L, arg27: Long = 0L, arg28: Long = 0L, arg29: Long = 0L,
arg30: Long = 0L, x: A = A(0U, 1)
) = "OK"
fun test33(
arg00: Long = 0L, arg01: Long = 0L, arg02: Long = 0L, arg03: Long = 0L, arg04: Long = 0L,
arg05: Long = 0L, arg06: Long = 0L, arg07: Long = 0L, arg08: Long = 0L, arg09: Long = 0L,
arg10: Long = 0L, arg11: Long = 0L, arg12: Long = 0L, arg13: Long = 0L, arg14: Long = 0L,
arg15: Long = 0L, arg16: Long = 0L, arg17: Long = 0L, arg18: Long = 0L, arg19: Long = 0L,
arg20: Long = 0L, arg21: Long = 0L, arg22: Long = 0L, arg23: Long = 0L, arg24: Long = 0L,
arg25: Long = 0L, arg26: Long = 0L, arg27: Long = 0L, arg28: Long = 0L, arg29: Long = 0L,
arg30: Long = 0L, arg31: Long = 0L, x: A = A(0U, 1)
) = "OK"
fun test64(
arg00: Long = 0L, arg01: Long = 0L, arg02: Long = 0L, arg03: Long = 0L, arg04: Long = 0L,
arg05: Long = 0L, arg06: Long = 0L, arg07: Long = 0L, arg08: Long = 0L, arg09: Long = 0L,
arg10: Long = 0L, arg11: Long = 0L, arg12: Long = 0L, arg13: Long = 0L, arg14: Long = 0L,
arg15: Long = 0L, arg16: Long = 0L, arg17: Long = 0L, arg18: Long = 0L, arg19: Long = 0L,
arg20: Long = 0L, arg21: Long = 0L, arg22: Long = 0L, arg23: Long = 0L, arg24: Long = 0L,
arg25: Long = 0L, arg26: Long = 0L, arg27: Long = 0L, arg28: Long = 0L, arg29: Long = 0L,
arg30: Long = 0L, arg31: Long = 0L, arg32: Long = 0L, arg33: Long = 0L, arg34: Long = 0L,
arg35: Long = 0L, arg36: Long = 0L, arg37: Long = 0L, arg38: Long = 0L, arg39: Long = 0L,
arg40: Long = 0L, arg41: Long = 0L, arg42: Long = 0L, arg43: Long = 0L, arg44: Long = 0L,
arg45: Long = 0L, arg46: Long = 0L, arg47: Long = 0L, arg48: Long = 0L, arg49: Long = 0L,
arg50: Long = 0L, arg51: Long = 0L, arg52: Long = 0L, arg53: Long = 0L, arg54: Long = 0L,
arg55: Long = 0L, arg56: Long = 0L, arg57: Long = 0L, arg58: Long = 0L, arg59: Long = 0L,
arg60: Long = 0L, arg61: Long = 0L, arg62: Long = 0L, x: A = A(0U, 1)
) = "OK"
fun test65(
arg00: Long = 0L, arg01: Long = 0L, arg02: Long = 0L, arg03: Long = 0L, arg04: Long = 0L,
arg05: Long = 0L, arg06: Long = 0L, arg07: Long = 0L, arg08: Long = 0L, arg09: Long = 0L,
arg10: Long = 0L, arg11: Long = 0L, arg12: Long = 0L, arg13: Long = 0L, arg14: Long = 0L,
arg15: Long = 0L, arg16: Long = 0L, arg17: Long = 0L, arg18: Long = 0L, arg19: Long = 0L,
arg20: Long = 0L, arg21: Long = 0L, arg22: Long = 0L, arg23: Long = 0L, arg24: Long = 0L,
arg25: Long = 0L, arg26: Long = 0L, arg27: Long = 0L, arg28: Long = 0L, arg29: Long = 0L,
arg30: Long = 0L, arg31: Long = 0L, arg32: Long = 0L, arg33: Long = 0L, arg34: Long = 0L,
arg35: Long = 0L, arg36: Long = 0L, arg37: Long = 0L, arg38: Long = 0L, arg39: Long = 0L,
arg40: Long = 0L, arg41: Long = 0L, arg42: Long = 0L, arg43: Long = 0L, arg44: Long = 0L,
arg45: Long = 0L, arg46: Long = 0L, arg47: Long = 0L, arg48: Long = 0L, arg49: Long = 0L,
arg50: Long = 0L, arg51: Long = 0L, arg52: Long = 0L, arg53: Long = 0L, arg54: Long = 0L,
arg55: Long = 0L, arg56: Long = 0L, arg57: Long = 0L, arg58: Long = 0L, arg59: Long = 0L,
arg60: Long = 0L, arg61: Long = 0L, arg62: Long = 0L, arg63: Long = 0L, x: A = A(0U, 1)
) = "OK"
fun box(): String {
assertEquals("OK", ::test1.callBy(mapOf()))
assertEquals("OK", ::test32.callBy(mapOf()))
assertEquals("OK", ::test33.callBy(mapOf()))
assertEquals("OK", ::test64.callBy(mapOf()))
assertEquals("OK", ::test65.callBy(mapOf()))
return "OK"
}
@@ -0,0 +1,53 @@
// TARGET_BACKEND: JVM_IR
// WITH_REFLECT
// LANGUAGE: +ValueClasses
import kotlin.test.assertEquals
import kotlin.test.assertTrue
@JvmInline
value class S(val value1: UInt, val value2: String) {
operator fun plus(other: S): S = S(this.value1 * 10U + other.value1, this.value2 + other.value2)
}
class C {
fun member(a: S, b: S = S(1U, "b2")): S = a + b
}
fun topLevel(c: S, d: S = S(1U, "d2")): S = c + d
class D(e: S, f: S = S(1U, "f2")) {
val result = e + f
}
fun S.extension(h: S = S(1U, "h2")): S = this + h
fun box(): String {
assertEquals(S(11U, "a2b2"), C().member(S(1U, "a2")))
assertEquals(
S(11U, "a2b2"),
C::member.callBy(C::member.parameters.filter { it.name != "b" }.associateWith { (if (it.name == "a") S(1U, "a2") else C()) })
)
assertEquals(S(11U, "c2d2"), topLevel(S(1U, "c2")))
assertEquals(S(11U, "c2d2"), ::topLevel.callBy(::topLevel.parameters.filter { it.name != "d" }.associateWith { S(1U, "c2") }))
assertEquals(S(11U, "e2f2"), ::D.callBy(::D.parameters.filter { it.name != "f" }.associateWith { S(1U, "e2") }).result)
assertEquals(S(11U, "g2h2"), S(1U, "g2").extension())
assertEquals(S(11U, "g2h2"), S::extension.callBy(S::extension.parameters.filter { it.name != "h" }.associateWith { S(1U, "g2") }))
val boundMember = C()::member
assertEquals(S(11U, "a2b2"), boundMember.callBy(boundMember.parameters.associateWith { S(1U, it.name!! + "2") }))
val boundExtension = S(1U, "g2")::extension
assertEquals(S(11U, "g2h2"), boundExtension.callBy(boundExtension.parameters.associateWith { S(1U, it.name!! + "2") }))
val mfvcConstructor = ::S
val exception = runCatching { mfvcConstructor.callBy(mapOf(mfvcConstructor.parameters.first() to 1U)) }.exceptionOrNull()!!
assertTrue(exception is IllegalArgumentException)
assertTrue(exception.message!!.startsWith("No argument provided for a required parameter: parameter #1 value2 of fun `<init>`(kotlin.UInt, kotlin.String): "), exception.message)
assertTrue(exception.message!!.endsWith("S"), exception.message)
return "OK"
}
@@ -0,0 +1,77 @@
// TARGET_BACKEND: JVM_IR
// WITH_REFLECT
// LANGUAGE: +ValueClasses
import kotlin.test.assertEquals
interface IFoo {
fun fooFun(z: Z): Z
var fooVar: Z
}
var global = Z(0U, 0)
@JvmInline
value class Z(val x1: UInt, val x2: Int) : IFoo {
override fun fooFun(z: Z): Z = Z(z.x1 + x1, z.x2 + x2)
override var fooVar: Z
get() = Z(global.x1 + x1, global.x2 + x2)
set(value) {
global = Z(value.x1 + x1, value.x2 + x2)
}
fun barFun(z: Z): Z = Z(z.x1 * 100U + x1, z.x2 * 100 + x2)
var barVar: Z
get() = Z(global.x1 * 100U + x1, global.x2 * 100 + x2)
set(value) {
global = Z(value.x1 * 100U + x1, value.x2 * 100 + x2)
}
}
fun box(): String {
val fooFunR = Z::fooFun
assertEquals(Z(53U, -53), fooFunR.callBy(mapOf(fooFunR.parameters[0] to Z(42U, -42), fooFunR.parameters[1] to Z(11U, -11))))
val fooFunBR = Z(42U, -42)::fooFun
assertEquals(Z(142U, -142), fooFunBR.callBy(mapOf(fooFunBR.parameters[0] to Z(100U, -100))))
global = Z(0U, 0)
val fooVarR = Z::fooVar
assertEquals(Z(42U, -42), fooVarR.callBy(mapOf(fooVarR.parameters[0] to Z(42U, -42))))
assertEquals(Z(42U, -42), fooVarR.getter.callBy(mapOf(fooVarR.getter.parameters[0] to Z(42U, -42))))
fooVarR.setter.callBy(mapOf(fooVarR.setter.parameters[0] to Z(42U, -42), fooVarR.setter.parameters[1] to Z(1U, -1)))
assertEquals(Z(43U, -43), global)
global = Z(100U, -100)
val fooVarBR = Z(42U, -42)::fooVar
assertEquals(Z(142U, -142), fooVarBR.callBy(mapOf()))
assertEquals(Z(142U, -142), fooVarBR.getter.callBy(mapOf()))
fooVarBR.setter.callBy(mapOf(fooVarBR.setter.parameters[0] to Z(1U, -1)))
assertEquals(Z(43U, -43), global)
val barFunR = Z::barFun
assertEquals(Z(1142U, -1142), barFunR.callBy(mapOf(barFunR.parameters[0] to Z(42U, -42), barFunR.parameters[1] to Z(11U, -11))))
val barFunBR = Z(42U, -42)::barFun
assertEquals(Z(2242U, -2242), barFunBR.callBy(mapOf(barFunBR.parameters[0] to Z(22U, -22))))
global = Z(1U, -1)
val barVarR = Z::barVar
assertEquals(Z(142U, -142), barVarR.callBy(mapOf(barVarR.parameters[0] to Z(42U, -42))))
assertEquals(Z(142U, -142), barVarR.getter.callBy(mapOf(barVarR.getter.parameters[0] to Z(42U, -42))))
barVarR.setter.callBy(mapOf(barVarR.setter.parameters[0] to Z(42U, -42), barVarR.setter.parameters[1] to Z(3U, -3)))
assertEquals(Z(342U, -342), global)
global = Z(2U, -2)
val barVarBR = Z(42U, -42)::barVar
assertEquals(Z(242U, -242), barVarBR.callBy(mapOf()))
assertEquals(Z(242U, -242), barVarBR.getter.callBy(mapOf()))
barVarBR.setter.callBy(mapOf(barVarBR.setter.parameters[0] to Z(4U, -4)))
assertEquals(Z(442U, -442), global)
return "OK"
}