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<*>>
|
||||
)
|
||||
|
||||
@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,
|
||||
configuration: ScriptCompileConfiguration,
|
||||
processedScriptData: ProcessedScriptData = ProcessedScriptData()
|
||||
): ResultWithDiagnostics<ScriptCompileConfiguration>
|
||||
): ResultWithDiagnostics<ScriptCompileConfiguration> =
|
||||
defaultConfiguration.asSuccess()
|
||||
}
|
||||
|
||||
|
||||
@@ -5,19 +5,33 @@
|
||||
|
||||
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.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(
|
||||
script: ScriptSource,
|
||||
configuration: ScriptCompileConfiguration,
|
||||
processedScriptData: ProcessedScriptData
|
||||
): ResultWithDiagnostics<ScriptCompileConfiguration> =
|
||||
configuration.asSuccess()
|
||||
override val defaultConfiguration = run {
|
||||
val base = environment[ScriptingEnvironmentProperties.baseClass]
|
||||
val cfg = base.annotations.filterIsInstance(KotlinScriptDefaultCompilationConfiguration::class.java).flatMap {
|
||||
val params = try {
|
||||
it.compilationConfiguration.objectInstance ?: it.compilationConfiguration.primaryConstructor!!.callBy(emptyMap())
|
||||
} 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> {
|
||||
@@ -28,9 +42,3 @@ class DummyEvaluator<ScriptBase : Any>(val environment: ScriptingEnvironment) :
|
||||
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.KotlinScriptFileExtension
|
||||
import kotlin.script.experimental.api.*
|
||||
import kotlin.script.experimental.basic.AnnotationsBasedCompilationConfigurator
|
||||
import kotlin.script.experimental.basic.DummyEvaluator
|
||||
import kotlin.script.experimental.basic.PassThroughCompilationConfigurator
|
||||
import kotlin.script.experimental.util.TypedKey
|
||||
|
||||
private const val ERROR_MSG_PREFIX = "Unable to construct script definition: "
|
||||
@@ -42,7 +42,7 @@ open class ScriptDefinitionFromAnnotatedBaseClass(val environment: ScriptingEnvi
|
||||
override val compilationConfigurator =
|
||||
baseClass.findAnnotation<KotlinScriptCompilationConfigurator>()?.compilationConfigurator?.instantiateScriptHandler()
|
||||
?: explicitDefinition?.compilationConfigurator
|
||||
?: PassThroughCompilationConfigurator::class.instantiateScriptHandler()
|
||||
?: AnnotationsBasedCompilationConfigurator::class.instantiateScriptHandler()
|
||||
|
||||
override val evaluator =
|
||||
baseClass.findAnnotation<KotlinScriptEvaluator>()?.evaluator?.instantiateScriptHandler()
|
||||
|
||||
@@ -17,7 +17,7 @@ class 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?>>) :
|
||||
this(parent, HashMap<TypedKey<*>, Any?>().also { it.putAll(pairs) })
|
||||
|
||||
|
||||
Reference in New Issue
Block a user