Search code examples
kotlinanonymous-function

How to get anonymous function parameters information?


// normal function 
fun something(a: String, b: String): String {
    return "$a $b"
}
println(::something.parameters) <- not empty

but

// anonymous function 
var something = fun(a: String, b: String): String {
    return "$a $b"
}
println(::something.parameters) <- empty

how to get anonymous function parameters infomation?


Solution

  • In the second code snippet, something is a property, so ::something is a reference to the property. ::something is of type KMutableProperty0<(String, String) -> String>. You obviously don't want to get the parameters of the property.

    The "function" you want is the value stored in something, so ideally you would just do something.parameters. However, something is a (String, String) -> String, not a KFunction, so you cannot do reflection on it.

    There is an experimental API that gives you the KFunction representing the (String, String) -> String - reflect.

    So you can do:

    var something = fun(a: String, b: String): String {
        return "$a $b"
    }
    @OptIn(ExperimentalReflectionOnLambdas::class)
    fun main() {
        println(something.reflect()?.parameters)
    }
    

    For language version (not compiler version) 2.0, lambdas and anonymous functions are now created using invokedynamic calls, and reflect cannot work with those.

    For this to work in 2.0, you can annotate the function like this:

    var something = @JvmSerializableLambda 
        fun(a: String, b: String): String { ... }
    

    or use the -Xlambdas=class compiler option. Either of these will make the anonymous function compile to a class (the old behaviour before 2.0).