Refactor daemon interface
This commit is contained in:
@@ -24,7 +24,7 @@ interface ICReporter {
|
||||
|
||||
// used in Gradle plugin
|
||||
@Suppress("unused")
|
||||
fun reportCompileIteration(sourceFiles: Iterable<File>, exitCode: ExitCode) {}
|
||||
fun reportCompileIteration(sourceFiles: Collection<File>, exitCode: ExitCode) {}
|
||||
|
||||
fun pathsAsString(files: Iterable<File>): String =
|
||||
files.map { it.canonicalPath }.joinToString()
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.common
|
||||
|
||||
import java.io.File
|
||||
import java.io.Serializable
|
||||
|
||||
open class AdditionalCompilerArguments(val reportingFilters: List<ReportingFilter>) : Serializable {
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 0
|
||||
}
|
||||
}
|
||||
|
||||
class IncrementalCompilerArguments(
|
||||
val areFileChangesKnown: Boolean,
|
||||
val modifiedFiles: List<File>?,
|
||||
val deletedFiles: List<File>?,
|
||||
val workingDir: File,
|
||||
val customCacheVersionFileName: String,
|
||||
val customCacheVersion: Int,
|
||||
reportingFilters: List<ReportingFilter>
|
||||
) : AdditionalCompilerArguments(reportingFilters) {
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 0
|
||||
}
|
||||
}
|
||||
+12
-5
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.daemon.common
|
||||
|
||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.repl.*
|
||||
import java.io.File
|
||||
import java.io.Serializable
|
||||
@@ -35,6 +36,11 @@ interface CompileService : Remote {
|
||||
METADATA
|
||||
}
|
||||
|
||||
enum class CompilerMode : Serializable {
|
||||
NON_INCREMENTAL_COMPILER,
|
||||
INCREMENTAL_COMPILER
|
||||
}
|
||||
|
||||
companion object {
|
||||
val NO_SESSION: Int = 0
|
||||
}
|
||||
@@ -127,12 +133,13 @@ interface CompileService : Remote {
|
||||
): CallResult<Int>
|
||||
|
||||
@Throws(RemoteException::class)
|
||||
fun serverSideJvmIC(
|
||||
fun compile(
|
||||
sessionId: Int,
|
||||
args: Array<out String>,
|
||||
servicesFacade: IncrementalCompilationServicesFacade,
|
||||
compilerOutputStream: RemoteOutputStream,
|
||||
serviceOutputStream: RemoteOutputStream,
|
||||
compilerMode: CompilerMode,
|
||||
targetPlatform: TargetPlatform,
|
||||
compilerArguments: CommonCompilerArguments,
|
||||
additionalCompilerArguments: AdditionalCompilerArguments,
|
||||
servicesFacade: CompilerServicesFacadeBase,
|
||||
operationsTracer: RemoteOperationsTracer?
|
||||
): CallResult<Int>
|
||||
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.common
|
||||
|
||||
import java.io.File
|
||||
import java.io.Serializable
|
||||
import java.rmi.Remote
|
||||
import java.rmi.RemoteException
|
||||
|
||||
interface CompilerServicesFacadeBase : Remote {
|
||||
/**
|
||||
* Reports different kind of diagnostic messages from compile daemon to compile daemon clients (jps, gradle, ...)
|
||||
*/
|
||||
@Throws(RemoteException::class)
|
||||
fun report(category: ReportCategory, severity: Int, message: String?, attachment: Serializable?)
|
||||
}
|
||||
|
||||
interface IncrementalCompilerServicesFacade : CompilerServicesFacadeBase {
|
||||
// AnnotationFileUpdater
|
||||
@Throws(RemoteException::class)
|
||||
fun hasAnnotationsFileUpdater(): Boolean
|
||||
|
||||
@Throws(RemoteException::class)
|
||||
fun updateAnnotations(outdatedClassesJvmNames: Iterable<String>)
|
||||
|
||||
@Throws(RemoteException::class)
|
||||
fun revert()
|
||||
|
||||
// ChangesRegistry
|
||||
@Throws(RemoteException::class)
|
||||
fun registerChanges(timestamp: Long, dirtyData: SimpleDirtyData)
|
||||
|
||||
@Throws(RemoteException::class)
|
||||
fun unknownChanges(timestamp: Long)
|
||||
|
||||
@Throws(RemoteException::class)
|
||||
fun getChanges(artifact: File, sinceTS: Long): Iterable<SimpleDirtyData>?
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.common
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
enum class ReportCategory : Serializable {
|
||||
/**
|
||||
* Messages from compiler
|
||||
* For related severities see [org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity]
|
||||
*/
|
||||
COMPILER_MESSAGE,
|
||||
/**
|
||||
* Messages from compile daemon
|
||||
* For related severities see [org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity]
|
||||
*/
|
||||
DAEMON_MESSAGE,
|
||||
/**
|
||||
* For related severities see [org.jetbrains.kotlin.daemon.incremental.IncrementalCompilationSeverity]
|
||||
*/
|
||||
INCREMENTAL_COMPILATION;
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 0
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.common
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* Allows daemon clients to specify report category and severities for that category that should be reported from daemon
|
||||
*/
|
||||
data class ReportingFilter(val category: ReportCategory, val severities: List<Int>) : Serializable {
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 0
|
||||
}
|
||||
}
|
||||
@@ -20,34 +20,36 @@ import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.openapi.vfs.impl.ZipHandler
|
||||
import com.intellij.openapi.vfs.impl.jar.CoreJarFileSystem
|
||||
import org.jetbrains.kotlin.annotation.AnnotationFileUpdater
|
||||
import org.jetbrains.kotlin.cli.common.CLICompiler
|
||||
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.K2MetadataCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.messages.*
|
||||
import org.jetbrains.kotlin.cli.common.modules.ModuleXmlParser
|
||||
import org.jetbrains.kotlin.cli.common.repl.ReplCheckResult
|
||||
import org.jetbrains.kotlin.cli.common.repl.ReplCodeLine
|
||||
import org.jetbrains.kotlin.cli.common.repl.ReplCompileResult
|
||||
import org.jetbrains.kotlin.cli.common.repl.ReplEvalResult
|
||||
import org.jetbrains.kotlin.cli.js.K2JSCompiler
|
||||
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.cli.metadata.K2MetadataCompiler
|
||||
import org.jetbrains.kotlin.config.IncrementalCompilation
|
||||
import org.jetbrains.kotlin.config.Services
|
||||
import org.jetbrains.kotlin.daemon.common.*
|
||||
import org.jetbrains.kotlin.daemon.incremental.*
|
||||
import org.jetbrains.kotlin.daemon.report.CompileServiceReporter
|
||||
import org.jetbrains.kotlin.daemon.report.CompileServiceReporterImpl
|
||||
import org.jetbrains.kotlin.daemon.report.CompileServiceReporterStreamAdapter
|
||||
import org.jetbrains.kotlin.daemon.report.CompileServicesFacadeMessageCollector
|
||||
import org.jetbrains.kotlin.incremental.*
|
||||
import org.jetbrains.kotlin.incremental.multiproject.ArtifactChangesProvider
|
||||
import org.jetbrains.kotlin.incremental.multiproject.ChangesRegistry
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
|
||||
import org.jetbrains.kotlin.modules.Module
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.check
|
||||
import java.io.BufferedOutputStream
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.File
|
||||
import java.io.PrintStream
|
||||
import java.rmi.NoSuchObjectException
|
||||
@@ -99,7 +101,6 @@ class CompileServiceImpl(
|
||||
val timer: Timer,
|
||||
val onShutdown: () -> Unit
|
||||
) : CompileService {
|
||||
|
||||
init {
|
||||
System.setProperty(KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY, "true")
|
||||
}
|
||||
@@ -320,63 +321,98 @@ class CompileServiceImpl(
|
||||
}
|
||||
}
|
||||
|
||||
override fun serverSideJvmIC(
|
||||
override fun compile(
|
||||
sessionId: Int,
|
||||
args: Array<out String>,
|
||||
servicesFacade: IncrementalCompilationServicesFacade,
|
||||
compilerOutputStream: RemoteOutputStream,
|
||||
serviceOutputStream: RemoteOutputStream,
|
||||
compilerMode: CompileService.CompilerMode,
|
||||
targetPlatform: CompileService.TargetPlatform,
|
||||
compilerArguments: CommonCompilerArguments,
|
||||
additionalCompilerArguments: AdditionalCompilerArguments,
|
||||
servicesFacade: CompilerServicesFacadeBase,
|
||||
operationsTracer: RemoteOperationsTracer?
|
||||
): CompileService.CallResult<Int> {
|
||||
return doCompile(sessionId, args, compilerOutputStream, serviceOutputStream, operationsTracer) { printStream, eventManager, profiler ->
|
||||
val reporter = RemoteICReporter(servicesFacade)
|
||||
val annotationFileUpdater = if (servicesFacade.hasAnnotationsFileUpdater()) RemoteAnnotationsFileUpdater(servicesFacade) else null
|
||||
val messageCollector = CompileServicesFacadeMessageCollector(servicesFacade, additionalCompilerArguments)
|
||||
val serviceReporter = CompileServiceReporterImpl(servicesFacade, additionalCompilerArguments)
|
||||
|
||||
// these flags do not have any effect on the compiler (only on caches, incremental compilation logic, jps plugin)
|
||||
// so it's OK to just set them true
|
||||
IncrementalCompilation.setIsEnabled(true)
|
||||
IncrementalCompilation.setIsExperimental(true)
|
||||
|
||||
val k2jvmArgs = K2JVMCompilerArguments()
|
||||
(compiler[CompileService.TargetPlatform.JVM] as K2JVMCompiler).parseArguments(args, k2jvmArgs)
|
||||
|
||||
val moduleFile = k2jvmArgs.module?.let(::File)
|
||||
assert(moduleFile?.exists() ?: false) { "Module does not exist ${k2jvmArgs.module}" }
|
||||
val renderer = MessageRenderer.XML
|
||||
val messageCollector = PrintingMessageCollector(printStream, renderer, k2jvmArgs.verbose)
|
||||
val filteringMessageCollector = FilteringMessageCollector(messageCollector) { it == CompilerMessageSeverity.ERROR }
|
||||
|
||||
val parsedModule = ModuleXmlParser.parseModuleScript(k2jvmArgs.module, filteringMessageCollector)
|
||||
val javaSourceRoots = parsedModule.modules.flatMapTo(HashSet()) { it.getJavaSourceRoots().map { File(it.path) } }
|
||||
val allKotlinFiles = parsedModule.modules.flatMap { it.getSourceFiles().map(::File) }
|
||||
k2jvmArgs.friendPaths = parsedModule.modules.flatMap(Module::getFriendPaths).toTypedArray()
|
||||
|
||||
val changedFiles = if (servicesFacade.areFileChangesKnown()) {
|
||||
ChangedFiles.Known(servicesFacade.modifiedFiles()!!, servicesFacade.deletedFiles()!!)
|
||||
}
|
||||
else {
|
||||
ChangedFiles.Unknown()
|
||||
return when (compilerMode) {
|
||||
CompileService.CompilerMode.NON_INCREMENTAL_COMPILER -> {
|
||||
doCompile(sessionId, serviceReporter, operationsTracer) { eventManger, profiler ->
|
||||
execCompiler(targetPlatform, Services.EMPTY, compilerArguments, messageCollector)
|
||||
}
|
||||
}
|
||||
CompileService.CompilerMode.INCREMENTAL_COMPILER -> {
|
||||
if (targetPlatform != CompileService.TargetPlatform.JVM) {
|
||||
throw IllegalStateException("Incremental compilation is not supported for target platform: $targetPlatform")
|
||||
}
|
||||
|
||||
val artifactChanges = RemoteArtifactChangesProvider(servicesFacade)
|
||||
val changesRegistry = RemoteChangesRegostry(servicesFacade)
|
||||
val k2jvmArgs = compilerArguments as K2JVMCompilerArguments
|
||||
val gradleIncrementalArgs = additionalCompilerArguments as IncrementalCompilerArguments
|
||||
val gradleIncrementalServicesFacade = servicesFacade as IncrementalCompilerServicesFacade
|
||||
|
||||
val workingDir = servicesFacade.workingDir()
|
||||
val versions = commonCacheVersions(workingDir) +
|
||||
customCacheVersion(servicesFacade.customCacheVersion(), servicesFacade.customCacheVersionFileName(), workingDir, forceEnable = true)
|
||||
withIC {
|
||||
doCompile(sessionId, serviceReporter, operationsTracer) { eventManger, profiler ->
|
||||
execIncrementalCompiler(k2jvmArgs, gradleIncrementalArgs, gradleIncrementalServicesFacade, messageCollector)
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
printStream.print(renderer.renderPreamble())
|
||||
IncrementalJvmCompilerRunner(workingDir, javaSourceRoots, versions, reporter, annotationFileUpdater,
|
||||
artifactChanges, changesRegistry)
|
||||
.compile(allKotlinFiles, k2jvmArgs, messageCollector, { changedFiles })
|
||||
}
|
||||
finally {
|
||||
printStream.print(renderer.renderConclusion())
|
||||
}
|
||||
else -> throw IllegalStateException("Unknown compilation mode $compilerMode")
|
||||
}
|
||||
}
|
||||
|
||||
private fun execCompiler(
|
||||
targetPlatform: CompileService.TargetPlatform,
|
||||
services: Services,
|
||||
args: CommonCompilerArguments,
|
||||
messageCollector: MessageCollector
|
||||
): ExitCode =
|
||||
when(targetPlatform) {
|
||||
CompileService.TargetPlatform.JVM -> {
|
||||
K2JVMCompiler().exec(messageCollector, services, args as K2JVMCompilerArguments)
|
||||
}
|
||||
CompileService.TargetPlatform.JS -> {
|
||||
K2JSCompiler().exec(messageCollector, services, args as K2JSCompilerArguments)
|
||||
}
|
||||
CompileService.TargetPlatform.METADATA -> {
|
||||
K2MetadataCompiler().exec(messageCollector, services, args as K2MetadataCompilerArguments)
|
||||
}
|
||||
}
|
||||
|
||||
private fun execIncrementalCompiler(
|
||||
k2jvmArgs: K2JVMCompilerArguments,
|
||||
incrementalCompilerArgs: IncrementalCompilerArguments,
|
||||
servicesFacade: IncrementalCompilerServicesFacade,
|
||||
messageCollector: CompileServicesFacadeMessageCollector
|
||||
): ExitCode {
|
||||
val reporter = RemoteICReporter(servicesFacade, incrementalCompilerArgs)
|
||||
val annotationFileUpdater = if (servicesFacade.hasAnnotationsFileUpdater()) RemoteAnnotationsFileUpdater(servicesFacade) else null
|
||||
|
||||
val moduleFile = k2jvmArgs.module?.let(::File)
|
||||
assert(moduleFile?.exists() ?: false) { "Module does not exist ${k2jvmArgs.module}" }
|
||||
|
||||
val temporaryMessageCollectorForModuleParsing = FilteringMessageCollector(messageCollector) { it != CompilerMessageSeverity.ERROR }
|
||||
val parsedModule = ModuleXmlParser.parseModuleScript(k2jvmArgs.module, temporaryMessageCollectorForModuleParsing)
|
||||
val javaSourceRoots = parsedModule.modules.flatMapTo(HashSet()) { it.getJavaSourceRoots().map { File(it.path) } }
|
||||
val allKotlinFiles = parsedModule.modules.flatMap { it.getSourceFiles().map(::File) }
|
||||
|
||||
val changedFiles = if (incrementalCompilerArgs.areFileChangesKnown) {
|
||||
ChangedFiles.Known(incrementalCompilerArgs.modifiedFiles!!, incrementalCompilerArgs.deletedFiles!!)
|
||||
}
|
||||
else {
|
||||
ChangedFiles.Unknown()
|
||||
}
|
||||
|
||||
val artifactChanges = RemoteArtifactChangesProvider(servicesFacade)
|
||||
val changesRegistry = RemoteChangesRegostry(servicesFacade)
|
||||
|
||||
val workingDir = incrementalCompilerArgs.workingDir
|
||||
val versions = commonCacheVersions(workingDir) +
|
||||
customCacheVersion(incrementalCompilerArgs.customCacheVersion, incrementalCompilerArgs.customCacheVersionFileName, workingDir, forceEnable = true)
|
||||
|
||||
return IncrementalJvmCompilerRunner(workingDir, javaSourceRoots, versions, reporter, annotationFileUpdater,
|
||||
artifactChanges, changesRegistry)
|
||||
.compile(allKotlinFiles, k2jvmArgs, messageCollector, { changedFiles })
|
||||
}
|
||||
|
||||
override fun leaseReplSession(
|
||||
aliveFlagPath: String?,
|
||||
targetPlatform: CompileService.TargetPlatform,
|
||||
@@ -599,6 +635,7 @@ class CompileServiceImpl(
|
||||
return res
|
||||
}
|
||||
|
||||
// todo: remove after remoteIncrementalCompile is removed
|
||||
private fun doCompile(sessionId: Int,
|
||||
args: Array<out String>,
|
||||
compilerMessagesStreamProxy: RemoteOutputStream,
|
||||
@@ -613,10 +650,14 @@ class CompileServiceImpl(
|
||||
val compilerMessagesStream = PrintStream(BufferedOutputStream(RemoteOutputStreamClient(compilerMessagesStreamProxy, rpcProfiler), REMOTE_STREAM_BUFFER_SIZE))
|
||||
val serviceOutputStream = PrintStream(BufferedOutputStream(RemoteOutputStreamClient(serviceOutputStreamProxy, rpcProfiler), REMOTE_STREAM_BUFFER_SIZE))
|
||||
try {
|
||||
CompileService.CallResult.Good(
|
||||
checkedCompile(args, serviceOutputStream, rpcProfiler) {
|
||||
body(compilerMessagesStream, eventManger, rpcProfiler).code
|
||||
})
|
||||
val compileServiceReporter = CompileServiceReporterStreamAdapter(serviceOutputStream)
|
||||
if (args.none())
|
||||
throw IllegalArgumentException("Error: empty arguments list.")
|
||||
log.info("Starting compilation with args: " + args.joinToString(" "))
|
||||
val exitCode = checkedCompile(compileServiceReporter, rpcProfiler) {
|
||||
body(compilerMessagesStream, eventManger, rpcProfiler).code
|
||||
}
|
||||
CompileService.CallResult.Good(exitCode)
|
||||
}
|
||||
finally {
|
||||
serviceOutputStream.flush()
|
||||
@@ -627,6 +668,28 @@ class CompileServiceImpl(
|
||||
}
|
||||
}
|
||||
|
||||
private fun doCompile(sessionId: Int,
|
||||
compileServiceReporter: CompileServiceReporter,
|
||||
operationsTracer: RemoteOperationsTracer?,
|
||||
body: (EventManger, Profiler) -> ExitCode): CompileService.CallResult<Int> =
|
||||
ifAlive {
|
||||
withValidClientOrSessionProxy(sessionId) { session ->
|
||||
operationsTracer?.before("compile")
|
||||
val rpcProfiler = if (daemonOptions.reportPerf) WallAndThreadTotalProfiler() else DummyProfiler()
|
||||
val eventManger = EventMangerImpl()
|
||||
try {
|
||||
val exitCode = checkedCompile(compileServiceReporter, rpcProfiler) {
|
||||
body(eventManger, rpcProfiler).code
|
||||
}
|
||||
CompileService.CallResult.Good(exitCode)
|
||||
}
|
||||
finally {
|
||||
eventManger.fireCompilationFinished()
|
||||
operationsTracer?.after("compile")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createCompileServices(facade: CompilerCallbackServicesFacade, eventManger: EventManger, rpcProfiler: Profiler): Services {
|
||||
val builder = Services.Builder()
|
||||
if (facade.hasIncrementalCaches() || facade.hasLookupTracker()) {
|
||||
@@ -639,12 +702,8 @@ class CompileServiceImpl(
|
||||
}
|
||||
|
||||
|
||||
private fun<R> checkedCompile(args: Array<out String>, serviceOut: PrintStream, rpcProfiler: Profiler, body: () -> R): R {
|
||||
private fun<R> checkedCompile(compileServiceReporter: CompileServiceReporter, rpcProfiler: Profiler, body: () -> R): R {
|
||||
try {
|
||||
if (args.none())
|
||||
throw IllegalArgumentException("Error: empty arguments list.")
|
||||
log.info("Starting compilation with args: " + args.joinToString(" "))
|
||||
|
||||
val profiler = if (daemonOptions.reportPerf) WallAndThreadAndMemoryTotalProfiler(withGC = false) else DummyProfiler()
|
||||
|
||||
val res = profiler.withMeasure(null, body)
|
||||
@@ -660,14 +719,14 @@ class CompileServiceImpl(
|
||||
val rpc = rpcProfiler.getTotalCounters()
|
||||
|
||||
"PERF: Compile on daemon: ${pc.time.ms()} ms; thread: user ${pc.threadUserTime.ms()} ms, sys ${(pc.threadTime - pc.threadUserTime).ms()} ms; rpc: ${rpc.count} calls, ${rpc.time.ms()} ms, thread ${rpc.threadTime.ms()} ms; memory: ${endMem.kb()} kb (${"%+d".format(pc.memory.kb())} kb)".let {
|
||||
serviceOut.println(it)
|
||||
compileServiceReporter.info(it)
|
||||
log.info(it)
|
||||
}
|
||||
|
||||
// this will only be reported if if appropriate (e.g. ByClass) profiler is used
|
||||
for ((obj, counters) in rpcProfiler.getCounters()) {
|
||||
"PERF: rpc by $obj: ${counters.count} calls, ${counters.time.ms()} ms, thread ${counters.threadTime.ms()} ms".let {
|
||||
serviceOut.println(it)
|
||||
compileServiceReporter.info(it)
|
||||
log.info(it)
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -18,12 +18,13 @@ package org.jetbrains.kotlin.daemon.incremental
|
||||
|
||||
import org.jetbrains.kotlin.annotation.AnnotationFileUpdater
|
||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||
import org.jetbrains.kotlin.daemon.common.IncrementalCompilerServicesFacade
|
||||
import org.jetbrains.kotlin.daemon.common.IncrementalCompilationServicesFacade
|
||||
import org.jetbrains.kotlin.incremental.ICReporter
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import java.io.File
|
||||
|
||||
internal class RemoteAnnotationsFileUpdater(private val servicesFacade: IncrementalCompilationServicesFacade) : AnnotationFileUpdater {
|
||||
internal class RemoteAnnotationsFileUpdater(private val servicesFacade: IncrementalCompilerServicesFacade) : AnnotationFileUpdater {
|
||||
override fun updateAnnotations(outdatedClasses: Iterable<JvmClassName>) {
|
||||
servicesFacade.updateAnnotations(outdatedClasses.map { it.internalName })
|
||||
}
|
||||
|
||||
+2
-2
@@ -16,12 +16,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.daemon.incremental
|
||||
|
||||
import org.jetbrains.kotlin.daemon.common.IncrementalCompilationServicesFacade
|
||||
import org.jetbrains.kotlin.daemon.common.IncrementalCompilerServicesFacade
|
||||
import org.jetbrains.kotlin.incremental.DirtyData
|
||||
import org.jetbrains.kotlin.incremental.multiproject.ArtifactChangesProvider
|
||||
import java.io.File
|
||||
|
||||
class RemoteArtifactChangesProvider(private val servicesFacade: IncrementalCompilationServicesFacade) : ArtifactChangesProvider {
|
||||
class RemoteArtifactChangesProvider(private val servicesFacade: IncrementalCompilerServicesFacade) : ArtifactChangesProvider {
|
||||
override fun getChanges(artifact: File, sinceTS: Long): Iterable<DirtyData>? =
|
||||
servicesFacade.getChanges(artifact, sinceTS)?.map { it.toDirtyData() }
|
||||
}
|
||||
|
||||
+2
-2
@@ -16,11 +16,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.daemon.incremental
|
||||
|
||||
import org.jetbrains.kotlin.daemon.common.IncrementalCompilationServicesFacade
|
||||
import org.jetbrains.kotlin.daemon.common.IncrementalCompilerServicesFacade
|
||||
import org.jetbrains.kotlin.incremental.DirtyData
|
||||
import org.jetbrains.kotlin.incremental.multiproject.ChangesRegistry
|
||||
|
||||
internal class RemoteChangesRegostry(private val servicesFacade: IncrementalCompilationServicesFacade) : ChangesRegistry {
|
||||
internal class RemoteChangesRegostry(private val servicesFacade: IncrementalCompilerServicesFacade) : ChangesRegistry {
|
||||
override fun unknownChanges(timestamp: Long) {
|
||||
servicesFacade.unknownChanges(timestamp)
|
||||
}
|
||||
|
||||
@@ -17,20 +17,37 @@
|
||||
package org.jetbrains.kotlin.daemon.incremental
|
||||
|
||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||
import org.jetbrains.kotlin.daemon.report.FilteringReporterBase
|
||||
import org.jetbrains.kotlin.daemon.common.CompilerServicesFacadeBase
|
||||
import org.jetbrains.kotlin.daemon.common.AdditionalCompilerArguments
|
||||
import org.jetbrains.kotlin.daemon.common.IncrementalCompilationServicesFacade
|
||||
import org.jetbrains.kotlin.daemon.common.ReportCategory
|
||||
import org.jetbrains.kotlin.daemon.incremental.IncrementalCompilationSeverity.COMPILED_FILES
|
||||
import org.jetbrains.kotlin.daemon.incremental.IncrementalCompilationSeverity.LOGGING
|
||||
import org.jetbrains.kotlin.incremental.ICReporter
|
||||
import java.io.File
|
||||
|
||||
internal class RemoteICReporter(private val servicesFacade: IncrementalCompilationServicesFacade) : ICReporter() {
|
||||
internal class RemoteICReporter(
|
||||
servicesFacade: CompilerServicesFacadeBase,
|
||||
additionalCompilerArgs: AdditionalCompilerArguments
|
||||
) : FilteringReporterBase(servicesFacade, additionalCompilerArgs, ReportCategory.INCREMENTAL_COMPILATION), ICReporter {
|
||||
override fun report(message: () -> String) {
|
||||
if (servicesFacade.shouldReportIC()) {
|
||||
servicesFacade.reportIC(message())
|
||||
if (shouldReport(LOGGING.value)) {
|
||||
report(LOGGING.value, message())
|
||||
}
|
||||
}
|
||||
|
||||
override fun reportCompileIteration(sourceFiles: Iterable<File>, exitCode: ExitCode) {
|
||||
if (servicesFacade.shouldReportIC()) {
|
||||
servicesFacade.reportCompileIteration(sourceFiles, exitCode.code)
|
||||
override fun reportCompileIteration(sourceFiles: Collection<File>, exitCode: ExitCode) {
|
||||
if (shouldReport(COMPILED_FILES.value)) {
|
||||
report(COMPILED_FILES.value, message = null, attachment = ArrayList(sourceFiles))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See [RemoteICReporter]
|
||||
*/
|
||||
enum class IncrementalCompilationSeverity(val value: Int) {
|
||||
COMPILED_FILES(0),
|
||||
LOGGING(10)
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.report
|
||||
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
import org.jetbrains.kotlin.daemon.common.AdditionalCompilerArguments
|
||||
import org.jetbrains.kotlin.daemon.common.CompilerServicesFacadeBase
|
||||
import org.jetbrains.kotlin.daemon.common.ReportCategory
|
||||
import org.jetbrains.kotlin.daemon.report.FilteringReporterBase
|
||||
import java.io.PrintStream
|
||||
|
||||
// For messages of about compile daemon
|
||||
internal interface CompileServiceReporter {
|
||||
fun info(message: String) {
|
||||
report(CompilerMessageSeverity.INFO, message)
|
||||
}
|
||||
|
||||
fun report(severity: CompilerMessageSeverity, message: String)
|
||||
}
|
||||
|
||||
internal class CompileServiceReporterStreamAdapter(private val out: PrintStream) : CompileServiceReporter {
|
||||
override fun report(severity: CompilerMessageSeverity, message: String) {
|
||||
out.print("[Kotlin daemon][$severity] $message")
|
||||
}
|
||||
}
|
||||
|
||||
internal class CompileServiceReporterImpl(
|
||||
servicesFacade: CompilerServicesFacadeBase,
|
||||
additionalCompilerArguments: AdditionalCompilerArguments
|
||||
) : FilteringReporterBase(servicesFacade, additionalCompilerArguments, ReportCategory.DAEMON_MESSAGE), CompileServiceReporter {
|
||||
|
||||
override fun report(severity: CompilerMessageSeverity, message: String) {
|
||||
report(severity.value, message)
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.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.daemon.common.AdditionalCompilerArguments
|
||||
import org.jetbrains.kotlin.daemon.common.CompilerServicesFacadeBase
|
||||
import org.jetbrains.kotlin.daemon.common.ReportCategory
|
||||
|
||||
internal class CompileServicesFacadeMessageCollector(
|
||||
private val servicesFacade: CompilerServicesFacadeBase,
|
||||
additionalCompilerArguments: AdditionalCompilerArguments
|
||||
) : MessageCollector {
|
||||
private var hasErrors = false
|
||||
private val reportingFilter = additionalCompilerArguments.reportingFilters.firstOrNull { it.category == ReportCategory.DAEMON_MESSAGE }
|
||||
|
||||
override fun clear() {
|
||||
hasErrors = false
|
||||
}
|
||||
|
||||
override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation) {
|
||||
if (reportingFilter != null && severity.value !in reportingFilter.severities) return
|
||||
|
||||
hasErrors = hasErrors || severity == CompilerMessageSeverity.ERROR
|
||||
servicesFacade.report(ReportCategory.DAEMON_MESSAGE, severity.value, message, location)
|
||||
}
|
||||
|
||||
override fun hasErrors(): Boolean = hasErrors
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.report
|
||||
|
||||
import org.jetbrains.kotlin.daemon.common.AdditionalCompilerArguments
|
||||
import org.jetbrains.kotlin.daemon.common.CompilerServicesFacadeBase
|
||||
import org.jetbrains.kotlin.daemon.common.ReportCategory
|
||||
import java.io.Serializable
|
||||
|
||||
internal open class FilteringReporterBase(
|
||||
private val servicesFacade: CompilerServicesFacadeBase,
|
||||
additionalCompilerArgs: AdditionalCompilerArguments,
|
||||
private val reportCategory: ReportCategory
|
||||
) {
|
||||
private val reportingFilter = additionalCompilerArgs.reportingFilters.firstOrNull { it.category == reportCategory }
|
||||
|
||||
protected fun report(severity: Int, message: String?, attachment: Serializable? = null) {
|
||||
if (shouldReport(severity)) {
|
||||
servicesFacade.report(reportCategory, severity, message, attachment)
|
||||
}
|
||||
}
|
||||
|
||||
protected fun shouldReport(severity: Int): Boolean =
|
||||
reportingFilter == null || severity in reportingFilter.severities
|
||||
}
|
||||
+2
-2
@@ -71,14 +71,14 @@ private object EmptyICReporter : ICReporter {
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun withIC(fn: ()->Unit) {
|
||||
inline fun <R> withIC(fn: ()->R): R {
|
||||
val isEnabledBackup = IncrementalCompilation.isEnabled()
|
||||
val isExperimentalBackup = IncrementalCompilation.isExperimental()
|
||||
IncrementalCompilation.setIsEnabled(true)
|
||||
IncrementalCompilation.setIsExperimental(true)
|
||||
|
||||
try {
|
||||
fn()
|
||||
return fn()
|
||||
}
|
||||
finally {
|
||||
IncrementalCompilation.setIsEnabled(isEnabledBackup)
|
||||
|
||||
+1
-1
@@ -128,7 +128,7 @@ class KotlinStandaloneIncrementalCompilationTest : TestWithWorkingDir() {
|
||||
override fun report(message: ()->String) {
|
||||
}
|
||||
|
||||
override fun reportCompileIteration(sourceFiles: Iterable<File>, exitCode: ExitCode) {
|
||||
override fun reportCompileIteration(sourceFiles: Collection<File>, exitCode: ExitCode) {
|
||||
compiledSources.addAll(sourceFiles)
|
||||
resultExitCode = exitCode
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user