Implement params to pass args to generic and remote repls to support script templates with params

This commit is contained in:
Ilya Chernikov
2016-09-22 11:36:19 +02:00
parent f0d2f458e0
commit 43037373d7
6 changed files with 30 additions and 7 deletions
@@ -23,7 +23,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock
import kotlin.concurrent.read
import kotlin.concurrent.write
open class GenericReplCompiledEvaluator(baseClasspath: Iterable<File>, baseClassloader: ClassLoader?) : ReplCompiledEvaluator {
open class GenericReplCompiledEvaluator(baseClasspath: Iterable<File>, baseClassloader: ClassLoader?, val scriptArgs: Array<Any?>? = null, val scriptArgsTypes: Array<Class<*>>? = null) : ReplCompiledEvaluator {
private var classLoader: org.jetbrains.kotlin.cli.common.repl.ReplClassLoader =
org.jetbrains.kotlin.cli.common.repl.ReplClassLoader(URLClassLoader(baseClasspath.map { it.toURI().toURL() }.toTypedArray(), baseClassloader))
@@ -53,8 +53,16 @@ open class GenericReplCompiledEvaluator(baseClasspath: Iterable<File>, baseClass
val scriptClass = classLoaderLock.read { classLoader.loadClass("Line${codeLine.no}") }
val constructorParams = compiledLoadedClassesHistory.map { it.second.klass }.toTypedArray()
val constructorArgs = compiledLoadedClassesHistory.map { it.second.instance }.toTypedArray()
val constructorParams: Array<Class<*>> =
(compiledLoadedClassesHistory.map { it.second.klass } +
(scriptArgs?.asIterable()
?.mapIndexed { i, it ->
it?.javaClass ?: if (i < (scriptArgsTypes?.size ?: 0)) scriptArgsTypes!![i] else Any::class.java
}
?: emptyList()
)
).toTypedArray()
val constructorArgs: Array<Any?> = (compiledLoadedClassesHistory.map { it.second.instance } + (scriptArgs?.asIterable() ?: emptyList())).toTypedArray()
val scriptInstanceConstructor = scriptClass.getConstructor(*constructorParams)
val scriptInstance =
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.descriptors.ScriptDescriptor
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.parsing.KotlinParserDefinition
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.script.KotlinScriptDefinition
@@ -35,7 +35,9 @@ open class KotlinRemoteReplClientBase(
targetPlatform: CompileService.TargetPlatform,
templateClasspath: List<File>,
templateClassName: String,
compilerMessagesOutputStream: OutputStream,
scriptArgs: Array<Any?>? = null,
scriptArgsTypes: Array<Class<*>>? = null,
compilerMessagesOutputStream: OutputStream = System.err,
evalOutputStream: OutputStream? = null,
evalErrorStream: OutputStream? = null,
evalInputStream: InputStream? = null,
@@ -49,6 +51,8 @@ open class KotlinRemoteReplClientBase(
CompilerCallbackServicesFacadeServer(port = port),
templateClasspath,
templateClassName,
scriptArgs,
scriptArgsTypes,
RemoteOutputStreamServer(compilerMessagesOutputStream, port),
evalOutputStream?.let { RemoteOutputStreamServer(it, port) },
evalErrorStream?.let { RemoteOutputStreamServer(it, port) },
@@ -104,6 +108,8 @@ class KotlinRemoteReplEvaluator(
targetPlatform: CompileService.TargetPlatform,
templateClasspath: List<File>,
templateClassName: String,
scriptArgs: Array<Any?>?,
scriptArgsTypes: Array<Class<*>>?,
compilerMessagesOutputStream: OutputStream,
evalOutputStream: OutputStream?,
evalErrorStream: OutputStream?,
@@ -117,6 +123,8 @@ class KotlinRemoteReplEvaluator(
targetPlatform = targetPlatform,
templateClasspath = templateClasspath,
templateClassName = templateClassName,
scriptArgs = scriptArgs,
scriptArgsTypes = scriptArgsTypes,
compilerMessagesOutputStream = compilerMessagesOutputStream,
evalOutputStream = evalOutputStream,
evalErrorStream = evalErrorStream,
@@ -132,6 +132,8 @@ interface CompileService : Remote {
servicesFacade: CompilerCallbackServicesFacade,
templateClasspath: List<File>,
templateClassName: String,
scriptArgs: Array<Any?>?,
scriptArgsTypes: Array<Class<*>>?,
compilerMessagesOutputStream: RemoteOutputStream,
evalOutputStream: RemoteOutputStream?,
evalErrorStream: RemoteOutputStream?,
@@ -273,6 +273,8 @@ class CompileServiceImpl(
servicesFacade: CompilerCallbackServicesFacade,
templateClasspath: List<File>,
templateClassName: String,
scriptArgs: Array<Any?>?,
scriptArgsTypes: Array<Class<*>>?,
compilerMessagesOutputStream: RemoteOutputStream,
evalOutputStream: RemoteOutputStream?,
evalErrorStream: RemoteOutputStream?,
@@ -283,7 +285,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, compilerMessagesOutputStream, evalOutputStream, evalErrorStream, evalInputStream, operationsTracer)
val repl = KotlinJvmReplService(disposable, templateClasspath, templateClassName, scriptArgs, scriptArgsTypes, compilerMessagesOutputStream, evalOutputStream, evalErrorStream, evalInputStream, operationsTracer)
val sessionId = leaseSessionImpl(ClientOrSessionProxy(aliveFlagPath, repl, disposable))
CompileService.CallResult.Good(sessionId)
@@ -42,6 +42,8 @@ open class KotlinJvmReplService(
disposable: Disposable,
templateClasspath: List<File>,
templateClassName: String,
scriptArgs: Array<Any?>?,
scriptArgsTypes: Array<Class<*>>?,
compilerOutputStreamProxy: RemoteOutputStream,
evalOutputStream: RemoteOutputStream?,
evalErrorStream: RemoteOutputStream?,
@@ -115,8 +117,8 @@ open class KotlinJvmReplService(
private val compiledEvaluator : GenericReplCompiledEvaluator by lazy {
if (evalOutputStream == null && evalErrorStream == null && evalInputStream == null)
GenericReplCompiledEvaluator(configuration.jvmClasspathRoots, null)
else object : GenericReplCompiledEvaluator(configuration.jvmClasspathRoots, null) {
GenericReplCompiledEvaluator(configuration.jvmClasspathRoots, null, scriptArgs, scriptArgsTypes)
else object : GenericReplCompiledEvaluator(configuration.jvmClasspathRoots, null, scriptArgs, scriptArgsTypes) {
val out = PrintStream(BufferedOutputStream(RemoteOutputStreamClient(evalOutputStream!!, DummyProfiler()), REMOTE_STREAM_BUFFER_SIZE))
val err = PrintStream(BufferedOutputStream(RemoteOutputStreamClient(evalErrorStream!!, DummyProfiler()), REMOTE_STREAM_BUFFER_SIZE))
val `in` = BufferedInputStream(RemoteInputStreamClient(evalInputStream!!, DummyProfiler()), REMOTE_STREAM_BUFFER_SIZE)