diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptDefinitionsManager.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptDefinitionsManager.kt index cf926707ff0..72584c12f1b 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptDefinitionsManager.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptDefinitionsManager.kt @@ -208,14 +208,13 @@ fun loadDefinitionsFromTemplates( ) } template.annotations.firstIsInstanceOrNull() != null -> { + val hostEnvironment = ScriptingEnvironment( + ScriptingEnvironmentProperties.configurationDependencies to listOf(JvmDependency(classpath)), + ScriptingEnvironmentProperties.getScriptingClass to JvmGetScriptingClass() + ) KotlinScriptDefinitionAdapterFromNewAPI( - ScriptDefinitionFromAnnotatedBaseClass( - KotlinType(template), - ScriptingEnvironment( - ScriptingEnvironmentProperties.configurationDependencies to listOf(JvmDependency(classpath)), - ScriptingEnvironmentProperties.getScriptingClass to JvmGetScriptingClass() - ) - ) + ScriptDefinitionFromAnnotatedBaseClass(KotlinType(template), hostEnvironment), + hostEnvironment ) } else -> { diff --git a/libraries/examples/scripting/jvm-maven-deps/host/src/org/jetbrains/kotlin/script/examples/jvm/resolve/maven/host/host.kt b/libraries/examples/scripting/jvm-maven-deps/host/src/org/jetbrains/kotlin/script/examples/jvm/resolve/maven/host/host.kt index e797d1fccc7..b104f32921b 100644 --- a/libraries/examples/scripting/jvm-maven-deps/host/src/org/jetbrains/kotlin/script/examples/jvm/resolve/maven/host/host.kt +++ b/libraries/examples/scripting/jvm-maven-deps/host/src/org/jetbrains/kotlin/script/examples/jvm/resolve/maven/host/host.kt @@ -19,10 +19,10 @@ import kotlin.script.experimental.jvmhost.impl.KJVMCompilerImpl import kotlin.script.experimental.misc.invoke fun evalFile(scriptFile: File): ResultWithDiagnostics { - val scriptCompiler = JvmScriptCompiler(KJVMCompilerImpl(), DummyCompiledJvmScriptCache()) val environment = ScriptingEnvironment( ScriptingEnvironmentProperties.getScriptingClass(JvmGetScriptingClass()) ) + val scriptCompiler = JvmScriptCompiler(KJVMCompilerImpl(environment), DummyCompiledJvmScriptCache()) val scriptDefinition = ScriptDefinitionFromAnnotatedBaseClass( KotlinType(MyScriptWithMavenDeps::class), environment 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 bce35be04ce..f6b9f821f16 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 @@ -33,7 +33,6 @@ abstract class MyScriptWithMavenDeps { object MyConfiguration : ArrayList, Any?>>( jvmJavaHomeParams + with(ScriptCompileConfigurationProperties) { listOf( - baseClass(), defaultImports(DependsOn::class.qualifiedName!!, Repository::class.qualifiedName!!), dependencies( JvmDependency( diff --git a/libraries/examples/scripting/jvm-simple-script/host/src/org/jetbrains/kotlin/script/examples/jvm/simple/host/host.kt b/libraries/examples/scripting/jvm-simple-script/host/src/org/jetbrains/kotlin/script/examples/jvm/simple/host/host.kt index 3217e0d9ec0..12153ff99d6 100644 --- a/libraries/examples/scripting/jvm-simple-script/host/src/org/jetbrains/kotlin/script/examples/jvm/simple/host/host.kt +++ b/libraries/examples/scripting/jvm-simple-script/host/src/org/jetbrains/kotlin/script/examples/jvm/simple/host/host.kt @@ -18,16 +18,15 @@ import kotlin.script.experimental.misc.* val myJvmConfigParams = jvmJavaHomeParams + with(ScriptCompileConfigurationProperties) { listOf( - baseClass(), dependencies(JvmDependency(scriptCompilationClasspathFromContext("scripting-jvm-simple-script" /* script library jar name */))) ) } fun evalFile(scriptFile: File): ResultWithDiagnostics { - val scriptCompiler = JvmScriptCompiler(KJVMCompilerImpl(), DummyCompiledJvmScriptCache()) val environment = ScriptingEnvironment( ScriptingEnvironmentProperties.getScriptingClass(JvmGetScriptingClass()) ) + val scriptCompiler = JvmScriptCompiler(KJVMCompilerImpl(environment), DummyCompiledJvmScriptCache()) val scriptDefinition = ScriptDefinitionFromAnnotatedBaseClass( KotlinType(MyScript::class), environment diff --git a/libraries/scripting/common/src/kotlin/script/experimental/api/scriptDefinition.kt b/libraries/scripting/common/src/kotlin/script/experimental/api/scriptDefinition.kt index eb12bb54835..a870a8dcfa9 100644 --- a/libraries/scripting/common/src/kotlin/script/experimental/api/scriptDefinition.kt +++ b/libraries/scripting/common/src/kotlin/script/experimental/api/scriptDefinition.kt @@ -29,8 +29,3 @@ object ScriptDefinitionProperties { val baseClass by typedKey() // script base class } -fun ScriptDefinitionPropertiesBag.getScriptBaseClass(contextClass: KClass<*>): KClass<*> = - getScriptingClass(get(ScriptDefinitionProperties.baseClass), contextClass) - -fun ScriptDefinitionPropertiesBag.getScriptBaseClass(context: Any): KClass<*> = - getScriptingClass(get(ScriptDefinitionProperties.baseClass), context::class) diff --git a/libraries/scripting/common/src/kotlin/script/experimental/definitions/definitionFromAnnotation.kt b/libraries/scripting/common/src/kotlin/script/experimental/definitions/definitionFromAnnotation.kt index 5938f7480d0..148246e0279 100644 --- a/libraries/scripting/common/src/kotlin/script/experimental/definitions/definitionFromAnnotation.kt +++ b/libraries/scripting/common/src/kotlin/script/experimental/definitions/definitionFromAnnotation.kt @@ -15,7 +15,6 @@ import kotlin.script.experimental.annotations.KotlinScriptDefinition import kotlin.script.experimental.annotations.KotlinScriptFileExtension import kotlin.script.experimental.api.* import kotlin.script.experimental.util.TypedKey -import kotlin.script.experimental.util.chainPropertyBags private const val ERROR_MSG_PREFIX = "Unable to construct script definition: " @@ -44,12 +43,12 @@ open class ScriptDefinitionFromAnnotatedBaseClass( baseClass.findAnnotation()?.definition.takeIf { it != this::class }?.let { it.instantiateScriptHandler() } override val properties = run { - val baseProperties = chainPropertyBags(explicitDefinition?.properties, environment) - val propertiesData = arrayListOf, Any?>>(ScriptDefinitionProperties.baseClass to baseClassType) + val baseProperties = explicitDefinition?.properties + val propertiesData = hashMapOf, Any?>(ScriptDefinitionProperties.baseClass to baseClassType) baseClass.findAnnotation()?.let { - propertiesData += ScriptDefinitionProperties.fileExtension to it.extension + propertiesData[ScriptDefinitionProperties.fileExtension] = it.extension } - if (baseProperties.getOrNull(ScriptDefinitionProperties.name) == null) { + if (baseProperties?.getOrNull(ScriptDefinitionProperties.name) == null) { propertiesData += ScriptDefinitionProperties.name to mainAnnotation.name } baseClass.annotations.filterIsInstance(KotlinScriptDefaultCompilationConfiguration::class.java).forEach { ann -> @@ -61,10 +60,12 @@ open class ScriptDefinitionFromAnnotatedBaseClass( params.forEach { param -> if (param !is Pair<*, *> || param.first !is TypedKey<*>) throw IllegalArgumentException("$ILLEGAL_CONFIG_ANN_ARG: invalid parameter $param") - propertiesData.add(param as Pair, Any?>) + (param as Pair, Any?>).let { (k, v) -> + propertiesData[k] = v + } } } - ScriptingEnvironment(baseProperties, propertiesData) + ScriptingEnvironment.createOptimized(baseProperties, propertiesData) } private fun KClass.instantiateScriptHandler(): T { 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 8eeeead19b8..f87d63b1dbc 100644 --- a/libraries/scripting/common/src/kotlin/script/experimental/util/propertyBag.kt +++ b/libraries/scripting/common/src/kotlin/script/experimental/util/propertyBag.kt @@ -42,6 +42,7 @@ open class ChainedPropertyBag private constructor(private val parent: ChainedPro companion object { fun createOptimized(parent: ChainedPropertyBag?, data: Map, Any?>): ChainedPropertyBag = when { parent != null && data.isEmpty() -> parent + parent != null && parent.data.isEmpty() -> createOptimized(parent.parent, data) else -> ChainedPropertyBag(parent, data) } } 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 7b43ee35f8f..fe6852950ba 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 @@ -70,7 +70,7 @@ class KJVMCompiledScript( } } -class KJVMCompilerImpl : KJVMCompilerProxy { +class KJVMCompilerImpl(val hostEnvironment: ScriptingEnvironment) : KJVMCompilerProxy { override fun compile( script: ScriptSource, @@ -104,7 +104,7 @@ class KJVMCompilerImpl : KJVMCompilerProxy { val kotlinCompilerConfiguration = org.jetbrains.kotlin.config.CompilerConfiguration().apply { add( JVMConfigurationKeys.SCRIPT_DEFINITIONS, - BridgeScriptDefinition(scriptDefinition, scriptCompileConfiguration, ::updateClasspath) + BridgeScriptDefinition(scriptDefinition, scriptCompileConfiguration, hostEnvironment, ::updateClasspath) ) put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector) put(JVMConfigurationKeys.RETAIN_OUTPUT_IN_MEMORY, true) @@ -238,17 +238,23 @@ class ScriptDiagnosticsMessageCollector : MessageCollector { internal class BridgeScriptDefinition( scriptDefinition: ScriptDefinition, - calculatedBcriptCompilerConfiguration: ScriptCompileConfiguration, + calculatedScriptCompilerConfiguration: ScriptCompileConfiguration, + hostEnvironment: ScriptingEnvironment, updateClasspath: (List) -> Unit -) : KotlinScriptDefinition(calculatedBcriptCompilerConfiguration.getScriptBaseClass(BridgeScriptDefinition::class)) { +) : KotlinScriptDefinition( + hostEnvironment.getScriptingClass( + scriptDefinition.properties[ScriptDefinitionProperties.baseClass], + BridgeScriptDefinition::class + ) +) { override val acceptedAnnotations = run { val cl = this::class.java.classLoader - calculatedBcriptCompilerConfiguration.getOrNull(ScriptCompileConfigurationProperties.refineConfigurationOnAnnotations) + calculatedScriptCompilerConfiguration.getOrNull(ScriptCompileConfigurationProperties.refineConfigurationOnAnnotations) ?.map { (cl.loadClass(it.typeName) as Class).kotlin } ?: emptyList() } override val dependencyResolver: DependenciesResolver = - BridgeDependenciesResolver(scriptDefinition, calculatedBcriptCompilerConfiguration, updateClasspath) + BridgeDependenciesResolver(scriptDefinition, calculatedScriptCompilerConfiguration, updateClasspath) } 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 d96b1ee79a1..a873f468101 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 @@ -24,6 +24,8 @@ abstract class KotlinScriptDefinitionAdapterFromNewAPIBase : KotlinScriptDefinit protected abstract val scriptDefinition: ScriptDefinition + protected abstract val hostEnvironment: ScriptingEnvironment + abstract val scriptFileExtensionWithDot: String open val baseClass: KClass<*> by lazy(LazyThreadSafetyMode.PUBLICATION) { @@ -88,8 +90,8 @@ abstract class KotlinScriptDefinitionAdapterFromNewAPIBase : KotlinScriptDefinit .orEmpty() private val scriptingClassGetter by lazy(LazyThreadSafetyMode.PUBLICATION) { - scriptDefinition.properties.getOrNull(ScriptingEnvironmentProperties.getScriptingClass) - ?: throw IllegalArgumentException("Expecting 'getScriptingClass' property in the scripting environment") + hostEnvironment.getOrNull(ScriptingEnvironmentProperties.getScriptingClass) + ?: throw IllegalArgumentException("Expecting 'getScriptingClass' property in the scripting environment") } private fun getScriptingClass(type: KotlinType) = @@ -102,7 +104,8 @@ abstract class KotlinScriptDefinitionAdapterFromNewAPIBase : KotlinScriptDefinit class KotlinScriptDefinitionAdapterFromNewAPI( - override val scriptDefinition: ScriptDefinition + override val scriptDefinition: ScriptDefinition, + override val hostEnvironment: ScriptingEnvironment ) : KotlinScriptDefinitionAdapterFromNewAPIBase() { override val name: String get() = scriptDefinition.properties.getOrNull(ScriptDefinitionProperties.name) ?: super.name diff --git a/plugins/scripting/scripting-cli/src/org/jetbrains/kotlin/scripting/compiler/plugin/LazyScriptDefinitionFromDiscoveredClass.kt b/plugins/scripting/scripting-cli/src/org/jetbrains/kotlin/scripting/compiler/plugin/LazyScriptDefinitionFromDiscoveredClass.kt index 87b4186999d..df009639fcf 100644 --- a/plugins/scripting/scripting-cli/src/org/jetbrains/kotlin/scripting/compiler/plugin/LazyScriptDefinitionFromDiscoveredClass.kt +++ b/plugins/scripting/scripting-cli/src/org/jetbrains/kotlin/scripting/compiler/plugin/LazyScriptDefinitionFromDiscoveredClass.kt @@ -34,19 +34,20 @@ class LazyScriptDefinitionFromDiscoveredClass internal constructor( messageCollector: MessageCollector ) : this(loadAnnotationsFromClass(classBytes), className, classpath, messageCollector) + override val hostEnvironment: ScriptingEnvironment by lazy(LazyThreadSafetyMode.PUBLICATION) { + ScriptingEnvironment( + ScriptingEnvironmentProperties.configurationDependencies to listOf(JvmDependency(classpath)), + ScriptingEnvironmentProperties.getScriptingClass to JvmGetScriptingClass() + ) + } + override val scriptDefinition: ScriptDefinition by lazy(LazyThreadSafetyMode.PUBLICATION) { messageCollector.report( CompilerMessageSeverity.LOGGING, "Configure scripting: loading script definition class $className using classpath $classpath\n. ${Thread.currentThread().stackTrace}" ) try { - ScriptDefinitionFromAnnotatedBaseClass( - KotlinType(className), - ScriptingEnvironment( - ScriptingEnvironmentProperties.configurationDependencies to listOf(JvmDependency(classpath)), - ScriptingEnvironmentProperties.getScriptingClass to JvmGetScriptingClass() - ) - ) + ScriptDefinitionFromAnnotatedBaseClass(KotlinType(className), hostEnvironment) } catch (ex: ClassNotFoundException) { messageCollector.report(CompilerMessageSeverity.ERROR, "Cannot find script definition class $className") InvalidScriptDefinition diff --git a/plugins/scripting/scripting-cli/src/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptiDefinitionsFromClasspathDiscoverySource.kt b/plugins/scripting/scripting-cli/src/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptiDefinitionsFromClasspathDiscoverySource.kt index 424da2fc479..5e6699acde5 100644 --- a/plugins/scripting/scripting-cli/src/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptiDefinitionsFromClasspathDiscoverySource.kt +++ b/plugins/scripting/scripting-cli/src/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptiDefinitionsFromClasspathDiscoverySource.kt @@ -274,13 +274,15 @@ private fun loadScriptDefinition( val cls = classLoader.loadClass(template) val def = if (cls.annotations.firstIsInstanceOrNull() != null) { + val environment = ScriptingEnvironment( + ScriptingEnvironmentProperties.getScriptingClass to JvmGetScriptingClass() + ) KotlinScriptDefinitionAdapterFromNewAPI( ScriptDefinitionFromAnnotatedBaseClass( KotlinType(cls.kotlin), - ScriptingEnvironment( - ScriptingEnvironmentProperties.getScriptingClass to JvmGetScriptingClass() - ) - ) + environment + ), + environment ) } else { KotlinScriptDefinitionFromAnnotatedTemplate(cls.kotlin, scriptResolverEnv)