0
# Environment Management
1
2
Comprehensive environment management for Kotlin compilation projects including dependency resolution, file system setup, project configuration, and IntelliJ platform integration. The environment system provides isolation and proper resource management for compilation tasks.
3
4
## Capabilities
5
6
### KotlinCoreEnvironment
7
8
Central environment management providing project setup, dependency resolution, and resource lifecycle management.
9
10
```kotlin { .api }
11
/**
12
* Central environment for Kotlin compilation
13
* Manages project setup, dependencies, and IntelliJ platform integration
14
*/
15
class KotlinCoreEnvironment private constructor() {
16
/** IntelliJ project instance */
17
val project: Project
18
19
/** Compiler configuration */
20
val configuration: CompilerConfiguration
21
22
/** Source files in the project */
23
val getSourceFiles: List<KtFile>
24
25
companion object {
26
/**
27
* Create environment for production compilation
28
*
29
* @param parentDisposable Parent disposable for resource cleanup
30
* @param configuration Compiler configuration
31
* @param configFiles Environment configuration files
32
* @return Configured compilation environment
33
*/
34
fun createForProduction(
35
parentDisposable: Disposable,
36
configuration: CompilerConfiguration,
37
configFiles: EnvironmentConfigFiles
38
): KotlinCoreEnvironment
39
40
/**
41
* Create environment for tests
42
*
43
* @param parentDisposable Parent disposable for resource cleanup
44
* @param configuration Compiler configuration
45
* @param extensionRegistrars Additional extension registrars
46
* @param configFiles Environment configuration files
47
* @return Test compilation environment
48
*/
49
fun createForTests(
50
parentDisposable: Disposable,
51
configuration: CompilerConfiguration,
52
extensionRegistrars: List<EnvironmentExtension>,
53
configFiles: EnvironmentConfigFiles
54
): KotlinCoreEnvironment
55
56
/**
57
* Get or create application environment
58
*
59
* @param parentDisposable Parent disposable
60
* @param configuration Compiler configuration
61
* @return Application environment instance
62
*/
63
fun getOrCreateApplicationEnvironmentForProduction(
64
parentDisposable: Disposable,
65
configuration: CompilerConfiguration
66
): ApplicationEnvironment
67
}
68
69
/**
70
* Create package part provider for dependencies
71
*
72
* @param scope Global search scope
73
* @return Package part provider instance
74
*/
75
fun createPackagePartProvider(scope: GlobalSearchScope): PackagePartProvider
76
77
/**
78
* Project environment for managing project-level resources
79
*/
80
class ProjectEnvironment(
81
val parentDisposable: Disposable,
82
val applicationEnvironment: ApplicationEnvironment,
83
val configuration: CompilerConfiguration
84
) {
85
val project: MockProject
86
87
/**
88
* Register project extensions
89
*
90
* @param extensions Extensions to register
91
*/
92
fun registerExtensions(extensions: List<EnvironmentExtension>)
93
}
94
}
95
```
96
97
### Environment Configuration Files
98
99
Platform and target-specific environment configuration file sets.
100
101
```kotlin { .api }
102
/**
103
* Configuration files for different compilation targets
104
* Defines which IntelliJ platform components to load
105
*/
106
enum class EnvironmentConfigFiles(
107
private val configFiles: List<String>
108
) {
109
/** JVM compilation configuration */
110
JVM_CONFIG_FILES(listOf(
111
"intellij.platform.resources.xml",
112
"intellij.java.xml",
113
"intellij.kotlin.xml"
114
)),
115
116
/** JavaScript compilation configuration */
117
JS_CONFIG_FILES(listOf(
118
"intellij.platform.resources.xml",
119
"intellij.javascript.xml",
120
"intellij.kotlin.xml"
121
)),
122
123
/** Metadata-only compilation configuration */
124
METADATA_CONFIG_FILES(listOf(
125
"intellij.platform.resources.xml",
126
"intellij.kotlin.xml"
127
)),
128
129
/** Native compilation configuration */
130
NATIVE_CONFIG_FILES(listOf(
131
"intellij.platform.resources.xml",
132
"intellij.kotlin.xml",
133
"intellij.kotlin.native.xml"
134
));
135
136
/**
137
* Get configuration file paths
138
*
139
* @return List of configuration file paths
140
*/
141
fun getConfigFiles(): List<String> = configFiles
142
}
143
```
144
145
### Kotlin Paths
146
147
Kotlin installation and library path management.
148
149
```kotlin { .api }
150
/**
151
* Kotlin installation paths and library locations
152
* Provides access to standard library and compiler jars
153
*/
154
interface KotlinPaths {
155
/** Kotlin installation home directory */
156
val homePath: File
157
158
/** Kotlin standard library JAR */
159
val stdlibPath: File
160
161
/** Kotlin script runtime JAR */
162
val scriptRuntimePath: File
163
164
/** Kotlin reflect library JAR */
165
val reflectPath: File
166
167
/** Kotlin test library JAR */
168
val kotlinTestPath: File
169
170
/** Kotlin stdlib sources JAR */
171
val stdlibSourcesPath: File
172
173
/** All runtime JARs */
174
val runtimeJars: List<File>
175
176
/** Compiler JAR */
177
val compilerPath: File
178
179
/** JS standard library */
180
val jsStdLibJarPath: File
181
182
/** JS Kotlin test library */
183
val jsKotlinTestJarPath: File
184
185
/** All JS library JARs */
186
val jsLibJars: List<File>
187
}
188
189
/**
190
* Path utilities for Kotlin installation detection
191
*/
192
object PathUtil {
193
/**
194
* Get Kotlin paths from compiler JAR
195
*
196
* @param compilerJar Compiler JAR file
197
* @return Kotlin paths instance
198
*/
199
fun getKotlinPathsForCompiler(compilerJar: File): KotlinPaths
200
201
/**
202
* Get Kotlin paths from distribution
203
*
204
* @param kotlinHome Kotlin home directory
205
* @return Kotlin paths instance
206
*/
207
fun getKotlinPathsForDistribution(kotlinHome: File): KotlinPaths
208
209
/**
210
* Get Kotlin paths for IDE plugin
211
*
212
* @param ideaPluginPath IDE plugin path
213
* @return Kotlin paths instance
214
*/
215
fun getKotlinPathsForIdeaPlugin(ideaPluginPath: File): KotlinPaths
216
217
/**
218
* Get JDK classpath roots
219
*
220
* @param jdkHome JDK home directory
221
* @return List of JDK JAR files
222
*/
223
fun getJdkClasspathRoots(jdkHome: File): List<File>
224
}
225
```
226
227
### Content Roots
228
229
Source file and library content root management.
230
231
```kotlin { .api }
232
/**
233
* Base class for content roots (source directories, libraries)
234
*/
235
abstract class ContentRoot {
236
/** Content root file */
237
abstract val file: File
238
}
239
240
/**
241
* Source directory content root
242
*/
243
class KotlinSourceRoot(
244
override val file: File,
245
val isCommon: Boolean = false,
246
val packagePrefix: String? = null
247
) : ContentRoot()
248
249
/**
250
* Java source directory content root
251
*/
252
class JavaSourceRoot(
253
override val file: File,
254
val packagePrefix: String? = null
255
) : ContentRoot()
256
257
/**
258
* JAR or directory library content root
259
*/
260
class JvmClasspathRoot(
261
override val file: File
262
) : ContentRoot()
263
264
/**
265
* JavaScript library content root
266
*/
267
class JsLibrarySourceRoot(
268
override val file: File
269
) : ContentRoot()
270
```
271
272
### Module Management
273
274
Compilation module and dependency management.
275
276
```kotlin { .api }
277
/**
278
* Compilation module definition
279
*/
280
class Module(
281
val moduleName: String,
282
val outputDirectory: File,
283
val sources: List<File>,
284
val classpath: List<File>,
285
val friends: List<File> = emptyList()
286
) {
287
/**
288
* Get module identifier
289
*
290
* @return Module identifier string
291
*/
292
fun getModuleId(): String = moduleName
293
}
294
295
/**
296
* Module builder for configuring compilation modules
297
*/
298
class ModuleBuilder(private val moduleName: String) {
299
private val sources = mutableListOf<File>()
300
private val classpath = mutableListOf<File>()
301
private var outputDirectory: File? = null
302
303
/**
304
* Add source file or directory
305
*
306
* @param source Source file or directory
307
* @return Builder for chaining
308
*/
309
fun addSourceFiles(vararg source: File): ModuleBuilder {
310
sources.addAll(source)
311
return this
312
}
313
314
/**
315
* Add classpath entry
316
*
317
* @param cp Classpath file (JAR or directory)
318
* @return Builder for chaining
319
*/
320
fun addClasspathEntry(cp: File): ModuleBuilder {
321
classpath.add(cp)
322
return this
323
}
324
325
/**
326
* Set output directory
327
*
328
* @param output Output directory
329
* @return Builder for chaining
330
*/
331
fun setOutputDirectory(output: File): ModuleBuilder {
332
outputDirectory = output
333
return this
334
}
335
336
/**
337
* Build module instance
338
*
339
* @return Configured module
340
*/
341
fun build(): Module {
342
return Module(
343
moduleName = moduleName,
344
outputDirectory = outputDirectory ?: File("build"),
345
sources = sources.toList(),
346
classpath = classpath.toList()
347
)
348
}
349
}
350
351
/**
352
* Module chunk for batch compilation
353
*/
354
class ModuleChunk(val modules: List<Module>) {
355
/**
356
* Get all source files in chunk
357
*
358
* @return All source files across modules
359
*/
360
fun getSourceFiles(): List<File> {
361
return modules.flatMap { it.sources }
362
}
363
364
/**
365
* Get combined classpath
366
*
367
* @return Combined classpath from all modules
368
*/
369
fun getClasspath(): List<File> {
370
return modules.flatMap { it.classpath }.distinct()
371
}
372
}
373
```
374
375
### Environment Extensions
376
377
Extension mechanism for customizing environment setup.
378
379
```kotlin { .api }
380
/**
381
* Environment extension for customizing compilation environment
382
*/
383
interface EnvironmentExtension {
384
/**
385
* Register extension components
386
*
387
* @param project Project instance
388
* @param configuration Compiler configuration
389
*/
390
fun registerProjectExtensions(
391
project: MockProject,
392
configuration: CompilerConfiguration
393
)
394
}
395
396
/**
397
* Extension registrar for grouping related extensions
398
*/
399
interface EnvironmentExtensionRegistrar {
400
/**
401
* Get extensions to register
402
*
403
* @return List of environment extensions
404
*/
405
fun getExtensions(): List<EnvironmentExtension>
406
}
407
```
408
409
### Project File Management
410
411
Source file discovery and virtual file system management.
412
413
```kotlin { .api }
414
/**
415
* Kotlin source file representation
416
*/
417
abstract class KtFile : KtElement {
418
/** Virtual file backing this source file */
419
val virtualFile: VirtualFile
420
421
/** Package directive */
422
val packageDirective: KtPackageDirective?
423
424
/** Import directives */
425
val importDirectives: List<KtImportDirective>
426
427
/** Top-level declarations */
428
val declarations: List<KtDeclaration>
429
430
/** File annotation list */
431
val fileAnnotationList: KtFileAnnotationList?
432
433
/**
434
* Check if file is script
435
*
436
* @return true if file is Kotlin script (.kts)
437
*/
438
fun isScript(): Boolean
439
}
440
441
/**
442
* Virtual file system utilities
443
*/
444
object VfsUtil {
445
/**
446
* Find files by extension
447
*
448
* @param root Root directory
449
* @param extension File extension (without dot)
450
* @return List of matching virtual files
451
*/
452
fun findFilesByExtension(root: VirtualFile, extension: String): List<VirtualFile>
453
454
/**
455
* Create virtual file from physical file
456
*
457
* @param file Physical file
458
* @return Virtual file representation
459
*/
460
fun findFileByIoFile(file: File): VirtualFile?
461
}
462
```
463
464
## Usage Examples
465
466
### Basic Environment Setup
467
468
```kotlin
469
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
470
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
471
import org.jetbrains.kotlin.config.CompilerConfiguration
472
import org.jetbrains.kotlin.config.CommonConfigurationKeys
473
import org.jetbrains.kotlin.config.JVMConfigurationKeys
474
import com.intellij.openapi.util.Disposer
475
import java.io.File
476
477
// Create disposable for resource management
478
val parentDisposable = Disposer.newDisposable()
479
480
try {
481
// Configure compilation
482
val configuration = CompilerConfiguration().apply {
483
put(CommonConfigurationKeys.MODULE_NAME, "my-project")
484
put(JVMConfigurationKeys.OUTPUT_DIRECTORY, File("build/classes"))
485
put(JVMConfigurationKeys.CLASSPATH_ROOTS, listOf(
486
File("lib/kotlin-stdlib.jar")
487
))
488
489
// Add source roots
490
put(CommonConfigurationKeys.CONTENT_ROOTS, listOf(
491
KotlinSourceRoot(File("src/main/kotlin")),
492
JavaSourceRoot(File("src/main/java"))
493
))
494
}
495
496
// Create environment
497
val environment = KotlinCoreEnvironment.createForProduction(
498
parentDisposable = parentDisposable,
499
configuration = configuration,
500
configFiles = EnvironmentConfigFiles.JVM_CONFIG_FILES
501
)
502
503
// Access source files
504
val sourceFiles = environment.getSourceFiles()
505
println("Found ${sourceFiles.size} source files")
506
507
sourceFiles.forEach { ktFile ->
508
println("Processing: ${ktFile.virtualFile.path}")
509
510
// Access file content
511
ktFile.declarations.forEach { declaration ->
512
println(" Declaration: ${declaration.name}")
513
}
514
}
515
516
} finally {
517
// Clean up resources
518
Disposer.dispose(parentDisposable)
519
}
520
```
521
522
### Multi-Module Environment
523
524
```kotlin
525
import org.jetbrains.kotlin.cli.jvm.compiler.ModuleChunk
526
import org.jetbrains.kotlin.cli.jvm.compiler.ModuleBuilder
527
528
// Build modules
529
val coreModule = ModuleBuilder("core")
530
.addSourceFiles(File("src/core/kotlin"))
531
.addClasspathEntry(File("lib/kotlin-stdlib.jar"))
532
.setOutputDirectory(File("build/core"))
533
.build()
534
535
val apiModule = ModuleBuilder("api")
536
.addSourceFiles(File("src/api/kotlin"))
537
.addClasspathEntry(File("lib/kotlin-stdlib.jar"))
538
.addClasspathEntry(File("build/core")) // Depend on core
539
.setOutputDirectory(File("build/api"))
540
.build()
541
542
// Create module chunk
543
val moduleChunk = ModuleChunk(listOf(coreModule, apiModule))
544
545
// Configure for multi-module compilation
546
val configuration = CompilerConfiguration().apply {
547
put(CommonConfigurationKeys.MODULES, moduleChunk.modules)
548
549
// Set combined classpath
550
put(JVMConfigurationKeys.CLASSPATH_ROOTS, moduleChunk.getClasspath())
551
}
552
553
val environment = KotlinCoreEnvironment.createForProduction(
554
parentDisposable = parentDisposable,
555
configuration = configuration,
556
configFiles = EnvironmentConfigFiles.JVM_CONFIG_FILES
557
)
558
```
559
560
### Custom Path Configuration
561
562
```kotlin
563
import org.jetbrains.kotlin.utils.PathUtil
564
import org.jetbrains.kotlin.utils.KotlinPaths
565
566
// Detect Kotlin installation
567
val kotlinHome = File("/usr/local/kotlin")
568
val kotlinPaths = PathUtil.getKotlinPathsForDistribution(kotlinHome)
569
570
// Configure with detected paths
571
val configuration = CompilerConfiguration().apply {
572
put(JVMConfigurationKeys.CLASSPATH_ROOTS, listOf(
573
kotlinPaths.stdlibPath,
574
kotlinPaths.reflectPath,
575
kotlinPaths.kotlinTestPath
576
))
577
}
578
579
// Alternative: Detect from compiler JAR
580
val compilerJar = File("lib/kotlin-compiler.jar")
581
val pathsFromCompiler = PathUtil.getKotlinPathsForCompiler(compilerJar)
582
583
println("Kotlin home: ${pathsFromCompiler.homePath}")
584
println("Stdlib: ${pathsFromCompiler.stdlibPath}")
585
println("Runtime JARs: ${pathsFromCompiler.runtimeJars}")
586
```
587
588
### JavaScript Environment Setup
589
590
```kotlin
591
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
592
593
// JavaScript-specific configuration
594
val jsConfiguration = CompilerConfiguration().apply {
595
put(CommonConfigurationKeys.MODULE_NAME, "js-app")
596
put(JSConfigurationKeys.OUTPUT_FILE, "build/js/app.js")
597
put(JSConfigurationKeys.MODULE_KIND, ModuleKind.COMMON_JS)
598
put(JSConfigurationKeys.LIBRARIES, listOf("lib/kotlin-stdlib-js.jar"))
599
600
// Add JS sources
601
put(CommonConfigurationKeys.CONTENT_ROOTS, listOf(
602
KotlinSourceRoot(File("src/main/kotlin"))
603
))
604
}
605
606
// Create JS environment
607
val jsEnvironment = KotlinCoreEnvironment.createForProduction(
608
parentDisposable = parentDisposable,
609
configuration = jsConfiguration,
610
configFiles = EnvironmentConfigFiles.JS_CONFIG_FILES
611
)
612
```
613
614
### Environment with Extensions
615
616
```kotlin
617
// Custom environment extension
618
class MyEnvironmentExtension : EnvironmentExtension {
619
override fun registerProjectExtensions(
620
project: MockProject,
621
configuration: CompilerConfiguration
622
) {
623
// Register custom extensions
624
SyntheticResolveExtension.registerExtension(
625
project,
626
MySyntheticResolveExtension()
627
)
628
629
IrGenerationExtension.registerExtension(
630
project,
631
MyIrGenerationExtension()
632
)
633
}
634
}
635
636
// Environment with custom extensions
637
val extensions = listOf(MyEnvironmentExtension())
638
639
val environment = KotlinCoreEnvironment.createForTests(
640
parentDisposable = parentDisposable,
641
configuration = configuration,
642
extensionRegistrars = extensions,
643
configFiles = EnvironmentConfigFiles.JVM_CONFIG_FILES
644
)
645
```
646
647
### Project Environment Management
648
649
```kotlin
650
// Create project environment separately
651
val applicationEnvironment = KotlinCoreEnvironment.getOrCreateApplicationEnvironmentForProduction(
652
parentDisposable = parentDisposable,
653
configuration = configuration
654
)
655
656
val projectEnvironment = KotlinCoreEnvironment.ProjectEnvironment(
657
parentDisposable = parentDisposable,
658
applicationEnvironment = applicationEnvironment,
659
configuration = configuration
660
)
661
662
// Register project-specific extensions
663
projectEnvironment.registerExtensions(listOf(
664
MyEnvironmentExtension(),
665
AnotherCustomExtension()
666
))
667
668
// Access project
669
val project = projectEnvironment.project
670
val packagePartProvider = KotlinCoreEnvironment.createPackagePartProvider(
671
GlobalSearchScope.allScope(project)
672
)
673
```
674
675
### Resource Management Best Practices
676
677
```kotlin
678
// Proper resource management with try-with-resources pattern
679
class CompilationSession : AutoCloseable {
680
private val parentDisposable = Disposer.newDisposable()
681
private val environment: KotlinCoreEnvironment
682
683
init {
684
val configuration = CompilerConfiguration().apply {
685
// Configure compilation settings
686
}
687
688
environment = KotlinCoreEnvironment.createForProduction(
689
parentDisposable = parentDisposable,
690
configuration = configuration,
691
configFiles = EnvironmentConfigFiles.JVM_CONFIG_FILES
692
)
693
}
694
695
fun compile(): Boolean {
696
return try {
697
val sourceFiles = environment.getSourceFiles()
698
// Perform compilation
699
true
700
} catch (e: Exception) {
701
false
702
}
703
}
704
705
override fun close() {
706
Disposer.dispose(parentDisposable)
707
}
708
}
709
710
// Usage with automatic cleanup
711
CompilationSession().use { session ->
712
val success = session.compile()
713
println("Compilation ${if (success) "succeeded" else "failed"}")
714
}
715
```
716
717
### Environment Debugging
718
719
```kotlin
720
// Debug environment configuration
721
fun debugEnvironment(environment: KotlinCoreEnvironment) {
722
val configuration = environment.configuration
723
val project = environment.project
724
725
println("=== Environment Debug Info ===")
726
println("Module name: ${configuration.get(CommonConfigurationKeys.MODULE_NAME)}")
727
println("Source files: ${environment.getSourceFiles().size}")
728
729
// Debug content roots
730
val contentRoots = configuration.get(CommonConfigurationKeys.CONTENT_ROOTS) ?: emptyList()
731
println("Content roots:")
732
contentRoots.forEach { root ->
733
println(" ${root.javaClass.simpleName}: ${root.file}")
734
}
735
736
// Debug classpath
737
val classpath = configuration.get(JVMConfigurationKeys.CLASSPATH_ROOTS) ?: emptyList()
738
println("Classpath:")
739
classpath.forEach { jar ->
740
println(" ${jar.path} (exists: ${jar.exists()})")
741
}
742
743
// Debug project extensions
744
println("Registered extensions:")
745
project.extensionArea.getExtensionPoint<Any>("*").extensions.forEach { ext ->
746
println(" ${ext.javaClass.name}")
747
}
748
}
749
```
750
751
## Error Handling
752
753
```kotlin { .api }
754
class EnvironmentException(message: String, cause: Throwable? = null) : Exception(message, cause)
755
756
class InvalidEnvironmentConfigurationException(message: String) : EnvironmentException(message)
757
758
class MissingKotlinHomeException(message: String) : EnvironmentException(message)
759
```
760
761
Common environment errors:
762
- **KOTLIN_HOME_NOT_FOUND**: Kotlin installation not detected
763
- **INVALID_CONTENT_ROOT**: Source directory doesn't exist
764
- **CLASSPATH_ENTRY_NOT_FOUND**: JAR file missing from classpath
765
- **INCOMPATIBLE_CONFIG_FILES**: Wrong environment config for target platform
766
- **RESOURCE_DISPOSAL_ERROR**: Problems during environment cleanup