Refactoring heterogeneous map handling, add dsl builders

This commit is contained in:
Ilya Chernikov
2018-03-02 19:04:47 +01:00
parent 63d601e1be
commit 1723ff658d
5 changed files with 109 additions and 47 deletions
@@ -7,43 +7,10 @@
package kotlin.script.experimental.api
import kotlin.reflect.KClass
object ScriptCompileConfigurationParams {
val scriptSourceFragments by typedKey<ScriptSourceFragments>()
val scriptSignature by typedKey<ScriptSignature>()
val importedPackages by typedKey<Iterable<String>>()
val restrictions by typedKey<ResolvingRestrictions>()
val importedScripts by typedKey<Iterable<ScriptSource>>()
val dependencies by typedKey<Iterable<ScriptDependency>>()
val compilerOptions by typedKey<Iterable<String>>() // Q: CommonCompilerOptions instead?
val updateConfigurationOnAnnotations by typedKey<Iterable<KClass<out Annotation>>>()
val updateConfigurationOnSections by typedKey<Iterable<String>>()
}
typealias ScriptCompileConfiguration = HeterogeneousMap
fun ScriptSource.toScriptCompileConfiguration(vararg pairs: Pair<TypedKey<*>, Any?>) =
ScriptCompileConfiguration(ScriptCompileConfigurationParams.scriptSourceFragments to ScriptSourceFragments(this, null), *pairs)
object ProcessedScriptDataParams {
val annotations by typedKey<Iterable<Annotation>>()
val fragments by typedKey<Iterable<ScriptSourceNamedFragment>>()
}
typealias ProcessedScriptData = HeterogeneousMap
interface ScriptConfigurator {
// with null scriptSource should return a generic configuration for the script type
@@ -55,6 +22,3 @@ interface ScriptConfigurator {
): ResultWithDiagnostics<ScriptCompileConfiguration>
}
fun ScriptSource?.toConfigEntry(): Pair<TypedKey<*>, Any?> =
ScriptCompileConfigurationParams.scriptSourceFragments to this?.let { ScriptSourceFragments(this, null) }
@@ -0,0 +1,49 @@
/*
* Copyright 2000-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.
*/
@file:Suppress("unused")
package kotlin.script.experimental.api
import kotlin.reflect.KClass
object ScriptCompileConfigurationParams {
val scriptSourceFragments by typedKey<ScriptSourceFragments>()
val scriptSignature by typedKey<ScriptSignature>()
val importedPackages by typedKey<Iterable<String>>()
val restrictions by typedKey<ResolvingRestrictions>()
val importedScripts by typedKey<Iterable<ScriptSource>>()
val dependencies by typedKey<Iterable<ScriptDependency>>()
val compilerOptions by typedKey<Iterable<String>>() // Q: CommonCompilerOptions instead?
val updateConfigurationOnAnnotations by typedKey<Iterable<KClass<out Annotation>>>()
val updateConfigurationOnSections by typedKey<Iterable<String>>()
open class Builder : HeterogeneousMapBuilder() {
inline fun <reified T> signature(providedDeclarations: ProvidedDeclarations = ProvidedDeclarations.Empty) {
add(scriptSignature to ScriptSignature(T::class, providedDeclarations))
}
}
}
// DSL
inline
fun scriptConfiguration(from: HeterogeneousMap = HeterogeneousMap(), body: ScriptCompileConfigurationParams.Builder.() -> Unit) =
ScriptCompileConfigurationParams.Builder().build(from, body)
fun ScriptSource.toScriptCompileConfiguration(vararg pairs: Pair<TypedKey<*>, Any?>) =
ScriptCompileConfiguration(ScriptCompileConfigurationParams.scriptSourceFragments to ScriptSourceFragments(this, null), *pairs)
fun ScriptSource?.toConfigEntry(): Pair<TypedKey<*>, Any?> =
ScriptCompileConfigurationParams.scriptSourceFragments to this?.let { ScriptSourceFragments(this, null) }
@@ -7,13 +7,22 @@
package kotlin.script.experimental.api
object ScriptEvaluationEnvironmentParams {
val implicitReceivers by typedKey<List<Any>>()
val contextVariables by typedKey<Map<String, Any?>>() // external variables
val constructorArgs by typedKey<List<Any?>>()
val runArgs by typedKey<List<Any?>>()
open class ScriptEvaluationEnvironmentParams : HeterogeneousMapBuilder() {
companion object {
val implicitReceivers by typedKey<List<Any>>()
val contextVariables by typedKey<Map<String, Any?>>() // external variables
val constructorArgs by typedKey<List<Any?>>()
val runArgs by typedKey<List<Any?>>()
}
}
inline
fun scriptEvaluationEnvironment(from: HeterogeneousMap = HeterogeneousMap(), body: ScriptEvaluationEnvironmentParams.() -> Unit) =
ScriptEvaluationEnvironmentParams().build(from, body)
typealias ScriptEvaluationEnvironment = HeterogeneousMap
data class EvaluationResult(val returnValue: Any?, val environment: ScriptEvaluationEnvironment)
@@ -0,0 +1,18 @@
/*
* Copyright 2000-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
class ProcessedScriptDataParams : HeterogeneousMapBuilder() {
companion object {
val annotations by typedKey<Iterable<Annotation>>()
val fragments by typedKey<Iterable<ScriptSourceNamedFragment>>()
}
}
inline
fun processedScriptData(from: HeterogeneousMap = HeterogeneousMap(), body: ProcessedScriptDataParams.() -> Unit) =
ProcessedScriptDataParams().build(from, body)
@@ -7,6 +7,8 @@ package kotlin.script.experimental.api
import kotlin.reflect.KProperty
// copy placed into package org.jetbrains.kotlin.utils.addToStdlib as well
data class TypedKey<T>(val name: String)
class TypedKeyDelegate<T> {
@@ -15,15 +17,35 @@ class TypedKeyDelegate<T> {
fun <T> typedKey() = TypedKeyDelegate<T>()
class HeterogeneousMap(val data: Map<TypedKey<*>, Any?> = hashMapOf()) {
class HeterogeneousMap(private val data: Map<TypedKey<*>, Any?> = hashMapOf()) {
constructor(vararg pairs: Pair<TypedKey<*>, Any?>) : this(hashMapOf(*pairs))
constructor(from: HeterogeneousMap, vararg pairs: Pair<TypedKey<*>, Any?>) : this(HashMap(from.data).apply { putAll(pairs) })
constructor(from: HeterogeneousMap, pairs: Iterable<Pair<TypedKey<*>, Any?>>) : this(HashMap(from.data).apply { putAll(pairs) })
operator fun <T> get(key: TypedKey<T>): T =
if (data.containsKey(key)) data[key] as T
else throw IllegalArgumentException("Unknown key $key")
fun <T> getOrNull(key: TypedKey<T>): T? = data[key] as T?
}
fun HeterogeneousMap.cloneWith(vararg pairs: Pair<TypedKey<*>, Any?>) = HeterogeneousMap(HashMap(data).apply { putAll(pairs) })
fun HeterogeneousMap.cloneWith(vararg pairs: Pair<TypedKey<*>, Any?>) = HeterogeneousMap(this, *pairs)
operator fun <T> HeterogeneousMap.get(key: TypedKey<T>): T =
if (data.containsKey(key)) data[key] as T
else throw IllegalArgumentException("Unknown key $key")
fun <T> HeterogeneousMap.getOrNull(key: TypedKey<T>): T? = data[key] as T?
open class HeterogeneousMapBuilder {
val pairs: MutableList<Pair<TypedKey<*>, Any?>> = arrayListOf()
open operator fun <T> TypedKey<T>.invoke(v: T) {
pairs.add(this to v)
}
fun add(pair: Pair<TypedKey<*>, Any?>) {
pairs.add(pair)
}
}
inline
fun <T : HeterogeneousMapBuilder> T.build(from: HeterogeneousMap = HeterogeneousMap(), body: T.() -> Unit): HeterogeneousMap {
body()
return HeterogeneousMap(from, pairs)
}