KT-13440 Bound callable references in reflection

This commit is contained in:
Dmitry Petrov
2016-11-23 18:54:58 +03:00
parent 5879e201cd
commit 3d2696c81b
33 changed files with 1276 additions and 70 deletions
@@ -0,0 +1,53 @@
// TODO: investigate should it be ran for JS or not
// IGNORE_BACKEND: JS
// WITH_REFLECT
import kotlin.reflect.*
import kotlin.test.assertEquals
class Host {
companion object {
val x = 1
var y = 2
val xx: Int
get() = x
var yy: Int
get() = y
set(value) { y = value }
}
}
val c_x = Host.Companion::x
val c_xx = Host.Companion::xx
val c_y = Host.Companion::y
val c_yy = Host.Companion::yy
fun box(): String {
assertEquals(1, c_x.getter())
assertEquals(1, c_x.getter.call())
assertEquals(1, c_xx.getter())
assertEquals(1, c_xx.getter.call())
assertEquals(2, c_y.getter())
assertEquals(2, c_y.getter.call())
assertEquals(2, c_yy.getter())
assertEquals(2, c_yy.getter.call())
c_y.setter(10)
assertEquals(10, c_y.getter())
assertEquals(10, c_yy.getter())
c_yy.setter(20)
assertEquals(20, c_y.getter())
assertEquals(20, c_yy.getter())
c_y.setter.call(100)
assertEquals(100, c_yy.getter.call())
c_yy.setter.call(200)
assertEquals(200, c_y.getter.call())
return "OK"
}
@@ -0,0 +1,12 @@
// TODO: investigate should it be ran for JS or not
// IGNORE_BACKEND: JS
// WITH_REFLECT
import kotlin.reflect.*
fun String.foo(x: String) = this + x
fun String?.bar(x: String) = x
fun box() =
(""::foo).call("O") + (null::bar).call("K")
@@ -0,0 +1,45 @@
// TODO: investigate should it be ran for JS or not
// IGNORE_BACKEND: JS
// WITH_REFLECT
import kotlin.reflect.*
import kotlin.test.assertEquals
class C(val x: Int, var y: Int)
val C.xx: Int
get() = x
var C.yy: Int
get() = y
set(value) { y = value }
val c = C(1, 2)
val c_xx = c::xx
val c_y = c::y
val c_yy = c::yy
fun box(): String {
assertEquals(1, c_xx.getter())
assertEquals(1, c_xx.getter.call())
assertEquals(2, c_yy.getter())
assertEquals(2, c_yy.getter.call())
c_y.setter(10)
assertEquals(10, c_yy.getter())
c_yy.setter(20)
assertEquals(20, c_y.getter())
assertEquals(20, c_yy.getter())
c_y.setter.call(100)
assertEquals(100, c_yy.getter.call())
c_yy.setter.call(200)
assertEquals(200, c_y.getter.call())
return "OK"
}
@@ -0,0 +1,16 @@
// TODO: investigate should it be ran for JS or not
// IGNORE_BACKEND: JS
// WITH_REFLECT
class Outer(val x: String) {
inner class Inner(val y: String) {
fun foo() = x + y
}
}
fun box(): String {
val innerCtor = Outer("O")::Inner
val inner = innerCtor.call("K")
return inner.foo()
}
@@ -0,0 +1,40 @@
// TODO: investigate should it be ran for JS or not
// IGNORE_BACKEND: JS
// WITH_REFLECT
// FILE: J.java
public class J {
public final int finalField;
public String mutableField;
public J(int f, String m) {
this.finalField = f;
this.mutableField = m;
}
}
// FILE: K.kt
import kotlin.reflect.*
import kotlin.reflect.jvm.*
import kotlin.test.assertEquals
fun box(): String {
val j = J(0, "")
val jf = j::finalField
val jm = j::mutableField
assertEquals(0, jf.getter())
assertEquals(0, jf.getter.call())
assertEquals("", jm.getter())
assertEquals("", jm.getter.call())
jm.setter("1")
assertEquals("1", j.mutableField)
jm.setter.call("2")
assertEquals("2", j.mutableField)
return "OK"
}
@@ -0,0 +1,35 @@
// TODO: investigate should it be ran for JS or not
// IGNORE_BACKEND: JS
// WITH_REFLECT
// FILE: J.java
public class J {
private final int param;
public J(int param) {
this.param = param;
}
public String foo(int[] arr, Object[] arr2, Integer y) {
return "" + param + arr[0] + arr2[0] + y;
}
}
// FILE: K.kt
import kotlin.reflect.*
import kotlin.reflect.jvm.*
import kotlin.test.assertEquals
fun box(): String {
val f = J(0)::foo
assertEquals(
listOf(IntArray::class.java, Array<Any>::class.java, Integer::class.java),
f.parameters.map { it.type.javaType }
)
assertEquals(String::class.java, f.returnType.javaType)
assertEquals("01A2", f.call(intArrayOf(1), arrayOf("A"), 2))
return "OK"
}
@@ -0,0 +1,53 @@
// TODO: investigate should it be ran for JS or not
// IGNORE_BACKEND: JS
// WITH_REFLECT
import kotlin.reflect.*
import kotlin.test.assertEquals
class Host {
companion object {
@JvmStatic val x = 1
@JvmStatic var y = 2
@JvmStatic val xx: Int
get() = x
@JvmStatic var yy: Int
get() = y
set(value) { y = value }
}
}
val c_x = Host.Companion::x
val c_xx = Host.Companion::xx
val c_y = Host.Companion::y
val c_yy = Host.Companion::yy
fun box(): String {
assertEquals(1, c_x.getter())
assertEquals(1, c_x.getter.call())
assertEquals(1, c_xx.getter())
assertEquals(1, c_xx.getter.call())
assertEquals(2, c_y.getter())
assertEquals(2, c_y.getter.call())
assertEquals(2, c_yy.getter())
assertEquals(2, c_yy.getter.call())
c_y.setter(10)
assertEquals(10, c_y.getter())
assertEquals(10, c_yy.getter())
c_yy.setter(20)
assertEquals(20, c_y.getter())
assertEquals(20, c_yy.getter())
c_y.setter.call(100)
assertEquals(100, c_yy.getter.call())
c_yy.setter.call(200)
assertEquals(200, c_y.getter.call())
return "OK"
}
@@ -0,0 +1,19 @@
// TODO: investigate should it be ran for JS or not
// IGNORE_BACKEND: JS
// WITH_REFLECT
import kotlin.reflect.*
object Host {
@JvmStatic fun foo(x: String) = x
}
class CompanionOwner {
companion object {
@JvmStatic fun bar(x: String) = x
}
}
fun box(): String =
(Host::foo).call("O") + (CompanionOwner.Companion::bar).call("K")
@@ -0,0 +1,51 @@
// TODO: investigate should it be ran for JS or not
// IGNORE_BACKEND: JS
// WITH_REFLECT
import kotlin.reflect.*
import kotlin.test.assertEquals
object Host {
@JvmStatic val x = 1
@JvmStatic var y = 2
@JvmStatic val xx: Int
get() = x
@JvmStatic var yy: Int
get() = y
set(value) { y = value }
}
val c_x = Host::x
val c_xx = Host::xx
val c_y = Host::y
val c_yy = Host::yy
fun box(): String {
assertEquals(1, c_x.getter())
assertEquals(1, c_x.getter.call())
assertEquals(1, c_xx.getter())
assertEquals(1, c_xx.getter.call())
assertEquals(2, c_y.getter())
assertEquals(2, c_y.getter.call())
assertEquals(2, c_yy.getter())
assertEquals(2, c_yy.getter.call())
c_y.setter(10)
assertEquals(10, c_y.getter())
assertEquals(10, c_yy.getter())
c_yy.setter(20)
assertEquals(20, c_y.getter())
assertEquals(20, c_yy.getter())
c_y.setter.call(100)
assertEquals(100, c_yy.getter.call())
c_yy.setter.call(200)
assertEquals(200, c_y.getter.call())
return "OK"
}
@@ -0,0 +1,14 @@
// TODO: investigate should it be ran for JS or not
// IGNORE_BACKEND: JS
// WITH_REFLECT
import kotlin.reflect.*
class C(val k: String) {
fun foo(s: String) = s + k
}
fun box(): String =
C("K")::foo.call("O")
@@ -0,0 +1,50 @@
// TODO: investigate should it be ran for JS or not
// IGNORE_BACKEND: JS
// WITH_REFLECT
import kotlin.reflect.*
import kotlin.test.assertEquals
class C(val x: Int, var y: Int) {
val xx: Int
get() = x
var yy: Int
get() = y
set(value) { y = value }
}
val c = C(1, 2)
val c_x = c::x
val c_xx = c::xx
val c_y = c::y
val c_yy = c::yy
fun box(): String {
assertEquals(1, c_x.getter())
assertEquals(1, c_x.getter.call())
assertEquals(1, c_xx.getter())
assertEquals(1, c_xx.getter.call())
assertEquals(2, c_y.getter())
assertEquals(2, c_y.getter.call())
assertEquals(2, c_yy.getter())
assertEquals(2, c_yy.getter.call())
c_y.setter(10)
assertEquals(10, c_y.getter())
assertEquals(10, c_yy.getter())
c_yy.setter(20)
assertEquals(20, c_y.getter())
assertEquals(20, c_yy.getter())
c_y.setter.call(100)
assertEquals(100, c_yy.getter.call())
c_yy.setter.call(200)
assertEquals(200, c_y.getter.call())
return "OK"
}
@@ -0,0 +1,19 @@
// TODO: investigate should it be ran for JS or not
// IGNORE_BACKEND: JS
// WITH_REFLECT
import kotlin.reflect.*
object Host {
fun foo(x: String) = x
}
class CompanionOwner {
companion object {
fun bar(x: String) = x
}
}
fun box(): String =
(Host::foo).call("O") + (CompanionOwner.Companion::bar).call("K")
@@ -0,0 +1,51 @@
// TODO: investigate should it be ran for JS or not
// IGNORE_BACKEND: JS
// WITH_REFLECT
import kotlin.reflect.*
import kotlin.test.assertEquals
object Host {
val x = 1
var y = 2
val xx: Int
get() = x
var yy: Int
get() = y
set(value) { y = value }
}
val c_x = Host::x
val c_xx = Host::xx
val c_y = Host::y
val c_yy = Host::yy
fun box(): String {
assertEquals(1, c_x.getter())
assertEquals(1, c_x.getter.call())
assertEquals(1, c_xx.getter())
assertEquals(1, c_xx.getter.call())
assertEquals(2, c_y.getter())
assertEquals(2, c_y.getter.call())
assertEquals(2, c_yy.getter())
assertEquals(2, c_yy.getter.call())
c_y.setter(10)
assertEquals(10, c_y.getter())
assertEquals(10, c_yy.getter())
c_yy.setter(20)
assertEquals(20, c_y.getter())
assertEquals(20, c_yy.getter())
c_y.setter.call(100)
assertEquals(100, c_yy.getter.call())
c_yy.setter.call(200)
assertEquals(200, c_y.getter.call())
return "OK"
}