From c294a682dee86abbdbe80adf68891a84edf62ed0 Mon Sep 17 00:00:00 2001 From: Ilya Chernikov Date: Wed, 23 Sep 2015 12:55:18 +0200 Subject: [PATCH 1/6] Utils for checking presense of certain lines in a sequence, using this tool for checking log after daemon builds in tests, fixing explicit daemon shutdown used in the test, some minor fixes --- .../rmi/kotlinr/KotlinCompilerClient.kt | 8 +- .../org/jetbrains/kotlin/rmi/DaemonParams.kt | 2 + .../kotlin/rmi/service/CompileDaemon.kt | 21 +++-- .../kotlin/daemon/CompilerDaemonTest.kt | 67 ++++++++++---- .../jetbrains/kotlin/daemon/LogCheckUtil.kt | 91 +++++++++++++++++++ .../jps/build/SimpleKotlinJpsBuildTest.kt | 6 +- 6 files changed, 160 insertions(+), 35 deletions(-) create mode 100644 compiler/tests/org/jetbrains/kotlin/daemon/LogCheckUtil.kt 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 cc7aa7f342d..2b115f861e9 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 @@ -93,14 +93,14 @@ public object KotlinCompilerClient { } - public fun shutdownCompileService(daemonOptions: DaemonOptions): Unit { - KotlinCompilerClient.connectToCompileService(CompilerId(), DaemonJVMOptions(), daemonOptions, DaemonReportingTargets(out = System.out), autostart = false, checkId = false) + public fun shutdownCompileService(compilerId: CompilerId, daemonOptions: DaemonOptions): Unit { + KotlinCompilerClient.connectToCompileService(compilerId, DaemonJVMOptions(), daemonOptions, DaemonReportingTargets(out = System.out), autostart = false, checkId = false) ?.shutdown() } - public fun shutdownCompileService(): Unit { - shutdownCompileService(DaemonOptions()) + public fun shutdownCompileService(compilerId: CompilerId): Unit { + shutdownCompileService(compilerId, DaemonOptions()) } 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 48e8f164c45..b081521d78c 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 @@ -36,6 +36,7 @@ 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_CLIENT_ALIVE_PATH_PROPERTY: String = "kotlin.daemon.client.alive.path" +public val COMPILE_DAEMON_LOG_PATH_PROPERTY: String = "kotlin.daemon.log.path" public val COMPILE_DAEMON_REPORT_PERF_PROPERTY: String = "kotlin.daemon.perf" public val COMPILE_DAEMON_VERBOSE_REPORT_PROPERTY: String = "kotlin.daemon.verbose" public val COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX: String = "--daemon-" @@ -299,6 +300,7 @@ public fun configureDaemonJVMOptions(opts: DaemonJVMOptions, inheritMemoryLimits System.getProperty(COMPILE_DAEMON_REPORT_PERF_PROPERTY)?.let { opts.jvmParams.add("D" + COMPILE_DAEMON_REPORT_PERF_PROPERTY) } System.getProperty(COMPILE_DAEMON_VERBOSE_REPORT_PROPERTY)?.let { opts.jvmParams.add("D" + COMPILE_DAEMON_VERBOSE_REPORT_PROPERTY) } + System.getProperty(COMPILE_DAEMON_LOG_PATH_PROPERTY)?.let { opts.jvmParams.add("D$COMPILE_DAEMON_LOG_PATH_PROPERTY=$it" ) } 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 a8354de5a8f..201d5498f00 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 @@ -59,18 +59,19 @@ class LogStream(name: String) : OutputStream() { public object CompileDaemon { init { - val logPath: String = System.getProperty("kotlin.daemon.log.path")?.trimEnd('/','\\') ?: "%t" val logTime: String = SimpleDateFormat("yyyy-MM-dd.HH-mm-ss-SSS").format(Date()) + val (logPath: String, fileIsGiven: Boolean) = + System.getProperty(COMPILE_DAEMON_LOG_PATH_PROPERTY)?.let { Pair(it, File(it).isFile) } ?: Pair("%t", false) val cfg: String = - "handlers = java.util.logging.FileHandler\n" + - "java.util.logging.FileHandler.level = ALL\n" + - "java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter\n" + - "java.util.logging.FileHandler.encoding = UTF-8\n" + - "java.util.logging.FileHandler.limit = 1073741824\n" + // 1Mb - "java.util.logging.FileHandler.count = 3\n" + - "java.util.logging.FileHandler.append = false\n" + - "java.util.logging.FileHandler.pattern = $logPath/$COMPILE_DAEMON_DEFAULT_FILES_PREFIX.$logTime.%u%g.log\n" + - "java.util.logging.SimpleFormatter.format = %1\$tF %1\$tT.%1\$tL [%3\$s] %4\$s: %5\$s\\n\n" + "handlers = java.util.logging.FileHandler\n" + + "java.util.logging.FileHandler.level = ALL\n" + + "java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter\n" + + "java.util.logging.FileHandler.encoding = UTF-8\n" + + "java.util.logging.FileHandler.limit = ${if (fileIsGiven) 0 else (1 shl 20)}\n" + // if file is provided - disabled, else - 1Mb + "java.util.logging.FileHandler.count = ${if (fileIsGiven) 1 else 3}\n" + + "java.util.logging.FileHandler.append = $fileIsGiven\n" + + "java.util.logging.FileHandler.pattern = ${if (fileIsGiven) logPath else (logPath + File.separator + "$COMPILE_DAEMON_DEFAULT_FILES_PREFIX.$logTime.%u%g.log")}\n" + + "java.util.logging.SimpleFormatter.format = %1\$tF %1\$tT.%1\$tL [%3\$s] %4\$s: %5\$s\\n\n" LogManager.getLogManager().readConfiguration(cfg.byteInputStream()) } diff --git a/compiler/tests/org/jetbrains/kotlin/daemon/CompilerDaemonTest.kt b/compiler/tests/org/jetbrains/kotlin/daemon/CompilerDaemonTest.kt index 8ac0f4709fd..96b306070e0 100644 --- a/compiler/tests/org/jetbrains/kotlin/daemon/CompilerDaemonTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/daemon/CompilerDaemonTest.kt @@ -31,7 +31,6 @@ public class CompilerDaemonTest : KotlinIntegrationTestBase() { data class CompilerResults(val resultCode: Int, val out: String) val daemonOptions by lazy(LazyThreadSafetyMode.NONE) { DaemonOptions(runFilesPath = tmpdir.absolutePath) } - val daemonJVMOptions by lazy(LazyThreadSafetyMode.NONE) { DaemonJVMOptions() } val compilerId by lazy(LazyThreadSafetyMode.NONE) { CompilerId.makeCompilerId( File(KotlinIntegrationTestBase.getCompilerLib(), "kotlin-compiler.jar"), @@ -39,33 +38,52 @@ public class CompilerDaemonTest : KotlinIntegrationTestBase() { File("dependencies/bootstrap-compiler/Kotlin/kotlinc/lib/kotlin-reflect.jar")) } - private fun compileOnDaemon(args: Array): CompilerResults { - System.setProperty(COMPILE_DAEMON_VERBOSE_REPORT_PROPERTY, "") - try { - val daemon = KotlinCompilerClient.connectToCompileService(compilerId, daemonJVMOptions, daemonOptions, DaemonReportingTargets(out = System.err), autostart = true, checkId = true) - TestCase.assertNotNull("failed to connect daemon", daemon) - val strm = ByteArrayOutputStream() - val code = KotlinCompilerClient.compile(daemon!!, args, strm) - return CompilerResults(code, strm.toString()) - } - finally { - System.clearProperty(COMPILE_DAEMON_VERBOSE_REPORT_PROPERTY) - } + private fun compileOnDaemon(daemonJVMOptions: DaemonJVMOptions, args: Array): CompilerResults { + val daemon = KotlinCompilerClient.connectToCompileService(compilerId, daemonJVMOptions, daemonOptions, DaemonReportingTargets(out = System.err), autostart = true, checkId = true) + TestCase.assertNotNull("failed to connect daemon", daemon) + val strm = ByteArrayOutputStream() + val code = KotlinCompilerClient.compile(daemon!!, args, strm) + return CompilerResults(code, strm.toString()) } private fun runDaemonCompilerTwice(logName: String, vararg arguments: String): Unit { - KotlinCompilerClient.shutdownCompileService(daemonOptions) + KotlinCompilerClient.shutdownCompileService(compilerId, daemonOptions) + + System.setProperty(COMPILE_DAEMON_VERBOSE_REPORT_PROPERTY, "") + val logFile = File.createTempFile("kotlin-daemon-test.", ".log") + System.setProperty(COMPILE_DAEMON_LOG_PATH_PROPERTY, logFile.absolutePath) + + val daemonJVMOptions = configureDaemonJVMOptions(false) + var daemonShotDown = false +// daemonJVMOptions.jvmParams.add("agentlib:jdwp=transport=dt_socket\\,server=y\\,suspend=y\\,address=5005") try { - val res1 = compileOnDaemon(arguments) + val res1 = compileOnDaemon(daemonJVMOptions, arguments) TestCase.assertEquals("first compilation failed:\n${res1.out}", 0, res1.resultCode) - val res2 = compileOnDaemon(arguments) + val res2 = compileOnDaemon(daemonJVMOptions, arguments) TestCase.assertEquals("second compilation failed:\n${res2.out}", 0, res2.resultCode) TestCase.assertEquals("build results differ", CliBaseTest.removePerfOutput(res1.out), CliBaseTest.removePerfOutput(res2.out)) + KotlinCompilerClient.shutdownCompileService(compilerId, daemonOptions) + daemonShotDown = true + logFile.reader().useLines { + it.ifNotContainsSequence( LinePattern("Kotlin compiler daemon version"), + LinePattern("Starting compilation with args: "), + LinePattern("Starting compilation with args: "), + LinePattern("Shutdown complete")) + { (unmatchedPattern, lineNo) -> + TestCase.fail("pattern not found in the input: " + unmatchedPattern.regex + + "\nunmatched part of the log file (" + logFile.absolutePath + + ") from line " + lineNo + ":\n\n" + logFile.reader().useLines { it.drop(lineNo).joinToString("\n") }) + } + } + logFile.delete() // TODO: add performance comparison assert } finally { - KotlinCompilerClient.shutdownCompileService(daemonOptions) + if (!daemonShotDown) + KotlinCompilerClient.shutdownCompileService(compilerId, daemonOptions) + System.clearProperty(COMPILE_DAEMON_LOG_PATH_PROPERTY) + System.clearProperty(COMPILE_DAEMON_VERBOSE_REPORT_PROPERTY) } } @@ -91,12 +109,12 @@ public class CompilerDaemonTest : KotlinIntegrationTestBase() { TestCase.assertEquals(arrayListOf("aaa", "bbb,ccc", "ddd", "xxx,yyy"), opts.jvmParams) } finally { - backupJvmOptions?.let { System.setProperty(COMPILE_DAEMON_JVM_OPTIONS_PROPERTY, it) } + restoreSystemProperty(COMPILE_DAEMON_JVM_OPTIONS_PROPERTY, backupJvmOptions) } } public fun testDaemonOptionsParsing() { - val backupJvmOptions = System.getProperty(COMPILE_DAEMON_OPTIONS_PROPERTY) + val backupOptions = System.getProperty(COMPILE_DAEMON_OPTIONS_PROPERTY) try { System.setProperty(COMPILE_DAEMON_OPTIONS_PROPERTY, "runFilesPath=abcd,clientAliveFlagPath=efgh,autoshutdownIdleSeconds=1111") val opts = configureDaemonOptions() @@ -105,7 +123,16 @@ public class CompilerDaemonTest : KotlinIntegrationTestBase() { TestCase.assertEquals(1111, opts.autoshutdownIdleSeconds) } finally { - backupJvmOptions?.let { System.setProperty(COMPILE_DAEMON_OPTIONS_PROPERTY, it) } + restoreSystemProperty(COMPILE_DAEMON_OPTIONS_PROPERTY, backupOptions) } } } + +fun restoreSystemProperty(propertyName: String, backupValue: String?) { + if (backupValue == null) { + System.clearProperty(propertyName) + } + else { + System.setProperty(propertyName, backupValue) + } +} diff --git a/compiler/tests/org/jetbrains/kotlin/daemon/LogCheckUtil.kt b/compiler/tests/org/jetbrains/kotlin/daemon/LogCheckUtil.kt new file mode 100644 index 00000000000..6b04f1f4c40 --- /dev/null +++ b/compiler/tests/org/jetbrains/kotlin/daemon/LogCheckUtil.kt @@ -0,0 +1,91 @@ +/* + * Copyright 2010-2015 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 kotlin.text.MatchResult +import kotlin.text.Regex + +/** + * holder of a [regex] and optional [matchCheck] for additional checks on match result + */ +internal class LinePattern(val regex: Regex, val matchCheck: (MatchResult) -> Boolean = { true }) +internal fun LinePattern(regex: String, matchCheck: (MatchResult) -> Boolean = { true }) = LinePattern(regex.toRegex(), matchCheck) + +/** + * calls [body] if receiver does not contain complete sequence of lines matched by [patternsIter], separated by any number of other lines + * [body] receives first unmatched pattern and index of last matched line in the sequence + */ +internal fun Sequence.ifNotContainsSequence(patternsIter: Iterator, + body: (LinePattern, Int) -> Unit) : Unit { + class Accumulator(it: Iterator) { + val iter = EndBoundIteratorWithValue(it) + var lineNo = 1 + var lastMatchedLineNo = 0 + fun nextLineAndPattern(): Accumulator { iter.traverseNext(); lastMatchedLineNo = lineNo; return nextLine() } + fun nextLine(): Accumulator { lineNo++; return this } + } + val res = fold(Accumulator(patternsIter)) + { acc, line -> + when { + !acc.iter.isValid() -> return@fold acc + acc.iter.value.regex.match(line)?.let { acc.iter.value.matchCheck(it) } ?: false -> acc.nextLineAndPattern() + else -> acc.nextLine() + } + } + if (res.iter.isValid()) { + body(res.iter.value, res.lastMatchedLineNo) + } +} + + +/** + * calls [body] if receiver does not contain complete sequence of lines matched by [patterns], separated by any number of other lines + * [body] receives first unmatched pattern and index of last matched line in the sequence + */ +internal fun Sequence.ifNotContainsSequence(patterns: List, + body: (LinePattern, Int) -> Unit): Unit { + ifNotContainsSequence(patterns.iterator(), body) +} + + +/** + * calls [body] if receiver does not contain complete sequence of lines matched by [patterns], separated by any number of other lines + * [body] receives first unmatched pattern and index of last matched line in the sequence + */ +internal fun Sequence.ifNotContainsSequence(vararg patterns: LinePattern, + body: (LinePattern, Int) -> Unit): Unit { + ifNotContainsSequence(patterns.iterator(), body) +} + + +// emulates Stepanov's / STL iterator, but with "embedded" end check via isValid: +// iterator points to a current value and upon init points to the first element or is invalid +// allows to express some algorithms more concisely +private class EndBoundIteratorWithValue>(val base: Iter) { + private var _value: T? = base.nextOrNull() + + val value: T get() = _value ?: throw Exception("Dereferencing invalid iterator") + + fun isValid(): Boolean = _value != null + + fun traverseNext(): EndBoundIteratorWithValue { + _value = base.nextOrNull() + return this + } +} + +private fun Iterator.nextOrNull(): T? = if (hasNext()) next() else null diff --git a/jps-plugin/test/org/jetbrains/kotlin/jps/build/SimpleKotlinJpsBuildTest.kt b/jps-plugin/test/org/jetbrains/kotlin/jps/build/SimpleKotlinJpsBuildTest.kt index 3b1a7f395b5..f32820d9b48 100644 --- a/jps-plugin/test/org/jetbrains/kotlin/jps/build/SimpleKotlinJpsBuildTest.kt +++ b/jps-plugin/test/org/jetbrains/kotlin/jps/build/SimpleKotlinJpsBuildTest.kt @@ -20,6 +20,7 @@ import com.intellij.util.PathUtil import org.jetbrains.jps.model.java.JpsJavaExtensionService import org.jetbrains.kotlin.rmi.COMPILE_DAEMON_CLIENT_ALIVE_PATH_PROPERTY import org.jetbrains.kotlin.rmi.COMPILE_DAEMON_ENABLED_PROPERTY +import org.jetbrains.kotlin.rmi.COMPILE_DAEMON_LOG_PATH_PROPERTY import org.jetbrains.kotlin.rmi.COMPILE_DAEMON_VERBOSE_REPORT_PROPERTY import org.jetbrains.kotlin.test.JetTestUtils import java.io.File @@ -71,12 +72,15 @@ public class SimpleKotlinJpsBuildTest : AbstractKotlinJpsBuildTestCase() { System.setProperty(COMPILE_DAEMON_VERBOSE_REPORT_PROPERTY, "") // spaces in the name to test proper file name handling val flagFile = File.createTempFile("kotlin-jps - tests-", "-is-running"); + val logFile = File.createTempFile("kotlin-daemon", ".log") + System.setProperty(COMPILE_DAEMON_CLIENT_ALIVE_PATH_PROPERTY, flagFile.absolutePath) + System.setProperty(COMPILE_DAEMON_LOG_PATH_PROPERTY, logFile.absolutePath) try { - System.setProperty(COMPILE_DAEMON_CLIENT_ALIVE_PATH_PROPERTY, flagFile.absolutePath) testLoadingKotlinFromDifferentModules() } finally { flagFile.delete() + System.clearProperty(COMPILE_DAEMON_LOG_PATH_PROPERTY) System.clearProperty(COMPILE_DAEMON_CLIENT_ALIVE_PATH_PROPERTY) System.clearProperty(COMPILE_DAEMON_VERBOSE_REPORT_PROPERTY) System.clearProperty(COMPILE_DAEMON_ENABLED_PROPERTY) From 886dc4b438f798f517e8663c114787a6923b0ded Mon Sep 17 00:00:00 2001 From: Ilya Chernikov Date: Wed, 23 Sep 2015 13:20:15 +0200 Subject: [PATCH 2/6] Refactoring daemon tests for more reusable code, adding instances test, minor fixes and improvements --- .../org/jetbrains/kotlin/rmi/DaemonParams.kt | 9 +- .../kotlin/rmi/service/CompileDaemon.kt | 2 +- .../kotlin/daemon/CompilerDaemonTest.kt | 135 +++++++++++++----- 3 files changed, 104 insertions(+), 42 deletions(-) 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 b081521d78c..73c573edab1 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 @@ -285,7 +285,7 @@ public data class CompilerId( public fun isDaemonEnabled(): Boolean = System.getProperty(COMPILE_DAEMON_ENABLED_PROPERTY) != null -public fun configureDaemonJVMOptions(opts: DaemonJVMOptions, inheritMemoryLimits: Boolean): DaemonJVMOptions { +public fun configureDaemonJVMOptions(opts: DaemonJVMOptions, inheritMemoryLimits: Boolean, vararg additionalParams: String): DaemonJVMOptions { // note: sequence matters, explicit override in COMPILE_DAEMON_JVM_OPTIONS_PROPERTY should be done after inputArguments processing if (inheritMemoryLimits) { ManagementFactory.getRuntimeMXBean().inputArguments.filterExtractProps(opts.mappers, "-") @@ -300,13 +300,14 @@ public fun configureDaemonJVMOptions(opts: DaemonJVMOptions, inheritMemoryLimits System.getProperty(COMPILE_DAEMON_REPORT_PERF_PROPERTY)?.let { opts.jvmParams.add("D" + COMPILE_DAEMON_REPORT_PERF_PROPERTY) } System.getProperty(COMPILE_DAEMON_VERBOSE_REPORT_PROPERTY)?.let { opts.jvmParams.add("D" + COMPILE_DAEMON_VERBOSE_REPORT_PROPERTY) } - System.getProperty(COMPILE_DAEMON_LOG_PATH_PROPERTY)?.let { opts.jvmParams.add("D$COMPILE_DAEMON_LOG_PATH_PROPERTY=$it" ) } + System.getProperty(COMPILE_DAEMON_LOG_PATH_PROPERTY)?.let { opts.jvmParams.add("D$COMPILE_DAEMON_LOG_PATH_PROPERTY=\"$it\"" ) } + opts.jvmParams.addAll(additionalParams) return opts } -public fun configureDaemonJVMOptions(inheritMemoryLimits: Boolean): DaemonJVMOptions = - configureDaemonJVMOptions(DaemonJVMOptions(), inheritMemoryLimits = inheritMemoryLimits) +public fun configureDaemonJVMOptions(inheritMemoryLimits: Boolean, vararg additionalParams: String): DaemonJVMOptions = + configureDaemonJVMOptions(DaemonJVMOptions(), inheritMemoryLimits = inheritMemoryLimits, additionalParams = *additionalParams) public fun configureDaemonOptions(opts: DaemonOptions): DaemonOptions { 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 201d5498f00..c27218e41f6 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 @@ -61,7 +61,7 @@ public object CompileDaemon { init { val logTime: String = SimpleDateFormat("yyyy-MM-dd.HH-mm-ss-SSS").format(Date()) val (logPath: String, fileIsGiven: Boolean) = - System.getProperty(COMPILE_DAEMON_LOG_PATH_PROPERTY)?.let { Pair(it, File(it).isFile) } ?: Pair("%t", false) + System.getProperty(COMPILE_DAEMON_LOG_PATH_PROPERTY)?.trimQuotes()?.let { Pair(it, File(it).isFile) } ?: Pair("%t", false) val cfg: String = "handlers = java.util.logging.FileHandler\n" + "java.util.logging.FileHandler.level = ALL\n" + diff --git a/compiler/tests/org/jetbrains/kotlin/daemon/CompilerDaemonTest.kt b/compiler/tests/org/jetbrains/kotlin/daemon/CompilerDaemonTest.kt index 96b306070e0..17df44c2cbd 100644 --- a/compiler/tests/org/jetbrains/kotlin/daemon/CompilerDaemonTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/daemon/CompilerDaemonTest.kt @@ -30,15 +30,11 @@ public class CompilerDaemonTest : KotlinIntegrationTestBase() { data class CompilerResults(val resultCode: Int, val out: String) - val daemonOptions by lazy(LazyThreadSafetyMode.NONE) { DaemonOptions(runFilesPath = tmpdir.absolutePath) } - val compilerId by lazy(LazyThreadSafetyMode.NONE) { - 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")) - } + val compilerClassPath = listOf( + File(KotlinIntegrationTestBase.getCompilerLib(), "kotlin-compiler.jar")) + val compilerId by lazy(LazyThreadSafetyMode.NONE) { CompilerId.makeCompilerId(compilerClassPath) } - private fun compileOnDaemon(daemonJVMOptions: DaemonJVMOptions, args: Array): CompilerResults { + private fun compileOnDaemon(compilerId: CompilerId, daemonJVMOptions: DaemonJVMOptions, daemonOptions: DaemonOptions, vararg args: String): CompilerResults { val daemon = KotlinCompilerClient.connectToCompileService(compilerId, daemonJVMOptions, daemonOptions, DaemonReportingTargets(out = System.err), autostart = true, checkId = true) TestCase.assertNotNull("failed to connect daemon", daemon) val strm = ByteArrayOutputStream() @@ -46,58 +42,68 @@ public class CompilerDaemonTest : KotlinIntegrationTestBase() { return CompilerResults(code, strm.toString()) } - private fun runDaemonCompilerTwice(logName: String, vararg arguments: String): Unit { - KotlinCompilerClient.shutdownCompileService(compilerId, daemonOptions) - - System.setProperty(COMPILE_DAEMON_VERBOSE_REPORT_PROPERTY, "") - val logFile = File.createTempFile("kotlin-daemon-test.", ".log") - System.setProperty(COMPILE_DAEMON_LOG_PATH_PROPERTY, logFile.absolutePath) - - val daemonJVMOptions = configureDaemonJVMOptions(false) - var daemonShotDown = false -// daemonJVMOptions.jvmParams.add("agentlib:jdwp=transport=dt_socket\\,server=y\\,suspend=y\\,address=5005") - - try { - val res1 = compileOnDaemon(daemonJVMOptions, arguments) + private fun runDaemonCompilerTwice(compilerId: CompilerId, daemonJVMOptions: DaemonJVMOptions, daemonOptions: DaemonOptions, vararg args: String): Unit { + val res1 = compileOnDaemon(compilerId, daemonJVMOptions, daemonOptions, *args) TestCase.assertEquals("first compilation failed:\n${res1.out}", 0, res1.resultCode) - val res2 = compileOnDaemon(daemonJVMOptions, arguments) + val res2 = compileOnDaemon(compilerId, daemonJVMOptions, daemonOptions, *args) TestCase.assertEquals("second compilation failed:\n${res2.out}", 0, res2.resultCode) TestCase.assertEquals("build results differ", CliBaseTest.removePerfOutput(res1.out), CliBaseTest.removePerfOutput(res2.out)) + } + + private fun getTestBaseDir(): String = JetTestUtils.getTestDataPathBase() + "/integration/smoke/" + getTestName(true) + private fun getHelloAppBaseDir(): String = JetTestUtils.getTestDataPathBase() + "/integration/smoke/helloApp" + + private fun run(logName: String, vararg args: String): Int = runJava(getTestBaseDir(), logName, *args) + + + public fun testHelloApp() { + val flagFile = createTempFile(getTestName(true), ".alive") + flagFile.deleteOnExit() + val daemonOptions = DaemonOptions(runFilesPath = File(tmpdir, getTestName(true)).absolutePath, + clientAliveFlagPath = flagFile.absolutePath) + + KotlinCompilerClient.shutdownCompileService(compilerId, daemonOptions) + + val logFile = createTempFile("kotlin-daemon-test.", ".log") + + val daemonJVMOptions = configureDaemonJVMOptions(false, + "D$COMPILE_DAEMON_VERBOSE_REPORT_PROPERTY", + "D$COMPILE_DAEMON_LOG_PATH_PROPERTY=\"${logFile.absolutePath}\"") + var daemonShotDown = false + + try { + val jar = tmpdir.absolutePath + File.separator + "hello.jar" + runDaemonCompilerTwice(compilerId, daemonJVMOptions, daemonOptions, + "-include-runtime", File(getTestBaseDir(), "hello.kt").absolutePath, "-d", jar) + KotlinCompilerClient.shutdownCompileService(compilerId, daemonOptions) daemonShotDown = true + var compileTime1 = 0L + var compileTime2 = 0L logFile.reader().useLines { it.ifNotContainsSequence( LinePattern("Kotlin compiler daemon version"), LinePattern("Starting compilation with args: "), + LinePattern("Elapsed time: (\\d+) ms", { it.groups.get(1)?.value?.toLong()?.let { compileTime1 = it }; true } ), LinePattern("Starting compilation with args: "), + LinePattern("Elapsed time: (\\d+) ms", { it.groups.get(1)?.value?.toLong()?.let { compileTime2 = it }; true } ), LinePattern("Shutdown complete")) - { (unmatchedPattern, lineNo) -> + { unmatchedPattern, lineNo -> TestCase.fail("pattern not found in the input: " + unmatchedPattern.regex + "\nunmatched part of the log file (" + logFile.absolutePath + ") from line " + lineNo + ":\n\n" + logFile.reader().useLines { it.drop(lineNo).joinToString("\n") }) } } + TestCase.assertTrue("Expecting that compilation 1 ($compileTime1 ms) is at least two times longer than compilation 2 ($compileTime2 ms)", + compileTime1 > compileTime2 * 2) logFile.delete() - // TODO: add performance comparison assert + run("hello.run", "-cp", jar, "Hello.HelloPackage") } finally { if (!daemonShotDown) KotlinCompilerClient.shutdownCompileService(compilerId, daemonOptions) - System.clearProperty(COMPILE_DAEMON_LOG_PATH_PROPERTY) - System.clearProperty(COMPILE_DAEMON_VERBOSE_REPORT_PROPERTY) } } - private fun getTestBaseDir(): String = JetTestUtils.getTestDataPathBase() + "/integration/smoke/" + getTestName(true) - - private fun run(logName: String, vararg args: String): Int = runJava(getTestBaseDir(), logName, *args) - - public fun testHelloApp() { - val jar = tmpdir.absolutePath + File.separator + "hello.jar" - - runDaemonCompilerTwice("hello.compile", "-include-runtime", File(getTestBaseDir(), "hello.kt").absolutePath, "-d", jar) - run("hello.run", "-cp", jar, "Hello.HelloPackage") - } - public fun testDaemonJvmOptionsParsing() { val backupJvmOptions = System.getProperty(COMPILE_DAEMON_JVM_OPTIONS_PROPERTY) try { @@ -126,6 +132,61 @@ public class CompilerDaemonTest : KotlinIntegrationTestBase() { restoreSystemProperty(COMPILE_DAEMON_OPTIONS_PROPERTY, backupOptions) } } + + public fun testDaemonInstances() { + val jar = tmpdir.absolutePath + File.separator + "hello1.jar" + val flagFile = createTempFile(getTestName(true), ".alive") + flagFile.deleteOnExit() + val daemonOptions = DaemonOptions(runFilesPath = File(tmpdir, getTestName(true)).absolutePath, + clientAliveFlagPath = flagFile.absolutePath) + val compilerId2 = CompilerId.makeCompilerId(compilerClassPath + + File(KotlinIntegrationTestBase.getCompilerLib(), "kotlin-compiler-sources.jar")) + + KotlinCompilerClient.shutdownCompileService(compilerId, daemonOptions) + KotlinCompilerClient.shutdownCompileService(compilerId2, daemonOptions) + + val logFile1 = createTempFile("kotlin-daemon1-test", ".log") + val logFile2 = createTempFile("kotlin-daemon2-test", ".log") + val daemonJVMOptions1 = + configureDaemonJVMOptions(false, + "D$COMPILE_DAEMON_LOG_PATH_PROPERTY=\"${logFile1.absolutePath}\"") + val daemonJVMOptions2 = + configureDaemonJVMOptions(false, + "D$COMPILE_DAEMON_LOG_PATH_PROPERTY=\"${logFile2.absolutePath}\"") + + TestCase.assertTrue(logFile1.length() == 0L && logFile2.length() == 0L) + + val res1 = compileOnDaemon(compilerId, daemonJVMOptions1, daemonOptions, + "-include-runtime", File(getHelloAppBaseDir(), "hello.kt").absolutePath, "-d", jar) + TestCase.assertEquals("first compilation failed:\n${res1.out}", 0, res1.resultCode) + + logFile1.assertLogContainsSequence("Starting compilation with args: ") + TestCase.assertEquals("expecting '${logFile2.absolutePath}' to be empty", 0L, logFile2.length()) + + val res2 = compileOnDaemon(compilerId2, daemonJVMOptions2, daemonOptions, + "-include-runtime", File(getHelloAppBaseDir(), "hello.kt").absolutePath, "-d", jar) + TestCase.assertEquals("second compilation failed:\n${res2.out}", 0, res1.resultCode) + + logFile2.assertLogContainsSequence("Starting compilation with args: ") + + KotlinCompilerClient.shutdownCompileService(compilerId, daemonOptions) + logFile1.assertLogContainsSequence("Shutdown complete") + logFile1.delete() + + KotlinCompilerClient.shutdownCompileService(compilerId2, daemonOptions) + logFile2.assertLogContainsSequence("Shutdown complete") + logFile2.delete() + } +} + + +fun File.assertLogContainsSequence(vararg patterns: String) { + reader().useLines { + it.ifNotContainsSequence( patterns.map { LinePattern(it) }) + { + pattern,lineNo -> TestCase.fail("Pattern '${pattern.regex}' is not found in the log file '$absolutePath'") + } + } } fun restoreSystemProperty(propertyName: String, backupValue: String?) { From fffe6dd83723eb405851a9b7af218006e5c37a91 Mon Sep 17 00:00:00 2001 From: Ilya Chernikov Date: Wed, 23 Sep 2015 14:52:41 +0200 Subject: [PATCH 3/6] Converting KotlinCompilerRunner.java to kotlin - phase 1 - renaming to .kt to preserve history --- .../{KotlinCompilerRunner.java => KotlinCompilerRunner.kt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename jps-plugin/src/org/jetbrains/kotlin/compilerRunner/{KotlinCompilerRunner.java => KotlinCompilerRunner.kt} (100%) diff --git a/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.java b/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt similarity index 100% rename from jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.java rename to jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt From 0047fb1272c1147c16e53fd4ae3bedab73ede5fc Mon Sep 17 00:00:00 2001 From: Ilya Chernikov Date: Wed, 23 Sep 2015 14:56:41 +0200 Subject: [PATCH 4/6] Converting KotlinCompilerRunner.java to kotlin - phase 2 - converter + manual fixes --- .../compilerRunner/KotlinCompilerRunner.kt | 338 +++++++++--------- .../kotlin/jps/build/KotlinBuilder.kt | 7 +- 2 files changed, 165 insertions(+), 180 deletions(-) diff --git a/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt b/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt index 3710979bd86..65dd3ccc23f 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt @@ -14,261 +14,247 @@ * limitations under the License. */ -package org.jetbrains.kotlin.compilerRunner; +package org.jetbrains.kotlin.compilerRunner -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.util.ArrayUtil; -import com.intellij.util.Function; -import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.xmlb.XmlSerializerUtil; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.kotlin.cli.common.ExitCode; -import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments; -import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments; -import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments; -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation; -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity; -import org.jetbrains.kotlin.cli.common.messages.MessageCollector; -import org.jetbrains.kotlin.cli.common.messages.MessageCollectorUtil; -import org.jetbrains.kotlin.config.CompilerSettings; -import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache; -import org.jetbrains.kotlin.modules.TargetId; -import org.jetbrains.kotlin.rmi.*; -import org.jetbrains.kotlin.rmi.kotlinr.DaemonReportCategory; -import org.jetbrains.kotlin.rmi.kotlinr.DaemonReportMessage; -import org.jetbrains.kotlin.rmi.kotlinr.DaemonReportingTargets; -import org.jetbrains.kotlin.rmi.kotlinr.KotlinCompilerClient; -import org.jetbrains.kotlin.utils.UtilsPackage; +import com.intellij.openapi.util.text.StringUtil +import com.intellij.util.ArrayUtil +import com.intellij.util.Function +import com.intellij.util.containers.ContainerUtil +import com.intellij.util.xmlb.XmlSerializerUtil +import org.jetbrains.kotlin.cli.common.ExitCode +import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments +import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments +import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity +import org.jetbrains.kotlin.cli.common.messages.MessageCollector +import org.jetbrains.kotlin.cli.common.messages.MessageCollectorUtil +import org.jetbrains.kotlin.config.CompilerSettings +import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache +import org.jetbrains.kotlin.modules.TargetId +import org.jetbrains.kotlin.rmi.* +import org.jetbrains.kotlin.rmi.kotlinr.DaemonReportCategory +import org.jetbrains.kotlin.rmi.kotlinr.DaemonReportMessage +import org.jetbrains.kotlin.rmi.kotlinr.DaemonReportingTargets +import org.jetbrains.kotlin.rmi.kotlinr.KotlinCompilerClient +import org.jetbrains.kotlin.utils.* -import java.io.*; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; +import java.io.* +import java.lang.reflect.Field +import java.lang.reflect.Modifier +import java.util.ArrayList -import static org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation.NO_LOCATION; -import static org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR; -import static org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.INFO; +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.INFO -public class KotlinCompilerRunner { - private static final String K2JVM_COMPILER = "org.jetbrains.kotlin.cli.jvm.K2JVMCompiler"; - private static final String K2JS_COMPILER = "org.jetbrains.kotlin.cli.js.K2JSCompiler"; - private static final String INTERNAL_ERROR = ExitCode.INTERNAL_ERROR.toString(); +public object KotlinCompilerRunner { + private val K2JVM_COMPILER = "org.jetbrains.kotlin.cli.jvm.K2JVMCompiler" + private val K2JS_COMPILER = "org.jetbrains.kotlin.cli.js.K2JSCompiler" + private val INTERNAL_ERROR = ExitCode.INTERNAL_ERROR.toString() - public static void runK2JvmCompiler( - CommonCompilerArguments commonArguments, - K2JVMCompilerArguments k2jvmArguments, - CompilerSettings compilerSettings, - MessageCollector messageCollector, - CompilerEnvironment environment, - Map incrementalCaches, - File moduleFile, - OutputItemsCollector collector - ) { - K2JVMCompilerArguments arguments = mergeBeans(commonArguments, k2jvmArguments); - setupK2JvmArguments(moduleFile, arguments); + public fun runK2JvmCompiler( + commonArguments: CommonCompilerArguments, + k2jvmArguments: K2JVMCompilerArguments, + compilerSettings: CompilerSettings, + messageCollector: MessageCollector, + environment: CompilerEnvironment, + incrementalCaches: Map?, + moduleFile: File, + collector: OutputItemsCollector) { + val arguments = mergeBeans(commonArguments, k2jvmArguments) + setupK2JvmArguments(moduleFile, arguments) - runCompiler(K2JVM_COMPILER, arguments, compilerSettings.getAdditionalArguments(), messageCollector, collector, environment, - incrementalCaches); + runCompiler(K2JVM_COMPILER, arguments, compilerSettings.additionalArguments, messageCollector, collector, environment, + incrementalCaches) } - public static void runK2JsCompiler( - @NotNull CommonCompilerArguments commonArguments, - @NotNull K2JSCompilerArguments k2jsArguments, - @NotNull CompilerSettings compilerSettings, - @NotNull MessageCollector messageCollector, - @NotNull CompilerEnvironment environment, - Map incrementalCaches, - @NotNull OutputItemsCollector collector, - @NotNull Collection sourceFiles, - @NotNull List libraryFiles, - @NotNull File outputFile - ) { - K2JSCompilerArguments arguments = mergeBeans(commonArguments, k2jsArguments); - setupK2JsArguments(outputFile, sourceFiles, libraryFiles, arguments); + public fun runK2JsCompiler( + commonArguments: CommonCompilerArguments, + k2jsArguments: K2JSCompilerArguments, + compilerSettings: CompilerSettings, + messageCollector: MessageCollector, + environment: CompilerEnvironment, + incrementalCaches: Map?, + collector: OutputItemsCollector, + sourceFiles: Collection, + libraryFiles: List, + outputFile: File) { + val arguments = mergeBeans(commonArguments, k2jsArguments) + setupK2JsArguments(outputFile, sourceFiles, libraryFiles, arguments) - runCompiler(K2JS_COMPILER, arguments, compilerSettings.getAdditionalArguments(), messageCollector, collector, environment, - incrementalCaches); + runCompiler(K2JS_COMPILER, arguments, compilerSettings.additionalArguments, messageCollector, collector, environment, + incrementalCaches) } - private static void ProcessCompilerOutput( - MessageCollector messageCollector, - OutputItemsCollector collector, - ByteArrayOutputStream stream, - String exitCode - ) { - BufferedReader reader = new BufferedReader(new StringReader(stream.toString())); - CompilerOutputParser.parseCompilerMessagesFromReader(messageCollector, reader, collector); + private fun ProcessCompilerOutput( + messageCollector: MessageCollector, + collector: OutputItemsCollector, + stream: ByteArrayOutputStream, + exitCode: String) { + val reader = BufferedReader(StringReader(stream.toString())) + CompilerOutputParser.parseCompilerMessagesFromReader(messageCollector, reader, collector) - if (INTERNAL_ERROR.equals(exitCode)) { - reportInternalCompilerError(messageCollector); + if (INTERNAL_ERROR == exitCode) { + reportInternalCompilerError(messageCollector) } } - private static void reportInternalCompilerError(MessageCollector messageCollector) { - messageCollector.report(ERROR, "Compiler terminated with internal error", NO_LOCATION); + private fun reportInternalCompilerError(messageCollector: MessageCollector) { + messageCollector.report(ERROR, "Compiler terminated with internal error", CompilerMessageLocation.NO_LOCATION) } - private static void runCompiler( - String compilerClassName, - CommonCompilerArguments arguments, - String additionalArguments, - MessageCollector messageCollector, - OutputItemsCollector collector, - CompilerEnvironment environment, - Map incrementalCaches - ) { + private fun runCompiler( + compilerClassName: String, + arguments: CommonCompilerArguments, + additionalArguments: String, + messageCollector: MessageCollector, + collector: OutputItemsCollector, + environment: CompilerEnvironment, + incrementalCaches: Map?) { try { - messageCollector.report(INFO, "Using kotlin-home = " + environment.getKotlinPaths().getHomePath(), NO_LOCATION); + messageCollector.report(INFO, "Using kotlin-home = " + environment.kotlinPaths.homePath, CompilerMessageLocation.NO_LOCATION) - List argumentsList = ArgumentUtils.convertArgumentsToStringList(arguments); - argumentsList.addAll(StringUtil.split(additionalArguments, " ")); + val argumentsList = ArgumentUtils.convertArgumentsToStringList(arguments) + argumentsList.addAll(StringUtil.split(additionalArguments, " ")) - String[] argsArray = ArrayUtil.toStringArray(argumentsList); + val argsArray = ArrayUtil.toStringArray(argumentsList) if (!tryCompileWithDaemon(messageCollector, collector, environment, incrementalCaches, argsArray)) { // otherwise fallback to in-process - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - PrintStream out = new PrintStream(stream); + val stream = ByteArrayOutputStream() + val out = PrintStream(stream) - Object rc = CompilerRunnerUtil.invokeExecMethod( compilerClassName, argsArray, environment, messageCollector, out); + val rc = CompilerRunnerUtil.invokeExecMethod(compilerClassName, argsArray, environment, messageCollector, out) // exec() returns an ExitCode object, class of which is loaded with a different class loader, // so we take it's contents through reflection - ProcessCompilerOutput(messageCollector, collector, stream, getReturnCodeFromObject(rc)); + ProcessCompilerOutput(messageCollector, collector, stream, getReturnCodeFromObject(rc)) } } - catch (Throwable e) { - MessageCollectorUtil.reportException(messageCollector, e); - reportInternalCompilerError(messageCollector); + catch (e: Throwable) { + MessageCollectorUtil.reportException(messageCollector, e) + reportInternalCompilerError(messageCollector) } + } - private static boolean tryCompileWithDaemon( - MessageCollector messageCollector, - OutputItemsCollector collector, - CompilerEnvironment environment, - Map incrementalCaches, - String[] argsArray - ) throws IOException { - if (incrementalCaches != null && RmiPackage.isDaemonEnabled()) { - File libPath = CompilerRunnerUtil.getLibPath(environment.getKotlinPaths(), messageCollector); + private fun tryCompileWithDaemon( + messageCollector: MessageCollector, + collector: OutputItemsCollector, + environment: CompilerEnvironment, + incrementalCaches: Map?, + argsArray: Array): Boolean { + if (incrementalCaches != null && isDaemonEnabled()) { + val libPath = CompilerRunnerUtil.getLibPath(environment.kotlinPaths, messageCollector) // TODO: it may be a good idea to cache the compilerId, since making it means calculating digest over jar(s) and if \\ // 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(); - DaemonJVMOptions daemonJVMOptions = RmiPackage.configureDaemonJVMOptions(true); + val compilerId = CompilerId.makeCompilerId(File(libPath, "kotlin-compiler.jar")) + val daemonOptions = configureDaemonOptions() + val daemonJVMOptions = configureDaemonJVMOptions(true) - ArrayList daemonReportMessages = new ArrayList(); + val daemonReportMessages = ArrayList() - CompileService daemon = KotlinCompilerClient.connectToCompileService(compilerId, daemonJVMOptions, daemonOptions, new DaemonReportingTargets(null, daemonReportMessages), true, true); + val daemon = KotlinCompilerClient.connectToCompileService(compilerId, daemonJVMOptions, daemonOptions, DaemonReportingTargets(null, daemonReportMessages), true, true) - for (DaemonReportMessage msg: daemonReportMessages) { - if (msg.getCategory() == DaemonReportCategory.EXCEPTION && daemon == null) { + for (msg in daemonReportMessages) { + if (msg.category === DaemonReportCategory.EXCEPTION && daemon == null) { messageCollector.report(CompilerMessageSeverity.INFO, - "Falling back to compilation without daemon due to error: " + msg.getMessage(), - CompilerMessageLocation.NO_LOCATION); + "Falling back to compilation without daemon due to error: " + msg.message, + CompilerMessageLocation.NO_LOCATION) } else { - messageCollector.report(CompilerMessageSeverity.INFO, msg.getMessage(), CompilerMessageLocation.NO_LOCATION); + messageCollector.report(CompilerMessageSeverity.INFO, msg.message, CompilerMessageLocation.NO_LOCATION) } } if (daemon != null) { - ByteArrayOutputStream compilerOut = new ByteArrayOutputStream(); - ByteArrayOutputStream daemonOut = new ByteArrayOutputStream(); + val compilerOut = ByteArrayOutputStream() + val daemonOut = ByteArrayOutputStream() - Integer res = KotlinCompilerClient.incrementalCompile(daemon, argsArray, incrementalCaches, compilerOut, daemonOut); + val res = KotlinCompilerClient.incrementalCompile(daemon, argsArray, incrementalCaches, compilerOut, daemonOut) - ProcessCompilerOutput(messageCollector, collector, compilerOut, res.toString()); - BufferedReader reader = new BufferedReader(new StringReader(daemonOut.toString())); - String line = null; - while ((line = reader.readLine()) != null) { - messageCollector.report(CompilerMessageSeverity.INFO, line, CompilerMessageLocation.NO_LOCATION); + ProcessCompilerOutput(messageCollector, collector, compilerOut, res.toString()) + BufferedReader(StringReader(daemonOut.toString())).forEachLine { + messageCollector.report(CompilerMessageSeverity.INFO, it, CompilerMessageLocation.NO_LOCATION) } - return true; + return true } } - return false; + return false } - @NotNull - private static String getReturnCodeFromObject(@Nullable Object rc) throws Exception { + private fun getReturnCodeFromObject(rc: Any?): String { if (rc == null) { - return INTERNAL_ERROR; + return INTERNAL_ERROR } - else if (ExitCode.class.getName().equals(rc.getClass().getName())) { - return rc.toString(); + else if (ExitCode::class.java.name == rc.javaClass.name) { + return rc.toString() } else { - throw new IllegalStateException("Unexpected return: " + rc); + throw IllegalStateException("Unexpected return: " + rc) } } - private static T mergeBeans(CommonCompilerArguments from, T to) { + private fun mergeBeans(from: CommonCompilerArguments, to: T): T { // TODO: rewrite when updated version of com.intellij.util.xmlb is available on TeamCity try { - T copy = XmlSerializerUtil.createCopy(to); + val copy = XmlSerializerUtil.createCopy(to) - List fromFields = collectFieldsToCopy(from.getClass()); - for (Field fromField : fromFields) { - Field toField = copy.getClass().getField(fromField.getName()); - toField.set(copy, fromField.get(from)); + val fromFields = collectFieldsToCopy(from.javaClass) + for (fromField in fromFields) { + val toField = copy.javaClass.getField(fromField.name) + toField.set(copy, fromField.get(from)) } - return copy; + return copy } - catch (NoSuchFieldException e) { - throw UtilsPackage.rethrow(e); + catch (e: NoSuchFieldException) { + throw rethrow(e) } - catch (IllegalAccessException e) { - throw UtilsPackage.rethrow(e); + catch (e: IllegalAccessException) { + throw rethrow(e) } + } - private static List collectFieldsToCopy(Class clazz) { - List fromFields = new ArrayList(); + private fun collectFieldsToCopy(clazz: Class<*>): List { + val fromFields = ArrayList() - Class currentClass = clazz; - do { - for (Field field : currentClass.getDeclaredFields()) { - int modifiers = field.getModifiers(); + var currentClass: Class<*>? = clazz + while (currentClass != null) { + for (field in currentClass.declaredFields) { + val modifiers = field.modifiers if (!Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers)) { - fromFields.add(field); + fromFields.add(field) } } + currentClass = currentClass.superclass } - while ((currentClass = currentClass.getSuperclass()) != null); - return fromFields; + return fromFields } - private static void setupK2JvmArguments(File moduleFile, K2JVMCompilerArguments settings) { - settings.module = moduleFile.getAbsolutePath(); - settings.noStdlib = true; - settings.noJdkAnnotations = true; - settings.noJdk = true; + private fun setupK2JvmArguments(moduleFile: File, settings: K2JVMCompilerArguments) { + settings.module = moduleFile.absolutePath + settings.noStdlib = true + settings.noJdkAnnotations = true + settings.noJdk = true } - private static void setupK2JsArguments( - @NotNull File outputFile, - @NotNull Collection sourceFiles, - @NotNull List libraryFiles, - @NotNull K2JSCompilerArguments settings - ) { - settings.noStdlib = true; - settings.freeArgs = ContainerUtil.map(sourceFiles, new Function() { - @Override - public String fun(File file) { - return file.getPath(); + private fun setupK2JsArguments( + outputFile: File, + sourceFiles: Collection, + libraryFiles: List, + settings: K2JSCompilerArguments) { + settings.noStdlib = true + settings.freeArgs = ContainerUtil.map(sourceFiles, object : Function { + override fun `fun`(file: File): String { + return file.path } - }); - settings.outputFile = outputFile.getPath(); - settings.metaInfo = true; - settings.libraryFiles = ArrayUtil.toStringArray(libraryFiles); + }) + settings.outputFile = outputFile.path + settings.metaInfo = true + settings.libraryFiles = ArrayUtil.toStringArray(libraryFiles) } } diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt index 3c10754f873..81a96f10aa0 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt @@ -47,8 +47,7 @@ import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.* import org.jetbrains.kotlin.cli.common.messages.MessageCollector import org.jetbrains.kotlin.cli.common.messages.OutputMessageUtil import org.jetbrains.kotlin.compilerRunner.CompilerEnvironment -import org.jetbrains.kotlin.compilerRunner.KotlinCompilerRunner.runK2JsCompiler -import org.jetbrains.kotlin.compilerRunner.KotlinCompilerRunner.runK2JvmCompiler +import org.jetbrains.kotlin.compilerRunner.KotlinCompilerRunner import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl import org.jetbrains.kotlin.config.CompilerRunnerConstants import org.jetbrains.kotlin.config.CompilerRunnerConstants.INTERNAL_ERROR_PREFIX @@ -520,7 +519,7 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR val compilerSettings = JpsKotlinCompilerSettings.getCompilerSettings(project) val k2JsArguments = JpsKotlinCompilerSettings.getK2JsCompilerArguments(project) - runK2JsCompiler(commonArguments, k2JsArguments, compilerSettings, messageCollector, environment, incrementalCaches, outputItemCollector, sourceFiles, libraryFiles, outputFile) + KotlinCompilerRunner.runK2JsCompiler(commonArguments, k2JsArguments, compilerSettings, messageCollector, environment, incrementalCaches, outputItemCollector, sourceFiles, libraryFiles, outputFile) return outputItemCollector } @@ -587,7 +586,7 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR + (if (totalRemovedFiles == 0) "" else " ($totalRemovedFiles removed files)") + " in " + filesToCompile.keySet().map { it.getPresentableName() }.join()) - runK2JvmCompiler(commonArguments, k2JvmArguments, compilerSettings, messageCollector, environment, incrementalCaches, moduleFile, outputItemCollector) + KotlinCompilerRunner.runK2JvmCompiler(commonArguments, k2JvmArguments, compilerSettings, messageCollector, environment, incrementalCaches, moduleFile, outputItemCollector) moduleFile.delete() return outputItemCollector From 3c16b2de871de534f1ff71a4452792e157601743 Mon Sep 17 00:00:00 2001 From: Ilya Chernikov Date: Thu, 24 Sep 2015 10:42:54 +0200 Subject: [PATCH 5/6] Converting KotlinCompilerRunner.java to kotlin - phase 3 - refactoring to more kotlin style --- .../compilerRunner/KotlinCompilerRunner.kt | 76 ++++++++----------- 1 file changed, 30 insertions(+), 46 deletions(-) diff --git a/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt b/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt index 65dd3ccc23f..4ebfec35d54 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt @@ -86,7 +86,7 @@ public object KotlinCompilerRunner { incrementalCaches) } - private fun ProcessCompilerOutput( + private fun processCompilerOutput( messageCollector: MessageCollector, collector: OutputItemsCollector, stream: ByteArrayOutputStream, @@ -115,9 +115,9 @@ public object KotlinCompilerRunner { messageCollector.report(INFO, "Using kotlin-home = " + environment.kotlinPaths.homePath, CompilerMessageLocation.NO_LOCATION) val argumentsList = ArgumentUtils.convertArgumentsToStringList(arguments) - argumentsList.addAll(StringUtil.split(additionalArguments, " ")) + argumentsList.addAll(additionalArguments.split(" ")) - val argsArray = ArrayUtil.toStringArray(argumentsList) + val argsArray = argumentsList.toTypedArray() if (!tryCompileWithDaemon(messageCollector, collector, environment, incrementalCaches, argsArray)) { // otherwise fallback to in-process @@ -129,7 +129,7 @@ public object KotlinCompilerRunner { // exec() returns an ExitCode object, class of which is loaded with a different class loader, // so we take it's contents through reflection - ProcessCompilerOutput(messageCollector, collector, stream, getReturnCodeFromObject(rc)) + processCompilerOutput(messageCollector, collector, stream, getReturnCodeFromObject(rc)) } } catch (e: Throwable) { @@ -145,6 +145,7 @@ public object KotlinCompilerRunner { environment: CompilerEnvironment, incrementalCaches: Map?, argsArray: Array): Boolean { + if (incrementalCaches != null && isDaemonEnabled()) { val libPath = CompilerRunnerUtil.getLibPath(environment.kotlinPaths, messageCollector) // TODO: it may be a good idea to cache the compilerId, since making it means calculating digest over jar(s) and if \\ @@ -174,7 +175,7 @@ public object KotlinCompilerRunner { val res = KotlinCompilerClient.incrementalCompile(daemon, argsArray, incrementalCaches, compilerOut, daemonOut) - ProcessCompilerOutput(messageCollector, collector, compilerOut, res.toString()) + processCompilerOutput(messageCollector, collector, compilerOut, res.toString()) BufferedReader(StringReader(daemonOut.toString())).forEachLine { messageCollector.report(CompilerMessageSeverity.INFO, it, CompilerMessageLocation.NO_LOCATION) } @@ -185,37 +186,24 @@ public object KotlinCompilerRunner { } private fun getReturnCodeFromObject(rc: Any?): String { - if (rc == null) { - return INTERNAL_ERROR - } - else if (ExitCode::class.java.name == rc.javaClass.name) { - return rc.toString() - } - else { - throw IllegalStateException("Unexpected return: " + rc) + when { + rc == null -> return INTERNAL_ERROR + ExitCode::class.java.name == rc.javaClass.name -> return rc.toString() + else -> throw IllegalStateException("Unexpected return: " + rc) } } private fun mergeBeans(from: CommonCompilerArguments, to: T): T { // TODO: rewrite when updated version of com.intellij.util.xmlb is available on TeamCity - try { - val copy = XmlSerializerUtil.createCopy(to) + val copy = XmlSerializerUtil.createCopy(to) - val fromFields = collectFieldsToCopy(from.javaClass) - for (fromField in fromFields) { - val toField = copy.javaClass.getField(fromField.name) - toField.set(copy, fromField.get(from)) - } - - return copy - } - catch (e: NoSuchFieldException) { - throw rethrow(e) - } - catch (e: IllegalAccessException) { - throw rethrow(e) + val fromFields = collectFieldsToCopy(from.javaClass) + for (fromField in fromFields) { + val toField = copy.javaClass.getField(fromField.name) + toField.set(copy, fromField.get(from)) } + return copy } private fun collectFieldsToCopy(clazz: Class<*>): List { @@ -236,25 +224,21 @@ public object KotlinCompilerRunner { } private fun setupK2JvmArguments(moduleFile: File, settings: K2JVMCompilerArguments) { - settings.module = moduleFile.absolutePath - settings.noStdlib = true - settings.noJdkAnnotations = true - settings.noJdk = true + with(settings) { + module = moduleFile.absolutePath + noStdlib = true + noJdkAnnotations = true + noJdk = true + } } - private fun setupK2JsArguments( - outputFile: File, - sourceFiles: Collection, - libraryFiles: List, - settings: K2JSCompilerArguments) { - settings.noStdlib = true - settings.freeArgs = ContainerUtil.map(sourceFiles, object : Function { - override fun `fun`(file: File): String { - return file.path - } - }) - settings.outputFile = outputFile.path - settings.metaInfo = true - settings.libraryFiles = ArrayUtil.toStringArray(libraryFiles) + private fun setupK2JsArguments( _outputFile: File, sourceFiles: Collection, _libraryFiles: List, settings: K2JSCompilerArguments) { + with(settings) { + noStdlib = true + freeArgs = sourceFiles.map { it.path } + outputFile = _outputFile.path + metaInfo = true + libraryFiles = _libraryFiles.toTypedArray() + } } } From 4b1601974f4f2c185cf5dc17d7668471a1085868 Mon Sep 17 00:00:00 2001 From: Ilya Chernikov Date: Wed, 23 Sep 2015 15:07:48 +0200 Subject: [PATCH 6/6] Refactoring parts related to passing services to compiler in daemon, adding uniform support for cancellation check and lookup tracking --- .../rmi/kotlinr/KotlinCompilerClient.kt | 24 ++++++-- .../RemoteCompilationCanceledStatusServer.kt | 35 ++++++++++++ ...eIncrementalCompilationComponentsServer.kt | 44 +++++++++++++++ .../rmi/kotlinr/RemoteLookupTrackerServer.kt | 40 ++++++++++++++ .../jetbrains/kotlin/rmi/CompileService.kt | 37 ++++++++++++- .../kotlin/rmi/service/CompileServiceImpl.kt | 33 ++++------- .../RemoteCompilationCanceledStatusClient.kt | 27 +++++++++ ...eIncrementalCompilationComponentsClient.kt | 31 +++++++++++ .../rmi/service/RemoteLookupTrackerClient.kt | 32 +++++++++++ .../compilerRunner/KotlinCompilerRunner.kt | 55 +++++++++---------- .../kotlin/jps/build/KotlinBuilder.kt | 10 +--- 11 files changed, 301 insertions(+), 67 deletions(-) create mode 100644 compiler/rmi/kotlinr/src/org/jetbrains/kotlin/rmi/kotlinr/RemoteCompilationCanceledStatusServer.kt create mode 100644 compiler/rmi/kotlinr/src/org/jetbrains/kotlin/rmi/kotlinr/RemoteIncrementalCompilationComponentsServer.kt create mode 100644 compiler/rmi/kotlinr/src/org/jetbrains/kotlin/rmi/kotlinr/RemoteLookupTrackerServer.kt create mode 100644 compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/RemoteCompilationCanceledStatusClient.kt create mode 100644 compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/RemoteIncrementalCompilationComponentsClient.kt create mode 100644 compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/RemoteLookupTrackerClient.kt 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 2b115f861e9..c44482d72e9 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 @@ -16,8 +16,9 @@ package org.jetbrains.kotlin.rmi.kotlinr -import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache +import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents import org.jetbrains.kotlin.modules.TargetId +import org.jetbrains.kotlin.progress.CompilationCanceledStatus import org.jetbrains.kotlin.rmi.* import java.io.* import java.rmi.ConnectException @@ -27,6 +28,12 @@ import java.util.concurrent.TimeUnit import kotlin.concurrent.thread +public class CompilationServices( + val incrementalCompilationComponents: IncrementalCompilationComponents? = null, + val compilationCanceledStatus: CompilationCanceledStatus? = null +) + + public object KotlinCompilerClient { val DAEMON_DEFAULT_STARTUP_TIMEOUT_MS = 10000L @@ -108,7 +115,7 @@ public object KotlinCompilerClient { val outStrm = RemoteOutputStreamServer(out) try { - return compiler.remoteCompile(args, outStrm, CompileService.OutputFormat.PLAIN, outStrm) + return compiler.remoteCompile(args, makeRemoteServices(CompilationServices()), outStrm, CompileService.OutputFormat.PLAIN, outStrm) } finally { outStrm.disconnect() @@ -118,14 +125,13 @@ public object KotlinCompilerClient { // TODO: remove jvmStatic after all use sites will switch to kotlin @JvmStatic - public fun incrementalCompile(compiler: CompileService, args: Array, caches: Map, compilerOut: OutputStream, daemonOut: OutputStream): Int { + public fun incrementalCompile(compiler: CompileService, args: Array, services: CompilationServices, compilerOut: OutputStream, daemonOut: OutputStream): Int { val compilerOutStreamServer = RemoteOutputStreamServer(compilerOut) val daemonOutStreamServer = RemoteOutputStreamServer(daemonOut) val cacheServers = hashMapOf() try { - caches.mapValuesTo(cacheServers, { RemoteIncrementalCacheServer(it.getValue()) }) - return compiler.remoteIncrementalCompile(args, cacheServers, compilerOutStreamServer, CompileService.OutputFormat.XML, daemonOutStreamServer) + return compiler.remoteIncrementalCompile(args, makeRemoteServices(services), compilerOutStreamServer, CompileService.OutputFormat.XML, daemonOutStreamServer) } finally { cacheServers.forEach { it.getValue().disconnect() } @@ -135,6 +141,12 @@ public object KotlinCompilerClient { } + fun makeRemoteServices(services: CompilationServices): CompileService.RemoteCompilationServices = + CompileService.RemoteCompilationServices( + incrementalCompilationComponents = if (services.incrementalCompilationComponents == null) null else RemoteIncrementalCompilationComponentsServer(services.incrementalCompilationComponents), + compilationCanceledStatus = if (services.compilationCanceledStatus == null) null else RemoteCompilationCanceledStatusServer(services.compilationCanceledStatus) + ) + data class ClientOptions( public var stop: Boolean = false ) : OptionsGroup { @@ -196,7 +208,7 @@ public object KotlinCompilerClient { val memBefore = daemon.getUsedMemory() / 1024 val startTime = System.nanoTime() - val res = daemon.remoteCompile(filteredArgs.toArrayList().toTypedArray(), outStrm, CompileService.OutputFormat.PLAIN, outStrm) + val res = daemon.remoteCompile(filteredArgs.toArrayList().toTypedArray(), makeRemoteServices(CompilationServices()), outStrm, CompileService.OutputFormat.PLAIN, outStrm) val endTime = System.nanoTime() println("Compilation result code: $res") diff --git a/compiler/rmi/kotlinr/src/org/jetbrains/kotlin/rmi/kotlinr/RemoteCompilationCanceledStatusServer.kt b/compiler/rmi/kotlinr/src/org/jetbrains/kotlin/rmi/kotlinr/RemoteCompilationCanceledStatusServer.kt new file mode 100644 index 00000000000..1557d6dee22 --- /dev/null +++ b/compiler/rmi/kotlinr/src/org/jetbrains/kotlin/rmi/kotlinr/RemoteCompilationCanceledStatusServer.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2010-2015 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.rmi.kotlinr + +import org.jetbrains.kotlin.progress.CompilationCanceledStatus +import org.jetbrains.kotlin.rmi.CompileService +import org.jetbrains.kotlin.rmi.LoopbackNetworkInterface +import org.jetbrains.kotlin.rmi.SOCKET_ANY_FREE_PORT +import java.rmi.server.UnicastRemoteObject + + +public class RemoteCompilationCanceledStatusServer(val base: CompilationCanceledStatus, port: Int = SOCKET_ANY_FREE_PORT) : CompileService.RemoteCompilationCanceledStatus { + + init { + UnicastRemoteObject.exportObject(this, port, LoopbackNetworkInterface.clientLoopbackSocketFactory, LoopbackNetworkInterface.serverLoopbackSocketFactory) + } + + override fun checkCanceled() { + base.checkCanceled() + } +} \ No newline at end of file diff --git a/compiler/rmi/kotlinr/src/org/jetbrains/kotlin/rmi/kotlinr/RemoteIncrementalCompilationComponentsServer.kt b/compiler/rmi/kotlinr/src/org/jetbrains/kotlin/rmi/kotlinr/RemoteIncrementalCompilationComponentsServer.kt new file mode 100644 index 00000000000..52eddc4c2a8 --- /dev/null +++ b/compiler/rmi/kotlinr/src/org/jetbrains/kotlin/rmi/kotlinr/RemoteIncrementalCompilationComponentsServer.kt @@ -0,0 +1,44 @@ +/* + * Copyright 2010-2015 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.rmi.kotlinr + +import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents +import org.jetbrains.kotlin.modules.TargetId +import org.jetbrains.kotlin.rmi.CompileService +import org.jetbrains.kotlin.rmi.LoopbackNetworkInterface +import org.jetbrains.kotlin.rmi.SOCKET_ANY_FREE_PORT +import java.rmi.server.UnicastRemoteObject + + +public class RemoteIncrementalCompilationComponentsServer(val base: IncrementalCompilationComponents, val port: Int = SOCKET_ANY_FREE_PORT) : CompileService.RemoteIncrementalCompilationComponents { + + init { + UnicastRemoteObject.exportObject(this, port, LoopbackNetworkInterface.clientLoopbackSocketFactory, LoopbackNetworkInterface.serverLoopbackSocketFactory) + } + + private val cacheServers = hashMapOf() + private val lookupTrackerServer by lazy { RemoteLookupTrackerServer(base.getLookupTracker()) } + + override fun getIncrementalCache(target: TargetId): CompileService.RemoteIncrementalCache = + cacheServers.get(target) ?: { + val newServer = RemoteIncrementalCacheServer(base.getIncrementalCache(target), port) + cacheServers.put(target, newServer) + newServer + }() + + override fun getLookupTracker(): CompileService.RemoteLookupTracker = lookupTrackerServer +} diff --git a/compiler/rmi/kotlinr/src/org/jetbrains/kotlin/rmi/kotlinr/RemoteLookupTrackerServer.kt b/compiler/rmi/kotlinr/src/org/jetbrains/kotlin/rmi/kotlinr/RemoteLookupTrackerServer.kt new file mode 100644 index 00000000000..197d8e817e6 --- /dev/null +++ b/compiler/rmi/kotlinr/src/org/jetbrains/kotlin/rmi/kotlinr/RemoteLookupTrackerServer.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2010-2015 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.rmi.kotlinr + +import org.jetbrains.kotlin.incremental.components.LookupTracker +import org.jetbrains.kotlin.incremental.components.ScopeKind +import org.jetbrains.kotlin.rmi.CompileService +import org.jetbrains.kotlin.rmi.LoopbackNetworkInterface +import org.jetbrains.kotlin.rmi.SOCKET_ANY_FREE_PORT +import java.rmi.server.UnicastRemoteObject + + +public class RemoteLookupTrackerServer(val base: LookupTracker, port: Int = SOCKET_ANY_FREE_PORT) : CompileService.RemoteLookupTracker { + + init { + UnicastRemoteObject.exportObject(this, port, LoopbackNetworkInterface.clientLoopbackSocketFactory, LoopbackNetworkInterface.serverLoopbackSocketFactory) + } + + override fun record(lookupContainingFile: String, lookupLine: Int?, lookupColumn: Int?, scopeFqName: String, scopeKind: ScopeKind, name: String) { + base.record(lookupContainingFile, lookupLine, lookupColumn, scopeFqName, scopeKind, name) + } + + private val _isDoNothing: Boolean = base == LookupTracker.DO_NOTHING + override fun isDoNothing(): Boolean = _isDoNothing +} + diff --git a/compiler/rmi/rmi-interface/src/org/jetbrains/kotlin/rmi/CompileService.kt b/compiler/rmi/rmi-interface/src/org/jetbrains/kotlin/rmi/CompileService.kt index 6c01ffba748..302d2281c9a 100644 --- a/compiler/rmi/rmi-interface/src/org/jetbrains/kotlin/rmi/CompileService.kt +++ b/compiler/rmi/rmi-interface/src/org/jetbrains/kotlin/rmi/CompileService.kt @@ -16,7 +16,9 @@ package org.jetbrains.kotlin.rmi +import org.jetbrains.kotlin.incremental.components.ScopeKind import org.jetbrains.kotlin.modules.TargetId +import java.io.Serializable import java.rmi.Remote import java.rmi.RemoteException @@ -47,6 +49,38 @@ public interface CompileService : Remote { public fun close() } + public interface RemoteLookupTracker : Remote { + @Throws(RemoteException::class) + fun record( + lookupContainingFile: String, + lookupLine: Int?, + lookupColumn: Int?, + scopeFqName: String, + scopeKind: ScopeKind, + name: String + ) + @Throws(RemoteException::class) + fun isDoNothing(): Boolean + } + + public interface RemoteIncrementalCompilationComponents : Remote { + @Throws(RemoteException::class) + public fun getIncrementalCache(target: TargetId): RemoteIncrementalCache + + @Throws(RemoteException::class) + public fun getLookupTracker(): RemoteLookupTracker + } + + public interface RemoteCompilationCanceledStatus : Remote { + @Throws(RemoteException::class) + fun checkCanceled(): Unit + } + + public data class RemoteCompilationServices( + public val incrementalCompilationComponents: RemoteIncrementalCompilationComponents? = null, + public val compilationCanceledStatus: RemoteCompilationCanceledStatus? = null + ) : Serializable + @Throws(RemoteException::class) public fun getCompilerId(): CompilerId @@ -59,6 +93,7 @@ public interface CompileService : Remote { @Throws(RemoteException::class) public fun remoteCompile( args: Array, + services: RemoteCompilationServices, compilerOutputStream: RemoteOutputStream, outputFormat: OutputFormat, serviceOutputStream: RemoteOutputStream @@ -67,7 +102,7 @@ public interface CompileService : Remote { @Throws(RemoteException::class) public fun remoteIncrementalCompile( args: Array, - caches: Map, + services: RemoteCompilationServices, compilerOutputStream: RemoteOutputStream, compilerOutputFormat: OutputFormat, serviceOutputStream: RemoteOutputStream 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 872f3a3beed..2a239d0fdca 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 @@ -19,22 +19,17 @@ package org.jetbrains.kotlin.rmi.service import org.jetbrains.kotlin.cli.common.CLICompiler import org.jetbrains.kotlin.cli.common.ExitCode import org.jetbrains.kotlin.config.Services -import org.jetbrains.kotlin.incremental.components.LookupTracker -import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents -import org.jetbrains.kotlin.modules.TargetId +import org.jetbrains.kotlin.progress.CompilationCanceledStatus import org.jetbrains.kotlin.rmi.* -import java.io.IOException import java.io.PrintStream import java.lang.management.ManagementFactory import java.lang.management.ThreadMXBean -import java.net.URLClassLoader import java.rmi.NoSuchObjectException import java.rmi.registry.Registry import java.rmi.server.UnicastRemoteObject import java.util.concurrent.TimeUnit import java.util.concurrent.locks.ReentrantReadWriteLock -import java.util.jar.Manifest import java.util.logging.Logger import kotlin.concurrent.read import kotlin.concurrent.write @@ -65,6 +60,7 @@ class CompileServiceImpl>( } override fun remoteCompile(args: Array, + services: CompileService.RemoteCompilationServices, compilerOutputStream: RemoteOutputStream, outputFormat: CompileService.OutputFormat, serviceOutputStream: RemoteOutputStream @@ -77,7 +73,7 @@ class CompileServiceImpl>( } override fun remoteIncrementalCompile(args: Array, - caches: Map, + services: CompileService.RemoteCompilationServices, compilerOutputStream: RemoteOutputStream, compilerOutputFormat: CompileService.OutputFormat, serviceOutputStream: RemoteOutputStream @@ -85,7 +81,7 @@ class CompileServiceImpl>( doCompile(args, compilerOutputStream, serviceOutputStream) { printStream -> when (compilerOutputFormat) { CompileService.OutputFormat.PLAIN -> throw NotImplementedError("Only XML output is supported in remote incremental compilation") - CompileService.OutputFormat.XML -> compiler.execAndOutputXml(printStream, createCompileServices(caches), *args) + CompileService.OutputFormat.XML -> compiler.execAndOutputXml(printStream, createCompileServices(services), *args) } } @@ -127,13 +123,6 @@ class CompileServiceImpl>( alive = true } - private class IncrementalCompilationComponentsImpl(val targetToCache: 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(target: TargetId): IncrementalCache = RemoteIncrementalCacheClient(targetToCache[target]!!) - // TODO: add appropriate proxy into interaction when lookup tracker is needed - override fun getLookupTracker(): LookupTracker = LookupTracker.DO_NOTHING - } - private fun doCompile(args: Array, compilerMessagesStreamProxy: RemoteOutputStream, serviceOutputStreamProxy: RemoteOutputStream, body: (PrintStream) -> ExitCode): Int = ifAlive { val compilerMessagesStream = PrintStream(RemoteOutputStreamClient(compilerMessagesStreamProxy)) @@ -145,14 +134,12 @@ class CompileServiceImpl>( } } - private fun createCompileServices(incrementalCaches: Map): Services = - Services.Builder() - .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() -// }) - .build() + private fun createCompileServices(services: CompileService.RemoteCompilationServices): Services { + val builder = Services.Builder() + services.incrementalCompilationComponents?.let { builder.register(IncrementalCompilationComponents::class.java, RemoteIncrementalCompilationComponentsClient(it)) } + services.compilationCanceledStatus?.let { builder.register(CompilationCanceledStatus::class.java, RemoteCompilationCanceledStatusClient(it)) } + return builder.build() + } fun usedMemory(): Long { diff --git a/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/RemoteCompilationCanceledStatusClient.kt b/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/RemoteCompilationCanceledStatusClient.kt new file mode 100644 index 00000000000..423def3e8c0 --- /dev/null +++ b/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/RemoteCompilationCanceledStatusClient.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2015 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.rmi.service + +import org.jetbrains.kotlin.progress.CompilationCanceledStatus +import org.jetbrains.kotlin.rmi.CompileService + + +class RemoteCompilationCanceledStatusClient(val proxy: CompileService.RemoteCompilationCanceledStatus): CompilationCanceledStatus { + override fun checkCanceled() { + proxy.checkCanceled() + } +} diff --git a/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/RemoteIncrementalCompilationComponentsClient.kt b/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/RemoteIncrementalCompilationComponentsClient.kt new file mode 100644 index 00000000000..e6ce460e0c3 --- /dev/null +++ b/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/RemoteIncrementalCompilationComponentsClient.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2010-2015 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.rmi.service + +import org.jetbrains.kotlin.incremental.components.LookupTracker +import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache +import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents +import org.jetbrains.kotlin.modules.TargetId +import org.jetbrains.kotlin.rmi.CompileService + + +class RemoteIncrementalCompilationComponentsClient(val proxy: CompileService.RemoteIncrementalCompilationComponents) : IncrementalCompilationComponents { + + override fun getIncrementalCache(target: TargetId): IncrementalCache = RemoteIncrementalCacheClient(proxy.getIncrementalCache(target)) + + override fun getLookupTracker(): LookupTracker = RemoteLookupTrackerClient(proxy.getLookupTracker()) +} diff --git a/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/RemoteLookupTrackerClient.kt b/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/RemoteLookupTrackerClient.kt new file mode 100644 index 00000000000..e3d1fd2c0aa --- /dev/null +++ b/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/RemoteLookupTrackerClient.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2010-2015 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.rmi.service + +import org.jetbrains.kotlin.incremental.components.LookupTracker +import org.jetbrains.kotlin.incremental.components.ScopeKind +import org.jetbrains.kotlin.rmi.CompileService + + +class RemoteLookupTrackerClient(val proxy: CompileService.RemoteLookupTracker) : LookupTracker { + + private val isDoNothing = proxy.isDoNothing() + + override fun record(lookupContainingFile: String, lookupLine: Int?, lookupColumn: Int?, scopeFqName: String, scopeKind: ScopeKind, name: String) { + if (!isDoNothing) + proxy.record(lookupContainingFile, lookupLine, lookupColumn, scopeFqName, scopeKind, name) + } +} diff --git a/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt b/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt index 4ebfec35d54..0dd541b1b9a 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt @@ -27,25 +27,23 @@ import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.INFO import org.jetbrains.kotlin.cli.common.messages.MessageCollector import org.jetbrains.kotlin.cli.common.messages.MessageCollectorUtil import org.jetbrains.kotlin.config.CompilerSettings -import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache -import org.jetbrains.kotlin.modules.TargetId -import org.jetbrains.kotlin.rmi.* -import org.jetbrains.kotlin.rmi.kotlinr.DaemonReportCategory -import org.jetbrains.kotlin.rmi.kotlinr.DaemonReportMessage -import org.jetbrains.kotlin.rmi.kotlinr.DaemonReportingTargets -import org.jetbrains.kotlin.rmi.kotlinr.KotlinCompilerClient -import org.jetbrains.kotlin.utils.* - +import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents +import org.jetbrains.kotlin.progress.CompilationCanceledStatus +import org.jetbrains.kotlin.rmi.CompilerId +import org.jetbrains.kotlin.rmi.configureDaemonJVMOptions +import org.jetbrains.kotlin.rmi.configureDaemonOptions +import org.jetbrains.kotlin.rmi.isDaemonEnabled +import org.jetbrains.kotlin.rmi.kotlinr.* +import org.jetbrains.kotlin.utils.rethrow import java.io.* import java.lang.reflect.Field import java.lang.reflect.Modifier -import java.util.ArrayList - -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.INFO +import java.util.* public object KotlinCompilerRunner { private val K2JVM_COMPILER = "org.jetbrains.kotlin.cli.jvm.K2JVMCompiler" @@ -58,14 +56,12 @@ public object KotlinCompilerRunner { compilerSettings: CompilerSettings, messageCollector: MessageCollector, environment: CompilerEnvironment, - incrementalCaches: Map?, moduleFile: File, collector: OutputItemsCollector) { val arguments = mergeBeans(commonArguments, k2jvmArguments) setupK2JvmArguments(moduleFile, arguments) - runCompiler(K2JVM_COMPILER, arguments, compilerSettings.additionalArguments, messageCollector, collector, environment, - incrementalCaches) + runCompiler(K2JVM_COMPILER, arguments, compilerSettings.additionalArguments, messageCollector, collector, environment) } public fun runK2JsCompiler( @@ -74,7 +70,6 @@ public object KotlinCompilerRunner { compilerSettings: CompilerSettings, messageCollector: MessageCollector, environment: CompilerEnvironment, - incrementalCaches: Map?, collector: OutputItemsCollector, sourceFiles: Collection, libraryFiles: List, @@ -82,8 +77,7 @@ public object KotlinCompilerRunner { val arguments = mergeBeans(commonArguments, k2jsArguments) setupK2JsArguments(outputFile, sourceFiles, libraryFiles, arguments) - runCompiler(K2JS_COMPILER, arguments, compilerSettings.additionalArguments, messageCollector, collector, environment, - incrementalCaches) + runCompiler(K2JS_COMPILER, arguments, compilerSettings.additionalArguments, messageCollector, collector, environment) } private fun processCompilerOutput( @@ -109,8 +103,7 @@ public object KotlinCompilerRunner { additionalArguments: String, messageCollector: MessageCollector, collector: OutputItemsCollector, - environment: CompilerEnvironment, - incrementalCaches: Map?) { + environment: CompilerEnvironment) { try { messageCollector.report(INFO, "Using kotlin-home = " + environment.kotlinPaths.homePath, CompilerMessageLocation.NO_LOCATION) @@ -119,7 +112,7 @@ public object KotlinCompilerRunner { val argsArray = argumentsList.toTypedArray() - if (!tryCompileWithDaemon(messageCollector, collector, environment, incrementalCaches, argsArray)) { + if (!tryCompileWithDaemon(messageCollector, collector, environment, argsArray)) { // otherwise fallback to in-process val stream = ByteArrayOutputStream() @@ -139,14 +132,12 @@ public object KotlinCompilerRunner { } - private fun tryCompileWithDaemon( - messageCollector: MessageCollector, - collector: OutputItemsCollector, - environment: CompilerEnvironment, - incrementalCaches: Map?, - argsArray: Array): Boolean { + private fun tryCompileWithDaemon(messageCollector: MessageCollector, + collector: OutputItemsCollector, + environment: CompilerEnvironment, + argsArray: Array): Boolean { - if (incrementalCaches != null && isDaemonEnabled()) { + if (isDaemonEnabled()) { val libPath = CompilerRunnerUtil.getLibPath(environment.kotlinPaths, messageCollector) // TODO: it may be a good idea to cache the compilerId, since making it means calculating digest over jar(s) and if \\ // the lifetime of JPS process is small anyway, we can neglect the probability of changed compiler @@ -173,7 +164,11 @@ public object KotlinCompilerRunner { val compilerOut = ByteArrayOutputStream() val daemonOut = ByteArrayOutputStream() - val res = KotlinCompilerClient.incrementalCompile(daemon, argsArray, incrementalCaches, compilerOut, daemonOut) + val services = CompilationServices( + incrementalCompilationComponents = environment.services.get(IncrementalCompilationComponents::class.java), + compilationCanceledStatus = environment.services.get(CompilationCanceledStatus::class.java)) + + val res = KotlinCompilerClient.incrementalCompile(daemon, argsArray, services, compilerOut, daemonOut) processCompilerOutput(messageCollector, collector, compilerOut, res.toString()) BufferedReader(StringReader(daemonOut.toString())).forEachLine { diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt index 81a96f10aa0..1c028a21d29 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt @@ -318,10 +318,7 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR ) } - return compileToJvm(allCompiledFiles, chunk, commonArguments, context, dirtyFilesHolder, environment, - incrementalCaches.mapKeysTo(HashMap(incrementalCaches.size()), - { TargetId(it.getKey()) }), - filesToCompile, messageCollector) + return compileToJvm(allCompiledFiles, chunk, commonArguments, context, dirtyFilesHolder, environment, filesToCompile, messageCollector) } private fun createCompileEnvironment( @@ -519,7 +516,7 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR val compilerSettings = JpsKotlinCompilerSettings.getCompilerSettings(project) val k2JsArguments = JpsKotlinCompilerSettings.getK2JsCompilerArguments(project) - KotlinCompilerRunner.runK2JsCompiler(commonArguments, k2JsArguments, compilerSettings, messageCollector, environment, incrementalCaches, outputItemCollector, sourceFiles, libraryFiles, outputFile) + KotlinCompilerRunner.runK2JsCompiler(commonArguments, k2JsArguments, compilerSettings, messageCollector, environment, outputItemCollector, sourceFiles, libraryFiles, outputFile) return outputItemCollector } @@ -542,7 +539,6 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR context: CompileContext, dirtyFilesHolder: DirtyFilesHolder, environment: CompilerEnvironment, - incrementalCaches: MutableMap?, filesToCompile: MultiMap, messageCollector: MessageCollectorAdapter ): OutputItemsCollectorImpl? { val outputItemCollector = OutputItemsCollectorImpl() @@ -586,7 +582,7 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR + (if (totalRemovedFiles == 0) "" else " ($totalRemovedFiles removed files)") + " in " + filesToCompile.keySet().map { it.getPresentableName() }.join()) - KotlinCompilerRunner.runK2JvmCompiler(commonArguments, k2JvmArguments, compilerSettings, messageCollector, environment, incrementalCaches, moduleFile, outputItemCollector) + KotlinCompilerRunner.runK2JvmCompiler(commonArguments, k2JvmArguments, compilerSettings, messageCollector, environment, moduleFile, outputItemCollector) moduleFile.delete() return outputItemCollector