Kotlin Scripting Compiler extension providing code completion and static analysis for IDE integration
npx @tessl/cli install tessl/maven-org-jetbrains-kotlin--kotlin-scripting-ide-services@2.2.0Kotlin Scripting IDE Services is a compiler extension that provides intelligent code completion and static analysis capabilities for Kotlin scripting environments. It extends the Kotlin compiler with specialized functionality for interactive development environments, enabling features like intelligent code completion, static analysis, and error detection in Kotlin script files.
implementation("org.jetbrains.kotlin:kotlin-scripting-ide-services:2.2.0")import org.jetbrains.kotlin.scripting.ide_services.compiler.KJvmReplCompilerWithIdeServices
import org.jetbrains.kotlin.scripting.ide_services.compiler.ReplCompletionOptionsBuilder
import org.jetbrains.kotlin.scripting.ide_services.compiler.filterOutShadowedDescriptors
import org.jetbrains.kotlin.scripting.ide_services.compiler.nameFilter
import kotlin.script.experimental.api.*
import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfigurationimport org.jetbrains.kotlin.scripting.ide_services.compiler.KJvmReplCompilerWithIdeServices
import kotlin.script.experimental.api.*
import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration
// Create a REPL compiler with IDE services
val compiler = KJvmReplCompilerWithIdeServices(defaultJvmScriptingHostConfiguration)
// Prepare script code and cursor position
val sourceCode = """
val x = 10
val y = 20
x + y.
""".trimIndent()
val cursor = SourceCode.Position(2, 6) // After the dot
// Get code completions
val completionResult = compiler.complete(
sourceCode.toScriptSource(),
cursor,
ScriptCompilationConfiguration()
)
// Analyze code for errors and type information
val analysisResult = compiler.analyze(
sourceCode.toScriptSource(),
cursor,
ScriptCompilationConfiguration()
)Kotlin Scripting IDE Services is built around several key components:
scripting-ide-services-embeddable) that includes all dependencies for standalone usescripting-ide-services)scripting-ide-common)Main compiler class that provides both code completion and static analysis for Kotlin scripts in REPL environments. Supports embeddable usage and advanced completion configuration.
class KJvmReplCompilerWithIdeServices(
hostConfiguration: ScriptingHostConfiguration = defaultJvmScriptingHostConfiguration
) : ReplCompleter, ReplCodeAnalyzer
interface ReplCompleter {
suspend fun complete(
snippet: SourceCode,
cursor: SourceCode.Position,
configuration: ScriptCompilationConfiguration
): ResultWithDiagnostics<ReplCompletionResult>
}
interface ReplCodeAnalyzer {
suspend fun analyze(
snippet: SourceCode,
cursor: SourceCode.Position,
configuration: ScriptCompilationConfiguration
): ResultWithDiagnostics<ReplAnalyzerResult>
}Configuration system for customizing code completion behavior including shadowed descriptor filtering and name filtering options.
interface ReplCompletionOptionsKeys
open class ReplCompletionOptionsBuilder : PropertiesCollection.Builder(), ReplCompletionOptionsKeys
fun ReplCompletionOptionsBuilder.filterOutShadowedDescriptors(value: Boolean)
fun ReplCompletionOptionsBuilder.nameFilter(value: (String, String) -> Boolean)
val ReplCompletionOptionsKeys.filterOutShadowedDescriptors: Boolean
val ReplCompletionOptionsKeys.nameFilter: (String, String) -> BooleanCore resolution services providing symbol resolution, reference finding, and IDE-like analysis capabilities for Kotlin scripts.
interface ResolutionFacade {
val project: Project
val moduleDescriptor: ModuleDescriptor
fun analyzeWithAllCompilerChecks(
elements: Collection<KtElement>,
callback: DiagnosticSink.DiagnosticsCallback? = null
): AnalysisResult
}
class ReferenceVariantsHelper(
bindingContext: BindingContext,
resolutionFacade: ResolutionFacade,
moduleDescriptor: ModuleDescriptor,
visibilityFilter: (DeclarationDescriptor) -> Boolean
) {
fun getReferenceVariants(
expression: KtSimpleNameExpression,
kindFilter: DescriptorKindFilter,
nameFilter: (Name) -> Boolean
): Collection<DeclarationDescriptor>
}Advanced call context analysis for determining the type of call being made and appropriate completion suggestions.
sealed class CallType<TReceiver : KtElement?>
sealed class CallTypeAndReceiver<TReceiver : KtElement?, out TCallType : CallType<TReceiver>> {
companion object {
fun detect(expression: KtSimpleNameExpression): CallTypeAndReceiver<*, *>
}
}
data class ReceiverType(
val type: KotlinType,
val receiverIndex: Int,
val implicitValue: ReceiverValue?
)Various utility classes for filtering, type handling, and descriptor management in IDE contexts.
class ShadowedDeclarationsFilter(
bindingContext: BindingContext,
resolutionFacade: ResolutionFacade,
context: PsiElement,
explicitReceiverValue: ReceiverValue?
) {
fun <TDescriptor : DeclarationDescriptor> filter(
declarations: Collection<TDescriptor>
): Collection<TDescriptor>
}
class FuzzyType(
type: KotlinType,
freeParameters: Collection<TypeParameterDescriptor>
)
object IdeDescriptorRenderersScriptingtypealias ReplCompletionResult = Sequence<SourceCodeCompletionVariant>
class ReplAnalyzerResult(baseConfigurations: Iterable<ReplAnalyzerResult>, body: Builder.() -> Unit = {}) :
PropertiesCollection(Builder(baseConfigurations).apply(body).data) {
constructor(body: Builder.() -> Unit = {}) : this(emptyList(), body)
class Builder internal constructor(baseConfigurations: Iterable<ReplAnalyzerResult>) :
ReplAnalyzerResultKeys,
PropertiesCollection.Builder(baseConfigurations)
companion object : ReplAnalyzerResultKeys
}
interface ReplAnalyzerResultKeys
val ReplAnalyzerResultKeys.analysisDiagnostics: Sequence<ScriptDiagnostic>
val ReplAnalyzerResultKeys.renderedResultType: String?
data class SourceCodeCompletionVariant(
val text: String,
val displayText: String,
val tail: String,
val icon: String,
val deprecationLevel: DeprecationLevel? = null
)data class AnalyzeWithCursorResult(
val ktScript: KtFile,
val bindingContext: BindingContext,
val resolutionFacade: KotlinResolutionFacadeForRepl,
val moduleDescriptor: ModuleDescriptor,
val cursorAbs: Int,
val resultProperty: PropertyDescriptor?
)
interface ReplLineAnalysisResultWithStateless {
data class Stateless(
val bindingContext: BindingContext,
val resolutionFacade: KotlinResolutionFacadeForRepl,
val moduleDescriptor: ModuleDescriptor,
val resultProperty: PropertyDescriptor?
) : ReplLineAnalysisResultWithStateless
}interface PropertiesCollection {
interface Key<T>
abstract class Builder(baseConfigurations: Iterable<PropertiesCollection>) {
protected val data: MutableMap<Key<*>, Any?>
constructor() : this(emptyList())
operator fun <T> set(key: Key<T>, value: T)
operator fun <T> get(key: Key<T>): T?
}
}
interface ScriptingHostConfiguration : PropertiesCollection
interface ScriptCompilationConfiguration : PropertiesCollection
interface SourceCode {
val text: String
val name: String?
val locationId: String?
data class Position(val line: Int, val col: Int)
}
interface ResultWithDiagnostics<out T> {
val value: T?
val diagnostics: List<ScriptDiagnostic>
}