Process script templates everywhere properly:

- add options to disable scripting plugin and standard script definition
- move standard definition adding logic into appropriate place
- fix logic of scripting plugin loading
- add standard script definition on the environment creation to
  ensure compatibility with all usages
- fix testdata
- some minor fixes
This commit is contained in:
Ilya Chernikov
2018-04-06 11:46:00 +02:00
parent b5da48c566
commit a29411a211
9 changed files with 118 additions and 55 deletions
@@ -11,15 +11,19 @@ import org.jetbrains.kotlin.compiler.plugin.CliOptionProcessingException
import org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.CompilerConfigurationKey
import org.jetbrains.kotlin.config.JVMConfigurationKeys
object ScriptingConfigurationKeys {
val DISABLE_SCRIPTING_PLUGIN_OPTION: CompilerConfigurationKey<Boolean> =
CompilerConfigurationKey.create("Disable scripting plugin")
val SCRIPT_DEFINITIONS: CompilerConfigurationKey<List<String>> =
CompilerConfigurationKey.create("Script definition classes")
val SCRIPT_DEFINITIONS_CLASSPATH: CompilerConfigurationKey<List<File>> =
CompilerConfigurationKey.create("Additional classpath for the script definitions")
val DISABLE_SCRIPT_DEFINITIONS_FROM_CLSSPATH_OPTION: CompilerConfigurationKey<Boolean> =
val DISABLE_SCRIPT_DEFINITIONS_FROM_CLASSPATH_OPTION: CompilerConfigurationKey<Boolean> =
CompilerConfigurationKey.create("Do not extract script definitions from the compilation classpath")
val LEGACY_SCRIPT_RESOLVER_ENVIRONMENT_OPTION: CompilerConfigurationKey<MutableMap<String, Any?>> =
@@ -28,6 +32,10 @@ object ScriptingConfigurationKeys {
class ScriptingCommandLineProcessor : CommandLineProcessor {
companion object {
val DISABLE_SCRIPTING_PLUGIN_OPTION = CliOption(
"disable", "true/false", "Disable scripting plugin",
required = false, allowMultipleOccurrences = false
)
val SCRIPT_DEFINITIONS_OPTION = CliOption(
"script-definitions", "<fully qualified class name[,]>", "Script definition classes",
required = false, allowMultipleOccurrences = true
@@ -36,6 +44,10 @@ class ScriptingCommandLineProcessor : CommandLineProcessor {
"script-definitions-classpath", "<classpath entry[:]>", "Additional classpath for the script definitions",
required = false, allowMultipleOccurrences = true
)
val DISABLE_STANDARD_SCRIPT_DEFINITION_OPTION = CliOption(
"disable-standard-script", "true/false", "Disable standard kotlin script support",
required = false, allowMultipleOccurrences = false
)
val DISABLE_SCRIPT_DEFINITIONS_FROM_CLSSPATH_OPTION = CliOption(
"disable-script-definitions-from-classpath", "true/false", "Do not extract script definitions from the compilation classpath",
required = false, allowMultipleOccurrences = false
@@ -56,14 +68,23 @@ class ScriptingCommandLineProcessor : CommandLineProcessor {
override val pluginId = PLUGIN_ID
override val pluginOptions =
listOf(
DISABLE_SCRIPTING_PLUGIN_OPTION,
SCRIPT_DEFINITIONS_OPTION,
SCRIPT_DEFINITIONS_CLASSPATH_OPTION,
DISABLE_STANDARD_SCRIPT_DEFINITION_OPTION,
DISABLE_SCRIPT_DEFINITIONS_FROM_CLSSPATH_OPTION,
LEGACY_SCRIPT_TEMPLATES_OPTION,
LEGACY_SCRIPT_RESOLVER_ENVIRONMENT_OPTION
)
override fun processOption(option: CliOption, value: String, configuration: CompilerConfiguration) = when (option) {
DISABLE_SCRIPTING_PLUGIN_OPTION -> {
configuration.put(
ScriptingConfigurationKeys.DISABLE_SCRIPTING_PLUGIN_OPTION,
value.takeUnless { it.isBlank() }?.toBoolean() ?: true
)
}
SCRIPT_DEFINITIONS_OPTION, LEGACY_SCRIPT_TEMPLATES_OPTION -> {
val currentDefs = configuration.getList(ScriptingConfigurationKeys.SCRIPT_DEFINITIONS).toMutableList()
currentDefs.addAll(value.split(','))
@@ -74,9 +95,15 @@ class ScriptingCommandLineProcessor : CommandLineProcessor {
currentCP.addAll(value.split(File.pathSeparatorChar).map(::File))
configuration.put(ScriptingConfigurationKeys.SCRIPT_DEFINITIONS_CLASSPATH, currentCP)
}
DISABLE_STANDARD_SCRIPT_DEFINITION_OPTION -> {
configuration.put(
JVMConfigurationKeys.DISABLE_STANDARD_SCRIPT_DEFINITION,
value.takeUnless { it.isBlank() }?.toBoolean() ?: true
)
}
DISABLE_SCRIPT_DEFINITIONS_FROM_CLSSPATH_OPTION -> {
configuration.put(
ScriptingConfigurationKeys.DISABLE_SCRIPT_DEFINITIONS_FROM_CLSSPATH_OPTION,
ScriptingConfigurationKeys.DISABLE_SCRIPT_DEFINITIONS_FROM_CLASSPATH_OPTION,
value.takeUnless { it.isBlank() }?.toBoolean() ?: true
)
}
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.extensions.CompilerConfigurationExtension
import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromAnnotatedTemplate
import org.jetbrains.kotlin.script.StandardScriptDefinition
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import java.io.File
import java.io.IOException
@@ -28,30 +29,39 @@ class ScriptingCompilerConfigurationExtension(val project: MockProject) : Compil
override fun updateConfiguration(configuration: CompilerConfiguration) {
val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY) ?: MessageCollector.NONE
val explicitScriptDefinitions = configuration.getList(ScriptingConfigurationKeys.SCRIPT_DEFINITIONS)
if (!configuration.getBoolean(ScriptingConfigurationKeys.DISABLE_SCRIPTING_PLUGIN_OPTION)) {
val scriptDefinitions =
if (configuration.getBoolean(ScriptingConfigurationKeys.DISABLE_SCRIPT_DEFINITIONS_FROM_CLSSPATH_OPTION))
explicitScriptDefinitions
else
explicitScriptDefinitions + discoverScriptTemplatesInClasspath(configuration, messageCollector)
val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY) ?: MessageCollector.NONE
val explicitScriptDefinitions = configuration.getList(ScriptingConfigurationKeys.SCRIPT_DEFINITIONS)
if (scriptDefinitions.isNotEmpty()) {
val projectRoot = project.run { basePath ?: baseDir?.canonicalPath }?.let(::File)
if (projectRoot != null) {
configuration.put(
ScriptingConfigurationKeys.LEGACY_SCRIPT_RESOLVER_ENVIRONMENT_OPTION,
"projectRoot",
projectRoot
val scriptDefinitions =
if (configuration.getBoolean(ScriptingConfigurationKeys.DISABLE_SCRIPT_DEFINITIONS_FROM_CLASSPATH_OPTION))
explicitScriptDefinitions
else
explicitScriptDefinitions + discoverScriptTemplatesInClasspath(configuration, messageCollector)
if (scriptDefinitions.isNotEmpty()) {
val projectRoot = project.run { basePath ?: baseDir?.canonicalPath }?.let(::File)
if (projectRoot != null) {
configuration.put(
ScriptingConfigurationKeys.LEGACY_SCRIPT_RESOLVER_ENVIRONMENT_OPTION,
"projectRoot",
projectRoot
)
}
configureScriptDefinitions(
scriptDefinitions,
configuration,
messageCollector,
configuration.getMap(ScriptingConfigurationKeys.LEGACY_SCRIPT_RESOLVER_ENVIRONMENT_OPTION)
)
}
configureScriptDefinitions(
scriptDefinitions,
configuration,
messageCollector,
configuration.getMap(ScriptingConfigurationKeys.LEGACY_SCRIPT_RESOLVER_ENVIRONMENT_OPTION)
)
// If not disabled explicitly, we should always support at least the standard script definition
if (!configuration.getBoolean(JVMConfigurationKeys.DISABLE_STANDARD_SCRIPT_DEFINITION) &&
!configuration.getList(JVMConfigurationKeys.SCRIPT_DEFINITIONS).contains(StandardScriptDefinition)
) {
configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, StandardScriptDefinition)
}
}
}
}
@@ -103,7 +113,10 @@ private fun discoverScriptTemplatesInClasspath(configuration: CompilerConfigurat
}
}
}
else -> messageCollector.report(CompilerMessageSeverity.WARNING, "Configure scripting: Unknown classpath entry $dep")
else -> {
// assuming that invalid classpath entries will be reported elsewhere anyway, so do not spam user with additional warnings here
messageCollector.report(CompilerMessageSeverity.LOGGING, "Configure scripting: Unknown classpath entry $dep")
}
}
}
return templates