Support 'call' for references to inline class members

This includes overriding and non-overriding functions and properties.

 #KT-26748
This commit is contained in:
Dmitry Petrov
2018-10-16 17:39:30 +03:00
parent 5003388d38
commit 94e1701089
13 changed files with 483 additions and 17 deletions
@@ -0,0 +1,35 @@
// IGNORE_BACKEND: JS_IR, JS, NATIVE, JVM_IR
// WITH_REFLECT
import kotlin.test.assertEquals
inline class Z(val x: Int) {
fun test(a: String, b: S) = "$x$a${b.x}"
}
inline class L(val x: Long) {
fun test(a: String, b: S) = "$x$a${b.x}"
}
inline class S(val x: String) {
fun test(a: String, b: S) = "$x$a${b.x}"
}
inline class A(val x: Any) {
fun test(a: String, b: S) = "$x$a${b.x}"
}
fun box(): String {
assertEquals("42-+", Z::test.call(Z(42), "-", S("+")))
assertEquals("42-+", Z(42)::test.call("-", S("+")))
assertEquals("42-+", L::test.call(L(42L), "-", S("+")))
assertEquals("42-+", L(42L)::test.call("-", S("+")))
assertEquals("42-+", S::test.call(S("42"), "-", S("+")))
assertEquals("42-+", S("42")::test.call("-", S("+")))
assertEquals("42-+", A::test.call(A("42"), "-", S("+")))
assertEquals("42-+", A("42")::test.call("-", S("+")))
return "OK"
}
@@ -0,0 +1,81 @@
// IGNORE_BACKEND: JS_IR, JS, NATIVE, JVM_IR
// WITH_REFLECT
import kotlin.test.assertEquals
var global = S("")
inline class Z(val x: Int) {
var test: S
get() = S("${global.x}$x")
set(value) {
global = S("${value.x}$x")
}
}
inline class L(val x: Long) {
var test: S
get() = S("${global.x}$x")
set(value) {
global = S("${value.x}$x")
}
}
inline class S(val x: String) {
var test: S
get() = S("${global.x}$x")
set(value) {
global = S("${value.x}$x")
}
}
inline class A(val x: Any) {
var test: S
get() = S("${global.x}$x")
set(value) {
global = S("${value.x}$x")
}
}
fun box(): String {
global = S("")
assertEquals(S("42"), Z::test.call(Z(42)))
assertEquals(S("42"), Z(42)::test.call())
assertEquals(S("42"), Z::test.getter.call(Z(42)))
assertEquals(S("42"), Z(42)::test.getter.call())
Z::test.setter.call(Z(42), S("Z-"))
assertEquals(S("Z-42"), global)
Z(42)::test.setter.call(S("Z+"))
assertEquals(S("Z+42"), global)
global = S("")
assertEquals(S("42"), L::test.call(L(42L)))
assertEquals(S("42"), L(42L)::test.call())
assertEquals(S("42"), L::test.getter.call(L(42L)))
assertEquals(S("42"), L(42L)::test.getter.call())
L::test.setter.call(L(42L), S("L-"))
assertEquals(S("L-42"), global)
L(42L)::test.setter.call(S("L+"))
assertEquals(S("L+42"), global)
global = S("")
assertEquals(S("42"), S::test.call(S("42")))
assertEquals(S("42"), S("42")::test.call())
assertEquals(S("42"), S::test.getter.call(S("42")))
assertEquals(S("42"), S("42")::test.getter.call())
S::test.setter.call(S("42"), S("S-"))
assertEquals(S("S-42"), global)
S("42")::test.setter.call(S("S+"))
assertEquals(S("S+42"), global)
global = S("")
assertEquals(S("42"), A::test.call(A(42)))
assertEquals(S("42"), A(42)::test.call())
assertEquals(S("42"), A::test.getter.call(A(42)))
assertEquals(S("42"), A(42)::test.getter.call())
A::test.setter.call(A(42), S("A-"))
assertEquals(S("A-42"), global)
A(42)::test.setter.call(S("A+"))
assertEquals(S("A+42"), global)
return "OK"
}
@@ -0,0 +1,39 @@
// IGNORE_BACKEND: JS_IR, JS, NATIVE, JVM_IR
// WITH_REFLECT
import kotlin.test.assertEquals
interface ITest {
fun test(a: String, b: S): String
}
inline class Z(val x: Int) : ITest {
override fun test(a: String, b: S) = "$x$a${b.x}"
}
inline class L(val x: Long) : ITest {
override fun test(a: String, b: S) = "$x$a${b.x}"
}
inline class S(val x: String) : ITest {
override fun test(a: String, b: S) = "$x$a${b.x}"
}
inline class A(val x: Any) : ITest {
override fun test(a: String, b: S) = "$x$a${b.x}"
}
fun box(): String {
assertEquals("42-+", Z::test.call(Z(42), "-", S("+")))
assertEquals("42-+", Z(42)::test.call("-", S("+")))
assertEquals("42-+", L::test.call(L(42L), "-", S("+")))
assertEquals("42-+", L(42L)::test.call("-", S("+")))
assertEquals("42-+", S::test.call(S("42"), "-", S("+")))
assertEquals("42-+", S("42")::test.call("-", S("+")))
assertEquals("42-+", A::test.call(A("42"), "-", S("+")))
assertEquals("42-+", A("42")::test.call("-", S("+")))
return "OK"
}
@@ -0,0 +1,85 @@
// IGNORE_BACKEND: JS_IR, JS, NATIVE, JVM_IR
// WITH_REFLECT
import kotlin.test.assertEquals
var global = S("")
interface ITest {
var test: S
}
inline class Z(val x: Int) : ITest {
override var test: S
get() = S("${global.x}$x")
set(value) {
global = S("${value.x}$x")
}
}
inline class L(val x: Long) : ITest {
override var test: S
get() = S("${global.x}$x")
set(value) {
global = S("${value.x}$x")
}
}
inline class S(val x: String) : ITest {
override var test: S
get() = S("${global.x}$x")
set(value) {
global = S("${value.x}$x")
}
}
inline class A(val x: Any) : ITest {
override var test: S
get() = S("${global.x}$x")
set(value) {
global = S("${value.x}$x")
}
}
fun box(): String {
global = S("")
assertEquals(S("42"), Z::test.call(Z(42)))
assertEquals(S("42"), Z(42)::test.call())
assertEquals(S("42"), Z::test.getter.call(Z(42)))
assertEquals(S("42"), Z(42)::test.getter.call())
Z::test.setter.call(Z(42), S("Z-"))
assertEquals(S("Z-42"), global)
Z(42)::test.setter.call(S("Z+"))
assertEquals(S("Z+42"), global)
global = S("")
assertEquals(S("42"), L::test.call(L(42L)))
assertEquals(S("42"), L(42L)::test.call())
assertEquals(S("42"), L::test.getter.call(L(42L)))
assertEquals(S("42"), L(42L)::test.getter.call())
L::test.setter.call(L(42L), S("L-"))
assertEquals(S("L-42"), global)
L(42L)::test.setter.call(S("L+"))
assertEquals(S("L+42"), global)
global = S("")
assertEquals(S("42"), S::test.call(S("42")))
assertEquals(S("42"), S("42")::test.call())
assertEquals(S("42"), S::test.getter.call(S("42")))
assertEquals(S("42"), S("42")::test.getter.call())
S::test.setter.call(S("42"), S("S-"))
assertEquals(S("S-42"), global)
S("42")::test.setter.call(S("S+"))
assertEquals(S("S+42"), global)
global = S("")
assertEquals(S("42"), A::test.call(A(42)))
assertEquals(S("42"), A(42)::test.call())
assertEquals(S("42"), A::test.getter.call(A(42)))
assertEquals(S("42"), A(42)::test.getter.call())
A::test.setter.call(A(42), S("A-"))
assertEquals(S("A-42"), global)
A(42)::test.setter.call(S("A+"))
assertEquals(S("A+42"), global)
return "OK"
}
@@ -0,0 +1,75 @@
// IGNORE_BACKEND: JS_IR, JS, NATIVE, JVM_IR
// WITH_REFLECT
import kotlin.test.assertEquals
interface IFoo {
fun fooFun(z: Z): Z
var fooVar: Z
}
var global = Z(0)
inline class Z(val x: Int) : IFoo {
override fun fooFun(z: Z): Z = Z(z.x + x)
override var fooVar: Z
get() = Z(global.x + x)
set(value) {
global = Z(value.x + x)
}
fun barFun(z: Z): Z = Z(z.x * 100 + x)
var barVar: Z
get() = Z(global.x * 100 + x)
set(value) {
global = Z(value.x * 100 + x)
}
}
fun box(): String {
val fooFunR = Z::fooFun
assertEquals(Z(53), fooFunR.callBy(mapOf(fooFunR.parameters[0] to Z(42), fooFunR.parameters[1] to Z(11))))
val fooFunBR = Z(42)::fooFun
assertEquals(Z(142), fooFunBR.callBy(mapOf(fooFunBR.parameters[0] to Z(100))))
global = Z(0)
val fooVarR = Z::fooVar
assertEquals(Z(42), fooVarR.callBy(mapOf(fooVarR.parameters[0] to Z(42))))
assertEquals(Z(42), fooVarR.getter.callBy(mapOf(fooVarR.getter.parameters[0] to Z(42))))
fooVarR.setter.callBy(mapOf(fooVarR.setter.parameters[0] to Z(42), fooVarR.setter.parameters[1] to Z(1)))
assertEquals(Z(43), global)
global = Z(100)
val fooVarBR = Z(42)::fooVar
assertEquals(Z(142), fooVarBR.callBy(mapOf()))
assertEquals(Z(142), fooVarBR.getter.callBy(mapOf()))
fooVarBR.setter.callBy(mapOf(fooVarBR.setter.parameters[0] to Z(1)))
assertEquals(Z(43), global)
val barFunR = Z::barFun
assertEquals(Z(1142), barFunR.callBy(mapOf(barFunR.parameters[0] to Z(42), barFunR.parameters[1] to Z(11))))
val barFunBR = Z(42)::barFun
assertEquals(Z(2242), barFunBR.callBy(mapOf(barFunBR.parameters[0] to Z(22))))
global = Z(1)
val barVarR = Z::barVar
assertEquals(Z(142), barVarR.callBy(mapOf(barVarR.parameters[0] to Z(42))))
assertEquals(Z(142), barVarR.getter.callBy(mapOf(barVarR.getter.parameters[0] to Z(42))))
barVarR.setter.callBy(mapOf(barVarR.setter.parameters[0] to Z(42), barVarR.setter.parameters[1] to Z(3)))
assertEquals(Z(342), global)
global = Z(2)
val barVarBR = Z(42)::barVar
assertEquals(Z(242), barVarBR.callBy(mapOf()))
assertEquals(Z(242), barVarBR.getter.callBy(mapOf()))
barVarBR.setter.callBy(mapOf(barVarBR.setter.parameters[0] to Z(4)))
assertEquals(Z(442), global)
return "OK"
}