Grand refactoring of the scripting DSL + many minor usability refactorings around it

This commit is contained in:
Ilya Chernikov
2018-07-30 17:55:13 +02:00
parent 45eaca1290
commit 74f8a541c0
41 changed files with 655 additions and 619 deletions
@@ -18,10 +18,12 @@ import kotlin.script.experimental.host.toScriptSource
import kotlin.script.experimental.jvm.JvmDependency
import kotlin.script.experimental.jvm.compat.mapToLegacyScriptReportPosition
import kotlin.script.experimental.jvm.compat.mapToLegacyScriptReportSeverity
import kotlin.script.experimental.util.getFirstFromChainOrNull
import kotlin.script.experimental.util.getOrNull
class BridgeDependenciesResolver(
val scriptDefinition: ScriptDefinition,
val calculatedBaseScriptCompilerConfiguration: ScriptCompileConfiguration,
private val additionalConfiguration: ScriptCompileConfiguration?,
val onClasspathUpdated: (List<File>) -> Unit = {}
) : AsyncDependenciesResolver {
@@ -34,14 +36,19 @@ class BridgeDependenciesResolver(
return try {
val diagnostics = arrayListOf<ScriptReport>()
val processedScriptData =
ProcessedScriptData(ProcessedScriptDataProperties.foundAnnotations to scriptContents.annotations)
val processedScriptData = object : ProcessedScriptData {
override val properties = properties {
foundAnnotations.append(scriptContents.annotations)
}
}
val refineFn = scriptDefinition.getOrNull(ScriptDefinitionProperties.refineConfigurationHandler)
val refineFn = scriptDefinition.getOrNull(ScriptDefinition.refineConfigurationHandler)
val refinedConfiguration =
if (refineFn == null) calculatedBaseScriptCompilerConfiguration
if (refineFn == null) null
else {
val res = refineFn(scriptContents.toScriptSource(), calculatedBaseScriptCompilerConfiguration, processedScriptData)
val res = refineFn(
scriptContents.toScriptSource(), scriptDefinition, additionalConfiguration, processedScriptData
)
when (res) {
is ResultWithDiagnostics.Failure ->
return@resolveAsync DependenciesResolver.ResolveResult.Failure(res.reports.mapScriptReportsToDiagnostics())
@@ -52,11 +59,12 @@ class BridgeDependenciesResolver(
}
}
val newClasspath = refinedConfiguration.getOrNull(ScriptDefinitionProperties.dependencies)
val newClasspath = refinedConfiguration?.getOrNull(ScriptDefinition.dependencies)
?.flatMap { (it as JvmDependency).classpath } ?: emptyList()
if (refinedConfiguration != calculatedBaseScriptCompilerConfiguration) {
val oldClasspath = calculatedBaseScriptCompilerConfiguration.getOrNull(ScriptDefinitionProperties.dependencies)
?.flatMap { (it as JvmDependency).classpath } ?: emptyList()
if (newClasspath.isNotEmpty()) {
val oldClasspath =
getFirstFromChainOrNull(ScriptDefinition.dependencies, additionalConfiguration, scriptDefinition)
?.flatMap { (it as JvmDependency).classpath } ?: emptyList()
if (newClasspath != oldClasspath) {
onClasspathUpdated(newClasspath)
}
@@ -64,8 +72,9 @@ class BridgeDependenciesResolver(
DependenciesResolver.ResolveResult.Success(
ScriptDependencies(
classpath = newClasspath, // TODO: maybe it should return only increment from the initial config
imports = refinedConfiguration.getOrNull(ScriptDefinitionProperties.defaultImports)?.toList()
?: emptyList()
imports = getFirstFromChainOrNull(
ScriptDefinition.defaultImports, refinedConfiguration, additionalConfiguration, scriptDefinition
)?.toList() ?: emptyList()
),
diagnostics
)
@@ -7,13 +7,14 @@
package kotlin.script.experimental.jvm
import java.io.File
import kotlin.script.experimental.api.PropertiesGroup
import kotlin.script.experimental.api.ScriptingProperties
import kotlin.script.experimental.util.typedKey
import kotlin.script.experimental.api.ScriptCompileConfiguration
import kotlin.script.experimental.util.PropertiesCollection
object JvmScriptCompileConfigurationProperties : PropertiesGroup {
val javaHomeDir by typedKey<File>(File(System.getProperty("java.home")))
open class JvmScriptCompilationConfiguration : JvmScriptDefinition() {
companion object : JvmScriptCompilationConfiguration()
}
val ScriptingProperties.jvmCompileConfiguration get() = JvmScriptCompileConfigurationProperties
val JvmScriptCompilationConfiguration.javaHome by PropertiesCollection.keyCopy(JvmScriptingEnvironment.javaHome)
val ScriptCompileConfiguration.jvm get() = JvmScriptCompilationConfiguration()
@@ -7,26 +7,33 @@ package kotlin.script.experimental.jvm
import org.jetbrains.kotlin.script.util.scriptCompilationClasspathFromContext
import java.io.File
import kotlin.script.experimental.api.ScriptDefinitionProperties
import kotlin.script.experimental.api.ScriptDefinition
import kotlin.script.experimental.api.ScriptDependency
import kotlin.script.experimental.api.ScriptingProperties
import kotlin.script.experimental.api.addToListProperty
import kotlin.script.experimental.api.dependencies
import kotlin.script.experimental.util.PropertiesCollection
open class JvmScriptDefinition : PropertiesCollection.Builder() {
companion object : JvmScriptDefinition()
}
val ScriptDefinition.jvm get() = JvmScriptDefinition()
class JvmDependency(val classpath: List<File>) : ScriptDependency {
constructor(vararg classpathEntries: File) : this(classpathEntries.asList())
}
fun ScriptingProperties.jvmDependenciesFromCurrentContext(vararg libraries: String, wholeClasspath: Boolean = false) {
jvmDependenciesFromClassloader(*libraries, wholeClasspath = wholeClasspath)
fun JvmScriptDefinition.dependenciesFromCurrentContext(vararg libraries: String, wholeClasspath: Boolean = false) {
dependenciesFromClassloader(*libraries, wholeClasspath = wholeClasspath)
}
fun ScriptingProperties.jvmDependenciesFromClassloader(
fun JvmScriptDefinition.dependenciesFromClassloader(
vararg libraries: String,
classLoader: ClassLoader = Thread.currentThread().contextClassLoader,
wholeClasspath: Boolean = false
) {
data.addToListProperty(
ScriptDefinitionProperties.dependencies,
ScriptDefinition.dependencies.append(
JvmDependency(scriptCompilationClasspathFromContext(*libraries, classLoader = classLoader, wholeClasspath = wholeClasspath))
)
}
@@ -5,18 +5,24 @@
package kotlin.script.experimental.jvm
import java.io.File
import java.net.URLClassLoader
import kotlin.reflect.KClass
import kotlin.script.experimental.api.*
import kotlin.script.experimental.util.PropertiesCollection
import kotlin.script.experimental.util.getOrNull
private object DefaultJvmScriptingEnvironmentPropertiesBuilder : ScriptingProperties() {
init {
ScriptingEnvironmentProperties.getScriptingClass(JvmGetScriptingClass())
}
open class JvmScriptingEnvironment : PropertiesCollection.Builder() {
companion object : JvmScriptingEnvironment()
}
val defaultJvmScriptingEnvironment = DefaultJvmScriptingEnvironmentPropertiesBuilder.build()
val JvmScriptingEnvironment.javaHome by PropertiesCollection.key<File>(File(System.getProperty("java.home")))
val ScriptingEnvironment.jvm get() = JvmScriptingEnvironment()
val defaultJvmScriptingEnvironment = ScriptingEnvironment.create {
getScriptingClass(JvmGetScriptingClass())
}
class JvmGetScriptingClass : GetScriptingClass {
@@ -37,7 +43,7 @@ class JvmGetScriptingClass : GetScriptingClass {
if (actualClassLoadersChain.any { it == fromClass.java.classLoader }) return fromClass
}
val newDeps = environment.getOrNull(ScriptingEnvironmentProperties.configurationDependencies)
val newDeps = environment.getOrNull(ScriptingEnvironment.configurationDependencies)
if (dependencies == null) {
dependencies = newDeps
} else {
@@ -55,10 +61,10 @@ class JvmGetScriptingClass : GetScriptingClass {
// }
if (classLoader == null) {
val classpath = dependencies?.flatMap {
when(it) {
is JvmDependency -> it.classpath.map { it.toURI().toURL() }
else -> throw IllegalArgumentException("unknown dependency type $it")
val classpath = dependencies?.flatMap { dependency ->
when(dependency) {
is JvmDependency -> dependency.classpath.map { it.toURI().toURL() }
else -> throw IllegalArgumentException("unknown dependency type $dependency")
}
}
classLoader =