Skip to content

Instantly share code, notes, and snippets.

@ivpal
Created March 12, 2021 04:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ivpal/32bc0729b79d9be15cb887011c3d8ef7 to your computer and use it in GitHub Desktop.
Save ivpal/32bc0729b79d9be15cb887011c3d8ef7 to your computer and use it in GitHub Desktop.
package org.acme
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.cli.common.messages.MessageRenderer
import org.jetbrains.kotlin.cli.common.messages.PrintingMessageCollector
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
import org.jetbrains.kotlin.config.Services
import java.io.File
import java.io.PrintWriter
import java.net.URLClassLoader
import java.nio.file.Files
import java.util.concurrent.ThreadLocalRandom
import kotlin.reflect.full.createInstance
inline fun <reified T> createAndLoad(className: String, classString: String, vararg args: Any?): T {
val random = ThreadLocalRandom.current()
val dir = Files.createTempDirectory(System.currentTimeMillis().toString()+ "_" + random.nextInt()).toFile()
val codegenOutputFile = File(dir.absolutePath + "/source.kt")
val writer = PrintWriter(codegenOutputFile, "UTF-8")
writer.println(classString)
writer.close()
Compiler.compile(codegenOutputFile, dir)
return Initializer(dir).createInstance(className, *args)!!
}
object Compiler {
fun compile(input: File, output: File): Boolean = K2JVMCompiler().run {
val args = K2JVMCompilerArguments().apply {
freeArgs = listOf(input.absolutePath)
destination = output.absolutePath
classpath =
System.getProperty("java.class.path")
.split(System.getProperty("path.separator"))
.filter {
File(it).exists() && File(it).canRead()
}.joinToString(":")
noStdlib = true
noReflect = true
skipRuntimeVersionCheck = true
}
output.deleteOnExit()
execImpl(
PrintingMessageCollector(
System.out,
MessageRenderer.WITHOUT_PATHS, true),
Services.EMPTY,
args)
}.code == 0
}
class Initializer(root: File) {
val loader = URLClassLoader(
listOf(root.toURI().toURL()).toTypedArray(),
this::class.java.classLoader
)
@Suppress("UNCHECKED_CAST")
inline fun <reified T> loadCompiledObject(clazzName: String): T? =
loader.loadClass(clazzName).kotlin.objectInstance as T
@Suppress("UNCHECKED_CAST")
inline fun <reified T> createInstance(clazzName: String): T? =
loader.loadClass(clazzName).kotlin.createInstance() as T
@Suppress("UNCHECKED_CAST")
inline fun <reified T> createInstance(clazzName: String, vararg args: Any?): T? =
loader.loadClass(clazzName).kotlin.constructors.first().call(*args) as T
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment