diff --git a/libraries/examples/scripting/jvm-maven-deps/script/src/org/jetbrains/kotlin/script/examples/jvm/resolve/maven/scriptDef.kt b/libraries/examples/scripting/jvm-maven-deps/script/src/org/jetbrains/kotlin/script/examples/jvm/resolve/maven/scriptDef.kt index 4b0544b0751..5ad5841ddb1 100644 --- a/libraries/examples/scripting/jvm-maven-deps/script/src/org/jetbrains/kotlin/script/examples/jvm/resolve/maven/scriptDef.kt +++ b/libraries/examples/scripting/jvm-maven-deps/script/src/org/jetbrains/kotlin/script/examples/jvm/resolve/maven/scriptDef.kt @@ -39,7 +39,7 @@ val myJvmConfigParams = jvmJavaHomeParams + with(ScriptCompileConfigurationPrope ) ) ), - updateConfigurationOnAnnotations(DependsOn::class, Repository::class) + refineConfigurationOnAnnotations(DependsOn::class, Repository::class) ) } @@ -49,9 +49,6 @@ class MyConfigurator(val environment: ScriptingEnvironment) : ScriptCompilationC override val defaultConfiguration = ScriptCompileConfiguration(environment, myJvmConfigParams) - override suspend fun baseConfiguration(scriptSource: ScriptSource): ResultWithDiagnostics = - defaultConfiguration.asSuccess() - override suspend fun refineConfiguration( scriptSource: ScriptSource, configuration: ScriptCompileConfiguration, diff --git a/libraries/scripting/common/src/kotlin/script/experimental/api/scriptCompilation.kt b/libraries/scripting/common/src/kotlin/script/experimental/api/scriptCompilation.kt index a6e9fe8dd9e..42c66258b3c 100644 --- a/libraries/scripting/common/src/kotlin/script/experimental/api/scriptCompilation.kt +++ b/libraries/scripting/common/src/kotlin/script/experimental/api/scriptCompilation.kt @@ -9,8 +9,8 @@ interface ScriptCompiler { suspend fun compile( script: ScriptSource, - configuration: ScriptCompileConfiguration, - configurator: ScriptCompilationConfigurator? = null + configurator: ScriptCompilationConfigurator? = null, + additionalConfiguration: ScriptCompileConfiguration? = null // overrides parameters from configurator.defaultConfiguration ): ResultWithDiagnostics> } diff --git a/libraries/scripting/common/src/kotlin/script/experimental/api/scriptConfiguration.kt b/libraries/scripting/common/src/kotlin/script/experimental/api/scriptConfiguration.kt index 9889be96ed3..47c90b4a46a 100644 --- a/libraries/scripting/common/src/kotlin/script/experimental/api/scriptConfiguration.kt +++ b/libraries/scripting/common/src/kotlin/script/experimental/api/scriptConfiguration.kt @@ -21,8 +21,6 @@ interface ScriptCompilationConfigurator { val defaultConfiguration: ScriptCompileConfiguration - suspend fun baseConfiguration(scriptSource: ScriptSource): ResultWithDiagnostics - suspend fun refineConfiguration( scriptSource: ScriptSource, configuration: ScriptCompileConfiguration, diff --git a/libraries/scripting/common/src/kotlin/script/experimental/api/scriptConfigurationProperties.kt b/libraries/scripting/common/src/kotlin/script/experimental/api/scriptConfigurationProperties.kt index e686ff70f01..ffb0594c1e5 100644 --- a/libraries/scripting/common/src/kotlin/script/experimental/api/scriptConfigurationProperties.kt +++ b/libraries/scripting/common/src/kotlin/script/experimental/api/scriptConfigurationProperties.kt @@ -33,8 +33,10 @@ object ScriptCompileConfigurationProperties { val compilerOptions by typedKey>() // Q: CommonCompilerOptions instead? - val updateConfigurationOnAnnotations by typedKey>>() + val refineBeforeParsing by typedKey() // default: false - val updateConfigurationOnSections by typedKey>() + val refineConfigurationOnAnnotations by typedKey>>() + + val refineConfigurationOnSections by typedKey>() } diff --git a/libraries/scripting/common/src/kotlin/script/experimental/basic/basicScript.kt b/libraries/scripting/common/src/kotlin/script/experimental/basic/basicScript.kt index d544ae71bca..6f0f8674086 100644 --- a/libraries/scripting/common/src/kotlin/script/experimental/basic/basicScript.kt +++ b/libraries/scripting/common/src/kotlin/script/experimental/basic/basicScript.kt @@ -12,9 +12,6 @@ class PassThroughCompilationConfigurator(val environment: ScriptingEnvironment) override val defaultConfiguration = ScriptCompileConfiguration(environment) - override suspend fun baseConfiguration(scriptSource: ScriptSource): ResultWithDiagnostics = - defaultConfiguration.asSuccess() - override suspend fun refineConfiguration( script: ScriptSource, configuration: ScriptCompileConfiguration, diff --git a/libraries/scripting/common/src/kotlin/script/experimental/host/BasicScriptingHost.kt b/libraries/scripting/common/src/kotlin/script/experimental/host/BasicScriptingHost.kt index 60f2dc36c4f..91da2cd2bf9 100644 --- a/libraries/scripting/common/src/kotlin/script/experimental/host/BasicScriptingHost.kt +++ b/libraries/scripting/common/src/kotlin/script/experimental/host/BasicScriptingHost.kt @@ -35,7 +35,7 @@ abstract class BasicScriptingHost( environment: ScriptEvaluationEnvironment ): ResultWithDiagnostics = runInCoroutineContext { - val compiled = compiler.compile(script, compileConfiguration, configurator) + val compiled = compiler.compile(script, configurator, compileConfiguration) when (compiled) { is ResultWithDiagnostics.Failure -> compiled is ResultWithDiagnostics.Success -> { diff --git a/libraries/scripting/common/src/kotlin/script/experimental/util/propertyBag.kt b/libraries/scripting/common/src/kotlin/script/experimental/util/propertyBag.kt index b180d69a93b..1f55fd50a39 100644 --- a/libraries/scripting/common/src/kotlin/script/experimental/util/propertyBag.kt +++ b/libraries/scripting/common/src/kotlin/script/experimental/util/propertyBag.kt @@ -17,12 +17,19 @@ class TypedKeyDelegate { fun typedKey() = TypedKeyDelegate() -class ChainedPropertyBag(private val parent: ChainedPropertyBag? = null, pairs: Iterable, Any?>>) { +class ChainedPropertyBag private constructor(private val parent: ChainedPropertyBag?, private val data: Map, Any?>) { + constructor(parent: ChainedPropertyBag? = null, pairs: Iterable, Any?>>) : + this(parent, HashMap, Any?>().also { it.putAll(pairs) }) + constructor(pairs: Iterable, Any?>>) : this(null, pairs) constructor(parent: ChainedPropertyBag, vararg pairs: Pair, Any?>) : this(parent, pairs.asIterable()) constructor(vararg pairs: Pair, Any?>) : this(null, pairs.asIterable()) - private val data = HashMap, Any?>().also { it.putAll(pairs) } + fun cloneWithNewParent(newParent: ChainedPropertyBag?): ChainedPropertyBag = when { + newParent == null -> this + parent == null -> ChainedPropertyBag(newParent, data) + else -> ChainedPropertyBag(parent.cloneWithNewParent(newParent), data) + } inline operator fun get(key: TypedKey): T = getUnchecked(key) as T diff --git a/libraries/scripting/jvm-host/src/kotlin/script/experimental/jvmhost/impl/KJVMCompilerImpl.kt b/libraries/scripting/jvm-host/src/kotlin/script/experimental/jvmhost/impl/KJVMCompilerImpl.kt index 6d77be00272..98295f54378 100644 --- a/libraries/scripting/jvm-host/src/kotlin/script/experimental/jvmhost/impl/KJVMCompilerImpl.kt +++ b/libraries/scripting/jvm-host/src/kotlin/script/experimental/jvmhost/impl/KJVMCompilerImpl.kt @@ -73,8 +73,8 @@ class KJVMCompilerImpl : KJVMCompilerProxy { override fun compile( script: ScriptSource, - scriptCompilerConfiguration: ScriptCompileConfiguration, - configurator: ScriptCompilationConfigurator? + configurator: ScriptCompilationConfigurator?, + additionalConfiguration: ScriptCompileConfiguration ): ResultWithDiagnostics> { val messageCollector = ScriptDiagnosticsMessageCollector() @@ -83,7 +83,7 @@ class KJVMCompilerImpl : KJVMCompilerProxy { try { var environment: KotlinCoreEnvironment? = null - var updatedScriptCompileConfiguration = scriptCompilerConfiguration + var updatedScriptCompileConfiguration = additionalConfiguration fun updateClasspath(classpath: List) { environment!!.updateClasspath(classpath.map(::JvmClasspathRoot)) @@ -100,19 +100,19 @@ class KJVMCompilerImpl : KJVMCompilerProxy { val kotlinCompilerConfiguration = org.jetbrains.kotlin.config.CompilerConfiguration().apply { add( JVMConfigurationKeys.SCRIPT_DEFINITIONS, - BridgeScriptDefinition(scriptCompilerConfiguration, configurator, ::updateClasspath) + BridgeScriptDefinition(additionalConfiguration, configurator, ::updateClasspath) ) put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector) put(JVMConfigurationKeys.RETAIN_OUTPUT_IN_MEMORY, true) var isModularJava = false - scriptCompilerConfiguration.getOrNull(JvmScriptCompileConfigurationProperties.javaHomeDir)?.let { + additionalConfiguration.getOrNull(JvmScriptCompileConfigurationProperties.javaHomeDir)?.let { put(JVMConfigurationKeys.JDK_HOME, it) isModularJava = CoreJrtFileSystem.isModularJdk(it) } var explicitStdlib = false - scriptCompilerConfiguration.getOrNull(ScriptCompileConfigurationProperties.dependencies)?.let { + additionalConfiguration.getOrNull(ScriptCompileConfigurationProperties.dependencies)?.let { addJvmClasspathRoots( it.flatMap { (it as JvmDependency).classpath.also { @@ -152,7 +152,7 @@ class KJVMCompilerImpl : KJVMCompilerProxy { val analyzerWithCompilerReport = AnalyzerWithCompilerReport(messageCollector, environment.configuration.languageVersionSettings) val psiFileFactory: PsiFileFactoryImpl = PsiFileFactory.getInstance(environment.project) as PsiFileFactoryImpl - val scriptText = getMergedScriptText(script, scriptCompilerConfiguration) + val scriptText = getMergedScriptText(script, additionalConfiguration) val scriptFileName = "script" // TODO: extract from file/url if available val virtualFile = LightVirtualFile( "$scriptFileName${KotlinParserDefinition.STD_SCRIPT_EXT}", @@ -247,7 +247,8 @@ internal class BridgeScriptDefinition( updateClasspath: (List) -> Unit ) : KotlinScriptDefinition(scriptCompilerConfiguration[ScriptingEnvironmentProperties.baseClass] as KClass) { override val acceptedAnnotations = - scriptCompilerConfiguration.getOrNull(ScriptCompileConfigurationProperties.updateConfigurationOnAnnotations)?.toList() ?: emptyList() + scriptCompilerConfiguration.getOrNull(ScriptCompileConfigurationProperties.refineConfigurationOnAnnotations)?.toList() + ?: emptyList() override val dependencyResolver: DependenciesResolver = BridgeDependenciesResolver(scriptConfigurator, scriptCompilerConfiguration, updateClasspath) diff --git a/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/jvmScriptCompilation.kt b/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/jvmScriptCompilation.kt index 781468a7919..910b0ab5002 100644 --- a/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/jvmScriptCompilation.kt +++ b/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/jvmScriptCompilation.kt @@ -16,20 +16,31 @@ open class JvmScriptCompiler( override suspend fun compile( script: ScriptSource, - configuration: ScriptCompileConfiguration, - configurator: ScriptCompilationConfigurator? + configurator: ScriptCompilationConfigurator?, + additionalConfiguration: ScriptCompileConfiguration? ): ResultWithDiagnostics> { - val refinedConfiguration = configurator?.refineConfiguration(script, configuration)?.let { - when (it) { - is ResultWithDiagnostics.Failure -> return it - is ResultWithDiagnostics.Success -> it.value + val baseConfiguration = additionalConfiguration?.cloneWithNewParent(configurator?.defaultConfiguration) + ?: configurator?.defaultConfiguration + ?: ScriptCompileConfiguration() + val refinedConfiguration = + if (baseConfiguration.getOrNull(ScriptCompileConfigurationProperties.refineBeforeParsing) == true) { + if (configurator == null) { + return ResultWithDiagnostics.Failure("Non-null configurator expected".asErrorDiagnostics()) + } + configurator.refineConfiguration(script, baseConfiguration).let { + when (it) { + is ResultWithDiagnostics.Failure -> return it + is ResultWithDiagnostics.Success -> it.value + } + } + } else { + baseConfiguration } - } ?: configuration val cached = cache.get(script, refinedConfiguration) if (cached != null) return cached.asSuccess() - return compilerProxy.compile(script, refinedConfiguration, configurator).also { + return compilerProxy.compile(script, configurator, refinedConfiguration).also { if (it is ResultWithDiagnostics.Success) { cache.store(it.value, refinedConfiguration) } @@ -45,8 +56,8 @@ interface CompiledJvmScriptsCache { interface KJVMCompilerProxy { fun compile( script: ScriptSource, - scriptCompilerConfiguration: ScriptCompileConfiguration, - configurator: ScriptCompilationConfigurator? + configurator: ScriptCompilationConfigurator?, + additionalConfiguration: ScriptCompileConfiguration ): ResultWithDiagnostics> } diff --git a/plugins/scripting/scripting-cli/src/org/jetbrains/kotlin/scripting/compiler/plugin/KotlinScriptDefinitionAdapterFromNewAPI.kt b/plugins/scripting/scripting-cli/src/org/jetbrains/kotlin/scripting/compiler/plugin/KotlinScriptDefinitionAdapterFromNewAPI.kt index 857858fd179..9a9b5a66261 100644 --- a/plugins/scripting/scripting-cli/src/org/jetbrains/kotlin/scripting/compiler/plugin/KotlinScriptDefinitionAdapterFromNewAPI.kt +++ b/plugins/scripting/scripting-cli/src/org/jetbrains/kotlin/scripting/compiler/plugin/KotlinScriptDefinitionAdapterFromNewAPI.kt @@ -47,7 +47,7 @@ class KotlinScriptDefinitionAdapterFromNewAPI(val scriptDefinition: ScriptDefini } override val acceptedAnnotations: List> by lazy { - scriptDefinition.compilationConfigurator.defaultConfiguration.getOrNull(ScriptCompileConfigurationProperties.updateConfigurationOnAnnotations)?.toList() + scriptDefinition.compilationConfigurator.defaultConfiguration.getOrNull(ScriptCompileConfigurationProperties.refineConfigurationOnAnnotations)?.toList() ?: emptyList() }