Implement script templates discovery in the cli compiler
This commit is contained in:
@@ -24,11 +24,8 @@ import org.jetbrains.kotlin.cli.common.CLITool
|
|||||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||||
import org.jetbrains.kotlin.cli.common.ExitCode.*
|
import org.jetbrains.kotlin.cli.common.ExitCode.*
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
||||||
|
import org.jetbrains.kotlin.cli.common.messages.*
|
||||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*
|
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*
|
||||||
import org.jetbrains.kotlin.cli.common.messages.FilteringMessageCollector
|
|
||||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
|
||||||
import org.jetbrains.kotlin.cli.common.messages.MessageUtil
|
|
||||||
import org.jetbrains.kotlin.cli.common.messages.OutputMessageUtil
|
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.CompileEnvironmentUtil
|
import org.jetbrains.kotlin.cli.jvm.compiler.CompileEnvironmentUtil
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||||
@@ -57,10 +54,12 @@ import org.jetbrains.kotlin.utils.KotlinPaths
|
|||||||
import org.jetbrains.kotlin.utils.PathUtil
|
import org.jetbrains.kotlin.utils.PathUtil
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.io.IOException
|
||||||
import java.lang.management.ManagementFactory
|
import java.lang.management.ManagementFactory
|
||||||
import java.net.URLClassLoader
|
import java.net.URLClassLoader
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
import java.util.jar.JarFile
|
||||||
import kotlin.script.experimental.definitions.ScriptDefinitionFromAnnotatedBaseClass
|
import kotlin.script.experimental.definitions.ScriptDefinitionFromAnnotatedBaseClass
|
||||||
|
|
||||||
class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||||
@@ -262,7 +261,13 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
|||||||
messageCollector: MessageCollector
|
messageCollector: MessageCollector
|
||||||
): KotlinCoreEnvironment? {
|
): KotlinCoreEnvironment? {
|
||||||
val scriptResolverEnv = createScriptResolverEnvironment(arguments, messageCollector) ?: return null
|
val scriptResolverEnv = createScriptResolverEnvironment(arguments, messageCollector) ?: return null
|
||||||
configureScriptDefinitions(arguments.scriptTemplates, configuration, messageCollector, scriptResolverEnv)
|
val templatesFromClasspath = discoverScriptTemplatesInClasspath(configuration, messageCollector)
|
||||||
|
configureScriptDefinitions(
|
||||||
|
arguments.scriptTemplates.orEmpty().asIterable() + templatesFromClasspath,
|
||||||
|
configuration,
|
||||||
|
messageCollector,
|
||||||
|
scriptResolverEnv
|
||||||
|
)
|
||||||
if (messageCollector.hasErrors()) return null
|
if (messageCollector.hasErrors()) return null
|
||||||
|
|
||||||
val environment = KotlinCoreEnvironment.createForProduction(rootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES)
|
val environment = KotlinCoreEnvironment.createForProduction(rootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES)
|
||||||
@@ -281,6 +286,49 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun discoverScriptTemplatesInClasspath(configuration: CompilerConfiguration, messageCollector: MessageCollector): Iterable<String> {
|
||||||
|
val templates = arrayListOf<String>()
|
||||||
|
val templatesPath = "META-INF/kotlin/script/templates/"
|
||||||
|
for (dep in configuration.jvmClasspathRoots) {
|
||||||
|
when {
|
||||||
|
dep.isFile ->
|
||||||
|
try {
|
||||||
|
with(JarFile(dep)) {
|
||||||
|
for (template in entries()) {
|
||||||
|
if (!template.isDirectory && template.name.startsWith(templatesPath)) {
|
||||||
|
val templateClassName = template.name.removePrefix(templatesPath)
|
||||||
|
templates.add(templateClassName)
|
||||||
|
messageCollector.report(
|
||||||
|
CompilerMessageSeverity.LOGGING,
|
||||||
|
"Configure scripting: Added template $templateClassName from $dep"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: IOException) {
|
||||||
|
messageCollector.report(
|
||||||
|
CompilerMessageSeverity.WARNING,
|
||||||
|
"Configure scripting: unable to process classpath entry $dep: $e"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
dep.isDirectory -> {
|
||||||
|
val dir = File(dep, templatesPath)
|
||||||
|
if (dir.isDirectory) {
|
||||||
|
dir.listFiles().forEach {
|
||||||
|
templates.add(it.name)
|
||||||
|
messageCollector.report(
|
||||||
|
CompilerMessageSeverity.LOGGING,
|
||||||
|
"Configure scripting: Added template ${it.name} from $dep"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> messageCollector.report(CompilerMessageSeverity.WARNING, "Configure scripting: Unknown classpath entry $dep")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return templates
|
||||||
|
}
|
||||||
|
|
||||||
override fun setupPlatformSpecificArgumentsAndServices(
|
override fun setupPlatformSpecificArgumentsAndServices(
|
||||||
configuration: CompilerConfiguration, arguments: K2JVMCompilerArguments, services: Services
|
configuration: CompilerConfiguration, arguments: K2JVMCompilerArguments, services: Services
|
||||||
) {
|
) {
|
||||||
@@ -460,14 +508,14 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun configureScriptDefinitions(
|
fun configureScriptDefinitions(
|
||||||
scriptTemplates: Array<String>?,
|
scriptTemplates: List<String>,
|
||||||
configuration: CompilerConfiguration,
|
configuration: CompilerConfiguration,
|
||||||
messageCollector: MessageCollector,
|
messageCollector: MessageCollector,
|
||||||
scriptResolverEnv: HashMap<String, Any?>
|
scriptResolverEnv: HashMap<String, Any?>
|
||||||
) {
|
) {
|
||||||
val classpath = configuration.jvmClasspathRoots
|
val classpath = configuration.jvmClasspathRoots
|
||||||
// TODO: consider using escaping to allow kotlin escaped names in class names
|
// TODO: consider using escaping to allow kotlin escaped names in class names
|
||||||
if (scriptTemplates != null && scriptTemplates.isNotEmpty()) {
|
if (scriptTemplates.isNotEmpty()) {
|
||||||
val classloader =
|
val classloader =
|
||||||
URLClassLoader(classpath.map { it.toURI().toURL() }.toTypedArray(), Thread.currentThread().contextClassLoader)
|
URLClassLoader(classpath.map { it.toURI().toURL() }.toTypedArray(), Thread.currentThread().contextClassLoader)
|
||||||
var hasErrors = false
|
var hasErrors = false
|
||||||
|
|||||||
Reference in New Issue
Block a user