Add generic properties builder dsl, convert maven example to it
This commit is contained in:
+12
-13
@@ -14,26 +14,25 @@ import kotlin.script.dependencies.ScriptContents
|
|||||||
import kotlin.script.dependencies.ScriptDependenciesResolver
|
import kotlin.script.dependencies.ScriptDependenciesResolver
|
||||||
import kotlin.script.experimental.annotations.KotlinScript
|
import kotlin.script.experimental.annotations.KotlinScript
|
||||||
import kotlin.script.experimental.annotations.KotlinScriptFileExtension
|
import kotlin.script.experimental.annotations.KotlinScriptFileExtension
|
||||||
|
import kotlin.script.experimental.annotations.KotlinScriptProperties
|
||||||
import kotlin.script.experimental.annotations.KotlinScriptPropertiesFromList
|
import kotlin.script.experimental.annotations.KotlinScriptPropertiesFromList
|
||||||
import kotlin.script.experimental.api.*
|
import kotlin.script.experimental.api.*
|
||||||
import kotlin.script.experimental.jvm.JvmDependency
|
import kotlin.script.experimental.jvm.*
|
||||||
import kotlin.script.experimental.jvm.jvmJavaHomeParams
|
|
||||||
import kotlin.script.experimental.jvm.mapLegacyDiagnosticSeverity
|
|
||||||
import kotlin.script.experimental.jvm.mapLegacyScriptPosition
|
|
||||||
import kotlin.script.experimental.misc.invoke
|
import kotlin.script.experimental.misc.invoke
|
||||||
import kotlin.script.experimental.util.TypedKey
|
import kotlin.script.experimental.util.TypedKey
|
||||||
|
|
||||||
@KotlinScript
|
@KotlinScript
|
||||||
@KotlinScriptFileExtension("scriptwithdeps.kts")
|
@KotlinScriptFileExtension("scriptwithdeps.kts")
|
||||||
@KotlinScriptPropertiesFromList(MyConfiguration::class)
|
@KotlinScriptProperties(MyConfiguration::class)
|
||||||
abstract class MyScriptWithMavenDeps {
|
abstract class MyScriptWithMavenDeps {
|
||||||
// abstract fun body(vararg args: String): Int
|
// abstract fun body(vararg args: String): Int
|
||||||
}
|
}
|
||||||
|
|
||||||
object MyConfiguration : ArrayList<Pair<TypedKey<*>, Any?>>(
|
object MyConfiguration : ScriptingProperties() {
|
||||||
jvmJavaHomeParams + with(ScriptDefinitionProperties) {
|
init {
|
||||||
listOf(
|
include(jvmJavaHomeScriptingProperties)
|
||||||
defaultImports(DependsOn::class.qualifiedName!!, Repository::class.qualifiedName!!),
|
ScriptDefinitionProperties {
|
||||||
|
defaultImports(DependsOn::class.qualifiedName!!, Repository::class.qualifiedName!!)
|
||||||
dependencies(
|
dependencies(
|
||||||
JvmDependency(
|
JvmDependency(
|
||||||
scriptCompilationClasspathFromContext(
|
scriptCompilationClasspathFromContext(
|
||||||
@@ -41,12 +40,12 @@ object MyConfiguration : ArrayList<Pair<TypedKey<*>, Any?>>(
|
|||||||
"kotlin-script-util" // DependsOn annotation is taken from script-util
|
"kotlin-script-util" // DependsOn annotation is taken from script-util
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
),
|
)
|
||||||
refineConfiguration(MyConfigurator()),
|
refineConfiguration(MyConfigurator())
|
||||||
refineConfigurationOnAnnotations(DependsOn::class, Repository::class)
|
refineConfigurationOnAnnotations(DependsOn::class, Repository::class)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
class MyConfigurator : RefineScriptCompilationConfiguration {
|
class MyConfigurator : RefineScriptCompilationConfiguration {
|
||||||
|
|
||||||
|
|||||||
+8
@@ -13,6 +13,7 @@
|
|||||||
package kotlin.script.experimental.annotations
|
package kotlin.script.experimental.annotations
|
||||||
|
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
import kotlin.script.experimental.api.ScriptingProperties
|
||||||
|
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
@Retention(AnnotationRetention.RUNTIME)
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
@@ -28,6 +29,13 @@ annotation class KotlinScriptFileExtension(
|
|||||||
|
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
@Retention(AnnotationRetention.RUNTIME)
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
@Deprecated("Use KotlinScriptProperties", replaceWith = ReplaceWith("KotlinScriptProperties"))
|
||||||
annotation class KotlinScriptPropertiesFromList(
|
annotation class KotlinScriptPropertiesFromList(
|
||||||
val definitionProperties: KClass<out List<*>> // object or class filled in 0-ary constructor
|
val definitionProperties: KClass<out List<*>> // object or class filled in 0-ary constructor
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
annotation class KotlinScriptProperties(
|
||||||
|
val definitionProperties: KClass<out ScriptingProperties> // object or class filled in 0-ary constructor
|
||||||
|
)
|
||||||
|
|||||||
@@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kotlin.script.experimental.api
|
||||||
|
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
import kotlin.reflect.KType
|
||||||
|
import kotlin.script.experimental.util.ChainedPropertyBag
|
||||||
|
import kotlin.script.experimental.util.TypedKey
|
||||||
|
|
||||||
|
interface PropertiesGroup
|
||||||
|
|
||||||
|
open class ScriptingProperties(body: ScriptingProperties.() -> Unit = {}) {
|
||||||
|
|
||||||
|
var parentPropertiesBag: ChainedPropertyBag? = null
|
||||||
|
var parentPropertiesBuilder: ScriptingProperties? = null
|
||||||
|
val data = HashMap<TypedKey<*>, Any?>()
|
||||||
|
|
||||||
|
init {
|
||||||
|
body()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun makePropertyBag(): ChainedPropertyBag =
|
||||||
|
ChainedPropertyBag.createOptimized(parentPropertiesBag ?: parentPropertiesBuilder?.makePropertyBag(), data)
|
||||||
|
|
||||||
|
// generic invoke for properties groups
|
||||||
|
inline operator fun <T : PropertiesGroup> T.invoke(body: T.() -> Unit) = body()
|
||||||
|
|
||||||
|
// chaining
|
||||||
|
|
||||||
|
private fun chain(propsBag: ChainedPropertyBag?, propsBuilder: ScriptingProperties?, replaceParent: Boolean) {
|
||||||
|
assert(propsBag == null || propsBuilder == null)
|
||||||
|
if (!replaceParent && parentPropertiesBag != null || parentPropertiesBuilder != null)
|
||||||
|
throw RuntimeException("Parent already defined for properties being build: ${parentPropertiesBag ?: parentPropertiesBuilder}")
|
||||||
|
parentPropertiesBag = propsBag
|
||||||
|
parentPropertiesBuilder = propsBuilder
|
||||||
|
}
|
||||||
|
|
||||||
|
fun chain(props: ScriptingProperties, replaceParent: Boolean = false) {
|
||||||
|
chain(null, props, replaceParent)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun chain(props: ChainedPropertyBag, replaceParent: Boolean = false) {
|
||||||
|
chain(props, null, replaceParent)
|
||||||
|
}
|
||||||
|
|
||||||
|
// inclusion
|
||||||
|
|
||||||
|
fun include(props: ScriptingProperties) {
|
||||||
|
data.putAll(props.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun include(props: ChainedPropertyBag) {
|
||||||
|
data.putAll(props.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// builders for known property types:
|
||||||
|
|
||||||
|
inline operator fun <reified T> TypedKey<T>.invoke(v: T) {
|
||||||
|
data[this] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
inline operator fun <reified K> TypedKey<KotlinType>.invoke() {
|
||||||
|
data[this] = KotlinType(K::class)
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun TypedKey<KotlinType>.invoke(kclass: KClass<*>) {
|
||||||
|
data[this] = KotlinType(kclass)
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun TypedKey<KotlinType>.invoke(ktype: KType) {
|
||||||
|
data[this] = KotlinType(ktype)
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun TypedKey<KotlinType>.invoke(fqname: String) {
|
||||||
|
data[this] = KotlinType(fqname)
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun TypedKey<List<KotlinType>>.invoke(vararg classes: KClass<*>) {
|
||||||
|
data[this] = classes.map { KotlinType(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun TypedKey<List<KotlinType>>.invoke(vararg types: KType) {
|
||||||
|
data[this] = types.map { KotlinType(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun TypedKey<List<KotlinType>>.invoke(vararg fqnames: String) {
|
||||||
|
data[this] = fqnames.map { KotlinType(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
inline operator fun <reified E> TypedKey<List<E>>.invoke(vararg vs: E) {
|
||||||
|
data[this] = vs.toList()
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmName("invoke_kotlintype_map_from_kclass")
|
||||||
|
inline operator fun <reified K> TypedKey<Map<K, KotlinType>>.invoke(vararg classes: Pair<K, KClass<*>>) {
|
||||||
|
data[this] = HashMap<K, KotlinType>().also { it.putAll(classes.asSequence().map { (k, v) -> k to KotlinType(v) }) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmName("invoke_kotlintype_map_from_ktype")
|
||||||
|
inline operator fun <reified K> TypedKey<Map<K, KotlinType>>.invoke(vararg types: Pair<K, KType>) {
|
||||||
|
data[this] = HashMap<K, KotlinType>().also { it.putAll(types.asSequence().map { (k, v) -> k to KotlinType(v) }) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmName("invoke_kotlintype_map_from_fqname")
|
||||||
|
inline operator fun <reified K> TypedKey<Map<K, KotlinType>>.invoke(vararg fqnames: Pair<K, String>) {
|
||||||
|
data[this] = HashMap<K, KotlinType>().also { it.putAll(fqnames.asSequence().map { (k, v) -> k to KotlinType(v) }) }
|
||||||
|
}
|
||||||
|
|
||||||
|
inline operator fun <reified K, reified V> TypedKey<Map<K, V>>.invoke(vararg vs: Pair<K, V>) {
|
||||||
|
data[this] = hashMapOf(*vs)
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-2
@@ -12,14 +12,14 @@ import kotlin.script.experimental.util.typedKey
|
|||||||
|
|
||||||
typealias ScriptCompileConfiguration = ChainedPropertyBag
|
typealias ScriptCompileConfiguration = ChainedPropertyBag
|
||||||
|
|
||||||
object ScriptCompileConfigurationProperties {
|
object ScriptCompileConfigurationProperties : PropertiesGroup {
|
||||||
|
|
||||||
val sourceFragments by typedKey<List<ScriptSourceNamedFragment>>()
|
val sourceFragments by typedKey<List<ScriptSourceNamedFragment>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
typealias ProcessedScriptData = ChainedPropertyBag
|
typealias ProcessedScriptData = ChainedPropertyBag
|
||||||
|
|
||||||
object ProcessedScriptDataProperties {
|
object ProcessedScriptDataProperties : PropertiesGroup {
|
||||||
val foundAnnotations by typedKey<List<Annotation>>()
|
val foundAnnotations by typedKey<List<Annotation>>()
|
||||||
|
|
||||||
val foundFragments by typedKey<List<ScriptSourceNamedFragment>>()
|
val foundFragments by typedKey<List<ScriptSourceNamedFragment>>()
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import kotlin.script.experimental.util.typedKey
|
|||||||
|
|
||||||
typealias ScriptDefinition = ChainedPropertyBag
|
typealias ScriptDefinition = ChainedPropertyBag
|
||||||
|
|
||||||
object ScriptDefinitionProperties {
|
object ScriptDefinitionProperties : PropertiesGroup {
|
||||||
|
|
||||||
val name by typedKey<String>() // Name of the script type, by default "Kotlin script"
|
val name by typedKey<String>() // Name of the script type, by default "Kotlin script"
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@ import kotlin.script.experimental.util.typedKey
|
|||||||
|
|
||||||
typealias ScriptingEnvironment = ChainedPropertyBag
|
typealias ScriptingEnvironment = ChainedPropertyBag
|
||||||
|
|
||||||
object ScriptingEnvironmentProperties {
|
object ScriptingEnvironmentProperties : PropertiesGroup {
|
||||||
|
|
||||||
// should contain all dependencies needed for baseClass and compilationConfigurator
|
// should contain all dependencies needed for baseClass and compilationConfigurator
|
||||||
val configurationDependencies by typedKey<List<ScriptDependency>>()
|
val configurationDependencies by typedKey<List<ScriptDependency>>()
|
||||||
|
|||||||
+10
@@ -10,6 +10,7 @@ import kotlin.reflect.full.createInstance
|
|||||||
import kotlin.reflect.full.findAnnotation
|
import kotlin.reflect.full.findAnnotation
|
||||||
import kotlin.script.experimental.annotations.KotlinScript
|
import kotlin.script.experimental.annotations.KotlinScript
|
||||||
import kotlin.script.experimental.annotations.KotlinScriptFileExtension
|
import kotlin.script.experimental.annotations.KotlinScriptFileExtension
|
||||||
|
import kotlin.script.experimental.annotations.KotlinScriptProperties
|
||||||
import kotlin.script.experimental.annotations.KotlinScriptPropertiesFromList
|
import kotlin.script.experimental.annotations.KotlinScriptPropertiesFromList
|
||||||
import kotlin.script.experimental.api.*
|
import kotlin.script.experimental.api.*
|
||||||
import kotlin.script.experimental.util.TypedKey
|
import kotlin.script.experimental.util.TypedKey
|
||||||
@@ -57,6 +58,15 @@ fun createScriptDefinitionFromAnnotatedBaseClass(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
baseClass.annotations.filterIsInstance(KotlinScriptProperties::class.java).forEach { ann ->
|
||||||
|
val params = try {
|
||||||
|
ann.definitionProperties.objectInstance ?: ann.definitionProperties.createInstance()
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
throw IllegalArgumentException(ILLEGAL_CONFIG_ANN_ARG, e)
|
||||||
|
}
|
||||||
|
propertiesData.putAll(params.data)
|
||||||
|
// TODO: chaining is lost here, fix it
|
||||||
|
}
|
||||||
return ScriptingEnvironment.createOptimized(null, propertiesData)
|
return ScriptingEnvironment.createOptimized(null, propertiesData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class TypedKeyDelegate<T>(val defaultValue: T? = null) {
|
|||||||
|
|
||||||
fun <T> typedKey(defaultValue: T? = null) = TypedKeyDelegate(defaultValue)
|
fun <T> typedKey(defaultValue: T? = null) = TypedKeyDelegate(defaultValue)
|
||||||
|
|
||||||
open class ChainedPropertyBag private constructor(private val parent: ChainedPropertyBag?, private val data: Map<TypedKey<*>, Any?>) {
|
open class ChainedPropertyBag internal constructor(private val parent: ChainedPropertyBag?, internal val data: Map<TypedKey<*>, Any?>) {
|
||||||
constructor(parent: ChainedPropertyBag? = null, pairs: Iterable<Pair<TypedKey<*>, Any?>>) :
|
constructor(parent: ChainedPropertyBag? = null, pairs: Iterable<Pair<TypedKey<*>, Any?>>) :
|
||||||
this(parent, HashMap<TypedKey<*>, Any?>().also { it.putAll(pairs) })
|
this(parent, HashMap<TypedKey<*>, Any?>().also { it.putAll(pairs) })
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,13 @@
|
|||||||
package kotlin.script.experimental.jvm
|
package kotlin.script.experimental.jvm
|
||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import kotlin.script.experimental.api.ScriptingProperties
|
||||||
|
|
||||||
val jvmJavaHomeParams = with(JvmScriptCompileConfigurationProperties) {
|
val jvmJavaHomeParams = with(JvmScriptCompileConfigurationProperties) {
|
||||||
listOf(javaHomeDir to File(System.getProperty("java.home")))
|
listOf(javaHomeDir to File(System.getProperty("java.home")))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object jvmJavaHomeScriptingProperties : ScriptingProperties(
|
||||||
|
{
|
||||||
|
JvmScriptCompileConfigurationProperties.javaHomeDir(File(System.getProperty("java.home")))
|
||||||
|
})
|
||||||
|
|||||||
@@ -8,10 +8,11 @@
|
|||||||
package kotlin.script.experimental.jvm
|
package kotlin.script.experimental.jvm
|
||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import kotlin.script.experimental.api.PropertiesGroup
|
||||||
import kotlin.script.experimental.api.ScriptDependency
|
import kotlin.script.experimental.api.ScriptDependency
|
||||||
import kotlin.script.experimental.util.typedKey
|
import kotlin.script.experimental.util.typedKey
|
||||||
|
|
||||||
object JvmScriptCompileConfigurationProperties {
|
object JvmScriptCompileConfigurationProperties : PropertiesGroup {
|
||||||
val javaHomeDir by typedKey<File>()
|
val javaHomeDir by typedKey<File>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user