diff --git a/compiler/tests/org/jetbrains/kotlin/scripts/ScriptCliCompilationTest.kt b/compiler/tests/org/jetbrains/kotlin/scripts/ScriptCliCompilationTest.kt index f1b01f9a89b..e29303ca021 100644 --- a/compiler/tests/org/jetbrains/kotlin/scripts/ScriptCliCompilationTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/scripts/ScriptCliCompilationTest.kt @@ -30,10 +30,7 @@ import kotlin.script.experimental.host.FileScriptSource import kotlin.script.experimental.host.ScriptingHostConfiguration import kotlin.script.experimental.host.configurationDependencies import kotlin.script.experimental.host.createCompilationConfigurationFromTemplate -import kotlin.script.experimental.jvm.JvmDependency -import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration -import kotlin.script.experimental.jvm.dependenciesFromCurrentContext -import kotlin.script.experimental.jvm.jvm +import kotlin.script.experimental.jvm.* private const val testDataPath = "compiler/testData/script/cliCompilation" @@ -136,7 +133,7 @@ object TestScriptWithRequireConfiguration : ScriptCompilationConfiguration( } ScriptCompilationConfiguration(context.compilationConfiguration) { if (sources?.isNotEmpty() == true) importScripts.append(sources) - if (deps?.isNotEmpty() == true) dependencies.append(JvmDependency(deps)) + if (deps != null) updateClasspath(deps) }.asSuccess() } } 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 c816773b359..b985984f6f1 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 @@ -18,6 +18,7 @@ import kotlin.script.experimental.jvm.compat.mapLegacyDiagnosticSeverity import kotlin.script.experimental.jvm.compat.mapLegacyScriptPosition import kotlin.script.experimental.jvm.dependenciesFromCurrentContext import kotlin.script.experimental.jvm.jvm +import kotlin.script.experimental.jvm.withUpdatedClasspath @KotlinScript( fileExtension = "scriptwithdeps.kts", @@ -66,9 +67,7 @@ fun configureMavenDepsOnAnnotations(context: ScriptConfigurationRefinementContex ?: return context.compilationConfiguration.asSuccess(diagnostics) val resolvedClasspath = newDepsFromResolver.classpath.toList().takeIf { it.isNotEmpty() } ?: return context.compilationConfiguration.asSuccess(diagnostics) - ScriptCompilationConfiguration(context.compilationConfiguration) { - dependencies.append(JvmDependency(resolvedClasspath)) - }.asSuccess(diagnostics) + context.compilationConfiguration.withUpdatedClasspath(resolvedClasspath).asSuccess(diagnostics) } catch (e: Throwable) { ResultWithDiagnostics.Failure(*diagnostics.toTypedArray(), e.asDiagnostics(path = context.script.locationId)) } 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 826c28f6bd7..854b5f1ffb6 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 @@ -51,6 +51,7 @@ import kotlin.script.experimental.jvm.JvmDependency import kotlin.script.experimental.jvm.impl.BridgeDependenciesResolver import kotlin.script.experimental.jvm.jdkHome import kotlin.script.experimental.jvm.jvm +import kotlin.script.experimental.jvm.withUpdatedClasspath import kotlin.script.experimental.jvmhost.KJvmCompilerProxy import kotlin.script.experimental.util.getOrError @@ -79,11 +80,8 @@ class KJvmCompilerImpl(val hostConfiguration: ScriptingHostConfiguration) : KJvm fun updateClasspath(classpath: List) { environment!!.updateClasspath(classpath.map(::JvmClasspathRoot)) - if (classpath.isNotEmpty()) { - updatedConfiguration = ScriptCompilationConfiguration(updatedConfiguration) { - dependencies.append(JvmDependency(classpath)) - } - } + + updatedConfiguration = updatedConfiguration.withUpdatedClasspath(classpath) } val disposable = Disposer.newDisposable() @@ -122,9 +120,7 @@ class KJvmCompilerImpl(val hostConfiguration: ScriptingHostConfiguration) : KJvm add(CLIConfigurationKeys.CONTENT_ROOTS, JvmClasspathRoot(file)) } } - updatedConfiguration = ScriptCompilationConfiguration(updatedConfiguration) { - dependencies.append(JvmDependency(standardLibs.map { it.second })) - } + updatedConfiguration = updatedConfiguration.withUpdatedClasspath(standardLibs.map { it.second }) put(CommonConfigurationKeys.MODULE_NAME, "kotlin-script") // TODO" take meaningful and valid name from somewhere languageVersionSettings = LanguageVersionSettingsImpl( 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 88195f9313e..82932436091 100644 --- a/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/jvmScriptCompilation.kt +++ b/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/jvmScriptCompilation.kt @@ -38,11 +38,42 @@ fun JvmScriptCompilationConfigurationBuilder.dependenciesFromClassloader( classLoader: ClassLoader = Thread.currentThread().contextClassLoader, wholeClasspath: Boolean = false ) { - ScriptCompilationConfiguration.dependencies.append( - JvmDependency(scriptCompilationClasspathFromContext(*libraries, classLoader = classLoader, wholeClasspath = wholeClasspath)) + updateClasspath( + scriptCompilationClasspathFromContext(*libraries, classLoader = classLoader, wholeClasspath = wholeClasspath) ) } +fun ScriptCompilationConfiguration.withUpdatedClasspath(classpath: Collection): ScriptCompilationConfiguration { + + val newClasspath = classpath.filterNewClasspath(this[ScriptCompilationConfiguration.dependencies]) + ?: return this + + return ScriptCompilationConfiguration(this) { + dependencies.append(JvmDependency(newClasspath)) + } +} + +fun ScriptCompilationConfiguration.Builder.updateClasspath(classpath: Collection) = updateClasspathImpl(classpath) + +fun JvmScriptCompilationConfigurationBuilder.updateClasspath(classpath: Collection) = updateClasspathImpl(classpath) + +private fun PropertiesCollection.Builder.updateClasspathImpl(classpath: Collection) { + val newClasspath = classpath.filterNewClasspath(this[ScriptCompilationConfiguration.dependencies]) + ?: return + + ScriptCompilationConfiguration.dependencies.append(JvmDependency(newClasspath)) +} + +private fun Collection.filterNewClasspath(known: Collection?): List? { + + if (isEmpty()) return null + + val knownClasspath = known?.flatMapTo(hashSetOf()) { + (it as? JvmDependency)?.classpath ?: emptyList() + } + return filterNot { knownClasspath?.contains(it) == true }.takeIf { it.isNotEmpty() } +} + @Deprecated("Unused") val JvmScriptCompilationConfigurationKeys.javaHome by PropertiesCollection.keyCopy(ScriptingHostConfiguration.jvm.javaHome) diff --git a/libraries/tools/kotlin-main-kts/src/org/jetbrains/kotlin/mainKts/scriptDef.kt b/libraries/tools/kotlin-main-kts/src/org/jetbrains/kotlin/mainKts/scriptDef.kt index 55da3cb807a..0c822835325 100644 --- a/libraries/tools/kotlin-main-kts/src/org/jetbrains/kotlin/mainKts/scriptDef.kt +++ b/libraries/tools/kotlin-main-kts/src/org/jetbrains/kotlin/mainKts/scriptDef.kt @@ -7,19 +7,19 @@ package org.jetbrains.kotlin.mainKts import org.jetbrains.kotlin.mainKts.impl.FilesAndIvyResolver import org.jetbrains.kotlin.script.util.DependsOn -import org.jetbrains.kotlin.script.util.Repository import org.jetbrains.kotlin.script.util.Import +import org.jetbrains.kotlin.script.util.Repository import java.io.File import kotlin.script.dependencies.ScriptContents import kotlin.script.dependencies.ScriptDependenciesResolver import kotlin.script.experimental.annotations.KotlinScript import kotlin.script.experimental.api.* import kotlin.script.experimental.host.FileScriptSource -import kotlin.script.experimental.jvm.JvmDependency import kotlin.script.experimental.jvm.compat.mapLegacyDiagnosticSeverity import kotlin.script.experimental.jvm.compat.mapLegacyScriptPosition import kotlin.script.experimental.jvm.dependenciesFromClassContext import kotlin.script.experimental.jvm.jvm +import kotlin.script.experimental.jvm.updateClasspath @Suppress("unused") @KotlinScript(fileExtension = "main.kts", compilationConfiguration = MainKtsScriptDefinition::class) @@ -79,7 +79,7 @@ class MainKtsConfigurator : RefineScriptCompilationConfigurationHandler { } return ScriptCompilationConfiguration(context.compilationConfiguration) { - if (resolvedClassPath?.isNotEmpty() == true) dependencies.append(JvmDependency(resolvedClassPath)) + if (resolvedClassPath != null) updateClasspath(resolvedClassPath) if (importedSources.isNotEmpty()) importScripts.append(importedSources) }.asSuccess(diagnostics) }