Support KCallable.callBy with map of parameters to arguments
callBy is able to handle optional parameters. #KT-8827 Fixed
This commit is contained in:
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
fun foo(a: String, b: String = "b", c: String, d: String = "d", e: String) =
|
||||
a + b + c + d + e
|
||||
|
||||
fun box(): String {
|
||||
val p = ::foo.parameters
|
||||
assertEquals("abcde", ::foo.callBy(mapOf(
|
||||
p[0] to "a",
|
||||
p[2] to "c",
|
||||
p[4] to "e"
|
||||
)))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
fun String.sum(other: String = "b") = this + other
|
||||
|
||||
fun box(): String {
|
||||
val f = String::sum
|
||||
assertEquals("ab", f.callBy(mapOf(f.parameters.first() to "a")))
|
||||
return "OK"
|
||||
}
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
// Generate:
|
||||
// (1..70).map { " p${"%02d".format(it)}: Int," }.joinToString("\n")
|
||||
|
||||
class A {
|
||||
fun foo(
|
||||
p01: Int,
|
||||
p02: Int,
|
||||
p03: Int,
|
||||
p04: Int,
|
||||
p05: Int,
|
||||
p06: Int,
|
||||
p07: Int,
|
||||
p08: Int,
|
||||
p09: Int,
|
||||
p10: Int,
|
||||
p11: Int,
|
||||
p12: Int,
|
||||
p13: Int,
|
||||
p14: Int,
|
||||
p15: Int,
|
||||
p16: Int,
|
||||
p17: Int,
|
||||
p18: Int,
|
||||
p19: Int,
|
||||
p20: Int,
|
||||
p21: Int,
|
||||
p22: Int,
|
||||
p23: Int,
|
||||
p24: Int,
|
||||
p25: Int,
|
||||
p26: Int,
|
||||
p27: Int,
|
||||
p28: Int,
|
||||
p29: Int,
|
||||
p30: Int,
|
||||
p31: Int,
|
||||
p32: Int,
|
||||
p33: Int,
|
||||
p34: Int,
|
||||
p35: Int,
|
||||
p36: Int,
|
||||
p37: Int,
|
||||
p38: Int,
|
||||
p39: Int,
|
||||
p40: Int,
|
||||
p41: Int,
|
||||
p42: Int = 239,
|
||||
p43: Int,
|
||||
p44: Int,
|
||||
p45: Int,
|
||||
p46: Int,
|
||||
p47: Int,
|
||||
p48: Int,
|
||||
p49: Int,
|
||||
p50: Int,
|
||||
p51: Int,
|
||||
p52: Int,
|
||||
p53: Int,
|
||||
p54: Int,
|
||||
p55: Int,
|
||||
p56: Int,
|
||||
p57: Int,
|
||||
p58: Int,
|
||||
p59: Int,
|
||||
p60: Int,
|
||||
p61: Int,
|
||||
p62: Int,
|
||||
p63: Int,
|
||||
p64: Int,
|
||||
p65: Int,
|
||||
p66: Int,
|
||||
p67: Int,
|
||||
p68: Int,
|
||||
p69: Int,
|
||||
p70: Int
|
||||
) {
|
||||
assertEquals(1, p01)
|
||||
assertEquals(41, p41)
|
||||
assertEquals(239, p42)
|
||||
assertEquals(43, p43)
|
||||
assertEquals(70, p70)
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val f = A::class.members.single { it.name == "foo" }
|
||||
val parameters = f.parameters
|
||||
|
||||
f.callBy(mapOf(
|
||||
parameters.first() to A(),
|
||||
*((1..41) + (43..70)).map { i -> parameters[i] to i }.toTypedArray()
|
||||
))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
// Generate:
|
||||
// (1..70).map { " p${"%02d".format(it)}: Int = $it," }.joinToString("\n")
|
||||
|
||||
class A {
|
||||
fun foo(
|
||||
p01: Int = 1,
|
||||
p02: Int = 2,
|
||||
p03: Int = 3,
|
||||
p04: Int = 4,
|
||||
p05: Int = 5,
|
||||
p06: Int = 6,
|
||||
p07: Int = 7,
|
||||
p08: Int = 8,
|
||||
p09: Int = 9,
|
||||
p10: Int = 10,
|
||||
p11: Int = 11,
|
||||
p12: Int = 12,
|
||||
p13: Int = 13,
|
||||
p14: Int = 14,
|
||||
p15: Int = 15,
|
||||
p16: Int = 16,
|
||||
p17: Int = 17,
|
||||
p18: Int = 18,
|
||||
p19: Int = 19,
|
||||
p20: Int = 20,
|
||||
p21: Int = 21,
|
||||
p22: Int = 22,
|
||||
p23: Int = 23,
|
||||
p24: Int = 24,
|
||||
p25: Int = 25,
|
||||
p26: Int = 26,
|
||||
p27: Int = 27,
|
||||
p28: Int = 28,
|
||||
p29: Int = 29,
|
||||
p30: Int = 30,
|
||||
p31: Int = 31,
|
||||
p32: Int = 32,
|
||||
p33: Int = 33,
|
||||
p34: Int = 34,
|
||||
p35: Int = 35,
|
||||
p36: Int = 36,
|
||||
p37: Int = 37,
|
||||
p38: Int = 38,
|
||||
p39: Int = 39,
|
||||
p40: Int = 40,
|
||||
p41: Int = 41,
|
||||
p42: Int,
|
||||
p43: Int = 43,
|
||||
p44: Int = 44,
|
||||
p45: Int = 45,
|
||||
p46: Int = 46,
|
||||
p47: Int = 47,
|
||||
p48: Int = 48,
|
||||
p49: Int = 49,
|
||||
p50: Int = 50,
|
||||
p51: Int = 51,
|
||||
p52: Int = 52,
|
||||
p53: Int = 53,
|
||||
p54: Int = 54,
|
||||
p55: Int = 55,
|
||||
p56: Int = 56,
|
||||
p57: Int = 57,
|
||||
p58: Int = 58,
|
||||
p59: Int = 59,
|
||||
p60: Int = 60,
|
||||
p61: Int = 61,
|
||||
p62: Int = 62,
|
||||
p63: Int = 63,
|
||||
p64: Int = 64,
|
||||
p65: Int = 65,
|
||||
p66: Int = 66,
|
||||
p67: Int = 67,
|
||||
p68: Int = 68,
|
||||
p69: Int = 69,
|
||||
p70: Int = 70
|
||||
) {
|
||||
assertEquals(1, p01)
|
||||
assertEquals(41, p41)
|
||||
assertEquals(239, p42)
|
||||
assertEquals(43, p43)
|
||||
assertEquals(70, p70)
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val f = A::class.members.single { it.name == "foo" }
|
||||
val parameters = f.parameters
|
||||
f.callBy(mapOf(
|
||||
parameters.first() to A(),
|
||||
parameters.single { it.name == "p42" } to 239
|
||||
))
|
||||
return "OK"
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
fun foo(x: Int, y: Int = 2) = x + y
|
||||
|
||||
fun box(): String {
|
||||
try {
|
||||
::foo.callBy(mapOf())
|
||||
return "Fail: IllegalArgumentException must have been thrown"
|
||||
}
|
||||
catch (e: IllegalArgumentException) {
|
||||
// OK
|
||||
}
|
||||
|
||||
try {
|
||||
::foo.callBy(mapOf(::foo.parameters.last() to 1))
|
||||
return "Fail: IllegalArgumentException must have been thrown"
|
||||
}
|
||||
catch (e: IllegalArgumentException) {
|
||||
// OK
|
||||
}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import kotlin.test.assertNull
|
||||
|
||||
fun foo(x: String? = "Fail") {
|
||||
assertNull(x)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
::foo.callBy(mapOf(::foo.parameters.single() to null))
|
||||
return "OK"
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
// FULL_JDK
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
fun foo(result: String = "foo") {
|
||||
assertEquals("box", result)
|
||||
|
||||
// Check that this function was invoked directly and not through the "foo$default", i.e. there's no "foo$default" in the stack trace
|
||||
val st = Thread.currentThread().stackTrace
|
||||
for (i in 0..5) {
|
||||
if ("foo\$default" in st[i].methodName) {
|
||||
throw AssertionError("KCallable.call should invoke the method directly if all arguments are provided")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
::foo.callBy(mapOf(::foo.parameters.single() to "box"))
|
||||
return "OK"
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
import kotlin.platform.platformStatic as static
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
object Obj {
|
||||
static fun foo(a: String, b: String = "b") = a + b
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val f = Obj::foo
|
||||
|
||||
// Any object method currently requires the object instance passed
|
||||
try {
|
||||
f.callBy(mapOf(
|
||||
f.parameters.single { it.name == "a" } to "a"
|
||||
))
|
||||
return "Fail: IllegalArgumentException should have been thrown"
|
||||
}
|
||||
catch (e: IllegalArgumentException) {
|
||||
// OK
|
||||
}
|
||||
|
||||
assertEquals("ab", f.callBy(mapOf(
|
||||
f.parameters.first() to Obj,
|
||||
f.parameters.single { it.name == "a" } to "a"
|
||||
)))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
fun primitives(
|
||||
boolean: Boolean = true,
|
||||
character: Char = 'z',
|
||||
byte: Byte = 5.toByte(),
|
||||
short: Short = (-5).toShort(),
|
||||
int: Int = 2000000000,
|
||||
float: Float = -2.72f,
|
||||
long: Long = 1000000000000000000L,
|
||||
double: Double = 3.14159265359
|
||||
) {
|
||||
assertEquals(true, boolean)
|
||||
assertEquals('z', character)
|
||||
assertEquals(5.toByte(), byte)
|
||||
assertEquals((-5).toShort(), short)
|
||||
assertEquals(2000000000, int)
|
||||
assertEquals(-2.72f, float)
|
||||
assertEquals(1000000000000000000L, long)
|
||||
assertEquals(3.14159265359, double)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
::primitives.callBy(emptyMap())
|
||||
return "OK"
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
import kotlin.reflect.IllegalCallableAccessException
|
||||
import kotlin.reflect.jvm.isAccessible
|
||||
|
||||
class A {
|
||||
private fun foo(default: Any? = this) {
|
||||
}
|
||||
|
||||
fun f() = A::foo
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val a = A()
|
||||
val f = a.f()
|
||||
|
||||
try {
|
||||
f.callBy(mapOf(f.parameters.first() to a))
|
||||
return "Fail: IllegalCallableAccessException should have been thrown"
|
||||
}
|
||||
catch (e: IllegalCallableAccessException) {
|
||||
// OK
|
||||
}
|
||||
|
||||
f.isAccessible = true
|
||||
f.callBy(mapOf(f.parameters.first() to a))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
class A(val result: String = "OK")
|
||||
|
||||
fun box(): String = ::A.callBy(mapOf()).result
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
class A(val result: String = "OK") {
|
||||
fun foo(x: Int = 42): String {
|
||||
assert(x == 42) { x }
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String = A::foo.callBy(mapOf(A::foo.parameters.first() to A()))
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun foo(result: String = "OK") = result
|
||||
|
||||
fun box(): String = ::foo.callBy(mapOf())
|
||||
Reference in New Issue
Block a user