diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/messages/OutputMessageUtil.java b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/messages/OutputMessageUtil.java index 5f0453dbdb3..c4f7784f289 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/messages/OutputMessageUtil.java +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/messages/OutputMessageUtil.java @@ -23,6 +23,7 @@ import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.PrintWriter; +import java.io.Serializable; import java.io.StringWriter; import java.util.Collection; @@ -75,7 +76,7 @@ public class OutputMessageUtil { return sourceFiles; } - public static class Output { + public static class Output implements Serializable { @NotNull public final Collection sourceFiles; @Nullable @@ -85,5 +86,7 @@ public class OutputMessageUtil { this.sourceFiles = sourceFiles; this.outputFile = outputFile; } + + static final long serialVersionUID = 0L; } } diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt index acec51c584d..06a437fdfb6 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt @@ -86,14 +86,16 @@ object KotlinToJVMBytecodeCompiler { mainClass: FqName? ) { val jarPath = configuration.get(JVMConfigurationKeys.OUTPUT_JAR) + val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE) if (jarPath != null) { val includeRuntime = configuration.get(JVMConfigurationKeys.INCLUDE_RUNTIME, false) CompileEnvironmentUtil.writeToJar(jarPath, includeRuntime, mainClass, outputFiles) + messageCollector.report(CompilerMessageSeverity.OUTPUT, + OutputMessageUtil.formatOutputMessage(outputFiles.asList().flatMap { it.sourceFiles }.distinct(), jarPath), CompilerMessageLocation.NO_LOCATION) return } val outputDir = configuration.get(JVMConfigurationKeys.OUTPUT_DIRECTORY) ?: File(".") - val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE) outputFiles.writeAll(outputDir, messageCollector) } diff --git a/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/BasicCompilerServicesWithResultsFacadeServer.kt b/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/BasicCompilerServicesWithResultsFacadeServer.kt new file mode 100644 index 00000000000..dce1bcec921 --- /dev/null +++ b/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/BasicCompilerServicesWithResultsFacadeServer.kt @@ -0,0 +1,100 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.daemon.client + +import org.jetbrains.kotlin.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.OutputMessageUtil +import org.jetbrains.kotlin.daemon.common.* +import java.io.Serializable +import java.io.File +import java.rmi.server.UnicastRemoteObject + + +open class BasicCompilerServicesWithResultsFacadeServer( + val messageCollector: MessageCollector, + val outputsCollector: ((File, List) -> Unit)? = null, + port: Int = SOCKET_ANY_FREE_PORT +) : CompilerServicesFacadeBase, + UnicastRemoteObject(port, LoopbackNetworkInterface.clientLoopbackSocketFactory, LoopbackNetworkInterface.serverLoopbackSocketFactory) +{ + override fun report(category: Int, severity: Int, message: String?, attachment: Serializable?) { + messageCollector.reportFromDaemon(outputsCollector, category, severity, message, attachment) + } +} + +fun MessageCollector.reportFromDaemon(outputsCollector: ((File, List) -> Unit)?, category: Int, severity: Int, message: String?, attachment: Serializable?) { + val reportCategory = ReportCategory.fromCode(category) + + when (reportCategory) { + ReportCategory.OUTPUT_MESSAGE -> { + if (outputsCollector != null) { + OutputMessageUtil.parseOutputMessage(message.orEmpty())?.let { outs -> + outs.outputFile?.let { + outputsCollector.invoke(it, outs.sourceFiles.toList()) + } + } + } + report(CompilerMessageSeverity.OUTPUT, message!!, CompilerMessageLocation.NO_LOCATION) + } + ReportCategory.EXCEPTION -> { + report(CompilerMessageSeverity.EXCEPTION, message.orEmpty(), CompilerMessageLocation.NO_LOCATION) + } + ReportCategory.COMPILER_MESSAGE -> { + val compilerSeverity = when (ReportSeverity.fromCode(severity)) { + ReportSeverity.ERROR -> CompilerMessageSeverity.ERROR + ReportSeverity.WARNING -> CompilerMessageSeverity.WARNING + ReportSeverity.INFO -> CompilerMessageSeverity.INFO + ReportSeverity.DEBUG -> CompilerMessageSeverity.LOGGING + else -> throw IllegalStateException("Unexpected compiler message report severity $severity") + } + if (message != null && attachment is CompilerMessageLocation) { + report(compilerSeverity, message, attachment) + } + else { + reportUnexpected(category, severity, message, attachment) + } + } + ReportCategory.DAEMON_MESSAGE, + ReportCategory.IC_MESSAGE -> { + if (message != null) { + report(CompilerMessageSeverity.LOGGING, message, CompilerMessageLocation.NO_LOCATION) + } + else { + reportUnexpected(category, severity, message, attachment) + } + } + else -> { + reportUnexpected(category, severity, message, attachment) + } + } +} + +private fun MessageCollector.reportUnexpected(category: Int, severity: Int, message: String?, attachment: Serializable?) { + val compilerMessageSeverity = when (ReportSeverity.fromCode(severity)) { + ReportSeverity.ERROR -> CompilerMessageSeverity.ERROR + ReportSeverity.WARNING -> CompilerMessageSeverity.WARNING + ReportSeverity.INFO -> CompilerMessageSeverity.INFO + else -> CompilerMessageSeverity.LOGGING + } + + report(compilerMessageSeverity, + "Unexpected message: category=$category; severity=$severity; message='$message'; attachment=$attachment", + CompilerMessageLocation.NO_LOCATION) +} + diff --git a/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/KotlinCompilerClient.kt b/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/KotlinCompilerClient.kt index 8a6585ccb15..d7f93107058 100644 --- a/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/KotlinCompilerClient.kt +++ b/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/KotlinCompilerClient.kt @@ -18,6 +18,9 @@ package org.jetbrains.kotlin.daemon.client import net.rubygrapefruit.platform.Native import net.rubygrapefruit.platform.ProcessLauncher +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.daemon.common.* import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents import org.jetbrains.kotlin.progress.CompilationCanceledStatus @@ -141,6 +144,32 @@ object KotlinCompilerClient { operationsTracer).get() } + fun compile(compilerService: CompileService, + sessionId: Int, + targetPlatform: CompileService.TargetPlatform, + args: Array, + messageCollector: MessageCollector, + outputsCollector: ((File, List) -> Unit)? = null, + compilerMode: CompilerMode = CompilerMode.NON_INCREMENTAL_COMPILER, + reportSeverity: ReportSeverity = ReportSeverity.INFO, + port: Int = SOCKET_ANY_FREE_PORT, + profiler: Profiler = DummyProfiler() + ): Int = profiler.withMeasure(this) { + val services = BasicCompilerServicesWithResultsFacadeServer(messageCollector, outputsCollector, port) + compilerService.compile( + sessionId, + args, + CompilationOptions( + compilerMode, + targetPlatform, + arrayOf(ReportCategory.COMPILER_MESSAGE.code, ReportCategory.DAEMON_MESSAGE.code, ReportCategory.EXCEPTION.code, ReportCategory.OUTPUT_MESSAGE.code), + reportSeverity.code, + emptyArray()), + services, + null + ).get() + } + val COMPILE_DAEMON_CLIENT_OPTIONS_PROPERTY: String = "kotlin.daemon.client.options" data class ClientOptions( var stop: Boolean = false @@ -245,9 +274,22 @@ object KotlinCompilerClient { if (category == DaemonReportCategory.DEBUG && !verboseReporting) return out?.println("[$source] ${category.name}: $message") messages?.add(DaemonReportMessage(category, "[$source] $message")) + messageCollector?.let { + when (category) { + DaemonReportCategory.DEBUG -> it.report(CompilerMessageSeverity.LOGGING, message, CompilerMessageLocation.NO_LOCATION) + DaemonReportCategory.INFO -> it.report(CompilerMessageSeverity.INFO, message, CompilerMessageLocation.NO_LOCATION) + DaemonReportCategory.EXCEPTION -> it.report(CompilerMessageSeverity.EXCEPTION, message, CompilerMessageLocation.NO_LOCATION) + } + } + compilerServices?.let { + when (category) { + DaemonReportCategory.DEBUG -> it.report(ReportCategory.DAEMON_MESSAGE, ReportSeverity.DEBUG, message, source) + DaemonReportCategory.INFO -> it.report(ReportCategory.DAEMON_MESSAGE, ReportSeverity.INFO, message, source) + DaemonReportCategory.EXCEPTION -> it.report(ReportCategory.EXCEPTION, ReportSeverity.ERROR, message, source) + } + } } - private fun tryFindSuitableDaemonOrNewOpts(registryDir: File, compilerId: CompilerId, daemonJVMOptions: DaemonJVMOptions, report: (DaemonReportCategory, String) -> Unit): Pair { val aliveWithOpts = walkDaemons(registryDir, compilerId, report = report) .map { Pair(it, it.getDaemonJVMOptions()) } @@ -337,7 +379,10 @@ object KotlinCompilerClient { data class DaemonReportMessage(val category: DaemonReportCategory, val message: String) -class DaemonReportingTargets(val out: PrintStream? = null, val messages: MutableCollection? = null) +class DaemonReportingTargets(val out: PrintStream? = null, + val messages: MutableCollection? = null, + val messageCollector: MessageCollector? = null, + val compilerServices: CompilerServicesFacadeBase? = null) internal fun isProcessAlive(process: Process) = diff --git a/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/CompileService.kt b/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/CompileService.kt index 3b435283a89..e2f76b715d1 100644 --- a/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/CompileService.kt +++ b/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/CompileService.kt @@ -132,7 +132,7 @@ interface CompileService : Remote { @Throws(RemoteException::class) fun compile( sessionId: Int, - compilerArguments: Array, + compilerArguments: Array, compilationOptions: CompilationOptions, servicesFacade: CompilerServicesFacadeBase, compilationResults: CompilationResults? diff --git a/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt b/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt index 074a89f5c01..a241a432115 100644 --- a/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt +++ b/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt @@ -317,7 +317,7 @@ class CompileServiceImpl( override fun compile( sessionId: Int, - compilerArguments: Array, + compilerArguments: Array, compilationOptions: CompilationOptions, servicesFacade: CompilerServicesFacadeBase, compilationResults: CompilationResults? diff --git a/compiler/daemon/src/org/jetbrains/kotlin/daemon/report/CompileServicesFacadeMessageCollector.kt b/compiler/daemon/src/org/jetbrains/kotlin/daemon/report/CompileServicesFacadeMessageCollector.kt index fc9444ea57c..98301df12d3 100644 --- a/compiler/daemon/src/org/jetbrains/kotlin/daemon/report/CompileServicesFacadeMessageCollector.kt +++ b/compiler/daemon/src/org/jetbrains/kotlin/daemon/report/CompileServicesFacadeMessageCollector.kt @@ -19,6 +19,8 @@ package org.jetbrains.kotlin.daemon.report 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.MessageRenderer +import org.jetbrains.kotlin.daemon.KotlinCompileDaemon.log import org.jetbrains.kotlin.daemon.common.* internal class CompileServicesFacadeMessageCollector( @@ -33,6 +35,7 @@ internal class CompileServicesFacadeMessageCollector( } override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation) { + log.info("Message: " + MessageRenderer.WITHOUT_PATHS.render(severity, message, location)) when (severity) { CompilerMessageSeverity.OUTPUT -> { servicesFacade.report(ReportCategory.OUTPUT_MESSAGE, ReportSeverity.ERROR, message) diff --git a/compiler/tests/org/jetbrains/kotlin/daemon/CompilerApiTest.kt b/compiler/tests/org/jetbrains/kotlin/daemon/CompilerApiTest.kt new file mode 100644 index 00000000000..8e8490492ba --- /dev/null +++ b/compiler/tests/org/jetbrains/kotlin/daemon/CompilerApiTest.kt @@ -0,0 +1,190 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.daemon + +import org.jetbrains.kotlin.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.OutputMessageUtil +import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler +import org.jetbrains.kotlin.config.Services +import org.jetbrains.kotlin.daemon.client.DaemonReportingTargets +import org.jetbrains.kotlin.daemon.client.KotlinCompilerClient +import org.jetbrains.kotlin.daemon.common.* +import org.jetbrains.kotlin.integration.KotlinIntegrationTestBase +import org.jetbrains.kotlin.scripts.captureOut +import org.jetbrains.kotlin.test.KotlinTestUtils +import org.junit.Assert +import java.io.File +import java.net.URLClassLoader + +class CompilerApiTest : KotlinIntegrationTestBase() { + + private val compilerLibDir = getCompilerLib() + + val compilerClassPath = listOf( + File(compilerLibDir, "kotlin-compiler.jar")) + val scriptRuntimeClassPath = listOf( + File(compilerLibDir, "kotlin-runtime.jar"), + File(compilerLibDir, "kotlin-script-runtime.jar")) + val compilerId by lazy(LazyThreadSafetyMode.NONE) { CompilerId.makeCompilerId(compilerClassPath) } + + private fun compileLocally(messageCollector: TestMessageCollector, vararg args: String): Pair> { + val code = K2JVMCompiler().exec(messageCollector, + Services.EMPTY, + K2JVMCompilerArguments().apply { K2JVMCompiler().parseArguments(args, this) }).code + val outputs = messageCollector.messages.filter { it.severity == CompilerMessageSeverity.OUTPUT }.mapNotNull { + OutputMessageUtil.parseOutputMessage(it.message)?.let { outs -> + outs.outputFile?.let { OutputMessageUtil.Output(outs.sourceFiles, it) } + } + } + return code to outputs + } + + private fun compileOnDaemon(clientAliveFile: File, compilerId: CompilerId, daemonJVMOptions: DaemonJVMOptions, daemonOptions: DaemonOptions, + messageCollector: MessageCollector, vararg args: String): Pair> { + val daemon = KotlinCompilerClient.connectToCompileService(compilerId, clientAliveFile, daemonJVMOptions, daemonOptions, + DaemonReportingTargets(messageCollector = messageCollector), autostart = true) + assertNotNull("failed to connect daemon", daemon) + + daemon?.registerClient(clientAliveFile.absolutePath) + + val outputs = arrayListOf() + + val code = KotlinCompilerClient.compile(daemon!!, CompileService.NO_SESSION, CompileService.TargetPlatform.JVM, args, messageCollector, + { outFile, srcFiles -> outputs.add(OutputMessageUtil.Output(srcFiles, outFile)) }, + reportSeverity = ReportSeverity.DEBUG) + return code to outputs + } + + private fun getHelloAppBaseDir(): String = KotlinTestUtils.getTestDataPathBase() + "/integration/smoke/helloApp" + private fun getSimpleScriptBaseDir(): String = KotlinTestUtils.getTestDataPathBase() + "/integration/smoke/simpleScript" + + private fun run(baseDir: String, logName: String, vararg args: String): Int = runJava(baseDir, logName, *args) + + private fun runScriptWithArgs(testDataDir: String, logName: String?, scriptClassName: String, classpath: List, vararg arguments: String) { + + val cl = URLClassLoader(classpath.map { it.toURI().toURL() }.toTypedArray()) + val scriptClass = cl.loadClass(scriptClassName) + + val scriptOut = captureOut { scriptClass.constructors.first().newInstance(arguments) } + + if (logName != null) { + val expectedFile = File(testDataDir, logName + ".expected") + val normalizedContent = normalizeOutput(File(testDataDir), "OUT:\n$scriptOut\nReturn code: 0") + + KotlinTestUtils.assertEqualsToFile(expectedFile, normalizedContent) + } + } + + fun testHelloAppLocal() { + val messageCollector = TestMessageCollector() + val jar = tmpdir.absolutePath + File.separator + "hello.jar" + val (code, outputs) = compileLocally(messageCollector, "-include-runtime", File(getHelloAppBaseDir(), "hello.kt").absolutePath, "-d", jar) + Assert.assertEquals(0, code) + Assert.assertTrue(outputs.isNotEmpty()) + Assert.assertEquals(jar, outputs.first().outputFile?.absolutePath) + run(getHelloAppBaseDir(), "hello.run", "-cp", jar, "Hello.HelloKt") + } + + fun testHelloApp() { + withFlagFile(getTestName(true), ".alive") { flagFile -> + val daemonOptions = DaemonOptions(runFilesPath = File(tmpdir, getTestName(true)).absolutePath, + verbose = true, + reportPerf = true) + + KotlinCompilerClient.shutdownCompileService(compilerId, daemonOptions) + + val logFile = createTempFile("kotlin-daemon-test.", ".log") + + val daemonJVMOptions = configureDaemonJVMOptions("D$COMPILE_DAEMON_LOG_PATH_PROPERTY=\"${logFile.loggerCompatiblePath}\"", + inheritMemoryLimits = false, inheritAdditionalProperties = false) + val messageCollector = TestMessageCollector() + val jar = tmpdir.absolutePath + File.separator + "hello.jar" + + try { + val (code, outputs) = compileOnDaemon(flagFile, compilerId, daemonJVMOptions, daemonOptions, messageCollector, + "-include-runtime", File(getHelloAppBaseDir(), "hello.kt").absolutePath, "-d", jar) + Assert.assertEquals(0, code) + Assert.assertTrue(outputs.isNotEmpty()) + Assert.assertEquals(jar, outputs.first().outputFile?.absolutePath) + run(getHelloAppBaseDir(), "hello.run", "-cp", jar, "Hello.HelloKt") + } + finally { + KotlinCompilerClient.shutdownCompileService(compilerId, daemonOptions) + logFile.delete() + } + } + } + + fun testSimpleScriptLocal() { + val messageCollector = TestMessageCollector() + val (code, outputs) = compileLocally(messageCollector, File(getSimpleScriptBaseDir(), "script.kts").absolutePath, "-d", tmpdir.absolutePath) + Assert.assertEquals(0, code) + Assert.assertTrue(outputs.isNotEmpty()) + Assert.assertEquals(File(tmpdir, "Script.class").absolutePath, outputs.first().outputFile?.absolutePath) + runScriptWithArgs(getSimpleScriptBaseDir(), "script", "Script", scriptRuntimeClassPath + tmpdir, "hi", "there") + } + + fun testSimpleScript() { + withFlagFile(getTestName(true), ".alive") { flagFile -> + val daemonOptions = DaemonOptions(runFilesPath = File(tmpdir, getTestName(true)).absolutePath, + verbose = true, + reportPerf = true) + + KotlinCompilerClient.shutdownCompileService(compilerId, daemonOptions) + + val logFile = createTempFile("kotlin-daemon-test.", ".log") + + val daemonJVMOptions = configureDaemonJVMOptions("D$COMPILE_DAEMON_LOG_PATH_PROPERTY=\"${logFile.loggerCompatiblePath}\"", + inheritMemoryLimits = false, inheritAdditionalProperties = false) + val messageCollector = TestMessageCollector() + val jar = tmpdir.absolutePath + File.separator + "hello.jar" + + try { + val (code, outputs) = compileOnDaemon(flagFile, compilerId, daemonJVMOptions, daemonOptions, messageCollector, + File(getSimpleScriptBaseDir(), "script.kts").absolutePath, "-d", tmpdir.absolutePath) + Assert.assertEquals(0, code) + Assert.assertTrue(outputs.isNotEmpty()) + Assert.assertEquals(File(tmpdir, "Script.class").absolutePath, outputs.first().outputFile?.absolutePath) + runScriptWithArgs(getSimpleScriptBaseDir(), "script", "Script", scriptRuntimeClassPath + tmpdir, "hi", "there") + } + finally { + KotlinCompilerClient.shutdownCompileService(compilerId, daemonOptions) + logFile.delete() + } + } + } +} + +class TestMessageCollector : MessageCollector { + + data class Message(val severity: CompilerMessageSeverity, val message: String, val location: CompilerMessageLocation) + + val messages = arrayListOf() + + override fun clear() { + messages.clear() + } + + override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation) { + messages.add(Message(severity, message, location)) + } + + override fun hasErrors(): Boolean = messages.any { it.severity == CompilerMessageSeverity.EXCEPTION || it.severity == CompilerMessageSeverity.ERROR } +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/daemon/CompilerDaemonTest.kt b/compiler/tests/org/jetbrains/kotlin/daemon/CompilerDaemonTest.kt index 53265810e59..ccb7c5cc01f 100644 --- a/compiler/tests/org/jetbrains/kotlin/daemon/CompilerDaemonTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/daemon/CompilerDaemonTest.kt @@ -701,7 +701,7 @@ internal inline fun withDisposable(body: (Disposable) -> Unit) { // java.util.Logger used in the daemon silently forgets to log into a file specified in the config on Windows, // if file path is given in windows form (using backslash as a separator); the reason is unknown // this function makes a path with forward slashed, that works on windows too -private val File.loggerCompatiblePath: String +internal val File.loggerCompatiblePath: String get() = if (OSKind.current == OSKind.Windows) absolutePath.replace('\\', '/') else absolutePath diff --git a/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsCompilerServicesFacadeImpl.kt b/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsCompilerServicesFacadeImpl.kt index 285677acf08..3410543678a 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsCompilerServicesFacadeImpl.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsCompilerServicesFacadeImpl.kt @@ -16,11 +16,10 @@ package org.jetbrains.kotlin.compilerRunner -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity -import org.jetbrains.kotlin.cli.common.messages.OutputMessageUtil import org.jetbrains.kotlin.daemon.client.CompilerCallbackServicesFacadeServer -import org.jetbrains.kotlin.daemon.common.* +import org.jetbrains.kotlin.daemon.client.reportFromDaemon +import org.jetbrains.kotlin.daemon.common.JpsCompilerServicesFacade +import org.jetbrains.kotlin.daemon.common.SOCKET_ANY_FREE_PORT import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents import org.jetbrains.kotlin.progress.CompilationCanceledStatus import java.io.Serializable @@ -34,58 +33,8 @@ internal class JpsCompilerServicesFacadeImpl( JpsCompilerServicesFacade { override fun report(category: Int, severity: Int, message: String?, attachment: Serializable?) { - val reportCategory = ReportCategory.fromCode(category) - - when (reportCategory) { - ReportCategory.OUTPUT_MESSAGE -> { - val output = OutputMessageUtil.parseOutputMessage(message!!) - if (output != null) { - env.outputItemsCollector.add(output.sourceFiles, output.outputFile) - } - } - ReportCategory.EXCEPTION -> { - env.messageCollector.report(CompilerMessageSeverity.EXCEPTION, message!!, CompilerMessageLocation.NO_LOCATION) - } - ReportCategory.COMPILER_MESSAGE -> { - val compilerSeverity = when (ReportSeverity.fromCode(severity)) { - ReportSeverity.ERROR -> CompilerMessageSeverity.ERROR - ReportSeverity.WARNING -> CompilerMessageSeverity.WARNING - ReportSeverity.INFO -> CompilerMessageSeverity.INFO - ReportSeverity.DEBUG -> CompilerMessageSeverity.LOGGING - else -> throw IllegalStateException("Unexpected compiler message report severity $severity") - } - if (message != null && attachment is CompilerMessageLocation) { - env.messageCollector.report(compilerSeverity, message, attachment) - } - else { - reportUnexpected(category, severity, message, attachment) - } - } - ReportCategory.DAEMON_MESSAGE, - ReportCategory.IC_MESSAGE -> { - if (message != null) { - env.messageCollector.report(CompilerMessageSeverity.LOGGING, message, CompilerMessageLocation.NO_LOCATION) - } - else { - reportUnexpected(category, severity, message, attachment) - } - } - else -> { - reportUnexpected(category, severity, message, attachment) - } - } - } - - private fun reportUnexpected(category: Int, severity: Int, message: String?, attachment: Serializable?) { - val compilerMessageSeverity = when (ReportSeverity.fromCode(severity)) { - ReportSeverity.ERROR -> CompilerMessageSeverity.ERROR - ReportSeverity.WARNING -> CompilerMessageSeverity.WARNING - ReportSeverity.INFO -> CompilerMessageSeverity.INFO - else -> CompilerMessageSeverity.LOGGING - } - - env.messageCollector.report(compilerMessageSeverity, - "Unexpected message: category=$category; severity=$severity; message='$message'; attachment=$attachment", - CompilerMessageLocation.NO_LOCATION) + env.messageCollector.reportFromDaemon( + { outFile, srcFiles -> env.outputItemsCollector.add(srcFiles, outFile) }, + category, severity, message, attachment) } } \ No newline at end of file