diff --git a/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsCompilerServicesFacadeImpl.kt b/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsCompilerServicesFacadeImpl.kt new file mode 100644 index 00000000000..71b8337a3fc --- /dev/null +++ b/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsCompilerServicesFacadeImpl.kt @@ -0,0 +1,69 @@ +/* + * 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.compilerRunner + +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity +import org.jetbrains.kotlin.daemon.client.CompilerCallbackServicesFacadeServer +import org.jetbrains.kotlin.daemon.common.JpsCompilerServicesFacade +import org.jetbrains.kotlin.daemon.common.ReportCategory +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 + +internal class JpsCompilerServicesFacadeImpl( + private val env: JpsCompilerEnvironment, + port: Int = SOCKET_ANY_FREE_PORT +) : CompilerCallbackServicesFacadeServer(env.services.get(IncrementalCompilationComponents::class.java), + env.services.get(CompilationCanceledStatus::class.java), + port), + JpsCompilerServicesFacade { + + override fun report(category: ReportCategory, severity: Int, message: String?, attachment: Serializable?) { + when (category) { + ReportCategory.COMPILER_MESSAGE -> { + val compilerMessageSeverity = CompilerMessageSeverity.values().firstOrNull { it.value == severity } + if (compilerMessageSeverity != null) { + val location = attachment as? CompilerMessageLocation ?: CompilerMessageLocation.NO_LOCATION + env.messageCollector.report(compilerMessageSeverity, message!!, location) + } + else { + reportUnexpected(category, severity, message, attachment) + } + } + ReportCategory.DAEMON_MESSAGE, + ReportCategory.INCREMENTAL_COMPILATION -> { + 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: ReportCategory, severity: Int, message: String?, attachment: Serializable?) { + env.messageCollector.report(CompilerMessageSeverity.LOGGING, + "Unexpected message: category=$category; severity=$severity; message='$message'; attachment=$attachment", + CompilerMessageLocation.NO_LOCATION) + } +} \ No newline at end of file diff --git a/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsKotlinCompilerRunner.kt b/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsKotlinCompilerRunner.kt index 4cf0d271471..8ccff1964fa 100644 --- a/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsKotlinCompilerRunner.kt +++ b/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsKotlinCompilerRunner.kt @@ -19,23 +19,19 @@ package org.jetbrains.kotlin.compilerRunner import org.jetbrains.jps.api.GlobalOptions import org.jetbrains.kotlin.cli.common.ExitCode import org.jetbrains.kotlin.cli.common.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY -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.arguments.mergeBeans +import org.jetbrains.kotlin.cli.common.arguments.* 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.config.CompilerSettings -import org.jetbrains.kotlin.daemon.common.CompilerId -import org.jetbrains.kotlin.daemon.common.isDaemonEnabled +import org.jetbrains.kotlin.daemon.common.* import org.jetbrains.kotlin.jps.build.KotlinBuilder import java.io.ByteArrayOutputStream import java.io.File import java.io.PrintStream +import java.util.* class JpsKotlinCompilerRunner : KotlinCompilerRunner() { - override val log: KotlinLogger = JpsKotlinLogger(KotlinBuilder.LOG) + override val log: KotlinLogger = JpsKotlinLogger(KotlinBuilder.LOG) companion object { private @Volatile var jpsDaemonConnection: DaemonConnection? = null @@ -50,8 +46,10 @@ class JpsKotlinCompilerRunner : KotlinCompilerRunner() { ) { val arguments = mergeBeans(commonArguments, k2jvmArguments) setupK2JvmArguments(moduleFile, arguments) + val additionalArguments = compilerSettings.additionalArguments.split(" ").toTypedArray() + parseArguments(additionalArguments, arguments) - runCompiler(K2JVM_COMPILER, arguments, compilerSettings.additionalArguments, environment) + runCompiler(K2JVM_COMPILER, arguments, environment) } fun runK2JsCompiler( @@ -65,15 +63,22 @@ class JpsKotlinCompilerRunner : KotlinCompilerRunner() { ) { val arguments = mergeBeans(commonArguments, k2jsArguments) setupK2JsArguments(outputFile, sourceFiles, libraryFiles, arguments) + val additionalArguments = compilerSettings.additionalArguments.split(" ").toTypedArray() + parseArguments(additionalArguments, arguments) - runCompiler(K2JS_COMPILER, arguments, compilerSettings.additionalArguments, environment) + runCompiler(K2JS_COMPILER, arguments, environment) } - override fun doRunCompiler(compilerClassName: String, argsArray: Array, environment: JpsCompilerEnvironment): ExitCode { + override fun compileWithDaemonOrFallback( + compilerClassName: String, + compilerArgs: CommonCompilerArguments, + environment: JpsCompilerEnvironment + ): ExitCode { environment.messageCollector.report(CompilerMessageSeverity.INFO, "Using kotlin-home = " + environment.kotlinPaths.homePath, CompilerMessageLocation.NO_LOCATION) + val argsArray = ArgumentUtils.convertArgumentsToStringList(compilerArgs).toTypedArray() return if (isDaemonEnabled()) { - val daemonExitCode = compileWithDaemon(compilerClassName, argsArray, environment) + val daemonExitCode = compileWithDaemon(compilerClassName, compilerArgs, environment) daemonExitCode ?: fallbackCompileStrategy(argsArray, compilerClassName, environment) } else { @@ -81,6 +86,57 @@ class JpsKotlinCompilerRunner : KotlinCompilerRunner() { } } + override fun compileWithDaemon( + compilerClassName: String, + compilerArgs: CommonCompilerArguments, + environment: JpsCompilerEnvironment + ): ExitCode? { + val targetPlatform = when (compilerClassName) { + K2JVM_COMPILER -> CompileService.TargetPlatform.JVM + K2JS_COMPILER -> CompileService.TargetPlatform.JS + K2METADATA_COMPILER -> CompileService.TargetPlatform.METADATA + else -> throw IllegalArgumentException("Unknown compiler type $compilerClassName") + } + + val res = withDaemon(environment, retryOnConnectionError = true) { daemon, sessionId -> + daemon.compile( + sessionId, + CompileService.CompilerMode.JPS_COMPILER, + targetPlatform, + compilerArgs, + AdditionalCompilerArguments(reportingFilters = getReportingFilters(compilerArgs.verbose)), + JpsCompilerServicesFacadeImpl(environment), + operationsTracer = null) + } + + return res?.get()?.let { exitCodeFromProcessExitCode(it) } + } + + private fun getReportingFilters(verbose: Boolean): List { + val result = ArrayList() + + val compilerMessagesSeverities = ArrayList().apply { + add(CompilerMessageSeverity.ERROR.value) + add(CompilerMessageSeverity.EXCEPTION.value) + add(CompilerMessageSeverity.WARNING.value) + add(CompilerMessageSeverity.INFO.value) + add(CompilerMessageSeverity.OUTPUT.value) + + if (verbose) { + add(CompilerMessageSeverity.LOGGING.value) + } + } + + if (verbose) { + result.add(ReportingFilter(ReportCategory.DAEMON_MESSAGE, emptyList())) + } + + val compilerMessagesFilter = ReportingFilter(ReportCategory.COMPILER_MESSAGE, compilerMessagesSeverities) + result.add(compilerMessagesFilter) + + return result + } + private fun fallbackCompileStrategy( argsArray: Array, compilerClassName: String,