0
# REPL System
1
2
Specialized interfaces for interactive Read-Eval-Print Loop functionality with snippet management, code analysis, completion, and evaluation. Provides the foundation for building interactive Kotlin scripting environments.
3
4
## Capabilities
5
6
### ReplCompiler Interface
7
8
Specialized compiler interface for compiling individual REPL snippets with incremental compilation support.
9
10
```kotlin { .api }
11
/**
12
* Compiler interface specialized for REPL snippet compilation
13
*/
14
interface ReplCompiler<CompiledSnippetT : Any> {
15
/**
16
* Compile a REPL snippet
17
* @param snippet Source code snippet to compile
18
* @param configuration Compilation configuration for the snippet
19
* @return Result containing compiled snippet or compilation errors
20
*/
21
suspend fun compile(
22
snippet: SourceCode,
23
configuration: ScriptCompilationConfiguration
24
): ResultWithDiagnostics<CompiledSnippetT>
25
}
26
```
27
28
### ReplEvaluator Interface
29
30
Evaluator interface specialized for executing compiled REPL snippets with state management.
31
32
```kotlin { .api }
33
/**
34
* Evaluator interface specialized for REPL snippet evaluation
35
*/
36
interface ReplEvaluator<CompiledSnippetT : Any, EvaluatedSnippetT : Any> {
37
/**
38
* Evaluate a compiled REPL snippet
39
* @param snippet Compiled snippet to evaluate
40
* @param configuration Evaluation configuration
41
* @return Result containing evaluated snippet or evaluation errors
42
*/
43
suspend fun eval(
44
snippet: CompiledSnippetT,
45
configuration: ScriptEvaluationConfiguration
46
): ResultWithDiagnostics<EvaluatedSnippetT>
47
}
48
```
49
50
### EvaluatedSnippet Interface
51
52
Represents an evaluated REPL snippet with access to its compilation and evaluation state.
53
54
```kotlin { .api }
55
/**
56
* Represents an evaluated REPL snippet
57
*/
58
interface EvaluatedSnippet {
59
/** The compiled snippet that was evaluated */
60
val compiledSnippet: CompiledSnippet
61
/** Configuration used during evaluation */
62
val configuration: ScriptEvaluationConfiguration
63
/** Result of the evaluation */
64
val result: ResultValue
65
}
66
```
67
68
### REPL Snippet Identification
69
70
System for uniquely identifying REPL snippets with sequence numbers and generations.
71
72
```kotlin { .api }
73
/**
74
* Unique identifier for REPL snippets
75
*/
76
interface ReplSnippetId {
77
/** Sequence number of the snippet */
78
val no: Int
79
/** Generation number for versioning */
80
val generation: Int
81
}
82
83
/**
84
* Implementation of REPL snippet identifier
85
*/
86
data class ReplSnippetIdImpl(
87
override val no: Int,
88
override val generation: Int
89
) : ReplSnippetId
90
91
/**
92
* Constants for REPL snippet numbering
93
*/
94
const val REPL_SNIPPET_FIRST_NO = 1
95
const val REPL_SNIPPET_FIRST_GEN = 1
96
```
97
98
### Code Analysis and Completion
99
100
Interfaces for REPL code analysis and intelligent code completion.
101
102
```kotlin { .api }
103
/**
104
* Interface for analyzing REPL code
105
*/
106
interface ReplCodeAnalyzer {
107
/**
108
* Analyze REPL code snippet
109
* @param snippet Code snippet to analyze
110
* @param cursor Cursor position within the snippet
111
* @param configuration Analysis configuration
112
* @return Analysis results
113
*/
114
suspend fun analyze(
115
snippet: SourceCode,
116
cursor: SourceCode.Position,
117
configuration: ScriptCompilationConfiguration
118
): ResultWithDiagnostics<ReplAnalyzerResult>
119
}
120
121
/**
122
* Interface for providing code completion in REPL
123
*/
124
interface ReplCompleter {
125
/**
126
* Get code completion suggestions
127
* @param snippet Code snippet for completion
128
* @param cursor Cursor position for completion
129
* @param configuration Compilation configuration
130
* @return Sequence of completion variants
131
*/
132
suspend fun complete(
133
snippet: SourceCode,
134
cursor: SourceCode.Position,
135
configuration: ScriptCompilationConfiguration
136
): ResultWithDiagnostics<ReplCompletionResult>
137
}
138
```
139
140
### Code Completion Types
141
142
Data structures for representing code completion suggestions.
143
144
```kotlin { .api }
145
/**
146
* Type alias for completion results
147
*/
148
typealias ReplCompletionResult = Sequence<SourceCodeCompletionVariant>
149
150
/**
151
* Individual completion suggestion
152
*/
153
data class SourceCodeCompletionVariant(
154
val text: String,
155
val displayText: String,
156
val tail: String = "",
157
val icon: String = "",
158
val deprecationLevel: DeprecationLevel? = null
159
)
160
```
161
162
### REPL Configuration Keys
163
164
Specialized configuration keys for REPL compilation and host settings.
165
166
```kotlin { .api }
167
/**
168
* Configuration keys specific to REPL compilation
169
*/
170
interface ReplScriptCompilationConfigurationKeys {
171
val makeSnippetIdentifier: PropertiesCollection.Key<MakeSnippetIdentifier>
172
val snippetIdKey: PropertiesCollection.Key<String>
173
}
174
175
/**
176
* Configuration keys for REPL scripting host
177
*/
178
interface ReplScriptingHostConfigurationKeys {
179
val replCompiler: PropertiesCollection.Key<ReplCompiler<*>>
180
val replEvaluator: PropertiesCollection.Key<ReplEvaluator<*, *>>
181
val replCodeAnalyzer: PropertiesCollection.Key<ReplCodeAnalyzer>
182
val replCompleter: PropertiesCollection.Key<ReplCompleter>
183
}
184
185
/**
186
* Keys for REPL analyzer results
187
*/
188
interface ReplAnalyzerResultKeys {
189
val isComplete: PropertiesCollection.Key<Boolean>
190
val completions: PropertiesCollection.Key<ReplCompletionResult>
191
val diagnostics: PropertiesCollection.Key<List<ScriptDiagnostic>>
192
}
193
```
194
195
### Type Aliases
196
197
Convenient type aliases for REPL-related function types.
198
199
```kotlin { .api }
200
/**
201
* Type alias for compiled snippet (same as CompiledScript)
202
*/
203
typealias CompiledSnippet = CompiledScript
204
205
/**
206
* Function type for creating snippet identifiers
207
*/
208
typealias MakeSnippetIdentifier = (ReplSnippetId) -> String
209
```
210
211
### REPL Analysis Results
212
213
Container for REPL code analysis results.
214
215
```kotlin { .api }
216
/**
217
* Results of REPL code analysis
218
*/
219
class ReplAnalyzerResult : PropertiesCollection
220
```
221
222
**Usage Examples:**
223
224
```kotlin
225
import kotlin.script.experimental.api.*
226
227
// Basic REPL implementation example
228
class SimpleReplSystem {
229
private val compiler: ReplCompiler<CompiledSnippet> = TODO("Implementation")
230
private val evaluator: ReplEvaluator<CompiledSnippet, EvaluatedSnippet> = TODO("Implementation")
231
private val completer: ReplCompleter = TODO("Implementation")
232
233
private var snippetCounter = REPL_SNIPPET_FIRST_NO
234
private val evaluatedSnippets = mutableListOf<EvaluatedSnippet>()
235
236
suspend fun execute(code: String): ReplResult {
237
// Create snippet source
238
val snippet = code.toScriptSource("snippet_$snippetCounter")
239
240
// Compile the snippet
241
val compilationResult = compiler.compile(snippet, getCompilationConfig())
242
if (compilationResult is ResultWithDiagnostics.Failure) {
243
return ReplResult.CompilationError(compilationResult.reports)
244
}
245
246
val compiledSnippet = compilationResult.value
247
248
// Evaluate the snippet
249
val evaluationResult = evaluator.eval(compiledSnippet, getEvaluationConfig())
250
if (evaluationResult is ResultWithDiagnostics.Failure) {
251
return ReplResult.EvaluationError(evaluationResult.reports)
252
}
253
254
val evaluatedSnippet = evaluationResult.value
255
evaluatedSnippets.add(evaluatedSnippet)
256
snippetCounter++
257
258
return ReplResult.Success(evaluatedSnippet.result)
259
}
260
261
suspend fun complete(code: String, cursorPos: Int): List<String> {
262
val snippet = code.toScriptSource("completion")
263
val cursor = SourceCode.Position(1, cursorPos)
264
265
val completionResult = completer.complete(snippet, cursor, getCompilationConfig())
266
return if (completionResult is ResultWithDiagnostics.Success) {
267
completionResult.value.map { it.text }.toList()
268
} else {
269
emptyList()
270
}
271
}
272
}
273
274
sealed class ReplResult {
275
data class Success(val value: ResultValue) : ReplResult()
276
data class CompilationError(val diagnostics: List<ScriptDiagnostic>) : ReplResult()
277
data class EvaluationError(val diagnostics: List<ScriptDiagnostic>) : ReplResult()
278
}
279
```
280
281
### REPL Snippet Management
282
283
```kotlin
284
// Snippet identifier management
285
class SnippetIdManager {
286
private var currentNo = REPL_SNIPPET_FIRST_NO
287
private var currentGen = REPL_SNIPPET_FIRST_GEN
288
289
fun nextSnippetId(): ReplSnippetId {
290
return ReplSnippetIdImpl(currentNo++, currentGen)
291
}
292
293
fun resetGeneration() {
294
currentGen++
295
currentNo = REPL_SNIPPET_FIRST_NO
296
}
297
}
298
299
// Custom snippet identifier function
300
val customMakeSnippetIdentifier: MakeSnippetIdentifier = { snippetId ->
301
"Snippet_${snippetId.no}_Gen${snippetId.generation}"
302
}
303
304
// REPL compilation configuration
305
val replCompilationConfig = ScriptCompilationConfiguration {
306
makeSnippetIdentifier(customMakeSnippetIdentifier)
307
snippetIdKey("replSnippetId")
308
309
// Standard compilation settings
310
defaultImports("kotlin.math.*", "kotlin.collections.*")
311
dependencies.append(JvmDependency("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4"))
312
}
313
```
314
315
### Code Completion Implementation
316
317
```kotlin
318
// Custom completion provider
319
class CustomReplCompleter : ReplCompleter {
320
override suspend fun complete(
321
snippet: SourceCode,
322
cursor: SourceCode.Position,
323
configuration: ScriptCompilationConfiguration
324
): ResultWithDiagnostics<ReplCompletionResult> {
325
326
val text = snippet.text
327
val cursorPos = cursor.absolutePos ?: return emptySequence<SourceCodeCompletionVariant>().asSuccess()
328
329
// Simple keyword completion example
330
val completions = mutableListOf<SourceCodeCompletionVariant>()
331
332
// Get word at cursor
333
val wordStart = text.lastIndexOf(' ', cursorPos - 1) + 1
334
val prefix = text.substring(wordStart, cursorPos)
335
336
// Kotlin keywords that start with prefix
337
val keywords = listOf("fun", "val", "var", "if", "else", "when", "for", "while", "class", "interface")
338
keywords.filter { it.startsWith(prefix) }.forEach { keyword ->
339
completions.add(SourceCodeCompletionVariant(
340
text = keyword,
341
displayText = keyword,
342
tail = " (keyword)",
343
icon = "keyword"
344
))
345
}
346
347
return completions.asSequence().asSuccess()
348
}
349
}
350
```
351
352
### Interactive REPL Session
353
354
```kotlin
355
// Example REPL session flow
356
class InteractiveReplSession {
357
private val replSystem = SimpleReplSystem()
358
359
suspend fun runSession() {
360
println("Kotlin REPL - Enter ':quit' to exit")
361
362
while (true) {
363
print("kotlin> ")
364
val input = readLine() ?: break
365
366
when {
367
input == ":quit" -> break
368
input.startsWith(":complete ") -> {
369
val code = input.removePrefix(":complete ")
370
val completions = replSystem.complete(code, code.length)
371
println("Completions: ${completions.joinToString(", ")}")
372
}
373
else -> {
374
when (val result = replSystem.execute(input)) {
375
is ReplResult.Success -> {
376
when (val value = result.value) {
377
is ResultValue.Value -> println("res: ${value.value}")
378
is ResultValue.Unit -> println("kotlin> ")
379
is ResultValue.Error -> println("Error: ${value.error.message}")
380
is ResultValue.NotEvaluated -> println("Not evaluated")
381
}
382
}
383
is ReplResult.CompilationError -> {
384
result.diagnostics.forEach {
385
println("Compilation error: ${it.message}")
386
}
387
}
388
is ReplResult.EvaluationError -> {
389
result.diagnostics.forEach {
390
println("Evaluation error: ${it.message}")
391
}
392
}
393
}
394
}
395
}
396
}
397
}
398
}
399
```