Move direct properties configuration code into public functions in scripting host jar

This commit is contained in:
Ilya Chernikov
2019-07-11 16:23:17 +02:00
parent 89a53fe028
commit e8fa139dc8
2 changed files with 64 additions and 47 deletions
@@ -8,11 +8,13 @@ package kotlin.script.experimental.jsr223
import org.jetbrains.kotlin.cli.common.repl.KOTLIN_SCRIPT_ENGINE_BINDINGS_KEY
import org.jetbrains.kotlin.cli.common.repl.KOTLIN_SCRIPT_STATE_BINDINGS_KEY
import javax.script.Bindings
import javax.script.ScriptContext
import javax.script.ScriptEngine
import kotlin.script.experimental.annotations.KotlinScript
import kotlin.script.experimental.api.*
import kotlin.script.experimental.jvmhost.jsr223.getScriptContext
import kotlin.script.experimental.api.ScriptCompilationConfiguration
import kotlin.script.experimental.api.ScriptEvaluationConfiguration
import kotlin.script.experimental.api.refineConfiguration
import kotlin.script.experimental.api.refineConfigurationBeforeEvaluate
import kotlin.script.experimental.jvmhost.jsr223.configureProvidedPropertiesFromJsr223Context
import kotlin.script.experimental.jvmhost.jsr223.importAllBindings
import kotlin.script.experimental.jvmhost.jsr223.jsr223
import kotlin.script.templates.standard.ScriptTemplateWithBindings
@@ -59,29 +61,7 @@ abstract class KotlinJsr223DefaultScript(val jsr223Bindings: Bindings) : ScriptT
object KotlinJsr223DefaultScriptCompilationConfiguration : ScriptCompilationConfiguration(
{
refineConfiguration {
beforeCompiling { context ->
val jsr223context = context.compilationConfiguration[ScriptCompilationConfiguration.jsr223.getScriptContext]?.invoke()
if (jsr223context != null && context.compilationConfiguration[ScriptCompilationConfiguration.jsr223.importAllBindings] == true) {
val updatedProperties =
context.compilationConfiguration[ScriptCompilationConfiguration.providedProperties]?.toMutableMap() ?: hashMapOf()
val allBindings = (jsr223context.getBindings(ScriptContext.GLOBAL_SCOPE).toMutableMap() ?: hashMapOf()).apply {
val engineBindings = jsr223context.getBindings(ScriptContext.ENGINE_SCOPE)
if (engineBindings != null)
putAll(engineBindings)
}
for ((k, v) in allBindings) {
// only adding bindings that are not already defined
if (!updatedProperties.containsKey(k)) {
// TODO: add only valid names
// TODO: find out how it's implemented in other jsr223 engines for typed languages, since this approach prevent certain usage scenarios, e.g. assigning back value of a "sibling" type
updatedProperties[k] = KotlinType(v::class)
}
}
ScriptCompilationConfiguration(context.compilationConfiguration) {
providedProperties(updatedProperties)
}.asSuccess()
} else context.compilationConfiguration.asSuccess()
}
beforeCompiling(::configureProvidedPropertiesFromJsr223Context)
}
jsr223 {
importAllBindings(true)
@@ -91,26 +71,6 @@ object KotlinJsr223DefaultScriptCompilationConfiguration : ScriptCompilationConf
object KotlinJsr223DefaultScriptEvaluationConfiguration : ScriptEvaluationConfiguration(
{
refineConfigurationBeforeEvaluate { context ->
val jsr223context = context.evaluationConfiguration[ScriptEvaluationConfiguration.jsr223.getScriptContext]?.invoke()
val knownProperties = context.compiledScript.compilationConfiguration[ScriptCompilationConfiguration.providedProperties]
if (jsr223context != null && knownProperties != null && knownProperties.isNotEmpty()) {
val updatedProperties =
context.evaluationConfiguration[ScriptEvaluationConfiguration.providedProperties]?.toMutableMap() ?: hashMapOf()
val engineBindings = jsr223context.getBindings(ScriptContext.ENGINE_SCOPE)
val globalBindings = jsr223context.getBindings(ScriptContext.GLOBAL_SCOPE)
for (prop in knownProperties) {
val v = when {
engineBindings?.containsKey(prop.key) == true -> engineBindings[prop.key]
globalBindings?.containsKey(prop.key) == true -> globalBindings[prop.key]
else -> return@refineConfigurationBeforeEvaluate ResultWithDiagnostics.Failure("Property ${prop.key} is not found in the bindings".asErrorDiagnostics())
}
updatedProperties[prop.key] = v
}
ScriptEvaluationConfiguration(context.evaluationConfiguration) {
providedProperties(updatedProperties)
}.asSuccess()
} else context.evaluationConfiguration.asSuccess()
}
refineConfigurationBeforeEvaluate(::configureProvidedPropertiesFromJsr223Context)
}
)
@@ -0,0 +1,57 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.jvmhost.jsr223
import javax.script.ScriptContext
import kotlin.script.experimental.api.*
fun configureProvidedPropertiesFromJsr223Context(context: ScriptConfigurationRefinementContext): ResultWithDiagnostics<ScriptCompilationConfiguration> {
val jsr223context = context.compilationConfiguration[ScriptCompilationConfiguration.jsr223.getScriptContext]?.invoke()
return if (jsr223context != null && context.compilationConfiguration[ScriptCompilationConfiguration.jsr223.importAllBindings] == true) {
val updatedProperties =
context.compilationConfiguration[ScriptCompilationConfiguration.providedProperties]?.toMutableMap() ?: hashMapOf()
val allBindings = (jsr223context.getBindings(ScriptContext.GLOBAL_SCOPE)?.toMutableMap() ?: hashMapOf()).apply {
val engineBindings = jsr223context.getBindings(ScriptContext.ENGINE_SCOPE)
if (engineBindings != null)
putAll(engineBindings)
}
for ((k, v) in allBindings) {
// only adding bindings that are not already defined
if (!updatedProperties.containsKey(k)) {
// TODO: add only valid names
// TODO: find out how it's implemented in other jsr223 engines for typed languages, since this approach prevent certain usage scenarios, e.g. assigning back value of a "sibling" type
updatedProperties[k] = KotlinType(v::class)
}
}
ScriptCompilationConfiguration(context.compilationConfiguration) {
providedProperties(updatedProperties)
}.asSuccess()
} else context.compilationConfiguration.asSuccess()
}
fun configureProvidedPropertiesFromJsr223Context(context: ScriptEvaluationConfigurationRefinementContext): ResultWithDiagnostics<ScriptEvaluationConfiguration> {
val jsr223context = context.evaluationConfiguration[ScriptEvaluationConfiguration.jsr223.getScriptContext]?.invoke()
val knownProperties = context.compiledScript.compilationConfiguration[ScriptCompilationConfiguration.providedProperties]
return if (jsr223context != null && knownProperties != null && knownProperties.isNotEmpty()) {
val updatedProperties =
context.evaluationConfiguration[ScriptEvaluationConfiguration.providedProperties]?.toMutableMap() ?: hashMapOf()
val engineBindings = jsr223context.getBindings(ScriptContext.ENGINE_SCOPE)
val globalBindings = jsr223context.getBindings(ScriptContext.GLOBAL_SCOPE)
for (prop in knownProperties) {
val v = when {
engineBindings?.containsKey(prop.key) == true -> engineBindings[prop.key]
globalBindings?.containsKey(prop.key) == true -> globalBindings[prop.key]
else -> return ResultWithDiagnostics.Failure("Property ${prop.key} is not found in the bindings".asErrorDiagnostics())
}
updatedProperties[prop.key] = v
}
ScriptEvaluationConfiguration(context.evaluationConfiguration) {
providedProperties(updatedProperties)
}.asSuccess()
} else context.evaluationConfiguration.asSuccess()
}