Use daemon if available for parsing files in JPS
This commit is contained in:
@@ -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<Int>
|
||||
|
||||
@Throws(RemoteException::class)
|
||||
fun classesFqNamesByFiles(
|
||||
sessionId: Int,
|
||||
sourceFiles: Set<File>
|
||||
): CallResult<Set<String>>
|
||||
|
||||
@Throws(RemoteException::class)
|
||||
fun clearJarCache()
|
||||
|
||||
|
||||
@@ -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<File>
|
||||
): CompileService.CallResult<Set<String>> =
|
||||
ifAlive {
|
||||
withValidClientOrSessionProxy(sessionId) {
|
||||
CompileService.CallResult.Good(classesFqNames(sourceFiles))
|
||||
}
|
||||
}
|
||||
|
||||
override fun compile(
|
||||
sessionId: Int,
|
||||
compilerArguments: Array<out String>,
|
||||
|
||||
@@ -101,8 +101,8 @@ object CompilerRunnerUtil {
|
||||
}
|
||||
|
||||
fun invokeClassesFqNames(
|
||||
files: Set<File>,
|
||||
environment: JpsCompilerEnvironment
|
||||
environment: JpsCompilerEnvironment,
|
||||
files: Set<File>
|
||||
): Set<String> = withCompilerClassloader(environment) { classLoader ->
|
||||
val klass = Class.forName("org.jetbrains.kotlin.parsing.util.ParseFileUtilsKt", true, classLoader)
|
||||
val method = klass.getMethod("classesFqNames", Set::class.java)
|
||||
|
||||
@@ -72,6 +72,20 @@ class JpsKotlinCompilerRunner : KotlinCompilerRunner<JpsCompilerEnvironment>() {
|
||||
const val FAIL_ON_FALLBACK_PROPERTY = "test.kotlin.jps.compiler.runner.fail.on.fallback"
|
||||
}
|
||||
|
||||
fun classesFqNamesByFiles(
|
||||
environment: JpsCompilerEnvironment,
|
||||
files: Set<File>
|
||||
): Set<String> = 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<JpsCompilerEnvironment>() {
|
||||
): 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<JpsCompilerEnvironment>() {
|
||||
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<JpsCompilerEnvironment>() {
|
||||
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 <T> withDaemonOrFallback(withDaemon: () -> T?, fallback: () -> T): T =
|
||||
if (isDaemonEnabled()) {
|
||||
withDaemon() ?: fallback()
|
||||
} else {
|
||||
fallback()
|
||||
}
|
||||
|
||||
private fun <T> doWithDaemon(
|
||||
environment: JpsCompilerEnvironment,
|
||||
fn: (sessionId: Int, daemon: CompileService) -> CompileService.CallResult<T>
|
||||
): 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<String> {
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user