Implement direct bindings to script properties mapping in the JSR-223 implementation

fix infrastructure and codegen parts
This commit is contained in:
Ilya Chernikov
2019-07-02 12:00:58 +02:00
parent 4940f64265
commit cfceeb1e8c
8 changed files with 252 additions and 12 deletions
@@ -0,0 +1,54 @@
/*
* 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.*
import kotlin.script.experimental.host.ScriptingHostConfiguration
import kotlin.script.experimental.host.ScriptingHostConfigurationKeys
import kotlin.script.experimental.util.PropertiesCollection
interface Jsr223HostConfigurationKeys
open class Jsr223HostConfigurationBuilder : PropertiesCollection.Builder(),
Jsr223HostConfigurationKeys {
companion object : Jsr223HostConfigurationBuilder()
}
val ScriptingHostConfigurationKeys.jsr223 get() = Jsr223HostConfigurationBuilder()
val Jsr223HostConfigurationKeys.getScriptContext by PropertiesCollection.key<() -> ScriptContext?>()
interface Jsr223CompilationConfigurationKeys
open class Jsr223CompilationConfigurationBuilder : PropertiesCollection.Builder(),
Jsr223CompilationConfigurationKeys {
companion object : Jsr223CompilationConfigurationBuilder()
}
val ScriptCompilationConfigurationKeys.jsr223 get() = Jsr223CompilationConfigurationBuilder()
val Jsr223CompilationConfigurationKeys.getScriptContext by PropertiesCollection.key<() -> ScriptContext?> {
get(ScriptCompilationConfiguration.hostConfiguration)?.get(ScriptingHostConfiguration.jsr223.getScriptContext)
}
val Jsr223CompilationConfigurationKeys.importAllBindings by PropertiesCollection.key<Boolean>(false)
interface Jsr223EvaluationConfigurationKeys
open class Jsr223EvaluationConfigurationBuilder : PropertiesCollection.Builder(),
Jsr223EvaluationConfigurationKeys {
companion object : Jsr223EvaluationConfigurationBuilder()
}
val ScriptEvaluationConfigurationKeys.jsr223 get() = Jsr223EvaluationConfigurationBuilder()
val Jsr223EvaluationConfigurationKeys.getScriptContext by PropertiesCollection.key<() -> ScriptContext?> {
get(ScriptEvaluationConfiguration.hostConfiguration)?.get(ScriptingHostConfiguration.jsr223.getScriptContext)
}
@@ -12,7 +12,10 @@ import javax.script.ScriptContext
import javax.script.ScriptEngineFactory
import kotlin.script.experimental.api.ScriptCompilationConfiguration
import kotlin.script.experimental.api.ScriptEvaluationConfiguration
import kotlin.script.experimental.api.hostConfiguration
import kotlin.script.experimental.host.ScriptingHostConfiguration
import kotlin.script.experimental.jvm.baseClassLoader
import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration
import kotlin.script.experimental.jvm.jvm
import kotlin.script.experimental.jvmhost.repl.JvmReplCompiler
import kotlin.script.experimental.jvmhost.repl.JvmReplEvaluator
@@ -22,13 +25,35 @@ import kotlin.script.experimental.jvmhost.repl.JvmReplEvaluatorState
class KotlinJsr223ScriptEngineImpl(
factory: ScriptEngineFactory,
val compilationConfiguration: ScriptCompilationConfiguration,
val evaluationConfiguration: ScriptEvaluationConfiguration
baseCompilationConfiguration: ScriptCompilationConfiguration,
baseEvaluationConfiguration: ScriptEvaluationConfiguration
) : KotlinJsr223JvmScriptEngineBase(factory), KotlinJsr223InvocableScriptEngine {
@Volatile
private var lastScriptContext: ScriptContext? = null
val jsr223HostConfiguration = ScriptingHostConfiguration(defaultJvmScriptingHostConfiguration) {
jsr223 {
getScriptContext { lastScriptContext ?: getContext() }
}
}
val compilationConfiguration by lazy {
ScriptCompilationConfiguration(baseCompilationConfiguration) {
hostConfiguration(jsr223HostConfiguration)
}
}
val evaluationConfiguration by lazy {
ScriptEvaluationConfiguration(baseEvaluationConfiguration) {
hostConfiguration(jsr223HostConfiguration)
}
}
override val replCompiler: ReplCompiler by lazy {
JvmReplCompiler(compilationConfiguration)
}
private val localEvaluator by lazy {
GenericReplCompilingEvaluatorBase(replCompiler, JvmReplEvaluator(evaluationConfiguration))
}
@@ -50,5 +75,15 @@ class KotlinJsr223ScriptEngineImpl(
override val baseClassLoader: ClassLoader
get() = evaluationConfiguration[ScriptEvaluationConfiguration.jvm.baseClassLoader]!!
override fun compileAndEval(script: String, context: ScriptContext): Any? {
// TODO: find a way to pass context to evaluation directly and avoid this hack
lastScriptContext = context
return try {
super.compileAndEval(script, context)
} finally {
lastScriptContext = null
}
}
}
@@ -71,7 +71,11 @@ class JvmReplEvaluator(
}
else -> throw IllegalStateException("Expecting value with script instance, got $retVal")
}
else -> ReplEvalResult.Error.Runtime(res.reports.joinToString("\n") { it.message + (it.exception?.let { e -> ": $e" } ?: "") })
else ->
ReplEvalResult.Error.Runtime(
res.reports.joinToString("\n") { it.message + (it.exception?.let { e -> ": $e" } ?: "") },
res.reports.find { it.exception != null }?.exception as? Exception
)
}
}
}