Add basic bindings support to IDEA JSR223 scripting, fix evaluator
This commit is contained in:
+1
-1
@@ -57,7 +57,7 @@ open class GenericReplCompiledEvaluator(baseClasspath: Iterable<File>, baseClass
|
|||||||
(compiledLoadedClassesHistory.map { it.second.klass } +
|
(compiledLoadedClassesHistory.map { it.second.klass } +
|
||||||
(scriptArgs?.asIterable()
|
(scriptArgs?.asIterable()
|
||||||
?.mapIndexed { i, it ->
|
?.mapIndexed { i, it ->
|
||||||
it?.javaClass ?: if (i < (scriptArgsTypes?.size ?: 0)) scriptArgsTypes!![i] else Any::class.java
|
if (i < (scriptArgsTypes?.size ?: 0)) scriptArgsTypes!![i] else it?.javaClass ?: Any::class.java
|
||||||
}
|
}
|
||||||
?: emptyList()
|
?: emptyList()
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -22,7 +22,10 @@ import org.jetbrains.kotlin.cli.common.repl.GenericReplCompiledEvaluator
|
|||||||
import org.jetbrains.kotlin.cli.common.repl.ReplCodeLine
|
import org.jetbrains.kotlin.cli.common.repl.ReplCodeLine
|
||||||
import org.jetbrains.kotlin.cli.common.repl.ReplCompileResult
|
import org.jetbrains.kotlin.cli.common.repl.ReplCompileResult
|
||||||
import org.jetbrains.kotlin.cli.common.repl.ReplEvalResult
|
import org.jetbrains.kotlin.cli.common.repl.ReplEvalResult
|
||||||
import org.jetbrains.kotlin.daemon.client.*
|
import org.jetbrains.kotlin.daemon.client.DaemonReportMessage
|
||||||
|
import org.jetbrains.kotlin.daemon.client.DaemonReportingTargets
|
||||||
|
import org.jetbrains.kotlin.daemon.client.KotlinCompilerClient
|
||||||
|
import org.jetbrains.kotlin.daemon.client.KotlinRemoteReplCompiler
|
||||||
import org.jetbrains.kotlin.daemon.common.*
|
import org.jetbrains.kotlin.daemon.common.*
|
||||||
import org.jetbrains.kotlin.utils.PathUtil
|
import org.jetbrains.kotlin.utils.PathUtil
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -34,7 +37,7 @@ class KotlinJvmJsr223ScriptEngine4Idea(
|
|||||||
private val factory: ScriptEngineFactory,
|
private val factory: ScriptEngineFactory,
|
||||||
templateClasspath: List<File>,
|
templateClasspath: List<File>,
|
||||||
templateClassName: String,
|
templateClassName: String,
|
||||||
scriptArgs: Array<Any?>?,
|
getScriptArgs: (ScriptContext) -> Array<Any?>?,
|
||||||
scriptArgsTypes: Array<Class<*>>?
|
scriptArgsTypes: Array<Class<*>>?
|
||||||
) : AbstractScriptEngine(), ScriptEngine {
|
) : AbstractScriptEngine(), ScriptEngine {
|
||||||
|
|
||||||
@@ -63,7 +66,8 @@ class KotlinJvmJsr223ScriptEngine4Idea(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val localEvaluator by lazy { GenericReplCompiledEvaluator(emptyList(), Thread.currentThread().contextClassLoader, scriptArgs, scriptArgsTypes) }
|
// 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) }
|
||||||
|
|
||||||
private var lineCount = 0
|
private var lineCount = 0
|
||||||
|
|
||||||
|
|||||||
+10
-3
@@ -19,6 +19,8 @@ package org.jetbrains.kotlin.jsr223
|
|||||||
import com.intellij.openapi.util.Disposer
|
import com.intellij.openapi.util.Disposer
|
||||||
import org.jetbrains.kotlin.cli.common.KotlinVersion
|
import org.jetbrains.kotlin.cli.common.KotlinVersion
|
||||||
import org.jetbrains.kotlin.utils.PathUtil
|
import org.jetbrains.kotlin.utils.PathUtil
|
||||||
|
import javax.script.Bindings
|
||||||
|
import javax.script.ScriptContext
|
||||||
import javax.script.ScriptEngine
|
import javax.script.ScriptEngine
|
||||||
import javax.script.ScriptEngineFactory
|
import javax.script.ScriptEngineFactory
|
||||||
|
|
||||||
@@ -38,9 +40,14 @@ class KotlinJvmJsr223StandardScriptEngineFactory4Idea : ScriptEngineFactory {
|
|||||||
Disposer.newDisposable(),
|
Disposer.newDisposable(),
|
||||||
this,
|
this,
|
||||||
listOf(PathUtil.getKotlinPathsForIdeaPlugin().runtimePath),
|
listOf(PathUtil.getKotlinPathsForIdeaPlugin().runtimePath),
|
||||||
"kotlin.script.StandardScriptTemplate",
|
"kotlin.script.ScriptTemplateWithArgsAndBindings",
|
||||||
arrayOf(emptyArray<String>()),
|
{ ctx ->
|
||||||
null)
|
val bindings = ctx.getBindings(ScriptContext.ENGINE_SCOPE)
|
||||||
|
arrayOf(
|
||||||
|
(bindings[ScriptEngine.ARGV] as? Array<*>) ?: emptyArray<String>(),
|
||||||
|
bindings) },
|
||||||
|
arrayOf(Array<String>::class.java, java.util.Map::class.java)
|
||||||
|
)
|
||||||
|
|
||||||
override fun getOutputStatement(toDisplay: String?): String = "print(\"$toDisplay\")"
|
override fun getOutputStatement(toDisplay: String?): String = "print(\"$toDisplay\")"
|
||||||
override fun getMethodCallSyntax(obj: String, m: String, vararg args: String): String = "$obj.$m(${args.joinToString()})"
|
override fun getMethodCallSyntax(obj: String, m: String, vararg args: String): String = "$obj.$m(${args.joinToString()})"
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ package org.jetbrains.kotlin.idea.repl
|
|||||||
|
|
||||||
import com.intellij.testFramework.PlatformTestCase
|
import com.intellij.testFramework.PlatformTestCase
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
import javax.script.ScriptContext
|
||||||
|
import javax.script.ScriptEngine
|
||||||
import javax.script.ScriptEngineManager
|
import javax.script.ScriptEngineManager
|
||||||
import javax.script.ScriptException
|
import javax.script.ScriptException
|
||||||
import kotlin.test.assertFails
|
import kotlin.test.assertFails
|
||||||
@@ -42,4 +44,21 @@ class IdeaJsr223Test : PlatformTestCase() {
|
|||||||
assertEquals(7, res2)
|
assertEquals(7, res2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testJsr223ScriptWithBindings() {
|
||||||
|
val semgr = ScriptEngineManager()
|
||||||
|
|
||||||
|
val engine = semgr.getEngineByName("kotlin")
|
||||||
|
|
||||||
|
val bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE)
|
||||||
|
|
||||||
|
bindings.put(ScriptEngine.ARGV, arrayOf("42"))
|
||||||
|
bindings.put("abc", 13)
|
||||||
|
|
||||||
|
val res1 = engine.eval("2 + args[0].toInt()")
|
||||||
|
assertEquals(44, res1)
|
||||||
|
|
||||||
|
val res2 = engine.eval("2 + (bindings[\"abc\"] as Int)")
|
||||||
|
assertEquals(15, res2)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user