Implement and use helpers for economical classpath update in script configs

This commit is contained in:
Ilya Chernikov
2019-01-15 17:48:16 +01:00
parent c7e5ad861c
commit 2bb5e8f51f
5 changed files with 44 additions and 21 deletions
@@ -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()
}
}
@@ -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))
}
@@ -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<File>) {
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(
@@ -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<File>): ScriptCompilationConfiguration {
val newClasspath = classpath.filterNewClasspath(this[ScriptCompilationConfiguration.dependencies])
?: return this
return ScriptCompilationConfiguration(this) {
dependencies.append(JvmDependency(newClasspath))
}
}
fun ScriptCompilationConfiguration.Builder.updateClasspath(classpath: Collection<File>) = updateClasspathImpl(classpath)
fun JvmScriptCompilationConfigurationBuilder.updateClasspath(classpath: Collection<File>) = updateClasspathImpl(classpath)
private fun PropertiesCollection.Builder.updateClasspathImpl(classpath: Collection<File>) {
val newClasspath = classpath.filterNewClasspath(this[ScriptCompilationConfiguration.dependencies])
?: return
ScriptCompilationConfiguration.dependencies.append(JvmDependency(newClasspath))
}
private fun Collection<File>.filterNewClasspath(known: Collection<ScriptDependency>?): List<File>? {
if (isEmpty()) return null
val knownClasspath = known?.flatMapTo(hashSetOf<File>()) {
(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)
@@ -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)
}