WIP daemon facade api, daemon client api
diff --git a/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/KotlinDaemonClient.kt b/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/KotlinDaemonClient.kt new file mode 100644 index 0000000..18f83a56 --- /dev/null +++ b/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/KotlinDaemonClient.kt
@@ -0,0 +1,86 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.daemon.client + +import org.jetbrains.kotlin.cli.common.ExitCode +import org.jetbrains.kotlin.daemon.common.CompilationOptions +import java.io.File + +typealias DaemonId = Int + +sealed class KotlinDaemonClient { + abstract fun compile(options: CompilationOptions, compilerArguments: List<String>/*, progressListener: ProgressListener?*/): ExitCode + + abstract fun getAvailableDaemons(): List<DaemonId> + + abstract fun getDaemonInfo(daemonId: DaemonId) + + abstract fun stopDaemon(daemonId: DaemonId) +} + +sealed interface KotlinDaemonClientProtocol<T : ProtocolSettings> { + object Rmi : KotlinDaemonClientProtocol<ProtocolSettings.RmiSettings> + object Http : KotlinDaemonClientProtocol<ProtocolSettings.HttpSettings> +} + +class DaemonSettings<T : ProtocolSettings>( + val compilerClasspath: List<File>, + val jvmArgs: List<String>, + val protocol: KotlinDaemonClientProtocol<T>, + val protocolSettings: T +) + +sealed interface ProtocolSettings { + class RmiSettings() : ProtocolSettings + class HttpSettings(/*host: String, port: Int*/) : ProtocolSettings +} + +// TODO: think more about this interface +internal class RmiKotlinDaemonClient(val daemonSettings: DaemonSettings<ProtocolSettings.RmiSettings>) : KotlinDaemonClient() { + override fun compile(options: CompilationOptions, compilerArguments: List<String>): ExitCode { + return ExitCode.OK + } + + override fun getAvailableDaemons(): List<DaemonId> { + TODO("Not yet implemented") + } + + override fun getDaemonInfo(daemonId: DaemonId) { + TODO("Not yet implemented") + } + + override fun stopDaemon(daemonId: DaemonId) { + TODO("Not yet implemented") + } +} + +internal class HttpKotlinDaemonClient(val daemonSettings: DaemonSettings<ProtocolSettings.HttpSettings>) : KotlinDaemonClient() { + override fun compile(options: CompilationOptions, compilerArguments: List<String>): ExitCode { + TODO("Not yet implemented") + } + + override fun getAvailableDaemons(): List<DaemonId> { + TODO("Not yet implemented") + } + + override fun getDaemonInfo(daemonId: DaemonId) { + TODO("Not yet implemented") + } + + override fun stopDaemon(daemonId: DaemonId) { + TODO("Not yet implemented") + } +} + +fun <T : ProtocolSettings> getKotlinDaemonClient(settings: DaemonSettings<T>) = when (settings.protocol) { + KotlinDaemonClientProtocol.Rmi -> RmiKotlinDaemonClient(settings as DaemonSettings<ProtocolSettings.RmiSettings>) + KotlinDaemonClientProtocol.Http -> HttpKotlinDaemonClient(settings as DaemonSettings<ProtocolSettings.HttpSettings>) +} \ No newline at end of file
diff --git a/compiler/daemon/daemon-facade/build.gradle.kts b/compiler/daemon/daemon-facade/build.gradle.kts new file mode 100644 index 0000000..04e82a8 --- /dev/null +++ b/compiler/daemon/daemon-facade/build.gradle.kts
@@ -0,0 +1,12 @@ +description = "Kotlin Daemon facade to unify running compilation via daemon, in-process, or out-of-process" + +plugins { + kotlin("jvm") +} + +dependencies { + // todo think about dependency configurations + implementation(project(":kotlin-daemon-client")) + implementation(project(":daemon-common")) + implementation(project(":compiler:cli")) +} \ No newline at end of file
diff --git a/compiler/daemon/daemon-facade/src/main/kotlin/org/jetbrains/kotlin/facade/CompilerDaemonFacade.kt b/compiler/daemon/daemon-facade/src/main/kotlin/org/jetbrains/kotlin/facade/CompilerDaemonFacade.kt new file mode 100644 index 0000000..b382209 --- /dev/null +++ b/compiler/daemon/daemon-facade/src/main/kotlin/org/jetbrains/kotlin/facade/CompilerDaemonFacade.kt
@@ -0,0 +1,55 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.facade + +import org.jetbrains.kotlin.cli.common.ExitCode +import org.jetbrains.kotlin.daemon.client.DaemonSettings +import org.jetbrains.kotlin.daemon.client.KotlinDaemonClient +import org.jetbrains.kotlin.daemon.client.ProtocolSettings +import org.jetbrains.kotlin.daemon.common.CompilationOptions +import org.jetbrains.kotlin.facade.internal.DefaultCompilerDaemonFacade +import java.io.File + +// TODO: think about progress reporting, metrics reporting, JPS integration problems? +interface CompilerDaemonFacade { + fun <T : ProtocolSettings> getDaemonClient( + settings: DaemonSettings<T> + ): KotlinDaemonClient + + // TODO: is this method needed? + /** + * Compile using Gradle daemon + */ + fun <T : ProtocolSettings> compileWithDaemon( + settings: DaemonSettings<T>, + options: CompilationOptions, + compilerArguments: List<String>, + ): ExitCode + + /** + * Compile invoking Kotlin compiler in the same process + */ + fun compileInProcess( + options: CompilationOptions, + compilerArguments: List<String>, + ): ExitCode + + /** + * Compile invoking Kotlin compiler in a separate process (each compilation runs inside separate process) + */ + fun compileOutOfProcess( + settings: OutOfProcessCompilationSettings, + options: CompilationOptions, + compilerArguments: List<String> + ): ExitCode +} + +class OutOfProcessCompilationSettings( + val compilerClasspath: List<File>, + val jvmArgs: List<String>, +) + +fun getCompilerDaemonFacade(): CompilerDaemonFacade = DefaultCompilerDaemonFacade() \ No newline at end of file
diff --git a/compiler/daemon/daemon-facade/src/main/kotlin/org/jetbrains/kotlin/facade/internal/DefaultCompilerDaemonFacade.kt b/compiler/daemon/daemon-facade/src/main/kotlin/org/jetbrains/kotlin/facade/internal/DefaultCompilerDaemonFacade.kt new file mode 100644 index 0000000..9268739 --- /dev/null +++ b/compiler/daemon/daemon-facade/src/main/kotlin/org/jetbrains/kotlin/facade/internal/DefaultCompilerDaemonFacade.kt
@@ -0,0 +1,39 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.facade.internal + +import org.jetbrains.kotlin.cli.common.ExitCode +import org.jetbrains.kotlin.daemon.client.DaemonSettings +import org.jetbrains.kotlin.daemon.client.KotlinDaemonClient +import org.jetbrains.kotlin.daemon.client.ProtocolSettings +import org.jetbrains.kotlin.daemon.common.CompilationOptions +import org.jetbrains.kotlin.facade.CompilerDaemonFacade +import org.jetbrains.kotlin.facade.OutOfProcessCompilationSettings + +internal class DefaultCompilerDaemonFacade : CompilerDaemonFacade { + override fun <T : ProtocolSettings> getDaemonClient(settings: DaemonSettings<T>): KotlinDaemonClient { + TODO("Not yet implemented") + } + + override fun <T : ProtocolSettings> compileWithDaemon( + settings: DaemonSettings<T>, + options: CompilationOptions, + compilerArguments: List<String> + ): ExitCode = getDaemonClient(settings).compile(options, compilerArguments) + + override fun compileInProcess(options: CompilationOptions, compilerArguments: List<String>): ExitCode { + TODO("Not yet implemented") + } + + override fun compileOutOfProcess( + settings: OutOfProcessCompilationSettings, + options: CompilationOptions, + compilerArguments: List<String> + ): ExitCode { + TODO("Not yet implemented") + } + +} \ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt index 5c82638..d5540ff1 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt
@@ -13,14 +13,16 @@ import org.jetbrains.kotlin.cli.common.messages.MessageCollector import org.jetbrains.kotlin.cli.common.toBooleanLenient import org.jetbrains.kotlin.config.Services +import org.jetbrains.kotlin.daemon.client.DaemonSettings +import org.jetbrains.kotlin.daemon.client.KotlinDaemonClientProtocol +import org.jetbrains.kotlin.daemon.client.ProtocolSettings +import org.jetbrains.kotlin.daemon.client.getKotlinDaemonClient import org.jetbrains.kotlin.daemon.common.* import org.jetbrains.kotlin.gradle.logging.* import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskExecutionResults import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskLoggers import org.jetbrains.kotlin.gradle.report.* -import org.jetbrains.kotlin.gradle.report.TaskExecutionInfo import org.jetbrains.kotlin.gradle.report.TaskExecutionProperties.ABI_SNAPSHOT -import org.jetbrains.kotlin.gradle.report.TaskExecutionResult import org.jetbrains.kotlin.gradle.tasks.KotlinCompilerExecutionStrategy import org.jetbrains.kotlin.gradle.tasks.cleanOutputsAndLocalState import org.jetbrains.kotlin.gradle.tasks.throwGradleExceptionIfError @@ -35,7 +37,6 @@ import java.util.concurrent.Callable import java.util.concurrent.Executors import javax.inject.Inject -import kotlin.collections.ArrayList internal class ProjectFilesForCompilation( val projectRootFile: File, @@ -176,6 +177,32 @@ } } + private fun compileWithDaemonNew(messageCollector: MessageCollector): ExitCode? { + val daemonClient = getKotlinDaemonClient( + DaemonSettings( + compilerClasspath = compilerFullClasspath, + jvmArgs = daemonJvmArgs ?: listOf(), + protocol = KotlinDaemonClientProtocol.Rmi, + protocolSettings = ProtocolSettings.RmiSettings() + ) + ) + val targetPlatform = when (compilerClassName) { + KotlinCompilerClass.JVM -> CompileService.TargetPlatform.JVM + KotlinCompilerClass.JS -> CompileService.TargetPlatform.JS + KotlinCompilerClass.METADATA -> CompileService.TargetPlatform.METADATA + else -> throw IllegalArgumentException("Unknown compiler type $compilerClassName") + } + val compilationOptions = CompilationOptions( + compilerMode = CompilerMode.NON_INCREMENTAL_COMPILER, + targetPlatform = targetPlatform, + reportCategories = reportCategories(isVerbose), + reportSeverity = reportSeverity(isVerbose), + requestedCompilationResults = emptyArray(), + kotlinScriptExtensions = kotlinScriptExtensions + ) + return daemonClient.compile(compilationOptions, compilerArgs.toList()) + } + private fun compileWithDaemon(messageCollector: MessageCollector): ExitCode? { val isDebugEnabled = log.isDebugEnabled || System.getProperty("kotlin.daemon.debug.log")?.toBoolean() ?: true val daemonMessageCollector =
diff --git a/settings.gradle b/settings.gradle index 5c2e5f3..22aef32 100644 --- a/settings.gradle +++ b/settings.gradle
@@ -101,6 +101,7 @@ ":kotlin-util-klib-metadata", ":daemon-common", ":daemon-common-new", + ":kotlin-daemon-facade", ":kotlin-daemon", ":kotlin-daemon-client", ":kotlin-daemon-client-new", @@ -585,6 +586,7 @@ project(':compiler:cli-js').projectDir = "$rootDir/compiler/cli/cli-js" as File project(':kotlin-runner').projectDir = "$rootDir/compiler/cli/cli-runner" as File project(':kotlin-daemon').projectDir = "$rootDir/compiler/daemon" as File +project(':kotlin-daemon-facade').projectDir = "$rootDir/compiler/daemon/daemon-facade" as File project(':daemon-common').projectDir = "$rootDir/compiler/daemon/daemon-common" as File project(':daemon-common-new').projectDir = "$rootDir/compiler/daemon/daemon-common-new" as File project(':kotlin-daemon-client').projectDir = "$rootDir/compiler/daemon/daemon-client" as File