Created
March 12, 2021 04:31
-
-
Save ivpal/32bc0729b79d9be15cb887011c3d8ef7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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