diff --git a/build.xml b/build.xml
index 6ef2272dc24..f1084a2b0b9 100644
--- a/build.xml
+++ b/build.xml
@@ -117,6 +117,8 @@
+
+
@@ -200,6 +202,8 @@
+
+
diff --git a/compiler/rmi/kotlinr/src/org/jetbrains/kotlin/rmi/kotlinr/KotlinCompilerClient.kt b/compiler/rmi/kotlinr/src/org/jetbrains/kotlin/rmi/kotlinr/KotlinCompilerClient.kt
index d6b863930e3..1850cafdaa6 100644
--- a/compiler/rmi/kotlinr/src/org/jetbrains/kotlin/rmi/kotlinr/KotlinCompilerClient.kt
+++ b/compiler/rmi/kotlinr/src/org/jetbrains/kotlin/rmi/kotlinr/KotlinCompilerClient.kt
@@ -26,12 +26,7 @@ import java.rmi.Remote
import java.rmi.registry.LocateRegistry
import java.util.concurrent.Semaphore
import java.util.concurrent.TimeUnit
-import java.util.concurrent.locks.ReentrantReadWriteLock
-import kotlin.concurrent.read
import kotlin.concurrent.thread
-import kotlin.concurrent.write
-import kotlin.platform.platformStatic
-import kotlin.reflect.KProperty1
fun Process.isAlive() =
try {
@@ -71,7 +66,7 @@ public class KotlinCompilerClient {
}
- private fun startDaemon(compilerId: CompilerId, daemonLaunchingOptions: DaemonLaunchingOptions, daemonOptions: DaemonOptions, errStream: PrintStream) {
+ private fun startDaemon(compilerId: CompilerId, daemonJVMOptions: DaemonJVMOptions, daemonOptions: DaemonOptions, errStream: PrintStream) {
val javaExecutable = File(System.getProperty("java.home"), "bin").let {
val javaw = File(it, "javaw.exe")
if (javaw.exists()) javaw
@@ -80,10 +75,10 @@ public class KotlinCompilerClient {
// TODO: add some specific environment variables to the cp and may be command line, to allow some specific startup configs
val args = listOf(javaExecutable.absolutePath,
"-cp", compilerId.compilerClasspath.joinToString(File.pathSeparator)) +
- daemonLaunchingOptions.extractors.flatMap { it.extract("-") } +
+ daemonJVMOptions.mappers.flatMap { it.toArgs("-") } +
COMPILER_DAEMON_CLASS_FQN +
- daemonOptions.extractors.flatMap { it.extract(COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) } +
- compilerId.extractors.flatMap { it.extract(COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) }
+ daemonOptions.mappers.flatMap { it.toArgs(COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) } +
+ compilerId.mappers.flatMap { it.toArgs(COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) }
errStream.println("[daemon client] starting the daemon as: " + args.joinToString(" "))
val processBuilder = ProcessBuilder(args).redirectErrorStream(true)
// assuming daemon process is deaf and (mostly) silent, so do not handle streams
@@ -135,14 +130,14 @@ public class KotlinCompilerClient {
(localId.compilerDigest.isEmpty() || remoteId.compilerDigest.isEmpty() || localId.compilerDigest == remoteId.compilerDigest)
}
- public fun connectToCompileService(compilerId: CompilerId, daemonLaunchingOptions: DaemonLaunchingOptions, daemonOptions: DaemonOptions, errStream: PrintStream, autostart: Boolean = true, checkId: Boolean = true): CompileService? {
+ public fun connectToCompileService(compilerId: CompilerId, daemonJVMOptions: DaemonJVMOptions, daemonOptions: DaemonOptions, errStream: PrintStream, autostart: Boolean = true, checkId: Boolean = true): CompileService? {
val service = connectToService(compilerId, daemonOptions, errStream)
if (service != null) {
if (!checkId || checkCompilerId(service, compilerId, errStream)) {
errStream.println("[daemon client] found the suitable daemon")
return service
}
- errStream.println("[daemon client] compiler identity don't match: " + compilerId.extractors.flatMap { it.extract("") }.joinToString(" "))
+ errStream.println("[daemon client] compiler identity don't match: " + compilerId.mappers.flatMap { it.toArgs("") }.joinToString(" "))
if (!autostart) return null;
errStream.println("[daemon client] shutdown the daemon")
service.shutdown()
@@ -155,13 +150,13 @@ public class KotlinCompilerClient {
else errStream.println("[daemon client] cannot connect to Compile Daemon, trying to start")
}
- startDaemon(compilerId, daemonLaunchingOptions, daemonOptions, errStream)
+ startDaemon(compilerId, daemonJVMOptions, daemonOptions, errStream)
errStream.println("[daemon client] daemon started, trying to connect")
return connectToService(compilerId, daemonOptions, errStream)
}
public fun shutdownCompileService(daemonOptions: DaemonOptions): Unit {
- KotlinCompilerClient.connectToCompileService(CompilerId(), DaemonLaunchingOptions(), daemonOptions, System.out, autostart = false, checkId = false)
+ KotlinCompilerClient.connectToCompileService(CompilerId(), DaemonJVMOptions(), daemonOptions, System.out, autostart = false, checkId = false)
?.shutdown()
}
@@ -196,20 +191,17 @@ public class KotlinCompilerClient {
data class ClientOptions(
public var stop: Boolean = false
- ) :CmdlineParams {
- override val extractors: List>
- get() = listOf( BoolPropExtractor(this, ::stop))
-
- override val parsers: List>
- get() = listOf( BoolPropParser(this, ::stop))
+ ) : OptionsGroup {
+ override val mappers: List>
+ get() = listOf( BoolPropMapper(this, ::stop))
}
- platformStatic public fun main(vararg args: String) {
+ jvmStatic public fun main(vararg args: String) {
val compilerId = CompilerId()
val daemonOptions = DaemonOptions()
- val daemonLaunchingOptions = DaemonLaunchingOptions()
+ val daemonLaunchingOptions = DaemonJVMOptions()
val clientOptions = ClientOptions()
- val filteredArgs = args.asIterable().filterSetProps(compilerId, daemonOptions, daemonLaunchingOptions, clientOptions, prefix = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX)
+ val filteredArgs = args.asIterable().filterExtractProps(compilerId, daemonOptions, daemonLaunchingOptions, clientOptions, prefix = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX)
if (!clientOptions.stop) {
if (compilerId.compilerClasspath.none()) {
diff --git a/compiler/rmi/rmi-interface/src/org/jetbrains/kotlin/rmi/DaemonParams.kt b/compiler/rmi/rmi-interface/src/org/jetbrains/kotlin/rmi/DaemonParams.kt
index 80c6302de7d..815ea746007 100644
--- a/compiler/rmi/rmi-interface/src/org/jetbrains/kotlin/rmi/DaemonParams.kt
+++ b/compiler/rmi/rmi-interface/src/org/jetbrains/kotlin/rmi/DaemonParams.kt
@@ -21,9 +21,7 @@ import java.io.Serializable
import java.lang.management.ManagementFactory
import java.security.DigestInputStream
import java.security.MessageDigest
-import kotlin.platform.platformStatic
import kotlin.reflect.KMutableProperty1
-import kotlin.reflect.KProperty1
public val COMPILER_JAR_NAME: String = "kotlin-compiler.jar"
@@ -34,85 +32,147 @@ public val COMPILE_DAEMON_ENABLED_PROPERTY: String ="kotlin.daemon.enabled"
public val COMPILE_DAEMON_JVM_OPTIONS_PROPERTY: String ="kotlin.daemon.jvm.options"
public val COMPILE_DAEMON_OPTIONS_PROPERTY: String ="kotlin.daemon.options"
public val COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX: String ="--daemon-"
+public val COMPILE_DAEMON_TIMEOUT_INFINITE_S: Int = 0
+public val COMPILE_DAEMON_MEMORY_THRESHOLD_INFINITE: Long = 0L
+val COMPILER_ID_DIGEST = "MD5"
-open class PropExtractor>(val dest: C,
- val prop: P,
- val name: String,
- val convert: ((v: V) -> String?) = { it.toString() },
- val skipIf: ((v: V) -> Boolean) = { false },
- val mergeWithDelimiter: String? = null)
+//open class PropExtractor>(val dest: C,
+// val prop: P,
+// val name: String,
+// val convert: ((v: V) -> String?) = { it.toString() },
+// val skipIf: ((v: V) -> Boolean) = { false },
+// val mergeWithDelimiter: String? = null)
+//{
+// constructor(dest: C, prop: P, convert: ((v: V) -> String?) = { it.toString() }, skipIf: ((v: V) -> Boolean) = { false }) : this(dest, prop, prop.name, convert, skipIf)
+// open fun extract(prefix: String = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX): List =
+// when {
+// skipIf(prop.get(dest)) -> listOf()
+// mergeWithDelimiter != null -> listOf(prefix + name + mergeWithDelimiter + convert(prop.get(dest))).filterNotNull()
+// else -> listOf(prefix + name, convert(prop.get(dest))).filterNotNull()
+// }
+//}
+//
+//class BoolPropExtractor>(dest: C, prop: P, name: String? = null)
+// : PropExtractor(dest, prop, name ?: prop.name, convert = { null }, skipIf = { !prop.get(dest) })
+//
+//class RestPropExtractor>>(dest: C, prop: P) : PropExtractor, P>(dest, prop, convert = { null }) {
+// override fun extract(prefix: String): List = prop.get(dest).map { prefix + it }
+//}
+//
+//
+//open class PropParser>(val dest: C,
+// val prop: P, alternativeNames: List,
+// val parse: (s: String) -> V,
+// val allowMergedArg: Boolean = false) {
+// val names = listOf(prop.name) + alternativeNames
+// constructor(dest: C, prop: P, parse: (s: String) -> V, allowMergedArg: Boolean = false) : this(dest, prop, listOf(), parse, allowMergedArg)
+// fun apply(s: String) = prop.set(dest, parse(s))
+//}
+//
+//class BoolPropParser>(dest: C, prop: P): PropParser(dest, prop, { true })
+//
+//class RestPropParser>>(dest: C, prop: P): PropParser, P>(dest, prop, { arrayListOf() }) {
+// fun add(s: String) { prop.get(dest).add(s) }
+//}
+
+// --------------------------------------------------------
+
+open class PropMapper>(val dest: C,
+ val prop: P,
+ val names: List = listOf(prop.name),
+ val fromString: (s: String) -> V,
+ val toString: ((v: V) -> String?) = { it.toString() },
+ val skipIf: ((v: V) -> Boolean) = { false },
+ val mergeDelimiter: String? = null)
{
- constructor(dest: C, prop: P, convert: ((v: V) -> String?) = { it.toString() }, skipIf: ((v: V) -> Boolean) = { false }) : this(dest, prop, prop.name, convert, skipIf)
- open fun extract(prefix: String = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX): List =
+ open fun toArgs(prefix: String = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX): List =
when {
skipIf(prop.get(dest)) -> listOf()
- mergeWithDelimiter != null -> listOf(prefix + name + mergeWithDelimiter + convert(prop.get(dest))).filterNotNull()
- else -> listOf(prefix + name, convert(prop.get(dest))).filterNotNull()
+ mergeDelimiter != null -> listOf(prefix + names.first() + mergeDelimiter + toString(prop.get(dest))).filterNotNull()
+ else -> listOf(prefix + names.first(), toString(prop.get(dest))).filterNotNull()
}
+ fun apply(s: String) = prop.set(dest, fromString(s))
}
-class BoolPropExtractor>(dest: C, prop: P, name: String? = null)
- : PropExtractor(dest, prop, name ?: prop.name, convert = { null }, skipIf = { !prop.get(dest) })
+class StringPropMapper>(dest: C,
+ prop: P,
+ names: List = listOf(),
+ fromString: ((String) -> String) = { it },
+ toString: ((String) -> String?) = { it.toString() },
+ skipIf: ((String) -> Boolean) = { it.isEmpty() },
+ mergeDelimiter: String? = null)
+: PropMapper(dest = dest, prop = prop, names = if (names.any()) names else listOf(prop.name),
+ fromString = fromString, toString = toString, skipIf = skipIf, mergeDelimiter = mergeDelimiter)
-class RestPropExtractor>>(dest: C, prop: P) : PropExtractor, P>(dest, prop, convert = { null }) {
- override fun extract(prefix: String): List = prop.get(dest).map { prefix + it }
-}
+class BoolPropMapper>(dest: C, prop: P, names: List = listOf())
+ : PropMapper(dest = dest, prop = prop, names = if (names.any()) names else listOf(prop.name),
+ fromString = { true }, toString = { null }, skipIf = { !prop.get(dest) })
-
-open class PropParser>(val dest: C,
- val prop: P, alternativeNames: List,
- val parse: (s: String) -> V,
- val allowMergedArg: Boolean = false) {
- val names = listOf(prop.name) + alternativeNames
- constructor(dest: C, prop: P, parse: (s: String) -> V, allowMergedArg: Boolean = false) : this(dest, prop, listOf(), parse, allowMergedArg)
- fun apply(s: String) = prop.set(dest, parse(s))
-}
-
-class BoolPropParser>(dest: C, prop: P): PropParser(dest, prop, { true })
-
-class RestPropParser>>(dest: C, prop: P): PropParser, P>(dest, prop, { arrayListOf() }) {
+class RestPropMapper>>(dest: C, prop: P)
+ : PropMapper, P>(dest = dest, prop = prop, toString = { null }, fromString = { arrayListOf() })
+{
+ override fun toArgs(prefix: String): List = prop.get(dest).map { prefix + it }
fun add(s: String) { prop.get(dest).add(s) }
}
+// ------------------------------------------
-fun Iterable.filterSetProps(parsers: List>, prefix: String, restParser: RestPropParser<*,*>? = null) : Iterable {
- var currentParser: PropParser<*,*,*>? = null
+fun Iterable.filterExtractProps(propMappers: List>, prefix: String, restParser: RestPropMapper<*,*>? = null) : Iterable {
+ var currentPropMapper: PropMapper<*,*,*>? = null
var matchingOption = ""
val res = filter { param ->
- if (currentParser == null) {
- val parser = parsers.find { it.names.any { name ->
- if (param.startsWith(prefix + name)) { matchingOption = prefix + name; true }
- else false } }
- if (parser != null) {
- val optionLength = matchingOption.length()
- when {
- parser is BoolPropParser<*,*> ->
- if (param.length() > optionLength) throw IllegalArgumentException("Invalid switch option '$param', expecting $matchingOption without arguments")
- else parser.apply("")
- param.length() > optionLength ->
- if (param[optionLength] != '=') {
- if (parser.allowMergedArg) parser.apply(param.substring(optionLength))
- else throw IllegalArgumentException("Invalid option syntax '$param', expecting $matchingOption[= ]")
- }
- else parser.apply(param.substring(optionLength + 1))
- else -> currentParser = parser
+ if (currentPropMapper == null) {
+ val propMapper = propMappers.find {
+ it !is RestPropMapper<*,*> &&
+ it.names.any { name ->
+ if (param.startsWith(prefix + name)) {
+ matchingOption = prefix + name
+ true
+ }
+ else {
+ false
+ }
}
- false
}
- else if (restParser != null && param.startsWith(prefix)) {
- restParser.add(param.removePrefix(prefix))
- false
+ when {
+ propMapper != null -> {
+ val optionLength = matchingOption.length()
+ when {
+ propMapper is BoolPropMapper<*,*> -> {
+ if (param.length() > optionLength)
+ throw IllegalArgumentException("Invalid switch option '$param', expecting $matchingOption without arguments")
+ propMapper.apply("")
+ }
+ param.length() > optionLength ->
+ if (param[optionLength] != '=') {
+ if (propMapper.mergeDelimiter == null)
+ throw IllegalArgumentException("Invalid option syntax '$param', expecting $matchingOption[= ]")
+ propMapper.apply(param.substring(optionLength))
+ }
+ else {
+ propMapper.apply(param.substring(optionLength + 1))
+ }
+ else ->
+ currentPropMapper = propMapper
+ }
+ false
+ }
+ restParser != null && param.startsWith(prefix) -> {
+ restParser.add(param.removePrefix(prefix))
+ false
+ }
+ else -> true
}
- else true
}
else {
- currentParser!!.apply(param)
- currentParser = null
+ currentPropMapper!!.apply(param)
+ currentPropMapper = null
false
}
}
- if (currentParser != null) throw IllegalArgumentException("Expecting argument for the option $matchingOption")
+ if (currentPropMapper != null)
+ throw IllegalArgumentException("Expecting argument for the option $matchingOption")
return res
}
@@ -124,59 +184,46 @@ fun Iterable.filterSetProps(parsers: List>, prefix: St
-public interface CmdlineParams : Serializable {
- public val extractors: List>
- public val parsers: List>
+public interface OptionsGroup : Serializable {
+ public val mappers: List>
}
-public fun Iterable.filterSetProps(vararg cs: CmdlineParams, prefix: String) : Iterable =
- filterSetProps(cs.flatMap { it.parsers }, prefix)
+public fun Iterable.filterExtractProps(vararg groups: OptionsGroup, prefix: String) : Iterable =
+ filterExtractProps(groups.flatMap { it.mappers }, prefix)
-public data class DaemonLaunchingOptions(
+public data class DaemonJVMOptions(
public var maxMemory: String = "",
public var maxPermSize: String = "",
public var reservedCodeCacheSize: String = "",
public var otherJvmParams: MutableCollection = arrayListOf()
-) : CmdlineParams {
+) : OptionsGroup {
- override val extractors: List>
- get() = listOf( PropExtractor(this, ::maxMemory, "Xmx", skipIf = { it.isEmpty() }, mergeWithDelimiter = ""),
- PropExtractor(this, ::maxPermSize, "XX:MaxPermSize", skipIf = { it.isEmpty() }, mergeWithDelimiter = "="),
- PropExtractor(this, ::reservedCodeCacheSize, "XX:ReservedCodeCacheSize", skipIf = { it.isEmpty() }, mergeWithDelimiter = "="),
- RestPropExtractor(this, ::otherJvmParams))
+ override val mappers: List>
+ get() = listOf( StringPropMapper(this, ::maxMemory, listOf("Xmx"), mergeDelimiter = ""),
+ StringPropMapper(this, ::maxPermSize, listOf("XX:MaxPermSize"), mergeDelimiter = "="),
+ StringPropMapper(this, ::reservedCodeCacheSize, listOf("XX:ReservedCodeCacheSize"), mergeDelimiter = "="),
+ restMapper)
- override val parsers: List>
- get() = listOf( PropParser(this, ::maxMemory, listOf("Xmx"), { it }, allowMergedArg = true),
- PropParser(this, ::maxPermSize, listOf("XX:MaxPermSize"), { it }, allowMergedArg = true),
- PropParser(this, ::reservedCodeCacheSize, listOf("XX:ReservedCodeCacheSize"), { it }, allowMergedArg = true))
- // otherJvmParams is missing here deliberately, it is used explicitly as a restParser param to filterSetProps
+ val restMapper: RestPropMapper<*,*>
+ get() = RestPropMapper(this, ::otherJvmParams)
}
public data class DaemonOptions(
public var port: Int = COMPILE_DAEMON_DEFAULT_PORT,
- public var autoshutdownMemoryThreshold: Long = 0 /* 0 means unchecked */,
- public var autoshutdownIdleSeconds: Int = 0 /* 0 means unchecked */,
+ public var autoshutdownMemoryThreshold: Long = COMPILE_DAEMON_MEMORY_THRESHOLD_INFINITE,
+ public var autoshutdownIdleSeconds: Int = COMPILE_DAEMON_TIMEOUT_INFINITE_S,
public var startEcho: String = COMPILER_SERVICE_RMI_NAME
-) : CmdlineParams {
+) : OptionsGroup {
- override val extractors: List>
- get() = listOf( PropExtractor(this, ::port),
- PropExtractor(this, ::autoshutdownMemoryThreshold, skipIf = { it == 0L }),
- PropExtractor(this, ::autoshutdownIdleSeconds, skipIf = { it == 0 }),
- PropExtractor(this, ::startEcho))
-
- override val parsers: List>
- get() = listOf( PropParser(this, ::port, { it.toInt()}),
- PropParser(this, ::autoshutdownMemoryThreshold, { it.toLong()}),
- PropParser(this, ::autoshutdownIdleSeconds, { it.toInt()}),
- PropParser(this, ::startEcho, { it.trim('"') }))
+ override val mappers: List>
+ get() = listOf( PropMapper(this, ::port, fromString = { it.toInt() }),
+ PropMapper(this, ::autoshutdownMemoryThreshold, fromString = { it.toLong() }, skipIf = { it == 0L }),
+ PropMapper(this, ::autoshutdownIdleSeconds, fromString = { it.toInt() }, skipIf = { it == 0 }),
+ PropMapper(this, ::startEcho, fromString = { it.trim('"') }))
}
-val COMPILER_ID_DIGEST = "MD5"
-
-
fun updateSingleFileDigest(file: File, md: MessageDigest) {
DigestInputStream(file.inputStream(), md).use {
val buf = ByteArray(1024)
@@ -215,27 +262,21 @@ public data class CompilerId(
public var compilerDigest: String = "",
public var compilerVersion: String = ""
// TODO: checksum
-) : CmdlineParams {
+) : OptionsGroup {
- override val extractors: List>
- get() = listOf( PropExtractor(this, ::compilerClasspath, convert = { it.joinToString(File.pathSeparator) }),
- PropExtractor(this, ::compilerDigest),
- PropExtractor(this, ::compilerVersion, skipIf = { it.isEmpty() }))
-
- override val parsers: List>
- get() =
- listOf( PropParser(this, ::compilerClasspath, { it.trim('"').split(File.pathSeparator)}),
- PropParser(this, ::compilerDigest, { it.trim('"') }),
- PropParser(this, ::compilerVersion, { it.trim('"') }))
+ override val mappers: List>
+ get() = listOf( PropMapper(this, ::compilerClasspath, toString = { it.joinToString(File.pathSeparator) }, fromString = { it.trim('"').split(File.pathSeparator)}),
+ StringPropMapper(this, ::compilerDigest),
+ StringPropMapper(this, ::compilerVersion))
public fun updateDigest() {
compilerDigest = compilerClasspath.getClasspathDigest()
}
companion object {
- public platformStatic fun makeCompilerId(vararg paths: File): CompilerId = makeCompilerId(paths.asIterable())
+ public jvmStatic fun makeCompilerId(vararg paths: File): CompilerId = makeCompilerId(paths.asIterable())
- public platformStatic fun makeCompilerId(paths: Iterable): CompilerId =
+ public jvmStatic fun makeCompilerId(paths: Iterable): CompilerId =
// TODO consider reading version here
CompilerId(compilerClasspath = paths.map { it.absolutePath }, compilerDigest = paths.getFilesClasspathDigest())
}
@@ -245,27 +286,27 @@ public data class CompilerId(
public fun isDaemonEnabled(): Boolean = System.getProperty(COMPILE_DAEMON_ENABLED_PROPERTY) != null
-public fun configureDaemonLaunchingOptions(opts: DaemonLaunchingOptions, inheritMemoryLimits: Boolean): DaemonLaunchingOptions {
+public fun configureDaemonLaunchingOptions(opts: DaemonJVMOptions, inheritMemoryLimits: Boolean): DaemonJVMOptions {
// note: sequence matters, explicit override in COMPILE_DAEMON_JVM_OPTIONS_PROPERTY should be done after inputArguments processing
if (inheritMemoryLimits)
- ManagementFactory.getRuntimeMXBean().inputArguments.filterSetProps(opts.parsers, "-")
+ ManagementFactory.getRuntimeMXBean().inputArguments.filterExtractProps(opts.mappers, "-")
System.getProperty(COMPILE_DAEMON_JVM_OPTIONS_PROPERTY)?.let {
- opts.otherJvmParams.addAll( it.trim('"', '\'').split(",").filterSetProps(opts.parsers, "-", RestPropParser(opts, DaemonLaunchingOptions::otherJvmParams)))
+ opts.otherJvmParams.addAll( it.trim('"', '\'').split(",").filterExtractProps(opts.mappers, "-", opts.restMapper))
}
return opts
}
-public fun configureDaemonLaunchingOptions(inheritMemoryLimits: Boolean): DaemonLaunchingOptions =
- configureDaemonLaunchingOptions(DaemonLaunchingOptions(), inheritMemoryLimits = inheritMemoryLimits)
+public fun configureDaemonLaunchingOptions(inheritMemoryLimits: Boolean): DaemonJVMOptions =
+ configureDaemonLaunchingOptions(DaemonJVMOptions(), inheritMemoryLimits = inheritMemoryLimits)
jvmOverloads public fun configureDaemonOptions(opts: DaemonOptions = DaemonOptions()): DaemonOptions {
System.getProperty(COMPILE_DAEMON_OPTIONS_PROPERTY)?.let {
- val unrecognized = it.trim('"', '\'').split(",").filterSetProps(opts.parsers, "")
+ val unrecognized = it.trim('"', '\'').split(",").filterExtractProps(opts.mappers, "")
if (unrecognized.any())
throw IllegalArgumentException(
"Unrecognized daemon options passed via property $COMPILE_DAEMON_OPTIONS_PROPERTY: " + unrecognized.joinToString(" ") +
- "\nSupported options: " + opts.extractors.joinToString(", ", transform = { it.name }))
+ "\nSupported options: " + opts.mappers.joinToString(", ", transform = { it.names.first() }))
}
return opts
}
diff --git a/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/CompileDaemon.kt b/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/CompileDaemon.kt
index 3c274d52f72..84c70919de2 100644
--- a/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/CompileDaemon.kt
+++ b/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/CompileDaemon.kt
@@ -17,10 +17,7 @@
package org.jetbrains.kotlin.rmi.service
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
-import org.jetbrains.kotlin.rmi.COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX
-import org.jetbrains.kotlin.rmi.CompilerId
-import org.jetbrains.kotlin.rmi.DaemonOptions
-import org.jetbrains.kotlin.rmi.filterSetProps
+import org.jetbrains.kotlin.rmi.*
import org.jetbrains.kotlin.service.CompileServiceImpl
import java.io.OutputStream
import java.io.PrintStream
@@ -96,7 +93,7 @@ public class CompileDaemon {
val compilerId = CompilerId()
val daemonOptions = DaemonOptions()
- val filteredArgs = args.asIterable().filterSetProps(compilerId, daemonOptions, prefix = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX)
+ val filteredArgs = args.asIterable().filterExtractProps(compilerId, daemonOptions, prefix = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX)
if (filteredArgs.any()) {
val helpLine = "usage: "
diff --git a/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/CompileServiceImpl.kt b/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/CompileServiceImpl.kt
index fd2b51fbaf2..f3ca7bd58a9 100644
--- a/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/CompileServiceImpl.kt
+++ b/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/CompileServiceImpl.kt
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.service
import org.jetbrains.kotlin.cli.common.CLICompiler
-import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
@@ -25,15 +24,12 @@ import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompil
import org.jetbrains.kotlin.rmi.*
import org.jetbrains.kotlin.rmi.service.RemoteIncrementalCacheClient
import org.jetbrains.kotlin.rmi.service.RemoteOutputStreamClient
-import java.io.File
-import java.io.FileNotFoundException
import java.io.IOException
import java.io.PrintStream
import java.lang.management.ManagementFactory
import java.net.URLClassLoader
import java.rmi.registry.Registry
import java.rmi.server.UnicastRemoteObject
-import java.util.*
import java.util.concurrent.TimeUnit
import java.util.concurrent.locks.ReentrantReadWriteLock
import java.util.jar.Manifest
@@ -86,12 +82,14 @@ class CompileServiceImpl>(
public class IncrementalCompilationComponentsImpl(val idToCache: Map): IncrementalCompilationComponents {
// perf: cheap object, but still the pattern may be costly if there are too many calls to cache with the same id (which seems not to be the case now)
override fun getIncrementalCache(moduleId: String): IncrementalCache = RemoteIncrementalCacheClient(idToCache[moduleId]!!)
+ // TODO: add appropriate proxy into interaction when lookup tracker is needed
override fun getLookupTracker(): LookupTracker = LookupTracker.DO_NOTHING
}
private fun createCompileServices(incrementalCaches: Map): Services =
Services.Builder()
- .register(javaClass(), IncrementalCompilationComponentsImpl(incrementalCaches))
+ .register(IncrementalCompilationComponents::class.java, IncrementalCompilationComponentsImpl(incrementalCaches))
+ // TODO: add remote proxy for cancellation status tracking
// .register(javaClass(), object: CompilationCanceledStatus {
// override fun checkCanceled(): Unit = if (context.getCancelStatus().isCanceled()) throw CompilationCanceledException()
// })
@@ -111,6 +109,7 @@ class CompileServiceImpl>(
return memHeap.used
}
+ // TODO: consider using version as a part of compiler ID or drop this function
private fun loadKotlinVersionFromResource(): String {
(javaClass.classLoader as? URLClassLoader)
?.findResource("META-INF/MANIFEST.MF")
@@ -158,6 +157,7 @@ class CompileServiceImpl>(
else body()
}
+ // sometimes used for debugging
fun spy(msg: String, body: () -> R): R {
val res = body()
log.info(msg + " = " + res.toString())
@@ -178,26 +178,25 @@ class CompileServiceImpl>(
}
override fun remoteCompile(args: Array, errStream: RemoteOutputStream, outputFormat: CompileService.OutputFormat): Int =
- ifAlive {
- checkedCompile(args) {
- val strm = RemoteOutputStreamClient(errStream)
- val printStrm = PrintStream(strm)
- when (outputFormat) {
- CompileService.OutputFormat.PLAIN -> compiler.exec(printStrm, *args)
- CompileService.OutputFormat.XML -> compiler.execAndOutputXml(printStrm, Services.EMPTY, *args)
- }.code
- }
+ doCompile(args, errStream) { printStream ->
+ when (outputFormat) {
+ CompileService.OutputFormat.PLAIN -> compiler.exec(printStream, *args)
+ CompileService.OutputFormat.XML -> compiler.execAndOutputXml(printStream, Services.EMPTY, *args)
+ }.code
}
- override fun remoteIncrementalCompile(args: Array, caches: Map, errStream: RemoteOutputStream, outputFormat: CompileService.OutputFormat): Int =
+ override fun remoteIncrementalCompile(args: Array, caches: Map, outputStream: RemoteOutputStream, outputFormat: CompileService.OutputFormat): Int =
+ doCompile(args, outputStream) { printStream ->
+ when (outputFormat) {
+ CompileService.OutputFormat.PLAIN -> throw NotImplementedError("Only XML output is supported in remote incremental compilation")
+ CompileService.OutputFormat.XML -> compiler.execAndOutputXml(printStream, createCompileServices(caches), *args)
+ }.code
+ }
+
+ fun doCompile(args: Array, errStream: RemoteOutputStream, body: (PrintStream) -> Int): Int =
ifAlive {
checkedCompile(args) {
- val strm = RemoteOutputStreamClient(errStream)
- val printStrm = PrintStream(strm)
- when (outputFormat) {
- CompileService.OutputFormat.PLAIN -> throw NotImplementedError("Only XML output is supported in remote incremental compilation")
- CompileService.OutputFormat.XML -> compiler.execAndOutputXml(printStrm, createCompileServices(caches), *args)
- }.code
+ body( PrintStream( RemoteOutputStreamClient(errStream)))
}
}
}
diff --git a/compiler/tests/org/jetbrains/kotlin/daemon/CompilerDaemonTest.kt b/compiler/tests/org/jetbrains/kotlin/daemon/CompilerDaemonTest.kt
index dd5842f9e5e..804afae51dc 100644
--- a/compiler/tests/org/jetbrains/kotlin/daemon/CompilerDaemonTest.kt
+++ b/compiler/tests/org/jetbrains/kotlin/daemon/CompilerDaemonTest.kt
@@ -20,7 +20,7 @@ import junit.framework.TestCase
import org.jetbrains.kotlin.cli.CliBaseTest
import org.jetbrains.kotlin.integration.KotlinIntegrationTestBase
import org.jetbrains.kotlin.rmi.CompilerId
-import org.jetbrains.kotlin.rmi.DaemonLaunchingOptions
+import org.jetbrains.kotlin.rmi.DaemonJVMOptions
import org.jetbrains.kotlin.rmi.DaemonOptions
import org.jetbrains.kotlin.rmi.kotlinr.KotlinCompilerClient
import org.jetbrains.kotlin.test.JetTestUtils
@@ -34,7 +34,7 @@ public class CompilerDaemonTest : KotlinIntegrationTestBase() {
data class CompilerResults(val resultCode: Int, val out: String)
val daemonOptions = DaemonOptions(port = KOTLIN_DAEMON_TEST_PORT)
- val daemonLaunchingOptions = DaemonLaunchingOptions()
+ val daemonLaunchingOptions = DaemonJVMOptions()
val compilerId by lazy { CompilerId.makeCompilerId( File(KotlinIntegrationTestBase.getCompilerLib(), "kotlin-compiler.jar"),
File("dependencies/bootstrap-compiler/Kotlin/kotlinc/lib/kotlin-runtime.jar"),
File("dependencies/bootstrap-compiler/Kotlin/kotlinc/lib/kotlin-reflect.jar")) }
diff --git a/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.java b/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.java
index c5460c78d48..3f62f14e35b 100644
--- a/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.java
+++ b/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.java
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.compilerRunner;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
@@ -136,9 +135,9 @@ public class KotlinCompilerRunner {
// the lifetime of JPS process is small anyway, we can neglect the probability of changed compiler
CompilerId compilerId = CompilerId.makeCompilerId(new File(libPath, "kotlin-compiler.jar"));
DaemonOptions daemonOptions = RmiPackage.configureDaemonOptions();
- DaemonLaunchingOptions daemonLaunchingOptions = RmiPackage.configureDaemonLaunchingOptions(true);
+ DaemonJVMOptions daemonJVMOptions = RmiPackage.configureDaemonLaunchingOptions(true);
// TODO: find proper stream to report daemon connection progress
- CompileService daemon = KotlinCompilerClient.Companion.connectToCompileService(compilerId, daemonLaunchingOptions, daemonOptions, System.out, true, true);
+ CompileService daemon = KotlinCompilerClient.Companion.connectToCompileService(compilerId, daemonJVMOptions, daemonOptions, System.out, true, true);
if (daemon != null) {
Integer res = KotlinCompilerClient.Companion.incrementalCompile(daemon, argsArray, incrementalCaches, out);
return res.toString();