https://kotlinlang.org logo
Title
s

Serge

11/08/2018, 9:51 PM
If I have a package and have functions declared in it (not any class besides package itself) - is it possible by using reflection to obtain list of those declared functions? I have tried to do something like this -
val o = object{}
val mm = o.javaClass.declaredMethods
but it doesn't return anything. is it possible at all? if so, would the function modifier affect this search (private, public, etc)?
d

diesieben07

11/08/2018, 10:13 PM
Not without classpath scanning (quite ugly and unreliable). The functions could be scattered across many many class files.
s

Serge

11/08/2018, 10:26 PM
@diesieben07 if to assume I have only one *.tk file with
package temp.test
and few functions in it. how this would look like then? I don't have any class declared
d

diesieben07

11/08/2018, 10:30 PM
You'd have to get one of the functions in there, get it's
java.lang.Method
and then call
getDeclaringClass
. However this is a hack and not guaranteed to work in the future.
s

Serge

11/08/2018, 10:51 PM
@diesieben07 neither of these kc or fc would allow to do what you're just saying -
fun main(args: Array<String>) {
  val o = object{}
  val kc = o::class
  val jc = o.javaClass }
unfortunately
d

diesieben07

11/08/2018, 10:55 PM
Well, that is not at all what I said. Assuming you have
foo
and
bar
in
com.example
package. Then you can do
::foo.javaMethod!!.declaringClass.declaredMethods
. However that would only list the functions declared in that same .kt file.
A cleaner way to do this would be to use kotlin-metadata-jvm (https://github.com/JetBrains/kotlin/tree/master/libraries/kotlinx-metadata/jvm), which can parse the
@Metadata
annotation and could be used to obtain more kotlin-esque information about the function (not just Java reflection methods)
s

Serge

11/09/2018, 4:35 PM
Thank you @diesieben07 I see... I actually need it for one file, so this approach would work for me and i would do this from within main(), so it works too. Let's say I need find only functions that start with "foo" then I will do this like that (from within main) -
::main.javaMethod!!.declaringClass.declaredMethods.filter { it.name.startsWith("foo") }.map {it-> it.name}
d

diesieben07

11/09/2018, 4:36 PM
Yes, that would work, albeit being very ugly 😛