Alyssa Burlton
12/14/2022, 4:26 PMeval
in Python).
TL;DR is that it works, but it ain't pretty 😂 Details in 🧵Alyssa Burlton
12/14/2022, 4:28 PM.replace
calls so that e.g. "[[1],4]"
becomes "listOf(listOf(1), 4)"
. One slight edge case is that empty ones need explicitly typing, so "[]"
becomes "listOf<Any>()"
Bundle this up into a valid Kotlin class. At the end of all this, we end up with a String like:
class ListClass {
fun list0() = listOf(listOf(1), 4)
fun list1() = listOf(...)
fun allLists() = listOf(list0(), list1(), ...)
}
I'm using individual functions rather than one big list to avoid running into a "Method too large" error when we compile it (see next step 😂).
Step 2
Write the string to a file, then shell out to kotlinc to generate a raw class file from the Kotlin file.
Runtime.getRuntime().exec("kotlinc -no-jdk -no-reflect $file")
Step 3
Dynamically load the class file into the currently running JVM via a custom ClassLoader
that makes use of the defineClass
function.
class DynamicClassInjector : ClassLoader() {
fun injectClass(name: String): Class<*> {
val file = File("$name.class")
val bytes = file.readBytes()
return defineClass(
name,
bytes, 0, bytes.size
)
}
}
Step 4
Use reflection to construct an instance of our new class and invoke the method we're interested in, getting our parsed list.
val clazz = injectDynamicClass("ListClass", listClass)
val instance = clazz.getDeclaredConstructor().newInstance()
return clazz.getMethod("allLists").invoke(instance) as List<List<Any>>
rocketraman
12/14/2022, 6:36 PMAlyssa Burlton
12/14/2022, 6:37 PMeval
. When he showed me I was... a little peeved 😁rocketraman
12/14/2022, 6:39 PMrocketraman
12/14/2022, 6:41 PMephemient
12/14/2022, 6:53 PMephemient
12/14/2022, 6:53 PMAlyssa Burlton
12/14/2022, 6:56 PMrkechols
12/14/2022, 7:41 PM