From 100b908a943b5b31f0b7e863247afb48f94d0012 Mon Sep 17 00:00:00 2001 From: Ilya Chernikov Date: Tue, 17 Jul 2018 13:04:25 +0200 Subject: [PATCH] Add properties builders to the dsl, implement a builder for refineConfiguration --- .../examples/jvm/resolve/maven/scriptDef.kt | 10 ++-- .../script/experimental/api/propertiesDsl.kt | 17 ++++++ .../experimental/api/scriptConfiguration.kt | 2 +- .../experimental/api/scriptDefinition.kt | 52 ++++++++++++++++++- .../jvm/impl/BridgeDependenciesResolver.kt | 2 +- .../experimental/jvm/jvmScriptCompilation.kt | 4 +- 6 files changed, 76 insertions(+), 11 deletions(-) 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 aa20aba1163..a038cce8699 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 @@ -15,11 +15,9 @@ import kotlin.script.dependencies.ScriptDependenciesResolver import kotlin.script.experimental.annotations.KotlinScript import kotlin.script.experimental.annotations.KotlinScriptFileExtension import kotlin.script.experimental.annotations.KotlinScriptProperties -import kotlin.script.experimental.annotations.KotlinScriptPropertiesFromList import kotlin.script.experimental.api.* import kotlin.script.experimental.jvm.* import kotlin.script.experimental.misc.invoke -import kotlin.script.experimental.util.TypedKey @KotlinScript @KotlinScriptFileExtension("scriptwithdeps.kts") @@ -42,13 +40,15 @@ object MyConfiguration : ScriptingProperties() { ) ) ) - refineConfiguration(MyConfigurator()) - refineConfigurationOnAnnotations(DependsOn::class, Repository::class) + refineConfiguration { + handler(MyConfigurator()) + onAnnotations(DependsOn::class, Repository::class) + } } } } -class MyConfigurator : RefineScriptCompilationConfiguration { +class MyConfigurator : RefineScriptCompilationConfigurationHandler { private val resolver = FilesAndMavenResolver() diff --git a/libraries/scripting/common/src/kotlin/script/experimental/api/propertiesDsl.kt b/libraries/scripting/common/src/kotlin/script/experimental/api/propertiesDsl.kt index 7b70a98f868..672b25ced1c 100644 --- a/libraries/scripting/common/src/kotlin/script/experimental/api/propertiesDsl.kt +++ b/libraries/scripting/common/src/kotlin/script/experimental/api/propertiesDsl.kt @@ -6,12 +6,23 @@ package kotlin.script.experimental.api import kotlin.reflect.KClass +import kotlin.reflect.KProperty import kotlin.reflect.KType import kotlin.script.experimental.util.ChainedPropertyBag import kotlin.script.experimental.util.TypedKey interface PropertiesGroup + +open class PropertiesBuilder(val props: ScriptingProperties) + +class PropertiesBuilderDelegate(val kclass: KClass) { + operator fun getValue(thisRef: Any?, property: KProperty<*>): KClass = kclass +} + +inline fun propertiesBuilder() = PropertiesBuilderDelegate(T::class) + + open class ScriptingProperties(body: ScriptingProperties.() -> Unit = {}) { var parentPropertiesBag: ChainedPropertyBag? = null @@ -35,6 +46,12 @@ open class ScriptingProperties(body: ScriptingProperties.() -> Unit = {}) { inline operator fun T.invoke(body: T.() -> Unit) = body() + // generic invoke for properties builder - for extending dsl with complex builders + + inline operator fun KClass.invoke(body: T.() -> Unit) { + constructors.first().call(this@ScriptingProperties).body() + } + // chaining: private fun chain(propsBag: ChainedPropertyBag?, propsBuilder: ScriptingProperties?, replaceParent: Boolean) { 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 e5f0aa2f350..92f6d2b7542 100644 --- a/libraries/scripting/common/src/kotlin/script/experimental/api/scriptConfiguration.kt +++ b/libraries/scripting/common/src/kotlin/script/experimental/api/scriptConfiguration.kt @@ -25,7 +25,7 @@ object ProcessedScriptDataProperties : PropertiesGroup { val foundFragments by typedKey>() } -interface RefineScriptCompilationConfiguration { +interface RefineScriptCompilationConfigurationHandler { suspend operator fun invoke( scriptSource: ScriptSource, configuration: ScriptCompileConfiguration, 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 c17cc0deb41..95a32ef53ba 100644 --- a/libraries/scripting/common/src/kotlin/script/experimental/api/scriptDefinition.kt +++ b/libraries/scripting/common/src/kotlin/script/experimental/api/scriptDefinition.kt @@ -7,6 +7,7 @@ package kotlin.script.experimental.api +import kotlin.reflect.KClass import kotlin.script.experimental.util.ChainedPropertyBag import kotlin.script.experimental.util.typedKey @@ -40,12 +41,59 @@ object ScriptDefinitionProperties : PropertiesGroup { val compilerOptions by typedKey>() // Q: CommonCompilerOptions instead? - val refineConfiguration by typedKey() // dynamic configurator + val refineConfigurationHandler by typedKey() // dynamic configurator - val refineBeforeParsing by typedKey() // default: false + val refineConfigurationBeforeParsing by typedKey() // default: false val refineConfigurationOnAnnotations by typedKey>() val refineConfigurationOnSections by typedKey>() + + // DSL: + + val refineConfiguration by propertiesBuilder() +} + +// DSL -------------------- + + +@Suppress("MemberVisibilityCanBePrivate") +class RefineConfigurationBuilder(props: ScriptingProperties) : PropertiesBuilder(props) { + + inline operator fun invoke(body: RefineConfigurationBuilder.() -> Unit) { + body() + } + + fun handler(fn: RefineScriptCompilationConfigurationHandler) { + props.data[ScriptDefinitionProperties.refineConfigurationHandler] = fn + } + + fun beforeParsing(value: Boolean = true) { + props.data[ScriptDefinitionProperties.refineConfigurationBeforeParsing] = value + } + + fun onAnnotations(annotations: Iterable) { + props.data.addToListProperty(ScriptDefinitionProperties.refineConfigurationOnAnnotations, annotations) + } + + fun onAnnotations(vararg annotations: KotlinType) { + onAnnotations(annotations.asIterable()) + } + + inline fun onAnnotations() { + onAnnotations(KotlinType(T::class)) + } + + fun onAnnotations(vararg annotations: KClass) { + onAnnotations(annotations.map { KotlinType(it) }) + } + + fun onSections(sections: Iterable) { + props.data.addToListProperty(ScriptDefinitionProperties.refineConfigurationOnSections, sections) + } + + fun onSections(vararg sections: String) { + props.data.addToListProperty(ScriptDefinitionProperties.refineConfigurationOnSections, *sections) + } } diff --git a/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/impl/BridgeDependenciesResolver.kt b/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/impl/BridgeDependenciesResolver.kt index 9cc5394456c..a10c4a0849e 100644 --- a/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/impl/BridgeDependenciesResolver.kt +++ b/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/impl/BridgeDependenciesResolver.kt @@ -37,7 +37,7 @@ class BridgeDependenciesResolver( val processedScriptData = ProcessedScriptData(ProcessedScriptDataProperties.foundAnnotations to scriptContents.annotations) - val refineFn = scriptDefinition.getOrNull(ScriptDefinitionProperties.refineConfiguration) + val refineFn = scriptDefinition.getOrNull(ScriptDefinitionProperties.refineConfigurationHandler) val refinedConfiguration = if (refineFn == null) calculatedBaseScriptCompilerConfiguration else { 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 ecaa8d47782..08b445eb50e 100644 --- a/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/jvmScriptCompilation.kt +++ b/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/jvmScriptCompilation.kt @@ -21,9 +21,9 @@ open class JvmScriptCompiler( additionalConfiguration: ScriptCompileConfiguration? ): ResultWithDiagnostics> { val baseConfiguration = chainPropertyBags(additionalConfiguration, scriptDefinition) - val refineConfigurationFn = baseConfiguration.getOrNull(ScriptDefinitionProperties.refineConfiguration) + val refineConfigurationFn = baseConfiguration.getOrNull(ScriptDefinitionProperties.refineConfigurationHandler) val refinedConfiguration = - if (baseConfiguration.getOrNull(ScriptDefinitionProperties.refineBeforeParsing) == true) { + if (baseConfiguration.getOrNull(ScriptDefinitionProperties.refineConfigurationBeforeParsing) == true) { if (refineConfigurationFn == null) { return ResultWithDiagnostics.Failure("Non-null configurator expected".asErrorDiagnostics()) }