From e8fa139dc84809159aabc2c017035921c8f10c76 Mon Sep 17 00:00:00 2001 From: Ilya Chernikov Date: Thu, 11 Jul 2019 16:23:17 +0200 Subject: [PATCH] Move direct properties configuration code into public functions in scripting host jar --- .../jsr223/KotlinJsr223DefaultScript.kt | 54 +++--------------- .../jvmhost/jsr223/propertiesFromContext.kt | 57 +++++++++++++++++++ 2 files changed, 64 insertions(+), 47 deletions(-) create mode 100644 libraries/scripting/jvm-host/src/kotlin/script/experimental/jvmhost/jsr223/propertiesFromContext.kt diff --git a/libraries/scripting/jsr223/src/kotlin/script/experimental/jsr223/KotlinJsr223DefaultScript.kt b/libraries/scripting/jsr223/src/kotlin/script/experimental/jsr223/KotlinJsr223DefaultScript.kt index 9a14df0af06..1811b1db820 100644 --- a/libraries/scripting/jsr223/src/kotlin/script/experimental/jsr223/KotlinJsr223DefaultScript.kt +++ b/libraries/scripting/jsr223/src/kotlin/script/experimental/jsr223/KotlinJsr223DefaultScript.kt @@ -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) } ) diff --git a/libraries/scripting/jvm-host/src/kotlin/script/experimental/jvmhost/jsr223/propertiesFromContext.kt b/libraries/scripting/jvm-host/src/kotlin/script/experimental/jvmhost/jsr223/propertiesFromContext.kt new file mode 100644 index 00000000000..ed66041f21c --- /dev/null +++ b/libraries/scripting/jvm-host/src/kotlin/script/experimental/jvmhost/jsr223/propertiesFromContext.kt @@ -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 { + 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 { + 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() +} + +