Use daemon if available for parsing files in JPS
This commit is contained in:
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.daemon.common
|
package org.jetbrains.kotlin.daemon.common
|
||||||
|
|
||||||
import org.jetbrains.kotlin.cli.common.repl.*
|
import org.jetbrains.kotlin.cli.common.repl.*
|
||||||
|
import org.jetbrains.kotlin.parsing.util.classesFqNames
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
import java.rmi.Remote
|
import java.rmi.Remote
|
||||||
@@ -140,6 +141,12 @@ interface CompileService : Remote {
|
|||||||
compilationResults: CompilationResults?
|
compilationResults: CompilationResults?
|
||||||
): CallResult<Int>
|
): CallResult<Int>
|
||||||
|
|
||||||
|
@Throws(RemoteException::class)
|
||||||
|
fun classesFqNamesByFiles(
|
||||||
|
sessionId: Int,
|
||||||
|
sourceFiles: Set<File>
|
||||||
|
): CallResult<Set<String>>
|
||||||
|
|
||||||
@Throws(RemoteException::class)
|
@Throws(RemoteException::class)
|
||||||
fun clearJarCache()
|
fun clearJarCache()
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ import org.jetbrains.kotlin.incremental.*
|
|||||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
|
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
|
||||||
import org.jetbrains.kotlin.modules.Module
|
import org.jetbrains.kotlin.modules.Module
|
||||||
|
import org.jetbrains.kotlin.parsing.util.classesFqNames
|
||||||
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
|
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
|
||||||
import java.io.BufferedOutputStream
|
import java.io.BufferedOutputStream
|
||||||
import java.io.ByteArrayOutputStream
|
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(
|
override fun compile(
|
||||||
sessionId: Int,
|
sessionId: Int,
|
||||||
compilerArguments: Array<out String>,
|
compilerArguments: Array<out String>,
|
||||||
|
|||||||
@@ -101,8 +101,8 @@ object CompilerRunnerUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun invokeClassesFqNames(
|
fun invokeClassesFqNames(
|
||||||
files: Set<File>,
|
environment: JpsCompilerEnvironment,
|
||||||
environment: JpsCompilerEnvironment
|
files: Set<File>
|
||||||
): Set<String> = withCompilerClassloader(environment) { classLoader ->
|
): Set<String> = withCompilerClassloader(environment) { classLoader ->
|
||||||
val klass = Class.forName("org.jetbrains.kotlin.parsing.util.ParseFileUtilsKt", true, classLoader)
|
val klass = Class.forName("org.jetbrains.kotlin.parsing.util.ParseFileUtilsKt", true, classLoader)
|
||||||
val method = klass.getMethod("classesFqNames", Set::class.java)
|
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"
|
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(
|
fun runK2JvmCompiler(
|
||||||
commonArguments: CommonCompilerArguments,
|
commonArguments: CommonCompilerArguments,
|
||||||
k2jvmArguments: K2JVMCompilerArguments,
|
k2jvmArguments: K2JVMCompilerArguments,
|
||||||
@@ -122,12 +136,10 @@ class JpsKotlinCompilerRunner : KotlinCompilerRunner<JpsCompilerEnvironment>() {
|
|||||||
): ExitCode {
|
): ExitCode {
|
||||||
log.debug("Using kotlin-home = " + environment.kotlinPaths.homePath)
|
log.debug("Using kotlin-home = " + environment.kotlinPaths.homePath)
|
||||||
|
|
||||||
return if (isDaemonEnabled()) {
|
return withDaemonOrFallback(
|
||||||
val daemonExitCode = compileWithDaemon(compilerClassName, compilerArgs, environment)
|
withDaemon = { compileWithDaemon(compilerClassName, compilerArgs, environment) },
|
||||||
daemonExitCode ?: fallbackCompileStrategy(compilerArgs, compilerClassName, environment)
|
fallback = { fallbackCompileStrategy(compilerArgs, compilerClassName, environment) }
|
||||||
} else {
|
)
|
||||||
fallbackCompileStrategy(compilerArgs, compilerClassName, environment)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun compileWithDaemon(
|
override fun compileWithDaemon(
|
||||||
@@ -141,15 +153,6 @@ class JpsKotlinCompilerRunner : KotlinCompilerRunner<JpsCompilerEnvironment>() {
|
|||||||
K2METADATA_COMPILER -> CompileService.TargetPlatform.METADATA
|
K2METADATA_COMPILER -> CompileService.TargetPlatform.METADATA
|
||||||
else -> throw IllegalArgumentException("Unknown compiler type $compilerClassName")
|
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 compilerMode = CompilerMode.JPS_COMPILER
|
||||||
val verbose = compilerArgs.verbose
|
val verbose = compilerArgs.verbose
|
||||||
val options = CompilationOptions(
|
val options = CompilationOptions(
|
||||||
@@ -159,10 +162,33 @@ class JpsKotlinCompilerRunner : KotlinCompilerRunner<JpsCompilerEnvironment>() {
|
|||||||
reportSeverity(verbose),
|
reportSeverity(verbose),
|
||||||
requestedCompilationResults = emptyArray()
|
requestedCompilationResults = emptyArray()
|
||||||
)
|
)
|
||||||
val res =
|
return doWithDaemon(environment) { sessionId, daemon ->
|
||||||
daemon.compile(sessionId, withAdditionalCompilerArgs(compilerArgs), options, JpsCompilerServicesFacadeImpl(environment), null)
|
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
|
// 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> {
|
private fun withAdditionalCompilerArgs(compilerArgs: CommonCompilerArguments): Array<String> {
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
|||||||
val dirtyFiles = chunkDirtyFiles[target]
|
val dirtyFiles = chunkDirtyFiles[target]
|
||||||
val removedFiles = chunkRemovedFiles[target] ?: emptyList()
|
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)
|
val previousClasses = cache.classesBySources(dirtyFiles + removedFiles)
|
||||||
for (jvmClassName in previousClasses) {
|
for (jvmClassName in previousClasses) {
|
||||||
val fqName = jvmClassName.fqNameForClassNameWithoutDollars.asString()
|
val fqName = jvmClassName.fqNameForClassNameWithoutDollars.asString()
|
||||||
|
|||||||
Reference in New Issue
Block a user