0
# Configuration Management
1
2
The Kotlin compiler uses a comprehensive type-safe configuration system with hierarchical key organization and service dependency injection. This system provides fine-grained control over compilation behavior while maintaining type safety and preventing configuration errors.
3
4
## Capabilities
5
6
### CompilerConfiguration
7
8
Central configuration container providing type-safe access to compilation settings through strongly-typed keys.
9
10
```kotlin { .api }
11
/**
12
* Type-safe configuration container for compiler settings
13
* Uses strongly-typed keys to prevent configuration errors
14
*/
15
class CompilerConfiguration {
16
/**
17
* Set a configuration value
18
*
19
* @param key Strongly-typed configuration key
20
* @param value Value to set (must match key type)
21
*/
22
fun <T> put(key: CompilerConfigurationKey<T>, value: T)
23
24
/**
25
* Get configuration value (nullable)
26
*
27
* @param key Configuration key to retrieve
28
* @return Value or null if not set
29
*/
30
fun <T> get(key: CompilerConfigurationKey<T>): T?
31
32
/**
33
* Get configuration value (non-null)
34
* Throws exception if value not set
35
*
36
* @param key Configuration key to retrieve
37
* @return Value (never null)
38
* @throws IllegalStateException if key not found
39
*/
40
fun <T> getNotNull(key: CompilerConfigurationKey<T>): T
41
42
/**
43
* Get configuration value with default
44
*
45
* @param key Configuration key
46
* @param defaultValue Value to return if key not set
47
* @return Value or default
48
*/
49
fun <T> get(key: CompilerConfigurationKey<T>, defaultValue: T): T
50
51
/**
52
* Check if configuration key is set
53
*
54
* @param key Configuration key to check
55
* @return true if key has been set
56
*/
57
fun isSet(key: CompilerConfigurationKey<*>): Boolean
58
59
/**
60
* Add to list-type configuration value
61
*
62
* @param key List-type configuration key
63
* @param value Value to append to list
64
*/
65
fun <T> addAll(key: CompilerConfigurationKey<List<T>>, values: Collection<T>)
66
67
/**
68
* Create immutable copy of configuration
69
*
70
* @return Read-only copy of current configuration
71
*/
72
fun copy(): CompilerConfiguration
73
}
74
```
75
76
### Configuration Keys
77
78
Strongly-typed configuration keys organized by functional area and platform.
79
80
```kotlin { .api }
81
/**
82
* Strongly-typed configuration key with type safety
83
*
84
* @param T Type of value stored with this key
85
*/
86
class CompilerConfigurationKey<T> private constructor(
87
private val name: String
88
) {
89
companion object {
90
/**
91
* Create a new configuration key
92
*
93
* @param name Descriptive name for the key
94
* @return New configuration key instance
95
*/
96
fun <T> create(name: String): CompilerConfigurationKey<T>
97
}
98
99
override fun toString(): String = name
100
}
101
```
102
103
### Common Configuration Keys
104
105
Cross-platform configuration keys used by all compiler targets.
106
107
```kotlin { .api }
108
object CommonConfigurationKeys {
109
/** Module name for compilation output */
110
val MODULE_NAME: CompilerConfigurationKey<String>
111
112
/** Language version settings and feature flags */
113
val LANGUAGE_VERSION_SETTINGS: CompilerConfigurationKey<LanguageVersionSettings>
114
115
/** Message collector for diagnostics and warnings */
116
val MESSAGE_COLLECTOR_KEY: CompilerConfigurationKey<MessageCollector>
117
118
/** Metadata version for binary compatibility */
119
val METADATA_VERSION: CompilerConfigurationKey<BinaryVersion>
120
121
/** Use FIR (K2) frontend */
122
val USE_FIR: CompilerConfigurationKey<Boolean>
123
124
/** Disable inline functions */
125
val DISABLE_INLINE: CompilerConfigurationKey<Boolean>
126
127
/** Report output files */
128
val REPORT_OUTPUT_FILES: CompilerConfigurationKey<Boolean>
129
130
/** Lookup tracker for incremental compilation */
131
val LOOKUP_TRACKER: CompilerConfigurationKey<LookupTracker>
132
133
/** Expect/actual tracker for multiplatform */
134
val EXPECT_ACTUAL_TRACKER: CompilerConfigurationKey<ExpectActualTracker>
135
136
/** Allow any scripts in source roots */
137
val ALLOW_ANY_SCRIPTS_IN_SOURCE_ROOTS: CompilerConfigurationKey<Boolean>
138
139
/** Render diagnostic names in messages */
140
val RENDER_DIAGNOSTIC_INTERNAL_NAME: CompilerConfigurationKey<Boolean>
141
142
/** Parallel backend threads */
143
val PARALLEL_BACKEND_THREADS: CompilerConfigurationKey<Int>
144
145
/** Content roots for source files and libraries */
146
val CONTENT_ROOTS: CompilerConfigurationKey<List<ContentRoot>>
147
148
/** Modules for compilation */
149
val MODULES: CompilerConfigurationKey<List<Module>>
150
151
/** Incremental compilation components */
152
val INCREMENTAL_COMPILATION: CompilerConfigurationKey<IncrementalCompilationComponents>
153
}
154
```
155
156
### CLI Configuration Keys
157
158
Command-line interface specific configuration keys.
159
160
```kotlin { .api }
161
object CLIConfigurationKeys {
162
/** Message collector for CLI output */
163
val MESSAGE_COLLECTOR_KEY: CompilerConfigurationKey<MessageCollector>
164
165
/** Metadata version override */
166
val METADATA_VERSION: CompilerConfigurationKey<BinaryVersion>
167
168
/** Performance manager for profiling */
169
val PERF_MANAGER: CompilerConfigurationKey<CommonCompilerPerformanceManager>
170
171
/** Allow Kotlin package */
172
val ALLOW_KOTLIN_PACKAGE: CompilerConfigurationKey<Boolean>
173
174
/** Verify bytecode */
175
val VERIFY_BYTECODE: CompilerConfigurationKey<Boolean>
176
177
/** Phase configuration */
178
val PHASE_CONFIG: CompilerConfigurationKey<PhaseConfig>
179
180
/** Intellij plugin root */
181
val INTELLIJ_PLUGIN_ROOT: CompilerConfigurationKey<String>
182
183
/** Flexible phase config flag */
184
val FLEXIBLE_PHASE_CONFIG: CompilerConfigurationKey<Boolean>
185
186
/** Original message collector */
187
val ORIGINAL_MESSAGE_COLLECTOR_KEY: CompilerConfigurationKey<MessageCollector>
188
}
189
```
190
191
### JVM Configuration Keys
192
193
JVM-specific compilation configuration keys.
194
195
```kotlin { .api }
196
object JVMConfigurationKeys {
197
/** Output directory for .class files */
198
val OUTPUT_DIRECTORY: CompilerConfigurationKey<File>
199
200
/** Output JAR file */
201
val OUTPUT_JAR: CompilerConfigurationKey<File>
202
203
/** Include Kotlin runtime in JAR */
204
val INCLUDE_RUNTIME: CompilerConfigurationKey<Boolean>
205
206
/** Classpath entries */
207
val CLASSPATH_ROOTS: CompilerConfigurationKey<List<File>>
208
209
/** JDK home directory */
210
val JDK_HOME: CompilerConfigurationKey<File>
211
212
/** JVM target version */
213
val JVM_TARGET: CompilerConfigurationKey<JvmTarget>
214
215
/** Assert runtime calls */
216
val ASSERTIONS_MODE: CompilerConfigurationKey<JVMAssertionsMode>
217
218
/** Constructor call optimization */
219
val CONSTRUCTOR_CALL_OPTIMIZATION: CompilerConfigurationKey<Boolean>
220
221
/** Inherit multifile parts */
222
val INHERIT_MULTIFILE_PARTS: CompilerConfigurationKey<Boolean>
223
224
/** Use type table */
225
val USE_TYPE_TABLE: CompilerConfigurationKey<Boolean>
226
227
/** Java module path */
228
val JVM_MODULE_PATH: CompilerConfigurationKey<List<File>>
229
230
/** Add modules */
231
val ADD_MODULES: CompilerConfigurationKey<List<String>>
232
233
/** No JDK flag */
234
val NO_JDK: CompilerConfigurationKey<Boolean>
235
236
/** Additional Java modules */
237
val ADDITIONAL_JAVA_MODULES: CompilerConfigurationKey<List<String>>
238
239
/** Module XML file */
240
val MODULE_XML_FILE: CompilerConfigurationKey<File>
241
242
/** Disable standard script definition */
243
val DISABLE_STANDARD_SCRIPT_DEFINITION: CompilerConfigurationKey<Boolean>
244
245
/** Retain output in memory */
246
val RETAIN_OUTPUT_IN_MEMORY: CompilerConfigurationKey<Boolean>
247
248
/** Disable optimization */
249
val DISABLE_OPTIMIZATION: CompilerConfigurationKey<Boolean>
250
251
/** Emit JVM debug info */
252
val EMIT_JVM_DEBUG_INFO: CompilerConfigurationKey<Boolean>
253
254
/** No optimized callable references */
255
val NO_OPTIMIZED_CALLABLE_REFERENCES: CompilerConfigurationKey<Boolean>
256
257
/** No Kotlin nothing value exception */
258
val NO_KOTLIN_NOTHING_VALUE_EXCEPTION: CompilerConfigurationKey<Boolean>
259
260
/** No reset bindings */
261
val NO_RESET_JAR_TIMESTAMPS: CompilerConfigurationKey<Boolean>
262
263
/** No unified null checks */
264
val NO_UNIFIED_NULL_CHECKS: CompilerConfigurationKey<Boolean>
265
}
266
```
267
268
### JavaScript Configuration Keys
269
270
JavaScript and WebAssembly specific configuration keys.
271
272
```kotlin { .api }
273
object JSConfigurationKeys {
274
/** Output file for generated JavaScript */
275
val OUTPUT_FILE: CompilerConfigurationKey<String>
276
277
/** Output directory */
278
val OUTPUT_DIR: CompilerConfigurationKey<File>
279
280
/** JavaScript module kind */
281
val MODULE_KIND: CompilerConfigurationKey<ModuleKind>
282
283
/** Generate source maps */
284
val SOURCE_MAP: CompilerConfigurationKey<Boolean>
285
286
/** Embed sources in source maps */
287
val SOURCE_MAP_EMBED_SOURCES: CompilerConfigurationKey<SourceMapEmbedSources>
288
289
/** Source map prefix */
290
val SOURCE_MAP_PREFIX: CompilerConfigurationKey<String>
291
292
/** Source map names policy */
293
val SOURCE_MAP_NAMES_POLICY: CompilerConfigurationKey<SourceMapNamesPolicy>
294
295
/** Library files */
296
val LIBRARIES: CompilerConfigurationKey<List<String>>
297
298
/** Transitive libraries */
299
val TRANSITIVE_LIBRARIES: CompilerConfigurationKey<List<String>>
300
301
/** Main call parameters */
302
val MAIN: CompilerConfigurationKey<String>
303
304
/** Meta info */
305
val META_INFO: CompilerConfigurationKey<Boolean>
306
307
/** Target platform */
308
val TARGET: CompilerConfigurationKey<String>
309
310
/** Friend modules */
311
val FRIEND_PATHS: CompilerConfigurationKey<List<String>>
312
313
/** Metadata output directory */
314
val METADATA_OUTPUT_DIR: CompilerConfigurationKey<File>
315
316
/** Pretty print output */
317
val PRETTY_PRINT: CompilerConfigurationKey<Boolean>
318
319
/** Minify output */
320
val MINIFY: CompilerConfigurationKey<Boolean>
321
322
/** Define platform main arguments */
323
val DEFINE_PLATFORM_MAIN_FUNCTION_ARGUMENTS: CompilerConfigurationKey<String>
324
325
/** Generate comments */
326
val GENERATE_COMMENTS: CompilerConfigurationKey<Boolean>
327
328
/** Generate region comments */
329
val GENERATE_REGION_COMMENTS: CompilerConfigurationKey<Boolean>
330
331
/** Generate strict mode directive */
332
val GENERATE_STRICT_MODE_DIRECTIVE: CompilerConfigurationKey<Boolean>
333
334
/** Optimize generated code */
335
val OPTIMIZE_GENERATED_JS: CompilerConfigurationKey<Boolean>
336
337
/** Use ES6 classes */
338
val USE_ES6_CLASSES: CompilerConfigurationKey<Boolean>
339
}
340
```
341
342
### Services Container
343
344
Dependency injection container for compiler services and components.
345
346
```kotlin { .api }
347
/**
348
* Service container for dependency injection
349
* Provides type-safe service resolution
350
*/
351
class Services private constructor() {
352
companion object {
353
/** Empty services instance */
354
val EMPTY: Services
355
356
/**
357
* Create services builder
358
*
359
* @return New services builder instance
360
*/
361
fun builder(): Builder
362
}
363
364
/**
365
* Get service by type
366
*
367
* @param serviceClass Service class to retrieve
368
* @return Service instance or null if not registered
369
*/
370
fun <T> get(serviceClass: Class<T>): T?
371
372
/**
373
* Builder for services container
374
*/
375
class Builder {
376
/**
377
* Register service implementation
378
*
379
* @param serviceClass Service interface class
380
* @param implementation Service implementation instance
381
* @return Builder for chaining
382
*/
383
fun <T> register(serviceClass: Class<T>, implementation: T): Builder
384
385
/**
386
* Build immutable services container
387
*
388
* @return Services container with registered services
389
*/
390
fun build(): Services
391
}
392
}
393
```
394
395
### Language Version Settings
396
397
Language feature and version configuration.
398
399
```kotlin { .api }
400
/**
401
* Language version and feature settings
402
* Controls available language features and compatibility
403
*/
404
interface LanguageVersionSettings {
405
/** Current language version */
406
val languageVersion: LanguageVersion
407
408
/** API version for binary compatibility */
409
val apiVersion: ApiVersion
410
411
/** Analysis flags for compiler behavior */
412
val analysisFlags: Map<AnalysisFlag<*>, Any?>
413
414
/** Specific feature support */
415
val specificFeatures: Map<LanguageFeature, LanguageFeature.State>
416
417
/**
418
* Check if language feature is enabled
419
*
420
* @param feature Language feature to check
421
* @return true if feature is enabled or warning level
422
*/
423
fun supportsFeature(feature: LanguageFeature): Boolean
424
425
/**
426
* Get feature support state
427
*
428
* @param feature Language feature to check
429
* @return Feature state (enabled, warning, error)
430
*/
431
fun getFeatureSupport(feature: LanguageFeature): LanguageFeature.State
432
433
/**
434
* Check if flag is set
435
*
436
* @param flag Analysis flag to check
437
* @return true if flag is enabled
438
*/
439
fun <T> getFlag(flag: AnalysisFlag<T>): T
440
}
441
442
/**
443
* Language version enumeration
444
*/
445
enum class LanguageVersion(val major: Int, val minor: Int) {
446
KOTLIN_1_0(1, 0),
447
KOTLIN_1_1(1, 1),
448
KOTLIN_1_2(1, 2),
449
KOTLIN_1_3(1, 3),
450
KOTLIN_1_4(1, 4),
451
KOTLIN_1_5(1, 5),
452
KOTLIN_1_6(1, 6),
453
KOTLIN_1_7(1, 7),
454
KOTLIN_1_8(1, 8),
455
KOTLIN_1_9(1, 9),
456
KOTLIN_2_0(2, 0),
457
KOTLIN_2_1(2, 1),
458
KOTLIN_2_2(2, 2);
459
460
companion object {
461
/** Latest stable version */
462
val LATEST_STABLE: LanguageVersion
463
464
/** Default version for compilation */
465
val DEFAULT: LanguageVersion
466
467
fun fromVersionString(version: String): LanguageVersion?
468
}
469
}
470
471
/**
472
* API version for binary compatibility
473
*/
474
enum class ApiVersion(val version: LanguageVersion) {
475
KOTLIN_1_0(LanguageVersion.KOTLIN_1_0),
476
KOTLIN_1_1(LanguageVersion.KOTLIN_1_1),
477
KOTLIN_1_2(LanguageVersion.KOTLIN_1_2),
478
KOTLIN_1_3(LanguageVersion.KOTLIN_1_3),
479
KOTLIN_1_4(LanguageVersion.KOTLIN_1_4),
480
KOTLIN_1_5(LanguageVersion.KOTLIN_1_5),
481
KOTLIN_1_6(LanguageVersion.KOTLIN_1_6),
482
KOTLIN_1_7(LanguageVersion.KOTLIN_1_7),
483
KOTLIN_1_8(LanguageVersion.KOTLIN_1_8),
484
KOTLIN_1_9(LanguageVersion.KOTLIN_1_9),
485
KOTLIN_2_0(LanguageVersion.KOTLIN_2_0),
486
KOTLIN_2_1(LanguageVersion.KOTLIN_2_1),
487
KOTLIN_2_2(LanguageVersion.KOTLIN_2_2);
488
489
companion object {
490
/** Latest stable API version */
491
val LATEST_STABLE: ApiVersion
492
493
fun fromVersionString(version: String): ApiVersion?
494
}
495
}
496
```
497
498
## Usage Examples
499
500
### Basic Configuration Setup
501
502
```kotlin
503
import org.jetbrains.kotlin.config.CompilerConfiguration
504
import org.jetbrains.kotlin.config.CommonConfigurationKeys
505
import org.jetbrains.kotlin.config.JVMConfigurationKeys
506
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
507
import org.jetbrains.kotlin.config.LanguageVersion
508
import org.jetbrains.kotlin.config.ApiVersion
509
import java.io.File
510
511
// Create basic compiler configuration
512
val configuration = CompilerConfiguration().apply {
513
// Module name
514
put(CommonConfigurationKeys.MODULE_NAME, "my-module")
515
516
// Language version settings
517
put(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS,
518
LanguageVersionSettingsImpl(
519
languageVersion = LanguageVersion.KOTLIN_1_9,
520
apiVersion = ApiVersion.KOTLIN_1_9
521
)
522
)
523
524
// JVM-specific settings
525
put(JVMConfigurationKeys.OUTPUT_DIRECTORY, File("build/classes"))
526
put(JVMConfigurationKeys.JVM_TARGET, JvmTarget.JVM_11)
527
put(JVMConfigurationKeys.CLASSPATH_ROOTS, listOf(
528
File("lib/kotlin-stdlib.jar"),
529
File("lib/my-deps.jar")
530
))
531
}
532
```
533
534
### Advanced Configuration with Services
535
536
```kotlin
537
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
538
import org.jetbrains.kotlin.cli.common.messages.PrintingMessageCollector
539
import org.jetbrains.kotlin.config.Services
540
import org.jetbrains.kotlin.incremental.components.LookupTracker
541
542
// Create message collector
543
val messageCollector = PrintingMessageCollector(
544
System.err,
545
MessageRenderer.PLAIN_FULL_PATHS,
546
true // verbose
547
)
548
549
// Build services container
550
val services = Services.builder()
551
.register(MessageCollector::class.java, messageCollector)
552
.register(LookupTracker::class.java, LookupTracker.DO_NOTHING)
553
.build()
554
555
// Configure with services
556
val configuration = CompilerConfiguration().apply {
557
put(CommonConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector)
558
put(CommonConfigurationKeys.LOOKUP_TRACKER, services.get(LookupTracker::class.java)!!)
559
}
560
```
561
562
### JavaScript Configuration
563
564
```kotlin
565
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
566
import org.jetbrains.kotlin.js.config.ModuleKind
567
import org.jetbrains.kotlin.js.config.SourceMapEmbedSources
568
569
val jsConfiguration = CompilerConfiguration().apply {
570
// Output settings
571
put(JSConfigurationKeys.OUTPUT_FILE, "build/js/app.js")
572
put(JSConfigurationKeys.MODULE_KIND, ModuleKind.COMMON_JS)
573
574
// Source map configuration
575
put(JSConfigurationKeys.SOURCE_MAP, true)
576
put(JSConfigurationKeys.SOURCE_MAP_EMBED_SOURCES, SourceMapEmbedSources.ALWAYS)
577
put(JSConfigurationKeys.SOURCE_MAP_PREFIX, "../src/")
578
579
// Libraries
580
put(JSConfigurationKeys.LIBRARIES, listOf(
581
"lib/kotlin-stdlib-js.jar",
582
"lib/kotlinx-coroutines-js.jar"
583
))
584
585
// Code generation
586
put(JSConfigurationKeys.PRETTY_PRINT, false)
587
put(JSConfigurationKeys.MINIFY, true)
588
}
589
```
590
591
### Language Feature Configuration
592
593
```kotlin
594
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
595
import org.jetbrains.kotlin.config.AnalysisFlags
596
import org.jetbrains.kotlin.config.LanguageFeature
597
598
// Create language settings with specific features
599
val languageSettings = LanguageVersionSettingsImpl(
600
languageVersion = LanguageVersion.KOTLIN_1_9,
601
apiVersion = ApiVersion.KOTLIN_1_9,
602
analysisFlags = mapOf(
603
AnalysisFlags.skipMetadataVersionCheck to true,
604
AnalysisFlags.multiPlatformDoNotCheckActual to false
605
),
606
specificFeatures = mapOf(
607
LanguageFeature.InlineClasses to LanguageFeature.State.ENABLED,
608
LanguageFeature.Coroutines to LanguageFeature.State.ENABLED
609
)
610
)
611
612
configuration.put(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS, languageSettings)
613
```
614
615
### Plugin Configuration
616
617
```kotlin
618
// Plugin-specific configuration keys
619
object MyPluginConfigurationKeys {
620
val ENABLE_FEATURE_X = CompilerConfigurationKey.create<Boolean>("plugin.feature.x")
621
val OUTPUT_FORMAT = CompilerConfigurationKey.create<String>("plugin.output.format")
622
val DEBUG_MODE = CompilerConfigurationKey.create<Boolean>("plugin.debug")
623
}
624
625
// Configure plugin settings
626
configuration.apply {
627
put(MyPluginConfigurationKeys.ENABLE_FEATURE_X, true)
628
put(MyPluginConfigurationKeys.OUTPUT_FORMAT, "json")
629
put(MyPluginConfigurationKeys.DEBUG_MODE, false)
630
}
631
632
// Access in plugin
633
class MyPlugin {
634
fun process(configuration: CompilerConfiguration) {
635
val featureEnabled = configuration.get(MyPluginConfigurationKeys.ENABLE_FEATURE_X) ?: false
636
val outputFormat = configuration.getNotNull(MyPluginConfigurationKeys.OUTPUT_FORMAT)
637
638
if (featureEnabled) {
639
processWithFeature(outputFormat)
640
}
641
}
642
}
643
```
644
645
### Configuration Validation
646
647
```kotlin
648
fun validateConfiguration(configuration: CompilerConfiguration): List<String> {
649
val errors = mutableListOf<String>()
650
651
// Check required settings
652
if (!configuration.isSet(CommonConfigurationKeys.MODULE_NAME)) {
653
errors.add("Module name is required")
654
}
655
656
// Validate JVM settings
657
val outputDir = configuration.get(JVMConfigurationKeys.OUTPUT_DIRECTORY)
658
if (outputDir != null && !outputDir.exists()) {
659
if (!outputDir.mkdirs()) {
660
errors.add("Cannot create output directory: ${outputDir.path}")
661
}
662
}
663
664
// Check classpath exists
665
val classpath = configuration.get(JVMConfigurationKeys.CLASSPATH_ROOTS) ?: emptyList()
666
classpath.forEach { file ->
667
if (!file.exists()) {
668
errors.add("Classpath entry not found: ${file.path}")
669
}
670
}
671
672
return errors
673
}
674
675
// Usage
676
val validationErrors = validateConfiguration(configuration)
677
if (validationErrors.isNotEmpty()) {
678
validationErrors.forEach { error ->
679
println("Configuration error: $error")
680
}
681
}
682
```
683
684
### Configuration Inheritance
685
686
```kotlin
687
// Base configuration
688
val baseConfig = CompilerConfiguration().apply {
689
put(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS, languageSettings)
690
put(CommonConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector)
691
}
692
693
// JVM-specific configuration inheriting from base
694
val jvmConfig = baseConfig.copy().apply {
695
put(JVMConfigurationKeys.JVM_TARGET, JvmTarget.JVM_11)
696
put(JVMConfigurationKeys.OUTPUT_DIRECTORY, File("build/jvm"))
697
}
698
699
// JS-specific configuration inheriting from base
700
val jsConfig = baseConfig.copy().apply {
701
put(JSConfigurationKeys.MODULE_KIND, ModuleKind.COMMON_JS)
702
put(JSConfigurationKeys.OUTPUT_FILE, "build/js/app.js")
703
}
704
```
705
706
## Error Handling
707
708
```kotlin { .api }
709
class ConfigurationException(message: String, cause: Throwable? = null) : Exception(message, cause)
710
711
class InvalidConfigurationKeyException(message: String) : ConfigurationException(message)
712
713
class MissingConfigurationException(message: String) : ConfigurationException(message)
714
```
715
716
Common configuration errors:
717
- **MISSING_REQUIRED_KEY**: Required configuration key not set (use `getNotNull()`)
718
- **INVALID_KEY_TYPE**: Type mismatch between key and value
719
- **INVALID_FILE_PATH**: File paths that don't exist or are inaccessible
720
- **INCOMPATIBLE_SETTINGS**: Conflicting configuration options