Refactoring after review
This commit is contained in:
@@ -117,6 +117,8 @@
|
|||||||
<include name="backend-common/**"/>
|
<include name="backend-common/**"/>
|
||||||
<include name="cli/**"/>
|
<include name="cli/**"/>
|
||||||
<include name="cli-common/**"/>
|
<include name="cli-common/**"/>
|
||||||
|
<include name="rmi-server/**"/>
|
||||||
|
<include name="rmi-interface/**"/>
|
||||||
<include name="util/**"/>
|
<include name="util/**"/>
|
||||||
<include name="util.runtime/**"/>
|
<include name="util.runtime/**"/>
|
||||||
<include name="light-classes/**"/>
|
<include name="light-classes/**"/>
|
||||||
@@ -200,6 +202,8 @@
|
|||||||
<fileset dir="compiler/builtins-serializer/src"/>
|
<fileset dir="compiler/builtins-serializer/src"/>
|
||||||
<fileset dir="compiler/cli/src"/>
|
<fileset dir="compiler/cli/src"/>
|
||||||
<fileset dir="compiler/cli/cli-common/src"/>
|
<fileset dir="compiler/cli/cli-common/src"/>
|
||||||
|
<include name="compiler/rmi/rmi-server/src"/>
|
||||||
|
<include name="compiler/rmi/rmi-interface/src"/>
|
||||||
<fileset dir="compiler/container/src"/>
|
<fileset dir="compiler/container/src"/>
|
||||||
<fileset dir="compiler/frontend/src"/>
|
<fileset dir="compiler/frontend/src"/>
|
||||||
<fileset dir="compiler/frontend.java/src"/>
|
<fileset dir="compiler/frontend.java/src"/>
|
||||||
|
|||||||
@@ -26,12 +26,7 @@ import java.rmi.Remote
|
|||||||
import java.rmi.registry.LocateRegistry
|
import java.rmi.registry.LocateRegistry
|
||||||
import java.util.concurrent.Semaphore
|
import java.util.concurrent.Semaphore
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock
|
|
||||||
import kotlin.concurrent.read
|
|
||||||
import kotlin.concurrent.thread
|
import kotlin.concurrent.thread
|
||||||
import kotlin.concurrent.write
|
|
||||||
import kotlin.platform.platformStatic
|
|
||||||
import kotlin.reflect.KProperty1
|
|
||||||
|
|
||||||
fun Process.isAlive() =
|
fun Process.isAlive() =
|
||||||
try {
|
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 javaExecutable = File(System.getProperty("java.home"), "bin").let {
|
||||||
val javaw = File(it, "javaw.exe")
|
val javaw = File(it, "javaw.exe")
|
||||||
if (javaw.exists()) javaw
|
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
|
// 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,
|
val args = listOf(javaExecutable.absolutePath,
|
||||||
"-cp", compilerId.compilerClasspath.joinToString(File.pathSeparator)) +
|
"-cp", compilerId.compilerClasspath.joinToString(File.pathSeparator)) +
|
||||||
daemonLaunchingOptions.extractors.flatMap { it.extract("-") } +
|
daemonJVMOptions.mappers.flatMap { it.toArgs("-") } +
|
||||||
COMPILER_DAEMON_CLASS_FQN +
|
COMPILER_DAEMON_CLASS_FQN +
|
||||||
daemonOptions.extractors.flatMap { it.extract(COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) } +
|
daemonOptions.mappers.flatMap { it.toArgs(COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) } +
|
||||||
compilerId.extractors.flatMap { it.extract(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(" "))
|
errStream.println("[daemon client] starting the daemon as: " + args.joinToString(" "))
|
||||||
val processBuilder = ProcessBuilder(args).redirectErrorStream(true)
|
val processBuilder = ProcessBuilder(args).redirectErrorStream(true)
|
||||||
// assuming daemon process is deaf and (mostly) silent, so do not handle streams
|
// 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)
|
(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)
|
val service = connectToService(compilerId, daemonOptions, errStream)
|
||||||
if (service != null) {
|
if (service != null) {
|
||||||
if (!checkId || checkCompilerId(service, compilerId, errStream)) {
|
if (!checkId || checkCompilerId(service, compilerId, errStream)) {
|
||||||
errStream.println("[daemon client] found the suitable daemon")
|
errStream.println("[daemon client] found the suitable daemon")
|
||||||
return service
|
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;
|
if (!autostart) return null;
|
||||||
errStream.println("[daemon client] shutdown the daemon")
|
errStream.println("[daemon client] shutdown the daemon")
|
||||||
service.shutdown()
|
service.shutdown()
|
||||||
@@ -155,13 +150,13 @@ public class KotlinCompilerClient {
|
|||||||
else errStream.println("[daemon client] cannot connect to Compile Daemon, trying to start")
|
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")
|
errStream.println("[daemon client] daemon started, trying to connect")
|
||||||
return connectToService(compilerId, daemonOptions, errStream)
|
return connectToService(compilerId, daemonOptions, errStream)
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun shutdownCompileService(daemonOptions: DaemonOptions): Unit {
|
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()
|
?.shutdown()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,20 +191,17 @@ public class KotlinCompilerClient {
|
|||||||
|
|
||||||
data class ClientOptions(
|
data class ClientOptions(
|
||||||
public var stop: Boolean = false
|
public var stop: Boolean = false
|
||||||
) :CmdlineParams {
|
) : OptionsGroup {
|
||||||
override val extractors: List<PropExtractor<*, *, *>>
|
override val mappers: List<PropMapper<*, *, *>>
|
||||||
get() = listOf( BoolPropExtractor(this, ::stop))
|
get() = listOf( BoolPropMapper(this, ::stop))
|
||||||
|
|
||||||
override val parsers: List<PropParser<*,*,*>>
|
|
||||||
get() = listOf( BoolPropParser(this, ::stop))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
platformStatic public fun main(vararg args: String) {
|
jvmStatic public fun main(vararg args: String) {
|
||||||
val compilerId = CompilerId()
|
val compilerId = CompilerId()
|
||||||
val daemonOptions = DaemonOptions()
|
val daemonOptions = DaemonOptions()
|
||||||
val daemonLaunchingOptions = DaemonLaunchingOptions()
|
val daemonLaunchingOptions = DaemonJVMOptions()
|
||||||
val clientOptions = ClientOptions()
|
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 (!clientOptions.stop) {
|
||||||
if (compilerId.compilerClasspath.none()) {
|
if (compilerId.compilerClasspath.none()) {
|
||||||
|
|||||||
@@ -21,9 +21,7 @@ import java.io.Serializable
|
|||||||
import java.lang.management.ManagementFactory
|
import java.lang.management.ManagementFactory
|
||||||
import java.security.DigestInputStream
|
import java.security.DigestInputStream
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
import kotlin.platform.platformStatic
|
|
||||||
import kotlin.reflect.KMutableProperty1
|
import kotlin.reflect.KMutableProperty1
|
||||||
import kotlin.reflect.KProperty1
|
|
||||||
|
|
||||||
|
|
||||||
public val COMPILER_JAR_NAME: String = "kotlin-compiler.jar"
|
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_JVM_OPTIONS_PROPERTY: String ="kotlin.daemon.jvm.options"
|
||||||
public val COMPILE_DAEMON_OPTIONS_PROPERTY: String ="kotlin.daemon.options"
|
public val COMPILE_DAEMON_OPTIONS_PROPERTY: String ="kotlin.daemon.options"
|
||||||
public val COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX: String ="--daemon-"
|
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<C, V, P: KProperty1<C, V>>(val dest: C,
|
//open class PropExtractor<C, V, P: KProperty1<C, V>>(val dest: C,
|
||||||
val prop: P,
|
// val prop: P,
|
||||||
val name: String,
|
// val name: String,
|
||||||
val convert: ((v: V) -> String?) = { it.toString() },
|
// val convert: ((v: V) -> String?) = { it.toString() },
|
||||||
val skipIf: ((v: V) -> Boolean) = { false },
|
// val skipIf: ((v: V) -> Boolean) = { false },
|
||||||
val mergeWithDelimiter: String? = null)
|
// 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<String> =
|
||||||
|
// when {
|
||||||
|
// skipIf(prop.get(dest)) -> listOf<String>()
|
||||||
|
// mergeWithDelimiter != null -> listOf(prefix + name + mergeWithDelimiter + convert(prop.get(dest))).filterNotNull()
|
||||||
|
// else -> listOf(prefix + name, convert(prop.get(dest))).filterNotNull()
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//class BoolPropExtractor<C, P: KMutableProperty1<C, Boolean>>(dest: C, prop: P, name: String? = null)
|
||||||
|
// : PropExtractor<C, Boolean, P>(dest, prop, name ?: prop.name, convert = { null }, skipIf = { !prop.get(dest) })
|
||||||
|
//
|
||||||
|
//class RestPropExtractor<C, P: KMutableProperty1<C, out MutableCollection<String>>>(dest: C, prop: P) : PropExtractor<C, MutableCollection<String>, P>(dest, prop, convert = { null }) {
|
||||||
|
// override fun extract(prefix: String): List<String> = prop.get(dest).map { prefix + it }
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//open class PropParser<C, V, P: KMutableProperty1<C, V>>(val dest: C,
|
||||||
|
// val prop: P, alternativeNames: List<String>,
|
||||||
|
// 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<C, P: KMutableProperty1<C, Boolean>>(dest: C, prop: P): PropParser<C, Boolean, P>(dest, prop, { true })
|
||||||
|
//
|
||||||
|
//class RestPropParser<C, P: KMutableProperty1<C, MutableCollection<String>>>(dest: C, prop: P): PropParser<C, MutableCollection<String>, P>(dest, prop, { arrayListOf() }) {
|
||||||
|
// fun add(s: String) { prop.get(dest).add(s) }
|
||||||
|
//}
|
||||||
|
|
||||||
|
// --------------------------------------------------------
|
||||||
|
|
||||||
|
open class PropMapper<C, V, P: KMutableProperty1<C, V>>(val dest: C,
|
||||||
|
val prop: P,
|
||||||
|
val names: List<String> = 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 toArgs(prefix: String = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX): List<String> =
|
||||||
open fun extract(prefix: String = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX): List<String> =
|
|
||||||
when {
|
when {
|
||||||
skipIf(prop.get(dest)) -> listOf<String>()
|
skipIf(prop.get(dest)) -> listOf<String>()
|
||||||
mergeWithDelimiter != null -> listOf(prefix + name + mergeWithDelimiter + convert(prop.get(dest))).filterNotNull()
|
mergeDelimiter != null -> listOf(prefix + names.first() + mergeDelimiter + toString(prop.get(dest))).filterNotNull()
|
||||||
else -> listOf(prefix + name, convert(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<C, P: KMutableProperty1<C, Boolean>>(dest: C, prop: P, name: String? = null)
|
class StringPropMapper<C, P: KMutableProperty1<C, String>>(dest: C,
|
||||||
: PropExtractor<C, Boolean, P>(dest, prop, name ?: prop.name, convert = { null }, skipIf = { !prop.get(dest) })
|
prop: P,
|
||||||
|
names: List<String> = listOf(),
|
||||||
|
fromString: ((String) -> String) = { it },
|
||||||
|
toString: ((String) -> String?) = { it.toString() },
|
||||||
|
skipIf: ((String) -> Boolean) = { it.isEmpty() },
|
||||||
|
mergeDelimiter: String? = null)
|
||||||
|
: PropMapper<C, String, P>(dest = dest, prop = prop, names = if (names.any()) names else listOf(prop.name),
|
||||||
|
fromString = fromString, toString = toString, skipIf = skipIf, mergeDelimiter = mergeDelimiter)
|
||||||
|
|
||||||
class RestPropExtractor<C, P: KMutableProperty1<C, out MutableCollection<String>>>(dest: C, prop: P) : PropExtractor<C, MutableCollection<String>, P>(dest, prop, convert = { null }) {
|
class BoolPropMapper<C, P: KMutableProperty1<C, Boolean>>(dest: C, prop: P, names: List<String> = listOf())
|
||||||
override fun extract(prefix: String): List<String> = prop.get(dest).map { prefix + it }
|
: PropMapper<C, Boolean, P>(dest = dest, prop = prop, names = if (names.any()) names else listOf(prop.name),
|
||||||
}
|
fromString = { true }, toString = { null }, skipIf = { !prop.get(dest) })
|
||||||
|
|
||||||
|
class RestPropMapper<C, P: KMutableProperty1<C, MutableCollection<String>>>(dest: C, prop: P)
|
||||||
open class PropParser<C, V, P: KMutableProperty1<C, V>>(val dest: C,
|
: PropMapper<C, MutableCollection<String>, P>(dest = dest, prop = prop, toString = { null }, fromString = { arrayListOf() })
|
||||||
val prop: P, alternativeNames: List<String>,
|
{
|
||||||
val parse: (s: String) -> V,
|
override fun toArgs(prefix: String): List<String> = prop.get(dest).map { prefix + it }
|
||||||
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<C, P: KMutableProperty1<C, Boolean>>(dest: C, prop: P): PropParser<C, Boolean, P>(dest, prop, { true })
|
|
||||||
|
|
||||||
class RestPropParser<C, P: KMutableProperty1<C, MutableCollection<String>>>(dest: C, prop: P): PropParser<C, MutableCollection<String>, P>(dest, prop, { arrayListOf() }) {
|
|
||||||
fun add(s: String) { prop.get(dest).add(s) }
|
fun add(s: String) { prop.get(dest).add(s) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
|
||||||
fun Iterable<String>.filterSetProps(parsers: List<PropParser<*,*,*>>, prefix: String, restParser: RestPropParser<*,*>? = null) : Iterable<String> {
|
fun Iterable<String>.filterExtractProps(propMappers: List<PropMapper<*,*,*>>, prefix: String, restParser: RestPropMapper<*,*>? = null) : Iterable<String> {
|
||||||
var currentParser: PropParser<*,*,*>? = null
|
var currentPropMapper: PropMapper<*,*,*>? = null
|
||||||
var matchingOption = ""
|
var matchingOption = ""
|
||||||
val res = filter { param ->
|
val res = filter { param ->
|
||||||
if (currentParser == null) {
|
if (currentPropMapper == null) {
|
||||||
val parser = parsers.find { it.names.any { name ->
|
val propMapper = propMappers.find {
|
||||||
if (param.startsWith(prefix + name)) { matchingOption = prefix + name; true }
|
it !is RestPropMapper<*,*> &&
|
||||||
else false } }
|
it.names.any { name ->
|
||||||
if (parser != null) {
|
if (param.startsWith(prefix + name)) {
|
||||||
val optionLength = matchingOption.length()
|
matchingOption = prefix + name
|
||||||
when {
|
true
|
||||||
parser is BoolPropParser<*,*> ->
|
}
|
||||||
if (param.length() > optionLength) throw IllegalArgumentException("Invalid switch option '$param', expecting $matchingOption without arguments")
|
else {
|
||||||
else parser.apply("")
|
false
|
||||||
param.length() > optionLength ->
|
}
|
||||||
if (param[optionLength] != '=') {
|
|
||||||
if (parser.allowMergedArg) parser.apply(param.substring(optionLength))
|
|
||||||
else throw IllegalArgumentException("Invalid option syntax '$param', expecting $matchingOption[= ]<arg>")
|
|
||||||
}
|
|
||||||
else parser.apply(param.substring(optionLength + 1))
|
|
||||||
else -> currentParser = parser
|
|
||||||
}
|
}
|
||||||
false
|
|
||||||
}
|
}
|
||||||
else if (restParser != null && param.startsWith(prefix)) {
|
when {
|
||||||
restParser.add(param.removePrefix(prefix))
|
propMapper != null -> {
|
||||||
false
|
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[= ]<arg>")
|
||||||
|
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 {
|
else {
|
||||||
currentParser!!.apply(param)
|
currentPropMapper!!.apply(param)
|
||||||
currentParser = null
|
currentPropMapper = null
|
||||||
false
|
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
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,59 +184,46 @@ fun Iterable<String>.filterSetProps(parsers: List<PropParser<*,*,*>>, prefix: St
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
public interface CmdlineParams : Serializable {
|
public interface OptionsGroup : Serializable {
|
||||||
public val extractors: List<PropExtractor<*,*,*>>
|
public val mappers: List<PropMapper<*,*,*>>
|
||||||
public val parsers: List<PropParser<*,*,*>>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun Iterable<String>.filterSetProps(vararg cs: CmdlineParams, prefix: String) : Iterable<String> =
|
public fun Iterable<String>.filterExtractProps(vararg groups: OptionsGroup, prefix: String) : Iterable<String> =
|
||||||
filterSetProps(cs.flatMap { it.parsers }, prefix)
|
filterExtractProps(groups.flatMap { it.mappers }, prefix)
|
||||||
|
|
||||||
|
|
||||||
public data class DaemonLaunchingOptions(
|
public data class DaemonJVMOptions(
|
||||||
public var maxMemory: String = "",
|
public var maxMemory: String = "",
|
||||||
public var maxPermSize: String = "",
|
public var maxPermSize: String = "",
|
||||||
public var reservedCodeCacheSize: String = "",
|
public var reservedCodeCacheSize: String = "",
|
||||||
public var otherJvmParams: MutableCollection<String> = arrayListOf()
|
public var otherJvmParams: MutableCollection<String> = arrayListOf()
|
||||||
) : CmdlineParams {
|
) : OptionsGroup {
|
||||||
|
|
||||||
override val extractors: List<PropExtractor<*,*,*>>
|
override val mappers: List<PropMapper<*,*,*>>
|
||||||
get() = listOf( PropExtractor(this, ::maxMemory, "Xmx", skipIf = { it.isEmpty() }, mergeWithDelimiter = ""),
|
get() = listOf( StringPropMapper(this, ::maxMemory, listOf("Xmx"), mergeDelimiter = ""),
|
||||||
PropExtractor(this, ::maxPermSize, "XX:MaxPermSize", skipIf = { it.isEmpty() }, mergeWithDelimiter = "="),
|
StringPropMapper(this, ::maxPermSize, listOf("XX:MaxPermSize"), mergeDelimiter = "="),
|
||||||
PropExtractor(this, ::reservedCodeCacheSize, "XX:ReservedCodeCacheSize", skipIf = { it.isEmpty() }, mergeWithDelimiter = "="),
|
StringPropMapper(this, ::reservedCodeCacheSize, listOf("XX:ReservedCodeCacheSize"), mergeDelimiter = "="),
|
||||||
RestPropExtractor(this, ::otherJvmParams))
|
restMapper)
|
||||||
|
|
||||||
override val parsers: List<PropParser<*,*,*>>
|
val restMapper: RestPropMapper<*,*>
|
||||||
get() = listOf( PropParser(this, ::maxMemory, listOf("Xmx"), { it }, allowMergedArg = true),
|
get() = RestPropMapper(this, ::otherJvmParams)
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public data class DaemonOptions(
|
public data class DaemonOptions(
|
||||||
public var port: Int = COMPILE_DAEMON_DEFAULT_PORT,
|
public var port: Int = COMPILE_DAEMON_DEFAULT_PORT,
|
||||||
public var autoshutdownMemoryThreshold: Long = 0 /* 0 means unchecked */,
|
public var autoshutdownMemoryThreshold: Long = COMPILE_DAEMON_MEMORY_THRESHOLD_INFINITE,
|
||||||
public var autoshutdownIdleSeconds: Int = 0 /* 0 means unchecked */,
|
public var autoshutdownIdleSeconds: Int = COMPILE_DAEMON_TIMEOUT_INFINITE_S,
|
||||||
public var startEcho: String = COMPILER_SERVICE_RMI_NAME
|
public var startEcho: String = COMPILER_SERVICE_RMI_NAME
|
||||||
) : CmdlineParams {
|
) : OptionsGroup {
|
||||||
|
|
||||||
override val extractors: List<PropExtractor<*, *, *>>
|
override val mappers: List<PropMapper<*, *, *>>
|
||||||
get() = listOf( PropExtractor(this, ::port),
|
get() = listOf( PropMapper(this, ::port, fromString = { it.toInt() }),
|
||||||
PropExtractor(this, ::autoshutdownMemoryThreshold, skipIf = { it == 0L }),
|
PropMapper(this, ::autoshutdownMemoryThreshold, fromString = { it.toLong() }, skipIf = { it == 0L }),
|
||||||
PropExtractor(this, ::autoshutdownIdleSeconds, skipIf = { it == 0 }),
|
PropMapper(this, ::autoshutdownIdleSeconds, fromString = { it.toInt() }, skipIf = { it == 0 }),
|
||||||
PropExtractor(this, ::startEcho))
|
PropMapper(this, ::startEcho, fromString = { it.trim('"') }))
|
||||||
|
|
||||||
override val parsers: List<PropParser<*,*,*>>
|
|
||||||
get() = listOf( PropParser(this, ::port, { it.toInt()}),
|
|
||||||
PropParser(this, ::autoshutdownMemoryThreshold, { it.toLong()}),
|
|
||||||
PropParser(this, ::autoshutdownIdleSeconds, { it.toInt()}),
|
|
||||||
PropParser(this, ::startEcho, { it.trim('"') }))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
val COMPILER_ID_DIGEST = "MD5"
|
|
||||||
|
|
||||||
|
|
||||||
fun updateSingleFileDigest(file: File, md: MessageDigest) {
|
fun updateSingleFileDigest(file: File, md: MessageDigest) {
|
||||||
DigestInputStream(file.inputStream(), md).use {
|
DigestInputStream(file.inputStream(), md).use {
|
||||||
val buf = ByteArray(1024)
|
val buf = ByteArray(1024)
|
||||||
@@ -215,27 +262,21 @@ public data class CompilerId(
|
|||||||
public var compilerDigest: String = "",
|
public var compilerDigest: String = "",
|
||||||
public var compilerVersion: String = ""
|
public var compilerVersion: String = ""
|
||||||
// TODO: checksum
|
// TODO: checksum
|
||||||
) : CmdlineParams {
|
) : OptionsGroup {
|
||||||
|
|
||||||
override val extractors: List<PropExtractor<*, *, *>>
|
override val mappers: List<PropMapper<*, *, *>>
|
||||||
get() = listOf( PropExtractor(this, ::compilerClasspath, convert = { it.joinToString(File.pathSeparator) }),
|
get() = listOf( PropMapper(this, ::compilerClasspath, toString = { it.joinToString(File.pathSeparator) }, fromString = { it.trim('"').split(File.pathSeparator)}),
|
||||||
PropExtractor(this, ::compilerDigest),
|
StringPropMapper(this, ::compilerDigest),
|
||||||
PropExtractor(this, ::compilerVersion, skipIf = { it.isEmpty() }))
|
StringPropMapper(this, ::compilerVersion))
|
||||||
|
|
||||||
override val parsers: List<PropParser<*,*,*>>
|
|
||||||
get() =
|
|
||||||
listOf( PropParser(this, ::compilerClasspath, { it.trim('"').split(File.pathSeparator)}),
|
|
||||||
PropParser(this, ::compilerDigest, { it.trim('"') }),
|
|
||||||
PropParser(this, ::compilerVersion, { it.trim('"') }))
|
|
||||||
|
|
||||||
public fun updateDigest() {
|
public fun updateDigest() {
|
||||||
compilerDigest = compilerClasspath.getClasspathDigest()
|
compilerDigest = compilerClasspath.getClasspathDigest()
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
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<File>): CompilerId =
|
public jvmStatic fun makeCompilerId(paths: Iterable<File>): CompilerId =
|
||||||
// TODO consider reading version here
|
// TODO consider reading version here
|
||||||
CompilerId(compilerClasspath = paths.map { it.absolutePath }, compilerDigest = paths.getFilesClasspathDigest())
|
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 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
|
// note: sequence matters, explicit override in COMPILE_DAEMON_JVM_OPTIONS_PROPERTY should be done after inputArguments processing
|
||||||
if (inheritMemoryLimits)
|
if (inheritMemoryLimits)
|
||||||
ManagementFactory.getRuntimeMXBean().inputArguments.filterSetProps(opts.parsers, "-")
|
ManagementFactory.getRuntimeMXBean().inputArguments.filterExtractProps(opts.mappers, "-")
|
||||||
|
|
||||||
System.getProperty(COMPILE_DAEMON_JVM_OPTIONS_PROPERTY)?.let {
|
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
|
return opts
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun configureDaemonLaunchingOptions(inheritMemoryLimits: Boolean): DaemonLaunchingOptions =
|
public fun configureDaemonLaunchingOptions(inheritMemoryLimits: Boolean): DaemonJVMOptions =
|
||||||
configureDaemonLaunchingOptions(DaemonLaunchingOptions(), inheritMemoryLimits = inheritMemoryLimits)
|
configureDaemonLaunchingOptions(DaemonJVMOptions(), inheritMemoryLimits = inheritMemoryLimits)
|
||||||
|
|
||||||
jvmOverloads public fun configureDaemonOptions(opts: DaemonOptions = DaemonOptions()): DaemonOptions {
|
jvmOverloads public fun configureDaemonOptions(opts: DaemonOptions = DaemonOptions()): DaemonOptions {
|
||||||
System.getProperty(COMPILE_DAEMON_OPTIONS_PROPERTY)?.let {
|
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())
|
if (unrecognized.any())
|
||||||
throw IllegalArgumentException(
|
throw IllegalArgumentException(
|
||||||
"Unrecognized daemon options passed via property $COMPILE_DAEMON_OPTIONS_PROPERTY: " + unrecognized.joinToString(" ") +
|
"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
|
return opts
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,10 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.rmi.service
|
package org.jetbrains.kotlin.rmi.service
|
||||||
|
|
||||||
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
|
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
|
||||||
import org.jetbrains.kotlin.rmi.COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX
|
import org.jetbrains.kotlin.rmi.*
|
||||||
import org.jetbrains.kotlin.rmi.CompilerId
|
|
||||||
import org.jetbrains.kotlin.rmi.DaemonOptions
|
|
||||||
import org.jetbrains.kotlin.rmi.filterSetProps
|
|
||||||
import org.jetbrains.kotlin.service.CompileServiceImpl
|
import org.jetbrains.kotlin.service.CompileServiceImpl
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
import java.io.PrintStream
|
import java.io.PrintStream
|
||||||
@@ -96,7 +93,7 @@ public class CompileDaemon {
|
|||||||
|
|
||||||
val compilerId = CompilerId()
|
val compilerId = CompilerId()
|
||||||
val daemonOptions = DaemonOptions()
|
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()) {
|
if (filteredArgs.any()) {
|
||||||
val helpLine = "usage: <daemon> <compilerId options> <daemon options>"
|
val helpLine = "usage: <daemon> <compilerId options> <daemon options>"
|
||||||
|
|||||||
+20
-21
@@ -17,7 +17,6 @@
|
|||||||
package org.jetbrains.kotlin.service
|
package org.jetbrains.kotlin.service
|
||||||
|
|
||||||
import org.jetbrains.kotlin.cli.common.CLICompiler
|
import org.jetbrains.kotlin.cli.common.CLICompiler
|
||||||
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
|
|
||||||
import org.jetbrains.kotlin.config.Services
|
import org.jetbrains.kotlin.config.Services
|
||||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
|
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.*
|
||||||
import org.jetbrains.kotlin.rmi.service.RemoteIncrementalCacheClient
|
import org.jetbrains.kotlin.rmi.service.RemoteIncrementalCacheClient
|
||||||
import org.jetbrains.kotlin.rmi.service.RemoteOutputStreamClient
|
import org.jetbrains.kotlin.rmi.service.RemoteOutputStreamClient
|
||||||
import java.io.File
|
|
||||||
import java.io.FileNotFoundException
|
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.io.PrintStream
|
import java.io.PrintStream
|
||||||
import java.lang.management.ManagementFactory
|
import java.lang.management.ManagementFactory
|
||||||
import java.net.URLClassLoader
|
import java.net.URLClassLoader
|
||||||
import java.rmi.registry.Registry
|
import java.rmi.registry.Registry
|
||||||
import java.rmi.server.UnicastRemoteObject
|
import java.rmi.server.UnicastRemoteObject
|
||||||
import java.util.*
|
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock
|
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||||
import java.util.jar.Manifest
|
import java.util.jar.Manifest
|
||||||
@@ -86,12 +82,14 @@ class CompileServiceImpl<Compiler: CLICompiler<*>>(
|
|||||||
public class IncrementalCompilationComponentsImpl(val idToCache: Map<String, CompileService.RemoteIncrementalCache>): IncrementalCompilationComponents {
|
public class IncrementalCompilationComponentsImpl(val idToCache: Map<String, CompileService.RemoteIncrementalCache>): 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)
|
// 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]!!)
|
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
|
override fun getLookupTracker(): LookupTracker = LookupTracker.DO_NOTHING
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createCompileServices(incrementalCaches: Map<String, CompileService.RemoteIncrementalCache>): Services =
|
private fun createCompileServices(incrementalCaches: Map<String, CompileService.RemoteIncrementalCache>): Services =
|
||||||
Services.Builder()
|
Services.Builder()
|
||||||
.register(javaClass<IncrementalCompilationComponents>(), IncrementalCompilationComponentsImpl(incrementalCaches))
|
.register(IncrementalCompilationComponents::class.java, IncrementalCompilationComponentsImpl(incrementalCaches))
|
||||||
|
// TODO: add remote proxy for cancellation status tracking
|
||||||
// .register(javaClass<CompilationCanceledStatus>(), object: CompilationCanceledStatus {
|
// .register(javaClass<CompilationCanceledStatus>(), object: CompilationCanceledStatus {
|
||||||
// override fun checkCanceled(): Unit = if (context.getCancelStatus().isCanceled()) throw CompilationCanceledException()
|
// override fun checkCanceled(): Unit = if (context.getCancelStatus().isCanceled()) throw CompilationCanceledException()
|
||||||
// })
|
// })
|
||||||
@@ -111,6 +109,7 @@ class CompileServiceImpl<Compiler: CLICompiler<*>>(
|
|||||||
return memHeap.used
|
return memHeap.used
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: consider using version as a part of compiler ID or drop this function
|
||||||
private fun loadKotlinVersionFromResource(): String {
|
private fun loadKotlinVersionFromResource(): String {
|
||||||
(javaClass.classLoader as? URLClassLoader)
|
(javaClass.classLoader as? URLClassLoader)
|
||||||
?.findResource("META-INF/MANIFEST.MF")
|
?.findResource("META-INF/MANIFEST.MF")
|
||||||
@@ -158,6 +157,7 @@ class CompileServiceImpl<Compiler: CLICompiler<*>>(
|
|||||||
else body()
|
else body()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sometimes used for debugging
|
||||||
fun<R> spy(msg: String, body: () -> R): R {
|
fun<R> spy(msg: String, body: () -> R): R {
|
||||||
val res = body()
|
val res = body()
|
||||||
log.info(msg + " = " + res.toString())
|
log.info(msg + " = " + res.toString())
|
||||||
@@ -178,26 +178,25 @@ class CompileServiceImpl<Compiler: CLICompiler<*>>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun remoteCompile(args: Array<out String>, errStream: RemoteOutputStream, outputFormat: CompileService.OutputFormat): Int =
|
override fun remoteCompile(args: Array<out String>, errStream: RemoteOutputStream, outputFormat: CompileService.OutputFormat): Int =
|
||||||
ifAlive {
|
doCompile(args, errStream) { printStream ->
|
||||||
checkedCompile(args) {
|
when (outputFormat) {
|
||||||
val strm = RemoteOutputStreamClient(errStream)
|
CompileService.OutputFormat.PLAIN -> compiler.exec(printStream, *args)
|
||||||
val printStrm = PrintStream(strm)
|
CompileService.OutputFormat.XML -> compiler.execAndOutputXml(printStream, Services.EMPTY, *args)
|
||||||
when (outputFormat) {
|
}.code
|
||||||
CompileService.OutputFormat.PLAIN -> compiler.exec(printStrm, *args)
|
|
||||||
CompileService.OutputFormat.XML -> compiler.execAndOutputXml(printStrm, Services.EMPTY, *args)
|
|
||||||
}.code
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun remoteIncrementalCompile(args: Array<out String>, caches: Map<String, CompileService.RemoteIncrementalCache>, errStream: RemoteOutputStream, outputFormat: CompileService.OutputFormat): Int =
|
override fun remoteIncrementalCompile(args: Array<out String>, caches: Map<String, CompileService.RemoteIncrementalCache>, 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<out String>, errStream: RemoteOutputStream, body: (PrintStream) -> Int): Int =
|
||||||
ifAlive {
|
ifAlive {
|
||||||
checkedCompile(args) {
|
checkedCompile(args) {
|
||||||
val strm = RemoteOutputStreamClient(errStream)
|
body( PrintStream( 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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import junit.framework.TestCase
|
|||||||
import org.jetbrains.kotlin.cli.CliBaseTest
|
import org.jetbrains.kotlin.cli.CliBaseTest
|
||||||
import org.jetbrains.kotlin.integration.KotlinIntegrationTestBase
|
import org.jetbrains.kotlin.integration.KotlinIntegrationTestBase
|
||||||
import org.jetbrains.kotlin.rmi.CompilerId
|
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.DaemonOptions
|
||||||
import org.jetbrains.kotlin.rmi.kotlinr.KotlinCompilerClient
|
import org.jetbrains.kotlin.rmi.kotlinr.KotlinCompilerClient
|
||||||
import org.jetbrains.kotlin.test.JetTestUtils
|
import org.jetbrains.kotlin.test.JetTestUtils
|
||||||
@@ -34,7 +34,7 @@ public class CompilerDaemonTest : KotlinIntegrationTestBase() {
|
|||||||
data class CompilerResults(val resultCode: Int, val out: String)
|
data class CompilerResults(val resultCode: Int, val out: String)
|
||||||
|
|
||||||
val daemonOptions = DaemonOptions(port = KOTLIN_DAEMON_TEST_PORT)
|
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"),
|
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-runtime.jar"),
|
||||||
File("dependencies/bootstrap-compiler/Kotlin/kotlinc/lib/kotlin-reflect.jar")) }
|
File("dependencies/bootstrap-compiler/Kotlin/kotlinc/lib/kotlin-reflect.jar")) }
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.compilerRunner;
|
package org.jetbrains.kotlin.compilerRunner;
|
||||||
|
|
||||||
import com.intellij.openapi.diagnostic.Logger;
|
|
||||||
import com.intellij.openapi.util.text.StringUtil;
|
import com.intellij.openapi.util.text.StringUtil;
|
||||||
import com.intellij.util.ArrayUtil;
|
import com.intellij.util.ArrayUtil;
|
||||||
import com.intellij.util.Function;
|
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
|
// 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"));
|
CompilerId compilerId = CompilerId.makeCompilerId(new File(libPath, "kotlin-compiler.jar"));
|
||||||
DaemonOptions daemonOptions = RmiPackage.configureDaemonOptions();
|
DaemonOptions daemonOptions = RmiPackage.configureDaemonOptions();
|
||||||
DaemonLaunchingOptions daemonLaunchingOptions = RmiPackage.configureDaemonLaunchingOptions(true);
|
DaemonJVMOptions daemonJVMOptions = RmiPackage.configureDaemonLaunchingOptions(true);
|
||||||
// TODO: find proper stream to report daemon connection progress
|
// 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) {
|
if (daemon != null) {
|
||||||
Integer res = KotlinCompilerClient.Companion.incrementalCompile(daemon, argsArray, incrementalCaches, out);
|
Integer res = KotlinCompilerClient.Companion.incrementalCompile(daemon, argsArray, incrementalCaches, out);
|
||||||
return res.toString();
|
return res.toString();
|
||||||
|
|||||||
Reference in New Issue
Block a user