Extend evaluation API for easier passing of evaluation configuration
refactor helpers accordingly
This commit is contained in:
+4
-4
@@ -39,12 +39,12 @@ abstract class BasicScriptingHost(
|
||||
*/
|
||||
open fun eval(
|
||||
script: SourceCode,
|
||||
scriptCompilationConfiguration: ScriptCompilationConfiguration,
|
||||
configuration: ScriptEvaluationConfiguration?
|
||||
compilationConfiguration: ScriptCompilationConfiguration,
|
||||
evaluationConfiguration: ScriptEvaluationConfiguration?
|
||||
): ResultWithDiagnostics<EvaluationResult> =
|
||||
runInCoroutineContext {
|
||||
compiler(script, scriptCompilationConfiguration).onSuccess {
|
||||
evaluator(it, configuration)
|
||||
compiler(script, compilationConfiguration).onSuccess {
|
||||
evaluator(it, evaluationConfiguration ?: ScriptEvaluationConfiguration.Default)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+69
-39
@@ -8,6 +8,7 @@ package kotlin.script.experimental.host
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.script.experimental.annotations.KotlinScript
|
||||
import kotlin.script.experimental.api.*
|
||||
import kotlin.script.experimental.util.PropertiesCollection
|
||||
|
||||
private const val ERROR_MSG_PREFIX = "Unable to construct script definition: "
|
||||
|
||||
@@ -20,7 +21,7 @@ private const val SCRIPT_RUNTIME_TEMPLATES_PACKAGE = "kotlin.script.templates.st
|
||||
private abstract class DummyScriptTemplate
|
||||
|
||||
/**
|
||||
* Creates the compilation configuration from annotated script base class
|
||||
* Creates compilation configuration from annotated script base class
|
||||
* @param baseClassType the annotated script base class to construct the configuration from
|
||||
* @param hostConfiguration scripting host configuration properties
|
||||
* @param contextClass optional context class to extract classloading strategy from
|
||||
@@ -33,48 +34,70 @@ fun createCompilationConfigurationFromTemplate(
|
||||
body: ScriptCompilationConfiguration.Builder.() -> Unit = {}
|
||||
): ScriptCompilationConfiguration {
|
||||
|
||||
val templateClass: KClass<*> = baseClassType.getTemplateClass(hostConfiguration, contextClass)
|
||||
|
||||
val mainAnnotation: KotlinScript = templateClass.kotlinScriptAnnotation
|
||||
|
||||
return ScriptCompilationConfiguration(scriptConfigInstance(mainAnnotation.compilationConfiguration)) {
|
||||
propertiesFromTemplate(templateClass, baseClassType, mainAnnotation)
|
||||
body()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates evaluation configuration from annotated script base class
|
||||
* @param baseClassType the annotated script base class to construct the configuration from
|
||||
* @param hostConfiguration scripting host configuration properties
|
||||
* @param contextClass optional context class to extract classloading strategy from
|
||||
* @param body optional configuration function to add more properties to the evaluation configuration
|
||||
*/
|
||||
fun createEvaluationConfigurationFromTemplate(
|
||||
baseClassType: KotlinType,
|
||||
hostConfiguration: ScriptingHostConfiguration,
|
||||
contextClass: KClass<*> = ScriptEvaluationConfiguration::class,
|
||||
body: ScriptEvaluationConfiguration.Builder.() -> Unit = {}
|
||||
): ScriptEvaluationConfiguration {
|
||||
|
||||
val templateClass: KClass<*> = baseClassType.getTemplateClass(hostConfiguration, contextClass)
|
||||
|
||||
val mainAnnotation = templateClass.kotlinScriptAnnotation
|
||||
|
||||
return ScriptEvaluationConfiguration(scriptConfigInstance(mainAnnotation.evaluationConfiguration), body = body)
|
||||
}
|
||||
|
||||
private fun ScriptCompilationConfiguration.Builder.propertiesFromTemplate(
|
||||
templateClass: KClass<*>, baseClassType: KotlinType, mainAnnotation: KotlinScript
|
||||
) {
|
||||
if (baseClass() == null) {
|
||||
baseClass(if (templateClass == baseClassType.fromClass) baseClassType else KotlinType(templateClass))
|
||||
}
|
||||
if (fileExtension() == null) {
|
||||
fileExtension(mainAnnotation.fileExtension)
|
||||
}
|
||||
if (displayName() == null) {
|
||||
displayName(mainAnnotation.displayName)
|
||||
}
|
||||
}
|
||||
|
||||
private val KClass<*>.kotlinScriptAnnotation: KotlinScript
|
||||
get() = findAnnotation()
|
||||
?: when (this@kotlinScriptAnnotation.qualifiedName) {
|
||||
// transitions to the new scripting API: substituting annotations for standard templates from script-runtime
|
||||
"$SCRIPT_RUNTIME_TEMPLATES_PACKAGE.SimpleScriptTemplate",
|
||||
"$SCRIPT_RUNTIME_TEMPLATES_PACKAGE.ScriptTemplateWithArgs",
|
||||
"$SCRIPT_RUNTIME_TEMPLATES_PACKAGE.ScriptTemplateWithBindings" -> DummyScriptTemplate::class.findAnnotation<KotlinScript>()
|
||||
else -> null
|
||||
}
|
||||
?: throw IllegalArgumentException("${ERROR_MSG_PREFIX}Expecting KotlinScript annotation on the ${this}")
|
||||
|
||||
private fun KotlinType.getTemplateClass(hostConfiguration: ScriptingHostConfiguration, contextClass: KClass<*>): KClass<*> {
|
||||
val getScriptingClass = hostConfiguration[ScriptingHostConfiguration.getScriptingClass]
|
||||
?: throw IllegalArgumentException("${ERROR_MSG_PREFIX}Expecting 'getScriptingClass' parameter in the scripting host configuration")
|
||||
|
||||
val baseClass: KClass<*> =
|
||||
try {
|
||||
getScriptingClass(baseClassType, contextClass, hostConfiguration)
|
||||
} catch (e: Throwable) {
|
||||
throw IllegalArgumentException("${ERROR_MSG_PREFIX}Unable to load base class $baseClassType", e)
|
||||
}
|
||||
val loadedBaseClassType = if (baseClass == baseClassType.fromClass) baseClassType else KotlinType(baseClass)
|
||||
|
||||
val mainAnnotation = baseClass.findAnnotation<KotlinScript>()
|
||||
?: run {
|
||||
// transitions to the new scripting API:
|
||||
// substituting annotations for standard templates from script-runtime
|
||||
when (baseClass.qualifiedName) {
|
||||
"$SCRIPT_RUNTIME_TEMPLATES_PACKAGE.SimpleScriptTemplate",
|
||||
"$SCRIPT_RUNTIME_TEMPLATES_PACKAGE.ScriptTemplateWithArgs",
|
||||
"$SCRIPT_RUNTIME_TEMPLATES_PACKAGE.ScriptTemplateWithBindings" -> DummyScriptTemplate::class
|
||||
else -> null
|
||||
}?.findAnnotation<KotlinScript>()
|
||||
}
|
||||
?: throw IllegalArgumentException("${ERROR_MSG_PREFIX}Expecting KotlinScript annotation on the $baseClass")
|
||||
|
||||
fun scriptConfigInstance(kclass: KClass<out ScriptCompilationConfiguration>): ScriptCompilationConfiguration = try {
|
||||
kclass.objectInstance ?: kclass.createInstance()
|
||||
return try {
|
||||
getScriptingClass(this, contextClass, hostConfiguration)
|
||||
} catch (e: Throwable) {
|
||||
throw IllegalArgumentException("$ILLEGAL_CONFIG_ANN_ARG: ${e.message}", e)
|
||||
}
|
||||
|
||||
return ScriptCompilationConfiguration(scriptConfigInstance(mainAnnotation.compilationConfiguration)) {
|
||||
if (baseClass() == null) {
|
||||
baseClass(loadedBaseClassType)
|
||||
}
|
||||
if (fileExtension() == null) {
|
||||
fileExtension(mainAnnotation.fileExtension)
|
||||
}
|
||||
if (displayName() == null) {
|
||||
displayName(mainAnnotation.displayName)
|
||||
}
|
||||
|
||||
body()
|
||||
throw IllegalArgumentException("${ERROR_MSG_PREFIX}Unable to load base class ${this}", e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,3 +113,10 @@ private fun <T : Any> KClass<T>.createInstance(): T {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return noArgsConstructor.newInstance() as T
|
||||
}
|
||||
|
||||
private fun <T : PropertiesCollection> scriptConfigInstance(kclass: KClass<out T>): T = try {
|
||||
kclass.objectInstance ?: kclass.createInstance()
|
||||
} catch (e: Throwable) {
|
||||
throw IllegalArgumentException("$ILLEGAL_CONFIG_ANN_ARG: ${e.message}", e)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user