From a47d5434f3865c4253fcbc540b6da477c8f0f30f 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 Original commit: 6f59b6da8eeed6898e164e22546f78080b2d9188 --- .../compilerRunner/CompilerRunnerUtil.kt | 4 +- .../compilerRunner/JpsKotlinCompilerRunner.kt | 60 +++++++++++++------ .../kotlin/jps/build/KotlinBuilder.kt | 2 +- 3 files changed, 46 insertions(+), 20 deletions(-) diff --git a/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/CompilerRunnerUtil.kt b/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/CompilerRunnerUtil.kt index 8f04d76bc37..998f615ceff 100644 --- a/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/CompilerRunnerUtil.kt +++ b/jps/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/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsKotlinCompilerRunner.kt b/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsKotlinCompilerRunner.kt index d384a812b23..09d289f0d8b 100644 --- a/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsKotlinCompilerRunner.kt +++ b/jps/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/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt index 2ba85aae5ac..a8c3179dec2 100644 --- a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt +++ b/jps/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()