Refactoring properties collection after review
This commit is contained in:
+29
-22
@@ -9,45 +9,52 @@ package kotlin.script.experimental.api
|
||||
|
||||
import kotlin.script.experimental.util.PropertiesCollection
|
||||
|
||||
interface ScriptCompileConfiguration : PropertiesCollection {
|
||||
interface ScriptCompileConfigurationKeys
|
||||
|
||||
class ScriptCompileConfiguration(baseConfigurations: Iterable<ScriptCompileConfiguration>, body: Builder.() -> Unit) :
|
||||
PropertiesCollection(Builder(baseConfigurations).apply(body).data) {
|
||||
|
||||
constructor(body: Builder.() -> Unit = {}) : this(emptyList(), body)
|
||||
constructor(
|
||||
vararg baseConfigurations: ScriptCompileConfiguration, body: Builder.() -> Unit = {}
|
||||
) : this(baseConfigurations.asIterable(), body)
|
||||
|
||||
class Builder internal constructor(baseConfigurations: Iterable<ScriptCompileConfiguration>) :
|
||||
ScriptCompileConfigurationKeys,
|
||||
PropertiesCollection.Builder(baseConfigurations)
|
||||
|
||||
companion object : ScriptCompileConfiguration {
|
||||
|
||||
class Builder internal constructor() : PropertiesCollection.Builder(), ScriptCompileConfiguration {
|
||||
override val properties = data
|
||||
}
|
||||
|
||||
fun create(body: Builder.() -> Unit): ScriptCompileConfiguration = Builder().apply(body)
|
||||
}
|
||||
companion object : ScriptCompileConfigurationKeys
|
||||
}
|
||||
|
||||
val ScriptCompileConfiguration.sourceFragments by PropertiesCollection.key<List<ScriptSourceNamedFragment>>()
|
||||
val ScriptCompileConfigurationKeys.sourceFragments by PropertiesCollection.key<List<ScriptSourceNamedFragment>>()
|
||||
|
||||
val ScriptCompileConfiguration.scriptBodyTarget by PropertiesCollection.keyCopy(ScriptDefinition.scriptBodyTarget)
|
||||
val ScriptCompileConfigurationKeys.scriptBodyTarget by PropertiesCollection.keyCopy(ScriptDefinition.scriptBodyTarget)
|
||||
|
||||
val ScriptCompileConfiguration.scriptImplicitReceivers by PropertiesCollection.keyCopy(ScriptDefinition.scriptImplicitReceivers)
|
||||
val ScriptCompileConfigurationKeys.scriptImplicitReceivers by PropertiesCollection.keyCopy(ScriptDefinition.scriptImplicitReceivers)
|
||||
|
||||
val ScriptCompileConfiguration.contextVariables by PropertiesCollection.keyCopy(ScriptDefinition.contextVariables)
|
||||
val ScriptCompileConfigurationKeys.contextVariables by PropertiesCollection.keyCopy(ScriptDefinition.contextVariables)
|
||||
|
||||
val ScriptCompileConfiguration.defaultImports by PropertiesCollection.keyCopy(ScriptDefinition.defaultImports)
|
||||
val ScriptCompileConfigurationKeys.defaultImports by PropertiesCollection.keyCopy(ScriptDefinition.defaultImports)
|
||||
|
||||
val ScriptCompileConfiguration.restrictions by PropertiesCollection.keyCopy(ScriptDefinition.restrictions)
|
||||
val ScriptCompileConfigurationKeys.restrictions by PropertiesCollection.keyCopy(ScriptDefinition.restrictions)
|
||||
|
||||
val ScriptCompileConfiguration.importedScripts by PropertiesCollection.keyCopy(ScriptDefinition.importedScripts)
|
||||
val ScriptCompileConfigurationKeys.importedScripts by PropertiesCollection.keyCopy(ScriptDefinition.importedScripts)
|
||||
|
||||
val ScriptCompileConfiguration.dependencies by PropertiesCollection.keyCopy(ScriptDefinition.dependencies)
|
||||
val ScriptCompileConfigurationKeys.dependencies by PropertiesCollection.keyCopy(ScriptDefinition.dependencies)
|
||||
|
||||
val ScriptCompileConfiguration.compilerOptions by PropertiesCollection.keyCopy(ScriptDefinition.compilerOptions)
|
||||
val ScriptCompileConfigurationKeys.compilerOptions by PropertiesCollection.keyCopy(ScriptDefinition.compilerOptions)
|
||||
|
||||
|
||||
interface ProcessedScriptData : PropertiesCollection {
|
||||
interface ProcessedScriptDataKeys
|
||||
|
||||
companion object : ProcessedScriptData
|
||||
class ProcessedScriptData(properties: Map<PropertiesCollection.Key<*>, Any>) : PropertiesCollection(properties) {
|
||||
|
||||
companion object : ProcessedScriptDataKeys
|
||||
}
|
||||
|
||||
val ProcessedScriptData.foundAnnotations by PropertiesCollection.key<List<Annotation>>()
|
||||
val ProcessedScriptDataKeys.foundAnnotations by PropertiesCollection.key<List<Annotation>>()
|
||||
|
||||
val ProcessedScriptData.foundFragments by PropertiesCollection.key<List<ScriptSourceNamedFragment>>()
|
||||
val ProcessedScriptDataKeys.foundFragments by PropertiesCollection.key<List<ScriptSourceNamedFragment>>()
|
||||
|
||||
|
||||
interface RefineScriptCompilationConfigurationHandler {
|
||||
|
||||
@@ -10,57 +10,62 @@ package kotlin.script.experimental.api
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.script.experimental.util.PropertiesCollection
|
||||
|
||||
interface ScriptDefinition : PropertiesCollection {
|
||||
interface ScriptDefinitionKeys
|
||||
|
||||
companion object : ScriptDefinition {
|
||||
open class ScriptDefinition(baseDefinitions: Iterable<ScriptDefinition>, body: Builder.() -> Unit) :
|
||||
PropertiesCollection(Builder(baseDefinitions).apply(body).data) {
|
||||
|
||||
class Builder internal constructor() : PropertiesCollection.Builder(), ScriptDefinition {
|
||||
override val properties = data
|
||||
}
|
||||
constructor(body: Builder.() -> Unit = {}) : this(emptyList(), body)
|
||||
constructor(vararg baseDefinitions: ScriptDefinition, body: Builder.() -> Unit = {}) : this(baseDefinitions.asIterable(), body)
|
||||
|
||||
fun create(body: Builder.() -> Unit): ScriptDefinition = Builder().apply(body)
|
||||
class Builder internal constructor(baseDefinitions: Iterable<ScriptDefinition>) :
|
||||
ScriptDefinitionKeys,
|
||||
PropertiesCollection.Builder(baseDefinitions)
|
||||
|
||||
// inherited from script definition for using as a keys anchor
|
||||
companion object : ScriptDefinitionKeys {
|
||||
|
||||
val Default = ScriptDefinition()
|
||||
}
|
||||
|
||||
object Default : ScriptDefinition
|
||||
}
|
||||
|
||||
val ScriptDefinition.name by PropertiesCollection.key<String>("Kotlin script") // Name of the script type
|
||||
val ScriptDefinitionKeys.name by PropertiesCollection.key<String>("Kotlin script") // Name of the script type
|
||||
|
||||
val ScriptDefinition.fileExtension by PropertiesCollection.key<String>("kts") // file extension
|
||||
val ScriptDefinitionKeys.fileExtension by PropertiesCollection.key<String>("kts") // file extension
|
||||
|
||||
val ScriptDefinition.baseClass by PropertiesCollection.key<KotlinType>() // script base class
|
||||
val ScriptDefinitionKeys.baseClass by PropertiesCollection.key<KotlinType>() // script base class
|
||||
|
||||
val ScriptDefinition.scriptBodyTarget by PropertiesCollection.key<ScriptBodyTarget>(ScriptBodyTarget.Constructor)
|
||||
val ScriptDefinitionKeys.scriptBodyTarget by PropertiesCollection.key<ScriptBodyTarget>(ScriptBodyTarget.Constructor)
|
||||
|
||||
val ScriptDefinition.scriptImplicitReceivers by PropertiesCollection.key<List<KotlinType>>() // in the order from outer to inner scope
|
||||
val ScriptDefinitionKeys.scriptImplicitReceivers by PropertiesCollection.key<List<KotlinType>>() // in the order from outer to inner scope
|
||||
|
||||
val ScriptDefinition.contextVariables by PropertiesCollection.key<Map<String, KotlinType>>() // external variables
|
||||
val ScriptDefinitionKeys.contextVariables by PropertiesCollection.key<Map<String, KotlinType>>() // external variables
|
||||
|
||||
val ScriptDefinition.defaultImports by PropertiesCollection.key<List<String>>()
|
||||
val ScriptDefinitionKeys.defaultImports by PropertiesCollection.key<List<String>>()
|
||||
|
||||
val ScriptDefinition.restrictions by PropertiesCollection.key<List<ResolvingRestrictionRule>>()
|
||||
val ScriptDefinitionKeys.restrictions by PropertiesCollection.key<List<ResolvingRestrictionRule>>()
|
||||
|
||||
val ScriptDefinition.importedScripts by PropertiesCollection.key<List<ScriptSource>>()
|
||||
val ScriptDefinitionKeys.importedScripts by PropertiesCollection.key<List<ScriptSource>>()
|
||||
|
||||
val ScriptDefinition.dependencies by PropertiesCollection.key<List<ScriptDependency>>()
|
||||
val ScriptDefinitionKeys.dependencies by PropertiesCollection.key<List<ScriptDependency>>()
|
||||
|
||||
val ScriptDefinition.generatedClassAnnotations by PropertiesCollection.key<List<Annotation>>()
|
||||
val ScriptDefinitionKeys.generatedClassAnnotations by PropertiesCollection.key<List<Annotation>>()
|
||||
|
||||
val ScriptDefinition.generatedMethodAnnotations by PropertiesCollection.key<List<Annotation>>()
|
||||
val ScriptDefinitionKeys.generatedMethodAnnotations by PropertiesCollection.key<List<Annotation>>()
|
||||
|
||||
val ScriptDefinition.compilerOptions by PropertiesCollection.key<List<String>>() // Q: CommonCompilerOptions instead?
|
||||
val ScriptDefinitionKeys.compilerOptions by PropertiesCollection.key<List<String>>() // Q: CommonCompilerOptions instead?
|
||||
|
||||
val ScriptDefinition.refineConfigurationHandler by PropertiesCollection.key<RefineScriptCompilationConfigurationHandler>() // dynamic configurator
|
||||
val ScriptDefinitionKeys.refineConfigurationHandler by PropertiesCollection.key<RefineScriptCompilationConfigurationHandler>() // dynamic configurator
|
||||
|
||||
val ScriptDefinition.refineConfigurationBeforeParsing by PropertiesCollection.key<Boolean>() // default: false
|
||||
val ScriptDefinitionKeys.refineConfigurationBeforeParsing by PropertiesCollection.key<Boolean>() // default: false
|
||||
|
||||
val ScriptDefinition.refineConfigurationOnAnnotations by PropertiesCollection.key<List<KotlinType>>()
|
||||
val ScriptDefinitionKeys.refineConfigurationOnAnnotations by PropertiesCollection.key<List<KotlinType>>()
|
||||
|
||||
val ScriptDefinition.refineConfigurationOnSections by PropertiesCollection.key<List<String>>()
|
||||
val ScriptDefinitionKeys.refineConfigurationOnSections by PropertiesCollection.key<List<String>>()
|
||||
|
||||
// DSL:
|
||||
|
||||
val ScriptDefinition.refineConfiguration get() = RefineConfigurationBuilder()
|
||||
val ScriptDefinition.Builder.refineConfiguration get() = RefineConfigurationBuilder()
|
||||
|
||||
|
||||
class RefineConfigurationBuilder : PropertiesCollection.Builder() {
|
||||
|
||||
@@ -9,25 +9,30 @@ package kotlin.script.experimental.api
|
||||
|
||||
import kotlin.script.experimental.util.PropertiesCollection
|
||||
|
||||
interface ScriptEvaluationEnvironment : PropertiesCollection {
|
||||
interface ScriptEvaluationEnvironmentKeys
|
||||
|
||||
companion object : ScriptEvaluationEnvironment {
|
||||
class ScriptEvaluationEnvironment(baseEvaluationEnvironments: Iterable<ScriptEvaluationEnvironment>, body: Builder.() -> Unit) :
|
||||
PropertiesCollection(Builder(baseEvaluationEnvironments).apply(body).data) {
|
||||
|
||||
class Builder internal constructor() : PropertiesCollection.Builder(), ScriptEvaluationEnvironment {
|
||||
override val properties = data
|
||||
}
|
||||
constructor(body: Builder.() -> Unit = {}) : this(emptyList(), body)
|
||||
constructor(
|
||||
vararg baseEvaluationEnvironments: ScriptEvaluationEnvironment, body: Builder.() -> Unit = {}
|
||||
) : this(baseEvaluationEnvironments.asIterable(), body)
|
||||
|
||||
fun create(body: Builder.() -> Unit): ScriptEvaluationEnvironment = Builder().apply(body)
|
||||
}
|
||||
class Builder internal constructor(baseEvaluationEnvironments: Iterable<ScriptEvaluationEnvironment>) :
|
||||
ScriptDefinitionKeys,
|
||||
PropertiesCollection.Builder(baseEvaluationEnvironments)
|
||||
|
||||
companion object : ScriptEvaluationEnvironmentKeys
|
||||
}
|
||||
|
||||
val ScriptEvaluationEnvironment.implicitReceivers by PropertiesCollection.key<List<Any>>()
|
||||
val ScriptEvaluationEnvironmentKeys.implicitReceivers by PropertiesCollection.key<List<Any>>()
|
||||
|
||||
val ScriptEvaluationEnvironment.contextVariables by PropertiesCollection.key<Map<String, Any?>>() // external variables
|
||||
val ScriptEvaluationEnvironmentKeys.contextVariables by PropertiesCollection.key<Map<String, Any?>>() // external variables
|
||||
|
||||
val ScriptEvaluationEnvironment.constructorArgs by PropertiesCollection.key<List<Any?>>()
|
||||
val ScriptEvaluationEnvironmentKeys.constructorArgs by PropertiesCollection.key<List<Any?>>()
|
||||
|
||||
val ScriptEvaluationEnvironment.runArgs by PropertiesCollection.key<List<Any?>>()
|
||||
val ScriptEvaluationEnvironmentKeys.runArgs by PropertiesCollection.key<List<Any?>>()
|
||||
|
||||
sealed class ResultValue {
|
||||
class Value(val name: String, val value: Any?, val type: String) : ResultValue() {
|
||||
|
||||
+17
-12
@@ -7,37 +7,42 @@ package kotlin.script.experimental.api
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.script.experimental.util.PropertiesCollection
|
||||
import kotlin.script.experimental.util.getOrNull
|
||||
|
||||
interface ScriptingEnvironment : PropertiesCollection {
|
||||
interface ScriptingEnvironmentKeys
|
||||
|
||||
companion object : ScriptingEnvironment {
|
||||
class ScriptingEnvironment(baseScriptingEnvironments: Iterable<ScriptingEnvironment>, body: Builder.() -> Unit) :
|
||||
PropertiesCollection(Builder(baseScriptingEnvironments).apply(body).data) {
|
||||
|
||||
class Builder internal constructor() : PropertiesCollection.Builder(), ScriptingEnvironment {
|
||||
override val properties = data
|
||||
}
|
||||
constructor(body: Builder.() -> Unit = {}) : this(emptyList(), body)
|
||||
constructor(
|
||||
vararg baseScriptingEnvironments: ScriptingEnvironment, body: Builder.() -> Unit = {}
|
||||
) : this(baseScriptingEnvironments.asIterable(), body)
|
||||
|
||||
fun create(body: Builder.() -> Unit): ScriptingEnvironment = Builder().apply(body)
|
||||
}
|
||||
class Builder internal constructor(baseScriptingEnvironments: Iterable<ScriptingEnvironment>) :
|
||||
ScriptingEnvironmentKeys,
|
||||
PropertiesCollection.Builder(baseScriptingEnvironments)
|
||||
|
||||
companion object : ScriptingEnvironmentKeys
|
||||
}
|
||||
|
||||
// should contain all dependencies needed for baseClass and compilationConfigurator
|
||||
val ScriptingEnvironment.configurationDependencies by PropertiesCollection.key<List<ScriptDependency>>()
|
||||
val ScriptingEnvironmentKeys.configurationDependencies by PropertiesCollection.key<List<ScriptDependency>>()
|
||||
|
||||
// do not use configurationDependencies as script dependencies, so only the dependencies defined by compilationConfigurator will be used
|
||||
// (NOTE: in this case they should include the dependencies for the base class anyway, since this class is needed for script
|
||||
// compilation and instantiation, but compilationConfigurator could be excluded)
|
||||
val ScriptingEnvironment.isolatedDependencies by PropertiesCollection.key<Boolean>(false)
|
||||
val ScriptingEnvironmentKeys.isolatedDependencies by PropertiesCollection.key<Boolean>(false)
|
||||
|
||||
// a "class loader" for KotlinTypes
|
||||
val ScriptingEnvironment.getScriptingClass by PropertiesCollection.key<GetScriptingClass>()
|
||||
val ScriptingEnvironmentKeys.getScriptingClass by PropertiesCollection.key<GetScriptingClass>()
|
||||
|
||||
|
||||
interface GetScriptingClass {
|
||||
operator fun invoke(classType: KotlinType, contextClass: KClass<*>, environment: ScriptingEnvironment): KClass<*>
|
||||
}
|
||||
|
||||
fun ScriptingEnvironment.getScriptingClass(type: KotlinType, contextClass: KClass<*>): KClass<*> {
|
||||
val getClass = getOrNull(ScriptingEnvironment.getScriptingClass)
|
||||
val getClass = get(ScriptingEnvironment.getScriptingClass)
|
||||
?: throw IllegalArgumentException("Expecting 'getScriptingClass' property in the scripting environment: unable to load scripting class $type")
|
||||
return getClass(type, contextClass, this)
|
||||
}
|
||||
|
||||
+8
-11
@@ -12,7 +12,6 @@ import kotlin.script.experimental.annotations.KotlinScript
|
||||
import kotlin.script.experimental.annotations.KotlinScriptFileExtension
|
||||
import kotlin.script.experimental.annotations.KotlinScriptProperties
|
||||
import kotlin.script.experimental.api.*
|
||||
import kotlin.script.experimental.util.getOrNull
|
||||
|
||||
private const val ERROR_MSG_PREFIX = "Unable to construct script definition: "
|
||||
|
||||
@@ -25,7 +24,7 @@ fun createScriptDefinitionFromAnnotatedBaseClass(
|
||||
contextClass: KClass<*> = ScriptDefinition::class
|
||||
): ScriptDefinition {
|
||||
|
||||
val getScriptingClass = environment.getOrNull(ScriptingEnvironment.getScriptingClass)
|
||||
val getScriptingClass = environment[ScriptingEnvironment.getScriptingClass]
|
||||
?: throw IllegalArgumentException("${ERROR_MSG_PREFIX}Expecting 'getScriptingClass' parameter in the scripting environment")
|
||||
|
||||
val baseClass: KClass<*> =
|
||||
@@ -44,17 +43,15 @@ fun createScriptDefinitionFromAnnotatedBaseClass(
|
||||
throw IllegalArgumentException(ILLEGAL_CONFIG_ANN_ARG, e)
|
||||
}
|
||||
|
||||
return object : ScriptDefinition {
|
||||
override val properties = properties {
|
||||
baseClass(baseClassType)
|
||||
fileExtension(baseClass.findAnnotation<KotlinScriptFileExtension>()?.extension ?: mainAnnotation.extension)
|
||||
name(mainAnnotation.name)
|
||||
return ScriptDefinition {
|
||||
baseClass(baseClassType)
|
||||
fileExtension(baseClass.findAnnotation<KotlinScriptFileExtension>()?.extension ?: mainAnnotation.extension)
|
||||
name(mainAnnotation.name)
|
||||
|
||||
include(scriptingPropsInstance(mainAnnotation.definition))
|
||||
include(scriptingPropsInstance(mainAnnotation.definition))
|
||||
|
||||
baseClass.annotations.filterIsInstance(KotlinScriptProperties::class.java).forEach { ann ->
|
||||
include(scriptingPropsInstance(ann.definition))
|
||||
}
|
||||
baseClass.annotations.filterIsInstance(KotlinScriptProperties::class.java).forEach { ann ->
|
||||
include(scriptingPropsInstance(ann.definition))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import kotlin.script.experimental.api.ScriptCompileConfiguration
|
||||
import kotlin.script.experimental.api.ScriptSource
|
||||
import kotlin.script.experimental.api.ScriptSourceNamedFragment
|
||||
import kotlin.script.experimental.api.sourceFragments
|
||||
import kotlin.script.experimental.util.getOrNull
|
||||
|
||||
fun ScriptSource.getScriptText(): String = when {
|
||||
text != null -> text!!
|
||||
@@ -22,7 +21,7 @@ fun ScriptSource.getScriptText(): String = when {
|
||||
|
||||
fun getMergedScriptText(script: ScriptSource, configuration: ScriptCompileConfiguration?): String {
|
||||
val originalScriptText = script.getScriptText()
|
||||
val sourceFragments = configuration?.getOrNull(ScriptCompileConfiguration.sourceFragments)
|
||||
val sourceFragments = configuration?.get(ScriptCompileConfiguration.sourceFragments)
|
||||
return if (sourceFragments == null || sourceFragments.isEmpty()) {
|
||||
originalScriptText
|
||||
} else {
|
||||
|
||||
@@ -9,16 +9,21 @@ import kotlin.script.experimental.api.EvaluationResult
|
||||
import kotlin.script.experimental.api.ResultWithDiagnostics
|
||||
import kotlin.script.experimental.util.PropertiesCollection
|
||||
|
||||
interface ReplEvaluationEnvironment : PropertiesCollection {
|
||||
interface ReplEvaluationEnvironmentKeys
|
||||
|
||||
companion object : ReplEvaluationEnvironment {
|
||||
class ReplEvaluationEnvironment(baseEvaluationEnvironments: Iterable<ReplEvaluationEnvironment>, body: Builder.() -> Unit) :
|
||||
PropertiesCollection(Builder(baseEvaluationEnvironments).apply(body).data) {
|
||||
|
||||
class Builder internal constructor() : PropertiesCollection.Builder(), ReplEvaluationEnvironment {
|
||||
override val properties = data
|
||||
}
|
||||
constructor(body: Builder.() -> Unit = {}) : this(emptyList(), body)
|
||||
constructor(
|
||||
vararg baseEvaluationEnvironments: ReplEvaluationEnvironment, body: Builder.() -> Unit = {}
|
||||
) : this(baseEvaluationEnvironments.asIterable(), body)
|
||||
|
||||
fun create(body: Builder.() -> Unit): ReplEvaluationEnvironment = Builder().apply(body)
|
||||
}
|
||||
class Builder internal constructor(baseEvaluationEnvironments: Iterable<ReplEvaluationEnvironment>) :
|
||||
ReplEvaluationEnvironmentKeys,
|
||||
PropertiesCollection.Builder(baseEvaluationEnvironments)
|
||||
|
||||
companion object : ReplEvaluationEnvironmentKeys
|
||||
}
|
||||
|
||||
interface ReplSnippetEvaluator {
|
||||
|
||||
@@ -22,19 +22,24 @@ interface ReplCommandProcessor {
|
||||
|
||||
data class ReplCommand(val commandName: String, val processor: ReplCommandProcessor)
|
||||
|
||||
interface ReplHostEnvironment : PropertiesCollection {
|
||||
interface ReplHostEnvironmentKeys
|
||||
|
||||
companion object : ReplHostEnvironment {
|
||||
class ReplHostEnvironment(baseReplHostEnvironments: Iterable<ReplHostEnvironment>, body: Builder.() -> Unit) :
|
||||
PropertiesCollection(Builder(baseReplHostEnvironments).apply(body).data) {
|
||||
|
||||
class Builder internal constructor() : PropertiesCollection.Builder(), ReplHostEnvironment {
|
||||
override val properties = data
|
||||
}
|
||||
constructor(body: Builder.() -> Unit = {}) : this(emptyList(), body)
|
||||
constructor(
|
||||
vararg baseReplHostEnvironments: ReplHostEnvironment, body: Builder.() -> Unit = {}
|
||||
) : this(baseReplHostEnvironments.asIterable(), body)
|
||||
|
||||
fun create(body: Builder.() -> Unit): ReplHostEnvironment = Builder().apply(body)
|
||||
}
|
||||
class Builder internal constructor(baseReplHostEnvironments: Iterable<ReplHostEnvironment>) :
|
||||
ReplHostEnvironmentKeys,
|
||||
PropertiesCollection.Builder(baseReplHostEnvironments)
|
||||
|
||||
companion object : ReplHostEnvironmentKeys
|
||||
}
|
||||
|
||||
val ReplHostEnvironment.replCommands by PropertiesCollection.key<List<ReplCommand>>()
|
||||
val ReplHostEnvironmentKeys.replCommands by PropertiesCollection.key<List<ReplCommand>>()
|
||||
|
||||
abstract class ReplHost(
|
||||
val environment: ReplHostEnvironment,
|
||||
|
||||
+30
-33
@@ -10,9 +10,7 @@ import kotlin.reflect.KProperty
|
||||
import kotlin.reflect.KType
|
||||
import kotlin.script.experimental.api.KotlinType
|
||||
|
||||
interface PropertiesCollection {
|
||||
|
||||
val properties: Map<Key<*>, Any> get() = emptyMap()
|
||||
open class PropertiesCollection(val properties: Map<Key<*>, Any> = emptyMap()) {
|
||||
|
||||
data class Key<T>(val name: String, val defaultValue: T? = null)
|
||||
|
||||
@@ -25,22 +23,27 @@ interface PropertiesCollection {
|
||||
operator fun getValue(thisRef: Any?, property: KProperty<*>): Key<T> = source
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
operator fun <T> get(key: PropertiesCollection.Key<T>): T? =
|
||||
properties[key]?.let { it as T } ?: key.defaultValue
|
||||
|
||||
|
||||
companion object {
|
||||
fun <T> key(defaultValue: T? = null) = PropertyKeyDelegate(defaultValue)
|
||||
fun <T> keyCopy(source: Key<T>) = PropertyKeyCopyDelegate(source)
|
||||
}
|
||||
|
||||
fun properties(body: Builder.() -> Unit): Map<Key<*>, Any> = Builder().apply(body).data
|
||||
|
||||
// properties builder base class (DSL for building properties collection)
|
||||
|
||||
open class Builder {
|
||||
open class Builder(baseProperties: Iterable<PropertiesCollection> = emptyList()) {
|
||||
|
||||
val data: MutableMap<PropertiesCollection.Key<*>, Any> = LinkedHashMap()
|
||||
val data: MutableMap<PropertiesCollection.Key<*>, Any> = LinkedHashMap<PropertiesCollection.Key<*>, Any>().apply {
|
||||
baseProperties.forEach { putAll(it.properties) }
|
||||
}
|
||||
|
||||
// generic builder for all properties
|
||||
operator fun <T : Any> PropertiesCollection.Key<T>.invoke(v: T) {
|
||||
set(this, v)
|
||||
data[this] = v
|
||||
}
|
||||
|
||||
// generic for lists
|
||||
@@ -59,28 +62,28 @@ interface PropertiesCollection {
|
||||
|
||||
@JvmName("invoke_string_fqn_from_generic")
|
||||
inline operator fun <reified K> PropertiesCollection.Key<String>.invoke() {
|
||||
set(this, K::class.qualifiedName!!)
|
||||
data[this] = K::class.java.name
|
||||
}
|
||||
|
||||
@JvmName("invoke_string_fqn_from_reflected_class")
|
||||
operator fun PropertiesCollection.Key<String>.invoke(kclass: KClass<*>) {
|
||||
set(this, kclass.qualifiedName!!)
|
||||
data[this] = kclass.java.name
|
||||
}
|
||||
|
||||
@JvmName("invoke_string_list_fqn_from_generic")
|
||||
inline operator fun <reified K> PropertiesCollection.Key<in List<String>>.invoke() {
|
||||
append(K::class.qualifiedName!!)
|
||||
append(K::class.java.name)
|
||||
}
|
||||
|
||||
@JvmName("invoke_string_list_fqn_from_reflected_class")
|
||||
operator fun PropertiesCollection.Key<in List<String>>.invoke(vararg kclasses: KClass<*>) {
|
||||
append(kclasses.map { it.qualifiedName!! })
|
||||
append(kclasses.map { it.java.name })
|
||||
}
|
||||
|
||||
// for KotlinType:
|
||||
|
||||
inline operator fun <reified K> PropertiesCollection.Key<KotlinType>.invoke() {
|
||||
set(this, KotlinType(K::class))
|
||||
data[this] = KotlinType(K::class)
|
||||
}
|
||||
|
||||
operator fun PropertiesCollection.Key<KotlinType>.invoke(kclass: KClass<*>) {
|
||||
@@ -138,7 +141,7 @@ interface PropertiesCollection {
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
operator fun <T : Any> get(key: PropertiesCollection.Key<in T>): T? = data[key]?.let { it as T }
|
||||
private operator fun <T : Any> get(key: PropertiesCollection.Key<in T>): T? = data[key]?.let { it as T }
|
||||
|
||||
// appenders to list and map properties
|
||||
|
||||
@@ -174,15 +177,22 @@ interface PropertiesCollection {
|
||||
this.body()
|
||||
this@Builder.data.putAll(this.data)
|
||||
}
|
||||
|
||||
// a class for extending properties
|
||||
interface BuilderExtension<T : Builder> {
|
||||
fun get(): T
|
||||
}
|
||||
|
||||
// include another builder extension
|
||||
operator fun <T : Builder> BuilderExtension<T>.invoke(body: T.() -> Unit) {
|
||||
val builder = this.get().apply(body)
|
||||
this@Builder.data.putAll(builder.data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T> PropertiesCollection.getOrNull(key: PropertiesCollection.Key<T>): T? =
|
||||
properties[key]?.let { it as T } ?: key.defaultValue
|
||||
|
||||
fun <T> PropertiesCollection.getOrError(key: PropertiesCollection.Key<T>): T =
|
||||
getOrNull(key) ?: throw IllegalArgumentException("Unknown key $key")
|
||||
fun <T> PropertiesCollection.getOrError(key: PropertiesCollection.Key<T>): T =
|
||||
get(key) ?: throw IllegalArgumentException("Unknown key $key")
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T> getFirstFromChainOrNull(key: PropertiesCollection.Key<T>, vararg propertyCollections: PropertiesCollection?): T? {
|
||||
@@ -193,16 +203,3 @@ fun <T> getFirstFromChainOrNull(key: PropertiesCollection.Key<T>, vararg propert
|
||||
return key.defaultValue
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T> getMergedFromChainOrNull(key: PropertiesCollection.Key<List<T>>, vararg propertyCollections: PropertiesCollection?): List<T>? {
|
||||
var found = false
|
||||
val res = ArrayList<T>()
|
||||
for (collection in propertyCollections) {
|
||||
val value = collection?.properties?.get(key)
|
||||
if (value != null) {
|
||||
found = true
|
||||
res.addAll(value as List<T>)
|
||||
}
|
||||
}
|
||||
return if (found) res else key.defaultValue
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user