Add remote repl support to the daemon, refactor repl classes accordingly, simple tests
This commit is contained in:
@@ -11,5 +11,6 @@
|
||||
<orderEntry type="module" module-name="frontend.java" />
|
||||
<orderEntry type="module" module-name="util" />
|
||||
<orderEntry type="library" name="native-platform-uberjar" level="project" />
|
||||
<orderEntry type="module" module-name="cli-common" />
|
||||
</component>
|
||||
</module>
|
||||
+6
-13
@@ -31,7 +31,6 @@ import java.util.concurrent.TimeUnit
|
||||
import kotlin.comparisons.compareByDescending
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
|
||||
class CompilationServices(
|
||||
val incrementalCompilationComponents: IncrementalCompilationComponents? = null,
|
||||
val compilationCanceledStatus: CompilationCanceledStatus? = null
|
||||
@@ -53,18 +52,12 @@ object KotlinCompilerClient {
|
||||
autostart: Boolean = true,
|
||||
checkId: Boolean = true
|
||||
): CompileService? {
|
||||
fun newFlagFile(): File {
|
||||
val flagFile = File.createTempFile("kotlin-compiler-client-", "-is-running")
|
||||
flagFile.deleteOnExit()
|
||||
return flagFile
|
||||
}
|
||||
|
||||
val flagFile = System.getProperty(COMPILE_DAEMON_CLIENT_ALIVE_PATH_PROPERTY)
|
||||
?.let { it.trimQuotes() }
|
||||
?.let(String::trimQuotes)
|
||||
?.check { !it.isBlank() }
|
||||
?.let { File(it) }
|
||||
?.check { it.exists() }
|
||||
?: newFlagFile()
|
||||
?.let(::File)
|
||||
?.check(File::exists)
|
||||
?: makeAutodeletingFlagFile()
|
||||
return connectToCompileService(compilerId, flagFile, daemonJVMOptions, daemonOptions, reportingTargets, autostart)
|
||||
}
|
||||
|
||||
@@ -287,7 +280,7 @@ object KotlinCompilerClient {
|
||||
val daemonLauncher = Native.get(ProcessLauncher::class.java)
|
||||
val daemon = daemonLauncher.start(processBuilder)
|
||||
|
||||
var isEchoRead = Semaphore(1)
|
||||
val isEchoRead = Semaphore(1)
|
||||
isEchoRead.acquire()
|
||||
|
||||
val stdoutThread =
|
||||
@@ -316,7 +309,7 @@ object KotlinCompilerClient {
|
||||
it.toLong()
|
||||
}
|
||||
catch (e: Exception) {
|
||||
reportingTargets.report(DaemonReportCategory.INFO, "unable to interpret ${COMPILE_DAEMON_STARTUP_TIMEOUT_PROPERTY} property ('$it'); using default timeout $DAEMON_DEFAULT_STARTUP_TIMEOUT_MS ms")
|
||||
reportingTargets.report(DaemonReportCategory.INFO, "unable to interpret $COMPILE_DAEMON_STARTUP_TIMEOUT_PROPERTY property ('$it'); using default timeout $DAEMON_DEFAULT_STARTUP_TIMEOUT_MS ms")
|
||||
null
|
||||
}
|
||||
} ?: DAEMON_DEFAULT_STARTUP_TIMEOUT_MS
|
||||
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.daemon.client
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import org.jetbrains.kotlin.cli.common.repl.*
|
||||
import org.jetbrains.kotlin.daemon.common.CompileService
|
||||
import org.jetbrains.kotlin.daemon.common.RemoteOperationsTracer
|
||||
import org.jetbrains.kotlin.daemon.common.SOCKET_ANY_FREE_PORT
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
|
||||
// TODO: reduce number of ports used then SOCKET_ANY_FREE_PORT is passed (same problem with other calls)
|
||||
|
||||
open class KotlinRemoteReplClientBase(
|
||||
disposable: Disposable,
|
||||
protected val compileService: CompileService,
|
||||
clientAliveFlagFile: File?,
|
||||
targetPlatform: CompileService.TargetPlatform,
|
||||
templateClasspath: List<File>,
|
||||
templateClassName: String,
|
||||
compilerMessagesOutputStream: OutputStream,
|
||||
evalOutputStream: OutputStream? = null,
|
||||
evalErrorStream: OutputStream? = null,
|
||||
evalInputStream: InputStream? = null,
|
||||
port: Int = SOCKET_ANY_FREE_PORT,
|
||||
operationsTracer: RemoteOperationsTracer? = null
|
||||
) : ReplChecker {
|
||||
|
||||
val sessionId = compileService.leaseReplSession(
|
||||
clientAliveFlagFile?.absolutePath,
|
||||
targetPlatform,
|
||||
CompilerCallbackServicesFacadeServer(port = port),
|
||||
templateClasspath,
|
||||
templateClassName,
|
||||
RemoteOutputStreamServer(compilerMessagesOutputStream, port),
|
||||
evalOutputStream?.let { RemoteOutputStreamServer(it, port) },
|
||||
evalErrorStream?.let { RemoteOutputStreamServer(it, port) },
|
||||
evalInputStream?.let { RemoteInputStreamServer(it, port) },
|
||||
operationsTracer
|
||||
).get()
|
||||
|
||||
init {
|
||||
Disposer.register(disposable, Disposable {
|
||||
compileService.releaseReplSession(sessionId)
|
||||
})
|
||||
}
|
||||
|
||||
override fun check(codeLine: ReplCodeLine, history: Iterable<ReplCodeLine>): ReplCheckResult {
|
||||
return compileService.remoteReplLineCheck(sessionId, codeLine, history.toList()).get()
|
||||
}
|
||||
}
|
||||
|
||||
class KotlinRemoteReplCompiler(
|
||||
disposable: Disposable,
|
||||
compileService: CompileService,
|
||||
clientAliveFlagFile: File?,
|
||||
targetPlatform: CompileService.TargetPlatform,
|
||||
templateClasspath: List<File>,
|
||||
templateClassName: String,
|
||||
compilerMessagesOutputStream: OutputStream,
|
||||
port: Int = SOCKET_ANY_FREE_PORT,
|
||||
operationsTracer: RemoteOperationsTracer? = null
|
||||
) : KotlinRemoteReplClientBase(
|
||||
disposable = disposable,
|
||||
compileService = compileService,
|
||||
clientAliveFlagFile = clientAliveFlagFile,
|
||||
targetPlatform = targetPlatform,
|
||||
templateClasspath = templateClasspath,
|
||||
templateClassName = templateClassName,
|
||||
compilerMessagesOutputStream = compilerMessagesOutputStream,
|
||||
evalOutputStream = null,
|
||||
evalErrorStream = null,
|
||||
evalInputStream = null,
|
||||
port = port,
|
||||
operationsTracer = operationsTracer
|
||||
), ReplCompiler {
|
||||
|
||||
override fun compile(codeLine: ReplCodeLine, history: Iterable<ReplCodeLine>): ReplCompileResult {
|
||||
return compileService.remoteReplLineCompile(sessionId, codeLine, history.toList()).get()
|
||||
}
|
||||
}
|
||||
|
||||
class KotlinRemoteReplEvaluator(
|
||||
disposable: Disposable,
|
||||
compileService: CompileService,
|
||||
clientAliveFlagFile: File?,
|
||||
targetPlatform: CompileService.TargetPlatform,
|
||||
templateClasspath: List<File>,
|
||||
templateClassName: String,
|
||||
compilerMessagesOutputStream: OutputStream,
|
||||
evalOutputStream: OutputStream?,
|
||||
evalErrorStream: OutputStream?,
|
||||
evalInputStream: InputStream?,
|
||||
port: Int = SOCKET_ANY_FREE_PORT,
|
||||
operationsTracer: RemoteOperationsTracer? = null
|
||||
) : KotlinRemoteReplClientBase(
|
||||
disposable = disposable,
|
||||
compileService = compileService,
|
||||
clientAliveFlagFile = clientAliveFlagFile,
|
||||
targetPlatform = targetPlatform,
|
||||
templateClasspath = templateClasspath,
|
||||
templateClassName = templateClassName,
|
||||
compilerMessagesOutputStream = compilerMessagesOutputStream,
|
||||
evalOutputStream = evalOutputStream,
|
||||
evalErrorStream = evalErrorStream,
|
||||
evalInputStream = evalInputStream,
|
||||
port = port,
|
||||
operationsTracer = operationsTracer
|
||||
), ReplEvaluator {
|
||||
|
||||
override fun eval(codeLine: ReplCodeLine, history: Iterable<ReplCodeLine>): ReplEvalResult {
|
||||
return compileService.remoteReplLineEval(sessionId, codeLine, history.toList()).get()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user