From 6f59b6da8eeed6898e164e22546f78080b2d9188 Mon Sep 17 00:00:00 2001 From: Alexey Tsvetkov Date: Tue, 3 Apr 2018 21:09:29 +0300 Subject: [PATCH] Use daemon if available for parsing files in JPS --- .../kotlin/daemon/common/CompileService.kt | 7 +++ .../kotlin/daemon/CompileServiceImpl.kt | 10 ++++ .../compilerRunner/CompilerRunnerUtil.kt | 4 +- .../compilerRunner/JpsKotlinCompilerRunner.kt | 60 +++++++++++++------ .../kotlin/jps/build/KotlinBuilder.kt | 2 +- 5 files changed, 63 insertions(+), 20 deletions(-) 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 a3a4482840e..53df258a198 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 @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.daemon.common import org.jetbrains.kotlin.cli.common.repl.* +import org.jetbrains.kotlin.parsing.util.classesFqNames import java.io.File import java.io.Serializable import java.rmi.Remote @@ -140,6 +141,12 @@ interface CompileService : Remote { compilationResults: CompilationResults? ): CallResult + @Throws(RemoteException::class) + fun classesFqNamesByFiles( + sessionId: Int, + sourceFiles: Set + ): CallResult> + @Throws(RemoteException::class) fun clearJarCache() diff --git a/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt b/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt index 9f4854de86f..c872b7483a1 100644 --- a/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt +++ b/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt @@ -51,6 +51,7 @@ import org.jetbrains.kotlin.incremental.* import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents import org.jetbrains.kotlin.modules.Module +import org.jetbrains.kotlin.parsing.util.classesFqNames import org.jetbrains.kotlin.progress.CompilationCanceledStatus import java.io.BufferedOutputStream import java.io.ByteArrayOutputStream @@ -352,6 +353,15 @@ class CompileServiceImpl( } } + override fun classesFqNamesByFiles( + sessionId: Int, sourceFiles: Set + ): CompileService.CallResult> = + ifAlive { + withValidClientOrSessionProxy(sessionId) { + CompileService.CallResult.Good(classesFqNames(sourceFiles)) + } + } + override fun compile( sessionId: Int, compilerArguments: Array, diff --git a/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/CompilerRunnerUtil.kt b/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/CompilerRunnerUtil.kt index 8f04d76bc37..998f615ceff 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/CompilerRunnerUtil.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/CompilerRunnerUtil.kt @@ -101,8 +101,8 @@ object CompilerRunnerUtil { } fun invokeClassesFqNames( - files: Set, - environment: JpsCompilerEnvironment + environment: JpsCompilerEnvironment, + files: Set ): Set = withCompilerClassloader(environment) { classLoader -> val klass = Class.forName("org.jetbrains.kotlin.parsing.util.ParseFileUtilsKt", true, classLoader) val method = klass.getMethod("classesFqNames", Set::class.java) diff --git a/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsKotlinCompilerRunner.kt b/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsKotlinCompilerRunner.kt index d384a812b23..09d289f0d8b 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsKotlinCompilerRunner.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsKotlinCompilerRunner.kt @@ -72,6 +72,20 @@ class JpsKotlinCompilerRunner : KotlinCompilerRunner() { const val FAIL_ON_FALLBACK_PROPERTY = "test.kotlin.jps.compiler.runner.fail.on.fallback" } + fun classesFqNamesByFiles( + environment: JpsCompilerEnvironment, + files: Set + ): Set = withDaemonOrFallback( + withDaemon = { + doWithDaemon(environment) { sessionId, daemon -> + daemon.classesFqNamesByFiles(sessionId, files) + } + }, + fallback = { + CompilerRunnerUtil.invokeClassesFqNames(environment, files) + } + ) + fun runK2JvmCompiler( commonArguments: CommonCompilerArguments, k2jvmArguments: K2JVMCompilerArguments, @@ -122,12 +136,10 @@ class JpsKotlinCompilerRunner : KotlinCompilerRunner() { ): ExitCode { log.debug("Using kotlin-home = " + environment.kotlinPaths.homePath) - return if (isDaemonEnabled()) { - val daemonExitCode = compileWithDaemon(compilerClassName, compilerArgs, environment) - daemonExitCode ?: fallbackCompileStrategy(compilerArgs, compilerClassName, environment) - } else { - fallbackCompileStrategy(compilerArgs, compilerClassName, environment) - } + return withDaemonOrFallback( + withDaemon = { compileWithDaemon(compilerClassName, compilerArgs, environment) }, + fallback = { fallbackCompileStrategy(compilerArgs, compilerClassName, environment) } + ) } override fun compileWithDaemon( @@ -141,15 +153,6 @@ class JpsKotlinCompilerRunner : KotlinCompilerRunner() { K2METADATA_COMPILER -> CompileService.TargetPlatform.METADATA else -> throw IllegalArgumentException("Unknown compiler type $compilerClassName") } - - log.debug("Try to connect to daemon") - val connection = getDaemonConnection(environment) - if (connection == null) { - log.info("Could not connect to daemon") - return null - } - - val (daemon, sessionId) = connection val compilerMode = CompilerMode.JPS_COMPILER val verbose = compilerArgs.verbose val options = CompilationOptions( @@ -159,10 +162,33 @@ class JpsKotlinCompilerRunner : KotlinCompilerRunner() { reportSeverity(verbose), requestedCompilationResults = emptyArray() ) - val res = + return doWithDaemon(environment) { sessionId, daemon -> daemon.compile(sessionId, withAdditionalCompilerArgs(compilerArgs), options, JpsCompilerServicesFacadeImpl(environment), null) + }?.let { exitCodeFromProcessExitCode(it) } + } + + private fun withDaemonOrFallback(withDaemon: () -> T?, fallback: () -> T): T = + if (isDaemonEnabled()) { + withDaemon() ?: fallback() + } else { + fallback() + } + + private fun doWithDaemon( + environment: JpsCompilerEnvironment, + fn: (sessionId: Int, daemon: CompileService) -> CompileService.CallResult + ): T? { + log.debug("Try to connect to daemon") + val connection = getDaemonConnection(environment) + if (connection == null) { + log.info("Could not connect to daemon") + return null + } + + val (daemon, sessionId) = connection + val res = fn(sessionId, daemon) // TODO: consider implementing connection retry, instead of fallback here - return res.takeUnless { it is CompileService.CallResult.Dying }?.let { exitCodeFromProcessExitCode(it.get()) } + return res.takeUnless { it is CompileService.CallResult.Dying }?.get() } private fun withAdditionalCompilerArgs(compilerArgs: CommonCompilerArguments): Array { 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 2ba85aae5ac..a8c3179dec2 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt @@ -190,7 +190,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { val dirtyFiles = chunkDirtyFiles[target] val removedFiles = chunkRemovedFiles[target] ?: emptyList() - val existingClasses = CompilerRunnerUtil.invokeClassesFqNames(dirtyFiles.toHashSet(), environment) + val existingClasses = JpsKotlinCompilerRunner().classesFqNamesByFiles(environment, dirtyFiles.toHashSet()) val previousClasses = cache.classesBySources(dirtyFiles + removedFiles) for (jvmClassName in previousClasses) { val fqName = jvmClassName.fqNameForClassNameWithoutDollars.asString()