Skip to content

Commit

Permalink
feat: ReflectionFunctionCaller can now invoke functions with any argu…
Browse files Browse the repository at this point in the history
…ment type, closes #1389
  • Loading branch information
AlmasB committed Dec 16, 2024
1 parent 13e26c6 commit e2973ef
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,26 @@ class ReflectionFunctionCaller {
return defaultFunctionHandler.apply(functionName, args.toList())
}

fun invoke(functionName: String, args: List<Any>): Any {
return invoke(functionName, args.toTypedArray())
}

/**
* An equivalent of [call], but allows any type of arguments, not just String.
*
* @return 0 for void type functions, otherwise return value from the invoked function
*/
fun invoke(functionName: String, args: Array<Any>): Any {
val function = functions[FunctionSignature(functionName, args.size)]

if (function != null) {
// void returns null, but Any is expected, so we return 0 in such cases
return function.method.invoke(function.functionCallTarget, *args) ?: 0
}

return defaultFunctionHandler.apply(functionName, args.toList().map { it.toString() })
}

private data class FunctionSignature(val name: String, val paramCount: Int)

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,42 @@ class ReflectionUtilsTest {
}
}

@Test
fun `ReflectionFunctionCaller can invoke functions with non-String arguments`() {
val value = 335
val data = TestClass2("world")

val obj = TestClass3()
val rfc = ReflectionFunctionCaller().also { it.addFunctionCallTarget(obj) }

val result = rfc.invoke("someFunction", arrayOf(value, data))

assertThat(result, `is`("335world"))
}

@Test
fun `ReflectionFunctionCaller fails if incorrect types of arguments`() {
val value = 335
val data = TestClass2("world")

val obj = TestClass3()
val rfc = ReflectionFunctionCaller().also { it.addFunctionCallTarget(obj) }

assertThrows<RuntimeException> {
rfc.invoke("someFunction", arrayOf(data, value))
}
}

@Test
fun `ReflectionFunctionCaller fails if incorrect number of arguments`() {
val obj = TestClass3()
val rfc = ReflectionFunctionCaller().also { it.addFunctionCallTarget(obj) }

assertThrows<RuntimeException> {
rfc.invoke("someFunction", arrayOf())
}
}

@Retention(AnnotationRetention.RUNTIME)
annotation class Ann

Expand Down Expand Up @@ -256,4 +292,10 @@ class ReflectionUtilsTest {
}

class TestClass2(val s: String) : TestClass1()

class TestClass3 {
fun someFunction(value: Int, data: TestClass2): String {
return "" + value + data.s
}
}
}

0 comments on commit e2973ef

Please sign in to comment.