Client library for communicating with the Kotlin compilation daemon, enabling remote compilation services and incremental compilation workflows.
—
Server implementations for handling compiler callbacks, incremental compilation services, and communication with the daemon process. These facades provide RMI-based services that bridge between client and daemon processes.
Basic implementation of compiler services facade for handling compilation messages and results.
/**
* Basic compiler services facade server for message handling
* @param messageCollector Handles compiler messages and diagnostics
* @param outputsCollector Optional callback for tracking output files
* @param port RMI port for service communication
*/
class BasicCompilerServicesWithResultsFacadeServer(
val messageCollector: MessageCollector,
val outputsCollector: ((File, List<File>) -> Unit)? = null,
port: Int = SOCKET_ANY_FREE_PORT
) : CompilerServicesFacadeBase, UnicastRemoteObject(
port,
LoopbackNetworkInterface.clientLoopbackSocketFactory,
LoopbackNetworkInterface.serverLoopbackSocketFactory
)/**
* Report compilation messages from daemon to client
* @param category Message category (compiler, daemon, exception, etc.)
* @param severity Message severity level
* @param message Message text content
* @param attachment Optional message attachment (e.g., source location)
*/
override fun report(category: Int, severity: Int, message: String?, attachment: Serializable?)Usage Example:
import org.jetbrains.kotlin.daemon.client.BasicCompilerServicesWithResultsFacadeServer
import org.jetbrains.kotlin.cli.common.messages.PrintingMessageCollector
import java.io.File
val messageCollector = PrintingMessageCollector(System.out, null, false)
val outputsCollector = { outputFile: File, sourceFiles: List<File> ->
println("Generated: $outputFile")
println("From sources: ${sourceFiles.joinToString { it.name }}")
}
val servicesFacade = BasicCompilerServicesWithResultsFacadeServer(
messageCollector = messageCollector,
outputsCollector = outputsCollector,
port = 0 // Use any free port
)
// Use with compilation
val exitCode = KotlinCompilerClient.compile(
compilerService = compileService,
sessionId = sessionId,
targetPlatform = CompileService.TargetPlatform.JVM,
args = compilationArgs,
messageCollector = messageCollector,
outputsCollector = outputsCollector
)Comprehensive server implementation for compiler callback services supporting incremental compilation.
/**
* Compiler callback services facade server with incremental compilation support
* @param incrementalCompilationComponents Components for incremental compilation
* @param lookupTracker Tracks symbol lookups for incremental builds
* @param compilationCanceledStatus Allows checking compilation cancellation
* @param expectActualTracker Tracks expect/actual declarations
* @param inlineConstTracker Tracks inline constant usage
* @param enumWhenTracker Tracks enum when expression usage
* @param importTracker Tracks import usage
* @param incrementalResultsConsumer Consumes incremental compilation results
* @param incrementalDataProvider Provides incremental compilation data
* @param port RMI port for service communication
*/
class CompilerCallbackServicesFacadeServer(
val incrementalCompilationComponents: IncrementalCompilationComponents? = null,
val lookupTracker: LookupTracker? = null,
val compilationCanceledStatus: CompilationCanceledStatus? = null,
val expectActualTracker: ExpectActualTracker? = null,
val inlineConstTracker: InlineConstTracker? = null,
val enumWhenTracker: EnumWhenTracker? = null,
val importTracker: ImportTracker? = null,
val incrementalResultsConsumer: IncrementalResultsConsumer? = null,
val incrementalDataProvider: IncrementalDataProvider? = null,
port: Int = SOCKET_ANY_FREE_PORT
) : CompilerCallbackServicesFacade, UnicastRemoteObject(...)/**
* Check if incremental caches are available
* @return true if incremental compilation components are configured
*/
fun hasIncrementalCaches(): Boolean
/**
* Check if lookup tracker is available
* @return true if lookup tracker is configured
*/
fun hasLookupTracker(): Boolean
/**
* Check if compilation canceled status is available
* @return true if cancellation status checker is configured
*/
fun hasCompilationCanceledStatus(): Boolean
/**
* Check if expect/actual tracker is available
* @return true if expect/actual tracker is configured
*/
fun hasExpectActualTracker(): Boolean
/**
* Check if inline constant tracker is available
* @return true if inline constant tracker is configured
*/
fun hasInlineConstTracker(): Boolean
/**
* Check if enum when tracker is available
* @return true if enum when tracker is configured
*/
fun hasEnumWhenTracker(): Boolean
/**
* Check if import tracker is available
* @return true if import tracker is configured
*/
fun hasImportTracker(): Boolean
/**
* Check if incremental results consumer is available
* @return true if results consumer is configured
*/
fun hasIncrementalResultsConsumer(): Boolean
/**
* Check if incremental data provider is available
* @return true if data provider is configured
*/
fun hasIncrementalDataProvider(): Boolean/**
* Get obsolete package parts for incremental compilation
* @param target Target identifier for the compilation target
* @return Collection of obsolete package part names
*/
fun incrementalCache_getObsoletePackageParts(target: TargetId): Collection<String>
/**
* Get obsolete multifile class facades
* @param target Target identifier
* @return Collection of obsolete multifile class names
*/
fun incrementalCache_getObsoleteMultifileClassFacades(target: TargetId): Collection<String>
/**
* Get multifile facade parts
* @param target Target identifier
* @param internalName Internal name of the multifile facade
* @return Collection of facade part names or null
*/
fun incrementalCache_getMultifileFacadeParts(target: TargetId, internalName: String): Collection<String>?
/**
* Get package part data
* @param target Target identifier
* @param partInternalName Internal name of the package part
* @return Package part proto data or null
*/
fun incrementalCache_getPackagePartData(target: TargetId, partInternalName: String): JvmPackagePartProto?
/**
* Get module mapping data
* @param target Target identifier
* @return Module mapping data as byte array or null
*/
fun incrementalCache_getModuleMappingData(target: TargetId): ByteArray?
/**
* Get class file path
* @param target Target identifier
* @param internalClassName Internal class name
* @return Path to the class file
*/
fun incrementalCache_getClassFilePath(target: TargetId, internalClassName: String): String
/**
* Close incremental cache for target
* @param target Target identifier
*/
fun incrementalCache_close(target: TargetId)/**
* Check if lookup tracker requires position information
* @return true if position tracking is required
*/
fun lookupTracker_requiresPosition(): Boolean
/**
* Record lookup information for incremental compilation
* @param lookups Collection of lookup information to record
*/
fun lookupTracker_record(lookups: Collection<LookupInfo>)
/**
* Check if lookup tracker is a no-op implementation
* @return true if this is a do-nothing tracker
*/
fun lookupTracker_isDoNothing(): Boolean/**
* Check if compilation has been canceled
* @return null if not canceled, throws exception if canceled
*/
fun compilationCanceledStatus_checkCanceled(): Void?/**
* Report expect/actual declaration relationship
* @param expectedFilePath Path to expect declaration file
* @param actualFilePath Path to actual declaration file
*/
fun expectActualTracker_report(expectedFilePath: String, actualFilePath: String)
/**
* Report expect declaration of lenient stub
* @param expectedFilePath Path to expect declaration file
*/
fun expectActualTracker_reportExpectOfLenientStub(expectedFilePath: String)
/**
* Report inline constant usage
* @param filePath File path where constant is used
* @param owner Owner class of the constant
* @param name Constant name
* @param constType Constant type
*/
fun inlineConstTracker_report(filePath: String, owner: String, name: String, constType: String)
/**
* Report enum when expression usage
* @param whenUsageClassPath Class path where when is used
* @param enumClassFqName Fully qualified enum class name
*/
fun enumWhenTracker_report(whenUsageClassPath: String, enumClassFqName: String)
/**
* Report import usage
* @param filePath File path where import is used
* @param importedFqName Fully qualified name of imported symbol
*/
fun importTracker_report(filePath: String, importedFqName: String)Extension function for handling daemon messages.
/**
* Report message from daemon to message collector
* @param outputsCollector Optional outputs collector callback
* @param category Message category code
* @param severity Message severity code
* @param message Message text
* @param attachment Optional message attachment
*/
fun MessageCollector.reportFromDaemon(
outputsCollector: ((File, List<File>) -> Unit)?,
category: Int,
severity: Int,
message: String?,
attachment: Serializable?
)import org.jetbrains.kotlin.daemon.client.BasicCompilerServicesWithResultsFacadeServer
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
class MyMessageCollector : MessageCollector {
private val messages = mutableListOf<String>()
override fun report(
severity: CompilerMessageSeverity,
message: String,
location: CompilerMessageSourceLocation?
) {
val locationStr = location?.let { "${it.path}:${it.line}" } ?: ""
messages.add("$severity: $locationStr: $message")
println("$severity: $locationStr: $message")
}
override fun hasErrors(): Boolean =
messages.any { it.startsWith("ERROR") }
override fun clear() = messages.clear()
fun getAllMessages(): List<String> = messages.toList()
}
val messageCollector = MyMessageCollector()
val servicesFacade = BasicCompilerServicesWithResultsFacadeServer(
messageCollector = messageCollector,
outputsCollector = null
)
// Use in compilation...import org.jetbrains.kotlin.daemon.client.CompilerCallbackServicesFacadeServer
import org.jetbrains.kotlin.incremental.components.LookupTracker
class MyLookupTracker : LookupTracker {
private val lookups = mutableListOf<String>()
override val requiresPosition: Boolean = true
override fun record(
filePath: String,
position: Int,
scopeFqName: String,
scopeKind: ScopeKind,
name: String
) {
lookups.add("$filePath:$position -> $scopeFqName.$name")
println("Lookup: $filePath:$position -> $scopeFqName.$name")
}
fun getLookups(): List<String> = lookups.toList()
}
val lookupTracker = MyLookupTracker()
val incrementalComponents = MyIncrementalCompilationComponents()
val callbacksFacade = CompilerCallbackServicesFacadeServer(
incrementalCompilationComponents = incrementalComponents,
lookupTracker = lookupTracker,
compilationCanceledStatus = null
)
// Check service availability
if (callbacksFacade.hasLookupTracker()) {
println("Lookup tracking enabled")
}
if (callbacksFacade.hasIncrementalCaches()) {
println("Incremental compilation enabled")
}val messageCollector = PrintingMessageCollector(System.out, null, true)
val outputsCollector = { outputFile: File, sourceFiles: List<File> ->
println("Compiled ${sourceFiles.size} files to $outputFile")
}
val basicServices = BasicCompilerServicesWithResultsFacadeServer(
messageCollector = messageCollector,
outputsCollector = outputsCollector
)
val callbackServices = CompilerCallbackServicesFacadeServer(
incrementalCompilationComponents = myIncrementalComponents,
lookupTracker = myLookupTracker,
compilationCanceledStatus = myCancellationStatus
)
// Services are now ready for daemon compilation
val compilationResult = compileService.compile(
sessionId,
args,
compilationOptions,
basicServices,
callbackServices
)Install with Tessl CLI
npx tessl i tessl/maven-org-jetbrains-kotlin--kotlin-daemon-client