diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/repl/GenericReplCompiledEvaluator.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/repl/GenericReplCompiledEvaluator.kt index c2e2277f9f7..541247e2543 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/repl/GenericReplCompiledEvaluator.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/repl/GenericReplCompiledEvaluator.kt @@ -16,20 +16,18 @@ package org.jetbrains.kotlin.cli.common.repl -import org.jetbrains.kotlin.utils.tryCreateCallableMapping import org.jetbrains.kotlin.resolve.jvm.JvmClassName import java.io.File import java.net.URLClassLoader import java.util.concurrent.locks.ReentrantReadWriteLock import kotlin.concurrent.read import kotlin.concurrent.write -import kotlin.reflect.* open class GenericReplCompiledEvaluator(baseClasspath: Iterable, baseClassloader: ClassLoader?, val scriptArgs: Array? = null, val scriptArgsTypes: Array>? = null -) : ReplCompiledEvaluator, ReplScriptInvoker { +) : ReplCompiledEvaluator { private var classLoader: org.jetbrains.kotlin.cli.common.repl.ReplClassLoader = makeReplClassLoader(baseClassloader, baseClasspath) private val classLoaderLock = ReentrantReadWriteLock() @@ -37,8 +35,6 @@ open class GenericReplCompiledEvaluator(baseClasspath: Iterable, // TODO: consider to expose it as a part of (evaluator, invoker) interface private val evalStateLock = ReentrantReadWriteLock() - private data class ClassWithInstance(val klass: Class<*>, val instance: Any) - private val compiledLoadedClassesHistory = ReplHistory() override fun eval(codeLine: ReplCodeLine, @@ -83,7 +79,7 @@ open class GenericReplCompiledEvaluator(baseClasspath: Iterable, } val constructorParams: Array> = - (compiledLoadedClassesHistory.values.map { it.klass } + + (compiledLoadedClassesHistory.values.map { it.klass.java } + (scriptArgs?.mapIndexed { i, it -> scriptArgsTypes?.getOrNull(i) ?: it?.javaClass ?: Any::class.java } ?: emptyList()) ).toTypedArray() val constructorArgs: Array = (compiledLoadedClassesHistory.values.map { it.instance } + scriptArgs.orEmpty()).toTypedArray() @@ -98,7 +94,7 @@ open class GenericReplCompiledEvaluator(baseClasspath: Iterable, return ReplEvalResult.Error.Runtime(compiledLoadedClassesHistory.lines, renderReplStackTrace(e.cause!!, startFromMethodName = "${scriptClass.name}."), e as? Exception) } - compiledLoadedClassesHistory.add(codeLine, ClassWithInstance(scriptClass, scriptInstance)) + compiledLoadedClassesHistory.add(codeLine, ClassWithInstance(scriptClass.kotlin, scriptInstance)) val rvField = scriptClass.getDeclaredField(SCRIPT_RESULT_FIELD_NAME).apply { isAccessible = true } val rv: Any? = rvField.get(scriptInstance) @@ -106,40 +102,7 @@ open class GenericReplCompiledEvaluator(baseClasspath: Iterable, return if (hasResult) ReplEvalResult.ValueResult(compiledLoadedClassesHistory.lines, rv) else ReplEvalResult.UnitResult(compiledLoadedClassesHistory.lines) } - override fun getInterface(klass: KClass): ReplScriptInvokeResult = evalStateLock.read { - val (_, instance) = compiledLoadedClassesHistory.values.lastOrNull() ?: return ReplScriptInvokeResult.Error.NoSuchEntity("no script ") - return getInterface(instance, klass) - } - - override fun getInterface(receiver: Any, klass: KClass): ReplScriptInvokeResult = evalStateLock.read { - return ReplScriptInvokeResult.ValueResult(klass.safeCast(receiver)) - } - - override fun invokeMethod(receiver: Any, name: String, vararg args: Any?, invokeWrapper: InvokeWrapper?): ReplScriptInvokeResult = evalStateLock.read { - return invokeImpl(receiver.javaClass.kotlin, receiver, name, args, invokeWrapper) - } - - override fun invokeFunction(name: String, vararg args: Any?, invokeWrapper: InvokeWrapper?): ReplScriptInvokeResult = evalStateLock.read { - val (klass, instance) = compiledLoadedClassesHistory.values.lastOrNull() ?: return ReplScriptInvokeResult.Error.NoSuchEntity("no script ") - return invokeImpl(klass.kotlin, instance, name, args, invokeWrapper) - } - - private fun invokeImpl(receiverClass: KClass<*>, receiverInstance: Any, name: String, args: Array, invokeWrapper: InvokeWrapper?): ReplScriptInvokeResult { - - val candidates = receiverClass.memberFunctions.filter { it.name == name } + - receiverClass.memberExtensionFunctions.filter { it.name == name } - val (fn, mapping) = candidates.findMapping(args.toList()) ?: - candidates.findMapping(listOf(receiverInstance) + args) ?: - return ReplScriptInvokeResult.Error.NoSuchEntity("no suitable function '$name' found") - val res = try { - invokeWrapper?.invoke { fn.callBy(mapping) } ?: fn.callBy(mapping) - } - catch (e: Throwable) { - // ignore everything in the stack trace until this constructor call - return ReplScriptInvokeResult.Error.Runtime(renderReplStackTrace(e.cause!!, startFromMethodName = "${fn.name}"), e as? Exception) - } - return if (fn.returnType.classifier == Unit::class) ReplScriptInvokeResult.UnitResult else ReplScriptInvokeResult.ValueResult(res) - } + override val lastEvaluatedScript: ClassWithInstance? get() = evalStateLock.read { compiledLoadedClassesHistory.values.lastOrNull() } companion object { private val SCRIPT_RESULT_FIELD_NAME = "\$\$result" @@ -149,10 +112,3 @@ open class GenericReplCompiledEvaluator(baseClasspath: Iterable, private fun makeReplClassLoader(baseClassloader: ClassLoader?, baseClasspath: Iterable) = ReplClassLoader(URLClassLoader(baseClasspath.map { it.toURI().toURL() }.toTypedArray(), baseClassloader)) -private fun Iterable>.findMapping(args: List): Pair, Map>? { - for (fn in this) { - val mapping = tryCreateCallableMapping(fn, args) - if (mapping != null) return fn to mapping - } - return null -} diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/repl/KotlinJsr223JvmInvocableScriptEngine.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/repl/KotlinJsr223JvmInvocableScriptEngine.kt index 4a343da17e1..37a5ca04def 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/repl/KotlinJsr223JvmInvocableScriptEngine.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/repl/KotlinJsr223JvmInvocableScriptEngine.kt @@ -16,45 +16,71 @@ package org.jetbrains.kotlin.cli.common.repl +import org.jetbrains.kotlin.utils.tryCreateCallableMapping import javax.script.Invocable import javax.script.ScriptException +import kotlin.reflect.* @Suppress("unused") // used externally (kotlin.script.utils) interface KotlinJsr223JvmInvocableScriptEngine : Invocable { - val replScriptInvoker: ReplScriptInvoker + val replScriptEvaluator: ReplEvaluatorBase + + fun getInterface(klass: KClass): Any? { + val (_, instance) = replScriptEvaluator.lastEvaluatedScript ?: throw IllegalArgumentException("no script ") + return getInterface(instance, klass) + } + + fun getInterface(receiver: Any, klass: KClass): Any? { + return klass.safeCast(receiver) + } override fun invokeFunction(name: String?, vararg args: Any?): Any? { if (name == null) throw java.lang.NullPointerException("function name cannot be null") - return processInvokeResult(replScriptInvoker.invokeFunction(name, *args), isMethod = true) + val (klass, instance) = replScriptEvaluator.lastEvaluatedScript ?: throw IllegalArgumentException("no script ") + return invokeImpl(klass, instance, name, args, invokeWrapper = null) } override fun invokeMethod(thiz: Any?, name: String?, vararg args: Any?): Any? { if (name == null) throw java.lang.NullPointerException("method name cannot be null") if (thiz == null) throw IllegalArgumentException("cannot invoke method on the null object") - return processInvokeResult(replScriptInvoker.invokeMethod(thiz, name, *args), isMethod = true) + return invokeImpl(thiz.javaClass.kotlin, thiz, name, args, invokeWrapper = null) } override fun getInterface(clasz: Class?): T? { - if (clasz == null) throw IllegalArgumentException("class object cannot be null") - if (!clasz.isInterface) throw IllegalArgumentException("expecting interface") - return processInvokeResult(replScriptInvoker.getInterface(clasz.kotlin), isMethod = false) as? T + val (_, instance) = replScriptEvaluator.lastEvaluatedScript ?: throw IllegalArgumentException("no script ") + return getInterface(instance, clasz) } override fun getInterface(thiz: Any?, clasz: Class?): T? { if (thiz == null) throw IllegalArgumentException("object cannot be null") if (clasz == null) throw IllegalArgumentException("class object cannot be null") if (!clasz.isInterface) throw IllegalArgumentException("expecting interface") - return processInvokeResult(replScriptInvoker.getInterface(thiz, clasz.kotlin), isMethod = false) as? T + return clasz.kotlin.safeCast(thiz) } +} - private fun processInvokeResult(res: ReplScriptInvokeResult, isMethod: Boolean): Any? = - when (res) { - is ReplScriptInvokeResult.Error.NoSuchEntity -> throw if (isMethod) NoSuchMethodException(res.message) else IllegalArgumentException(res.message) - is ReplScriptInvokeResult.Error.CompileTime -> throw IllegalArgumentException(res.message) // should not happen in the current code, so leaving it here despite the contradiction with Invocable's specs - is ReplScriptInvokeResult.Error.Runtime -> throw ScriptException(res.message) - is ReplScriptInvokeResult.Error -> throw ScriptException(res.message) - is ReplScriptInvokeResult.UnitResult -> Unit // TODO: check if it is suitable replacement for java's Void - is ReplScriptInvokeResult.ValueResult -> res.value - } -} \ No newline at end of file +private fun invokeImpl(receiverClass: KClass<*>, receiverInstance: Any, name: String, args: Array, invokeWrapper: InvokeWrapper?): Any? { + + val candidates = receiverClass.functions.filter { it.name == name } + val (fn, mapping) = candidates.findMapping(listOf(receiverInstance) + args) ?: + throw NoSuchMethodException("no suitable function '$name' found") + val res = try { + invokeWrapper?.invoke { + fn.callBy(mapping) + } ?: fn.callBy(mapping) + } + catch (e: Throwable) { + // ignore everything in the stack trace until this constructor call + throw ScriptException(renderReplStackTrace(e.cause!!, startFromMethodName = fn.name)) + } + return if (fn.returnType.classifier == Unit::class) Unit else res +} + +private fun Iterable>.findMapping(args: List): Pair, Map>? { + for (fn in this) { + val mapping = tryCreateCallableMapping(fn, args) + if (mapping != null) return fn to mapping + } + return null +} diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/repl/Repl.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/repl/Repl.kt index e1b0d8d67fc..d631f4d93b7 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/repl/Repl.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/repl/Repl.kt @@ -28,6 +28,8 @@ data class ReplCodeLine(val no: Int, val code: String) : Serializable { } } +data class ClassWithInstance(val klass: KClass<*>, val instance: Any) + // TODO: consider storing code hash where source is not needed data class CompiledClassData(val path: String, val bytes: ByteArray) : Serializable { @@ -73,22 +75,6 @@ sealed class ReplCompileResult(val updatedHistory: List) : Seriali } } -sealed class ReplScriptInvokeResult : Serializable { - class ValueResult(val value: Any?) : ReplScriptInvokeResult() { - override fun toString(): String = "Result: $value" - } - object UnitResult : ReplScriptInvokeResult() - sealed class Error(val message: String) : ReplScriptInvokeResult() { - class Runtime(message: String, val cause: Exception? = null) : Error(message) - class NoSuchEntity(message: String) : Error(message) - class CompileTime(message: String, val location: CompilerMessageLocation = CompilerMessageLocation.NO_LOCATION) : Error(message) - override fun toString(): String = "${this::class.simpleName}Error(message = \"$message\"" - } - companion object { - private val serialVersionUID: Long = 8228357578L - } -} - sealed class ReplEvalResult(val updatedHistory: List) : Serializable { class ValueResult(updatedHistory: List, val value: Any?) : ReplEvalResult(updatedHistory) { override fun toString(): String = "Result: $value" @@ -117,19 +103,11 @@ interface ReplCompiler : ReplChecker { fun compile(codeLine: ReplCodeLine, history: List): ReplCompileResult } -interface ReplScriptInvoker { - fun getInterface(clasz: KClass): ReplScriptInvokeResult - fun getInterface(receiver: Any, clasz: KClass): ReplScriptInvokeResult - fun invokeMethod(receiver: Any, name: String, vararg args: Any?, invokeWrapper: InvokeWrapper? = null): ReplScriptInvokeResult - fun invokeFunction(name: String, vararg args: Any?, invokeWrapper: InvokeWrapper? = null): ReplScriptInvokeResult +interface ReplEvaluatorBase { + val lastEvaluatedScript: ClassWithInstance? } -// TODO this is a bit cumbersome, consider some other ways to access an invoker -interface ReplScriptInvokerProxy { - val scriptInvoker: ReplScriptInvoker -} - -interface ReplCompiledEvaluator { +interface ReplCompiledEvaluator : ReplEvaluatorBase { fun eval(codeLine: ReplCodeLine, history: List, @@ -141,7 +119,7 @@ interface ReplCompiledEvaluator { } -interface ReplEvaluator : ReplChecker { +interface ReplEvaluator : ReplChecker, ReplEvaluatorBase { fun eval(codeLine: ReplCodeLine, history: List, diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/GenericRepl.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/GenericRepl.kt index c0f9f0a9164..ede265431a6 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/GenericRepl.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/GenericRepl.kt @@ -22,7 +22,6 @@ import com.intellij.openapi.vfs.CharsetToolkit import com.intellij.psi.PsiFileFactory import com.intellij.psi.impl.PsiFileFactoryImpl import com.intellij.testFramework.LightVirtualFile -import java.io.File import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport import org.jetbrains.kotlin.cli.common.messages.MessageCollector @@ -44,6 +43,7 @@ import org.jetbrains.kotlin.parsing.KotlinParserDefinition import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.script.KotlinScriptDefinition import org.jetbrains.kotlin.script.KotlinScriptExternalDependencies +import java.io.File private val logger = Logger.getInstance(GenericRepl::class.java) @@ -184,11 +184,11 @@ open class GenericRepl( baseClassloader: ClassLoader?, scriptArgs: Array? = null, scriptArgsTypes: Array>? = null -) : ReplEvaluator, ReplScriptInvokerProxy, GenericReplCompiler(disposable, scriptDefinition, compilerConfiguration, messageCollector) { +) : ReplEvaluator, GenericReplCompiler(disposable, scriptDefinition, compilerConfiguration, messageCollector) { private val compiledEvaluator = GenericReplCompiledEvaluator(compilerConfiguration.jvmClasspathRoots, baseClassloader, scriptArgs, scriptArgsTypes) - override val scriptInvoker: ReplScriptInvoker get() = compiledEvaluator + override val lastEvaluatedScript: ClassWithInstance? get() = compiledEvaluator.lastEvaluatedScript @Synchronized override fun eval(codeLine: ReplCodeLine, history: List, invokeWrapper: InvokeWrapper?): ReplEvalResult = diff --git a/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/KotlinRemoteReplClient.kt b/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/KotlinRemoteReplClient.kt index b99e7eef293..fbc24cf3326 100644 --- a/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/KotlinRemoteReplClient.kt +++ b/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/KotlinRemoteReplClient.kt @@ -106,6 +106,7 @@ class KotlinRemoteReplCompiler( } } +// TODO: consider removing daemon eval completely - it is not required now and has questionable security. This will simplify daemon interface as well class KotlinRemoteReplEvaluator( disposable: Disposable, compileService: CompileService, @@ -138,6 +139,8 @@ class KotlinRemoteReplEvaluator( operationsTracer = operationsTracer ), ReplEvaluator { + override val lastEvaluatedScript: ClassWithInstance? = null // not implemented, no need so far + // TODO: invokeWrapper is ignored here, and in the daemon the session wrapper is used instead; So consider to make it per call (avoid performance penalties though) override fun eval(codeLine: ReplCodeLine, history: List, invokeWrapper: InvokeWrapper?): ReplEvalResult { return compileService.remoteReplLineEval(sessionId, codeLine, history).get() diff --git a/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt b/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt index 2c0b8e5a71e..b50040e11f9 100644 --- a/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt +++ b/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt @@ -324,7 +324,7 @@ class CompileServiceImpl( CompileService.CallResult.Error("Sorry, only JVM target platform is supported now") else { val disposable = Disposer.newDisposable() - val repl = KotlinJvmReplService(disposable, templateClasspath, templateClassName, scriptArgs, scriptArgsTypes, compilerMessagesOutputStream, evalOutputStream, evalErrorStream, evalInputStream, operationsTracer) + val repl = KotlinJvmReplService(disposable, templateClasspath, templateClassName, scriptArgs, scriptArgsTypes, compilerMessagesOutputStream, operationsTracer) val sessionId = state.sessions.leaseSession(ClientOrSessionProxy(aliveFlagPath, repl, disposable)) CompileService.CallResult.Good(sessionId) diff --git a/compiler/daemon/src/org/jetbrains/kotlin/daemon/KotlinRemoteReplService.kt b/compiler/daemon/src/org/jetbrains/kotlin/daemon/KotlinRemoteReplService.kt index 3ea1d8847b6..91d61fe2e04 100644 --- a/compiler/daemon/src/org/jetbrains/kotlin/daemon/KotlinRemoteReplService.kt +++ b/compiler/daemon/src/org/jetbrains/kotlin/daemon/KotlinRemoteReplService.kt @@ -26,13 +26,11 @@ import org.jetbrains.kotlin.cli.jvm.repl.compileAndEval import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.daemon.common.DummyProfiler -import org.jetbrains.kotlin.daemon.common.RemoteInputStream import org.jetbrains.kotlin.daemon.common.RemoteOperationsTracer import org.jetbrains.kotlin.daemon.common.RemoteOutputStream import org.jetbrains.kotlin.script.KotlinScriptDefinition import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromAnnotatedTemplate import org.jetbrains.kotlin.utils.PathUtil -import java.io.BufferedInputStream import java.io.BufferedOutputStream import java.io.File import java.io.PrintStream @@ -45,9 +43,6 @@ open class KotlinJvmReplService( scriptArgs: Array?, scriptArgsTypes: Array>?, compilerOutputStreamProxy: RemoteOutputStream, - evalOutputStream: RemoteOutputStream?, - evalErrorStream: RemoteOutputStream?, - evalInputStream: RemoteInputStream?, val operationsTracer: RemoteOperationsTracer? ) : ReplCompiler, ReplEvaluator { @@ -115,32 +110,12 @@ open class KotlinJvmReplService( else GenericReplCompiler(disposable, scriptDef, configuration, messageCollector) } - private val invokeWrapper : InvokeWrapper? by lazy { - if (evalOutputStream == null && evalErrorStream == null && evalInputStream == null) null - else object : InvokeWrapper { - val out = evalOutputStream?.let { PrintStream(BufferedOutputStream(RemoteOutputStreamClient(it, DummyProfiler()), REMOTE_STREAM_BUFFER_SIZE)) } - val err = evalErrorStream?.let { PrintStream(BufferedOutputStream(RemoteOutputStreamClient(it, DummyProfiler()), REMOTE_STREAM_BUFFER_SIZE)) } - val `in` = evalInputStream?.let { BufferedInputStream(RemoteInputStreamClient(it, DummyProfiler()), REMOTE_STREAM_BUFFER_SIZE) } - override operator fun invoke(body: () -> T): T { - val prevOut = swapOrNull(out, { System.out }, { System.setOut(it) }) - val prevErr = swapOrNull(err, { System.err }, { System.setErr(it) }) - val prevIn = swapOrNull(`in`, { System.`in` }, { System.setIn(it) }) - try { - return body() - } - finally { - prevIn?.let { System.setIn(prevIn) } - prevErr?.let { System.setErr(prevErr) } - prevOut?.let { System.setOut(prevOut) } - } - } - } - } - private val compiledEvaluator : GenericReplCompiledEvaluator by lazy { GenericReplCompiledEvaluator(configuration.jvmClasspathRoots, null, scriptArgs, scriptArgsTypes) } + override val lastEvaluatedScript: ClassWithInstance? get() = compiledEvaluator.lastEvaluatedScript + override fun check(codeLine: ReplCodeLine, history: List): ReplCheckResult { operationsTracer?.before("check") try { @@ -180,10 +155,3 @@ open class KotlinJvmReplService( } } } - -private inline fun swapOrNull(value: T?, get: () -> T, set: (T) -> Unit): T? = - value?.let { - val prevValue = get() - set(value) - prevValue - } \ No newline at end of file diff --git a/libraries/tools/kotlin-script-util/src/main/kotlin/org/jetbrains/kotlin/script/jsr223/KotlinJsr223JvmDaemonCompileScriptEngine.kt b/libraries/tools/kotlin-script-util/src/main/kotlin/org/jetbrains/kotlin/script/jsr223/KotlinJsr223JvmDaemonCompileScriptEngine.kt index 9309f1fa37b..e383830a88d 100644 --- a/libraries/tools/kotlin-script-util/src/main/kotlin/org/jetbrains/kotlin/script/jsr223/KotlinJsr223JvmDaemonCompileScriptEngine.kt +++ b/libraries/tools/kotlin-script-util/src/main/kotlin/org/jetbrains/kotlin/script/jsr223/KotlinJsr223JvmDaemonCompileScriptEngine.kt @@ -58,9 +58,8 @@ class KotlinJsr223JvmDaemonCompileScriptEngine( // TODO: bindings passing works only once on the first eval, subsequent setContext/setBindings call have no effect. Consider making it dynamic, but take history into account val localEvaluator by lazy { GenericReplCompiledEvaluator(templateClasspath, Thread.currentThread().contextClassLoader, getScriptArgs(getContext()), scriptArgsTypes) } - override val replScriptInvoker: ReplScriptInvoker get() = localEvaluator - override val replEvaluator: ReplCompiledEvaluator get() = localEvaluator + override val replScriptEvaluator: ReplEvaluatorBase get() = localEvaluator } diff --git a/libraries/tools/kotlin-script-util/src/main/kotlin/org/jetbrains/kotlin/script/jsr223/KotlinJsr223JvmLocalScriptEngine.kt b/libraries/tools/kotlin-script-util/src/main/kotlin/org/jetbrains/kotlin/script/jsr223/KotlinJsr223JvmLocalScriptEngine.kt index 21b37be5270..f1bc6d671d3 100644 --- a/libraries/tools/kotlin-script-util/src/main/kotlin/org/jetbrains/kotlin/script/jsr223/KotlinJsr223JvmLocalScriptEngine.kt +++ b/libraries/tools/kotlin-script-util/src/main/kotlin/org/jetbrains/kotlin/script/jsr223/KotlinJsr223JvmLocalScriptEngine.kt @@ -51,9 +51,8 @@ class KotlinJsr223JvmLocalScriptEngine( // TODO: bindings passing works only once on the first eval, subsequent setContext/setBindings call have no effect. Consider making it dynamic, but take history into account val localEvaluator by lazy { GenericReplCompiledEvaluator(templateClasspath, Thread.currentThread().contextClassLoader, getScriptArgs(getContext()), scriptArgsTypes) } - override val replScriptInvoker: ReplScriptInvoker get() = localEvaluator - override val replEvaluator: ReplCompiledEvaluator get() = localEvaluator + override val replScriptEvaluator: ReplEvaluatorBase get() = localEvaluator private fun makeScriptDefinition(templateClasspath: List, templateClassName: String): KotlinScriptDefinition { val classloader = URLClassLoader(templateClasspath.map { it.toURI().toURL() }.toTypedArray(), this.javaClass.classLoader)