Refactor script infrastructure for easier usage and testability:
- add script annotation for specifying default configuration for a script - add support for this annotation in the default configurator - rename configurator accordingly - add default implementation of the refineConfiguration method - make property bag class open
This commit is contained in:
+5
@@ -42,3 +42,8 @@ annotation class KotlinScriptEvaluator(
|
|||||||
val evaluator: KClass<out ScriptEvaluator<*>>
|
val evaluator: KClass<out ScriptEvaluator<*>>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
annotation class KotlinScriptDefaultCompilationConfiguration(
|
||||||
|
val compilationConfiguration: KClass<out List<*>> // object or class filled in 0-ary constructor
|
||||||
|
)
|
||||||
|
|||||||
+2
-1
@@ -25,6 +25,7 @@ interface ScriptCompilationConfigurator {
|
|||||||
scriptSource: ScriptSource,
|
scriptSource: ScriptSource,
|
||||||
configuration: ScriptCompileConfiguration,
|
configuration: ScriptCompileConfiguration,
|
||||||
processedScriptData: ProcessedScriptData = ProcessedScriptData()
|
processedScriptData: ProcessedScriptData = ProcessedScriptData()
|
||||||
): ResultWithDiagnostics<ScriptCompileConfiguration>
|
): ResultWithDiagnostics<ScriptCompileConfiguration> =
|
||||||
|
defaultConfiguration.asSuccess()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,19 +5,33 @@
|
|||||||
|
|
||||||
package kotlin.script.experimental.basic
|
package kotlin.script.experimental.basic
|
||||||
|
|
||||||
|
import kotlin.reflect.full.primaryConstructor
|
||||||
|
import kotlin.script.experimental.annotations.KotlinScriptDefaultCompilationConfiguration
|
||||||
import kotlin.script.experimental.api.*
|
import kotlin.script.experimental.api.*
|
||||||
|
import kotlin.script.experimental.util.TypedKey
|
||||||
|
|
||||||
|
|
||||||
class PassThroughCompilationConfigurator(val environment: ScriptingEnvironment) : ScriptCompilationConfigurator {
|
private const val ILLEGAL_CONFIG_ANN_ARG =
|
||||||
|
"Illegal argument to KotlinScriptDefaultCompilationConfiguration annotation: expecting List-derived object or default-constructed class of configuration parameters"
|
||||||
|
|
||||||
override val defaultConfiguration = ScriptCompileConfiguration(environment)
|
open class AnnotationsBasedCompilationConfigurator(val environment: ScriptingEnvironment) : ScriptCompilationConfigurator {
|
||||||
|
|
||||||
override suspend fun refineConfiguration(
|
override val defaultConfiguration = run {
|
||||||
script: ScriptSource,
|
val base = environment[ScriptingEnvironmentProperties.baseClass]
|
||||||
configuration: ScriptCompileConfiguration,
|
val cfg = base.annotations.filterIsInstance(KotlinScriptDefaultCompilationConfiguration::class.java).flatMap {
|
||||||
processedScriptData: ProcessedScriptData
|
val params = try {
|
||||||
): ResultWithDiagnostics<ScriptCompileConfiguration> =
|
it.compilationConfiguration.objectInstance ?: it.compilationConfiguration.primaryConstructor!!.callBy(emptyMap())
|
||||||
configuration.asSuccess()
|
} catch (e: Throwable) {
|
||||||
|
throw IllegalArgumentException(ILLEGAL_CONFIG_ANN_ARG, e)
|
||||||
|
}
|
||||||
|
params.forEach {
|
||||||
|
if (it !is Pair<*, *> || it.first !is TypedKey<*>)
|
||||||
|
throw IllegalArgumentException("$ILLEGAL_CONFIG_ANN_ARG: invalid parameter $it")
|
||||||
|
}
|
||||||
|
params as List<Pair<TypedKey<*>, Any?>>
|
||||||
|
}
|
||||||
|
ScriptCompileConfiguration(environment, cfg)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DummyEvaluator<ScriptBase : Any>(val environment: ScriptingEnvironment) : ScriptEvaluator<ScriptBase> {
|
class DummyEvaluator<ScriptBase : Any>(val environment: ScriptingEnvironment) : ScriptEvaluator<ScriptBase> {
|
||||||
@@ -28,9 +42,3 @@ class DummyEvaluator<ScriptBase : Any>(val environment: ScriptingEnvironment) :
|
|||||||
ResultWithDiagnostics.Failure("not implemented".asErrorDiagnostics())
|
ResultWithDiagnostics.Failure("not implemented".asErrorDiagnostics())
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: from org.jetbrains.kotlin.utils.addToStdlib, take it from the stdlib when available
|
|
||||||
private inline fun <reified T : Any> Iterable<*>.firstIsInstanceOrNull(): T? {
|
|
||||||
for (element in this) if (element is T) return element
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -13,8 +13,8 @@ import kotlin.script.experimental.annotations.KotlinScriptCompilationConfigurato
|
|||||||
import kotlin.script.experimental.annotations.KotlinScriptEvaluator
|
import kotlin.script.experimental.annotations.KotlinScriptEvaluator
|
||||||
import kotlin.script.experimental.annotations.KotlinScriptFileExtension
|
import kotlin.script.experimental.annotations.KotlinScriptFileExtension
|
||||||
import kotlin.script.experimental.api.*
|
import kotlin.script.experimental.api.*
|
||||||
|
import kotlin.script.experimental.basic.AnnotationsBasedCompilationConfigurator
|
||||||
import kotlin.script.experimental.basic.DummyEvaluator
|
import kotlin.script.experimental.basic.DummyEvaluator
|
||||||
import kotlin.script.experimental.basic.PassThroughCompilationConfigurator
|
|
||||||
import kotlin.script.experimental.util.TypedKey
|
import kotlin.script.experimental.util.TypedKey
|
||||||
|
|
||||||
private const val ERROR_MSG_PREFIX = "Unable to construct script definition: "
|
private const val ERROR_MSG_PREFIX = "Unable to construct script definition: "
|
||||||
@@ -42,7 +42,7 @@ open class ScriptDefinitionFromAnnotatedBaseClass(val environment: ScriptingEnvi
|
|||||||
override val compilationConfigurator =
|
override val compilationConfigurator =
|
||||||
baseClass.findAnnotation<KotlinScriptCompilationConfigurator>()?.compilationConfigurator?.instantiateScriptHandler()
|
baseClass.findAnnotation<KotlinScriptCompilationConfigurator>()?.compilationConfigurator?.instantiateScriptHandler()
|
||||||
?: explicitDefinition?.compilationConfigurator
|
?: explicitDefinition?.compilationConfigurator
|
||||||
?: PassThroughCompilationConfigurator::class.instantiateScriptHandler()
|
?: AnnotationsBasedCompilationConfigurator::class.instantiateScriptHandler()
|
||||||
|
|
||||||
override val evaluator =
|
override val evaluator =
|
||||||
baseClass.findAnnotation<KotlinScriptEvaluator>()?.evaluator?.instantiateScriptHandler()
|
baseClass.findAnnotation<KotlinScriptEvaluator>()?.evaluator?.instantiateScriptHandler()
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class TypedKeyDelegate<T> {
|
|||||||
|
|
||||||
fun <T> typedKey() = TypedKeyDelegate<T>()
|
fun <T> typedKey() = TypedKeyDelegate<T>()
|
||||||
|
|
||||||
class ChainedPropertyBag private constructor(private val parent: ChainedPropertyBag?, private val data: Map<TypedKey<*>, Any?>) {
|
open class ChainedPropertyBag private constructor(private val parent: ChainedPropertyBag?, private 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) })
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user