diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/messages/CompilerMessageLocation.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/messages/CompilerMessageLocation.kt index f49e065f5e1..3ae51828be5 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/messages/CompilerMessageLocation.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/messages/CompilerMessageLocation.kt @@ -16,12 +16,14 @@ package org.jetbrains.kotlin.cli.common.messages +import java.io.Serializable + data class CompilerMessageLocation private constructor( val path: String?, val line: Int, val column: Int, val lineContent: String? -) { +) : Serializable { override fun toString(): String = path + (if (line != -1 || column != -1) " ($line:$column)" else "") @@ -35,5 +37,7 @@ data class CompilerMessageLocation private constructor( lineContent: String? ): CompilerMessageLocation = if (path == null) NO_LOCATION else CompilerMessageLocation(path, line, column, lineContent) + + private val serialVersionUID: Long = 8228357578L // just a random number, should be changed when serialized data is changed } } 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 518f574f562..16f48bc63bb 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 @@ -55,8 +55,11 @@ open class GenericReplChecker( messageCollector: MessageCollector ) : ReplChecker { protected val environment = run { - compilerConfiguration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, DelegatingScriptDefWithNoParams(scriptDefinition)) - compilerConfiguration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector) + compilerConfiguration.apply { + add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, DelegatingScriptDefWithNoParams(scriptDefinition)) + put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector) + put(JVMConfigurationKeys.RETAIN_OUTPUT_IN_MEMORY, true) + } KotlinCoreEnvironment.createForProduction(disposable, compilerConfiguration, EnvironmentConfigFiles.JVM_CONFIG_FILES) } diff --git a/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/RemoteInputStreamServer.kt b/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/RemoteInputStreamServer.kt new file mode 100644 index 00000000000..95533c5555f --- /dev/null +++ b/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/RemoteInputStreamServer.kt @@ -0,0 +1,43 @@ +/* + * 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 org.jetbrains.kotlin.daemon.common.LoopbackNetworkInterface +import org.jetbrains.kotlin.daemon.common.RemoteInputStream +import org.jetbrains.kotlin.daemon.common.SOCKET_ANY_FREE_PORT +import java.io.InputStream +import java.rmi.server.UnicastRemoteObject + + +class RemoteInputStreamServer(val `in`: InputStream, port: Int = SOCKET_ANY_FREE_PORT) +: RemoteInputStream, + UnicastRemoteObject(port, LoopbackNetworkInterface.clientLoopbackSocketFactory, LoopbackNetworkInterface.serverLoopbackSocketFactory) +{ + override fun close() { + `in`.close() + } + + override fun read(length: Int): ByteArray { + val buf = ByteArray(length) + val readBytes = `in`.read(buf, 0, length) + return if (readBytes == length) buf + else buf.copyOfRange(0, readBytes) + } + + override fun read(): Int = + `in`.read() +} diff --git a/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/ClientUtils.kt b/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/ClientUtils.kt index c1829f606b9..c00a268e86f 100644 --- a/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/ClientUtils.kt +++ b/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/ClientUtils.kt @@ -80,3 +80,11 @@ private inline fun tryConnectToDaemon(port: Int, report: (DaemonReportCategory, } return null } + + +fun makeAutodeletingFlagFile(keyword: String = "compiler-client"): File { + val validChars = "^a-zA-Z0-9-_" + val flagFile = File.createTempFile("kotlin-${keyword.filter { validChars.contains(it) }}-", "-is-running") + flagFile.deleteOnExit() + return flagFile +} diff --git a/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/RemoteInputStream.kt b/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/RemoteInputStream.kt new file mode 100644 index 00000000000..e72f6731490 --- /dev/null +++ b/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/RemoteInputStream.kt @@ -0,0 +1,32 @@ +/* + * 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.common + +import java.rmi.Remote +import java.rmi.RemoteException + +interface RemoteInputStream : Remote { + + @Throws(RemoteException::class) + fun close() + + @Throws(RemoteException::class) + fun read(length: Int): ByteArray + + @Throws(RemoteException::class) + fun read(): Int +} diff --git a/compiler/daemon/src/org/jetbrains/kotlin/daemon/RemoteInputStreamClient.kt b/compiler/daemon/src/org/jetbrains/kotlin/daemon/RemoteInputStreamClient.kt new file mode 100644 index 00000000000..55559040fb2 --- /dev/null +++ b/compiler/daemon/src/org/jetbrains/kotlin/daemon/RemoteInputStreamClient.kt @@ -0,0 +1,37 @@ +/* + * 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 + +import org.jetbrains.kotlin.daemon.common.DummyProfiler +import org.jetbrains.kotlin.daemon.common.Profiler +import org.jetbrains.kotlin.daemon.common.RemoteInputStream +import java.io.InputStream + +class RemoteInputStreamClient(val remote: RemoteInputStream, val profiler: Profiler = DummyProfiler()): InputStream() { + override fun read(data: ByteArray): Int = read(data, 0, data.size) + + override fun read(data: ByteArray, offset: Int, length: Int): Int = + profiler.withMeasure(this) { + val bytes = remote.read(length) + assert(bytes.size <= length) + System.arraycopy(bytes, 0, data, offset, length) + bytes.size + } + + override fun read(): Int = + profiler.withMeasure(this) { remote.read() } +} diff --git a/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt b/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt index 6a27f7074b3..d6fb529aa70 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt @@ -157,13 +157,8 @@ object KotlinCompilerRunner { val profiler = if (daemonOptions.reportPerf) WallAndThreadAndMemoryTotalProfiler(withGC = false) else DummyProfiler() profiler.withMeasure(null) { - fun newFlagFile(): File { - val flagFile = File.createTempFile("kotlin-compiler-jps-session-", "-is-running") - flagFile.deleteOnExit() - return flagFile - } val daemon = KotlinCompilerClient.connectToCompileService(compilerId, daemonJVMOptions, daemonOptions, DaemonReportingTargets(null, daemonReportMessages), true, true) - connection = DaemonConnection(daemon, daemon?.leaseCompileSession(newFlagFile().absolutePath)?.get() ?: CompileService.NO_SESSION) + connection = DaemonConnection(daemon, daemon?.leaseCompileSession(makeAutodeletingFlagFile("compiler-jps-session").absolutePath)?.get() ?: CompileService.NO_SESSION) } for (msg in daemonReportMessages) {