0
# Utilities and Language Support
1
2
Essential utilities for name allocation, modifier management, and platform-specific functionality across JVM, JavaScript, and WebAssembly targets.
3
4
## Capabilities
5
6
### Name Allocation and Collision Avoidance
7
8
Manages identifier names while avoiding collisions with Kotlin keywords and existing identifiers.
9
10
```kotlin { .api }
11
/**
12
* Allocates names while avoiding collisions with keywords and existing identifiers
13
*/
14
class NameAllocator {
15
/** Allocates a new name based on the suggestion, avoiding conflicts */
16
fun newName(suggestion: String, tag: Any? = null): String
17
18
/** Retrieves the allocated name for the given tag */
19
fun get(tag: Any): String
20
21
/** Creates a copy of this name allocator with the same allocated names */
22
fun copy(): NameAllocator
23
24
companion object {
25
/** Creates a new NameAllocator instance */
26
fun get(): NameAllocator
27
}
28
}
29
```
30
31
**Usage Examples:**
32
33
```kotlin
34
import com.squareup.kotlinpoet.*
35
36
// Basic name allocation
37
val allocator = NameAllocator()
38
39
// Allocate names avoiding conflicts
40
val className = allocator.newName("User", "userClass")
41
val methodName = allocator.newName("process", "processMethod")
42
43
// Avoid Kotlin keywords
44
val safeName = allocator.newName("class", "typeInfo") // Results in "class_" or similar
45
val safeObject = allocator.newName("object", "instanceRef")
46
47
// Use tags to retrieve allocated names later
48
val userTag = "USER_ENTITY"
49
val allocatedUserName = allocator.newName("User", userTag)
50
// Later retrieve the same name
51
val retrievedName = allocator.get(userTag) // Same as allocatedUserName
52
53
// Generate multiple related names
54
val propertyNames = listOf("name", "age", "email", "class", "object")
55
val allocatedProperties = propertyNames.mapIndexed { index, name ->
56
allocator.newName(name, "property_$index")
57
}
58
59
// Copy allocator for different scopes
60
val methodAllocator = allocator.copy()
61
val localVar = methodAllocator.newName("result", "localResult")
62
63
// Practical usage in code generation
64
fun generateDataClass(fields: List<Field>): TypeSpec {
65
val allocator = NameAllocator()
66
val className = allocator.newName("Generated${fields.first().type}", "mainClass")
67
68
return TypeSpec.classBuilder(className)
69
.addModifiers(KModifier.DATA)
70
.primaryConstructor(
71
FunSpec.constructorBuilder()
72
.apply {
73
fields.forEach { field ->
74
val paramName = allocator.newName(field.name, field)
75
addParameter(paramName, field.type)
76
}
77
}
78
.build()
79
)
80
.apply {
81
fields.forEach { field ->
82
val propName = allocator.get(field)
83
addProperty(
84
PropertySpec.builder(propName, field.type)
85
.initializer(propName)
86
.build()
87
)
88
}
89
}
90
.build()
91
}
92
```
93
94
### Kotlin Modifiers
95
96
Comprehensive enumeration of all Kotlin language modifiers with proper categorization.
97
98
```kotlin { .api }
99
/**
100
* Kotlin language modifiers
101
*/
102
enum class KModifier {
103
// Visibility modifiers
104
PUBLIC, PROTECTED, PRIVATE, INTERNAL,
105
106
// Inheritance modifiers
107
FINAL, OPEN, ABSTRACT, SEALED,
108
109
// Multiplatform modifiers
110
EXPECT, ACTUAL,
111
112
// Function/property modifiers
113
OVERRIDE, LATEINIT, CONST, EXTERNAL,
114
115
// Function-specific modifiers
116
TAILREC, OPERATOR, INFIX, INLINE, SUSPEND,
117
118
// Parameter modifiers
119
VARARG, CROSSINLINE, NOINLINE, REIFIED,
120
121
// Class type modifiers
122
DATA, INNER, ENUM, ANNOTATION, FUN, COMPANION, VALUE
123
}
124
```
125
126
**Usage Examples:**
127
128
```kotlin
129
// Visibility modifiers
130
val publicClass = TypeSpec.classBuilder("PublicClass")
131
.addModifiers(KModifier.PUBLIC)
132
.build()
133
134
val privateProperty = PropertySpec.builder("privateField", String::class)
135
.addModifiers(KModifier.PRIVATE)
136
.build()
137
138
val internalFunction = FunSpec.builder("internalHelper")
139
.addModifiers(KModifier.INTERNAL)
140
.build()
141
142
// Inheritance modifiers
143
val openClass = TypeSpec.classBuilder("BaseClass")
144
.addModifiers(KModifier.OPEN)
145
.build()
146
147
val abstractClass = TypeSpec.classBuilder("AbstractProcessor")
148
.addModifiers(KModifier.ABSTRACT)
149
.build()
150
151
val sealedClass = TypeSpec.classBuilder("Result")
152
.addModifiers(KModifier.SEALED)
153
.addTypeVariable(TypeVariableName("T"))
154
.build()
155
156
val finalClass = TypeSpec.classBuilder("ImmutableData")
157
.addModifiers(KModifier.FINAL) // Default for classes, explicit here
158
.build()
159
160
// Class type modifiers
161
val dataClass = TypeSpec.classBuilder("Person")
162
.addModifiers(KModifier.DATA)
163
.build()
164
165
val enumClass = TypeSpec.enumBuilder("Status")
166
.addModifiers(KModifier.ENUM) // Implicit with enumBuilder
167
.build()
168
169
val valueClass = TypeSpec.classBuilder("UserId")
170
.addModifiers(KModifier.VALUE)
171
.build()
172
173
val companionObject = TypeSpec.companionObjectBuilder()
174
.addModifiers(KModifier.COMPANION) // Implicit with companionObjectBuilder
175
.build()
176
177
// Function modifiers
178
val inlineFunction = FunSpec.builder("fastOperation")
179
.addModifiers(KModifier.INLINE)
180
.build()
181
182
val suspendFunction = FunSpec.builder("asyncTask")
183
.addModifiers(KModifier.SUSPEND)
184
.build()
185
186
val operatorFunction = FunSpec.builder("plus")
187
.addModifiers(KModifier.OPERATOR)
188
.build()
189
190
val infixFunction = FunSpec.builder("multiply")
191
.addModifiers(KModifier.INFIX)
192
.build()
193
194
val tailrecFunction = FunSpec.builder("factorial")
195
.addModifiers(KModifier.TAILREC)
196
.build()
197
198
// Property modifiers
199
val lateInitProperty = PropertySpec.varBuilder("database", ClassName("", "Database"))
200
.addModifiers(KModifier.LATEINIT)
201
.build()
202
203
val constProperty = PropertySpec.builder("MAX_SIZE", Int::class)
204
.addModifiers(KModifier.CONST)
205
.build()
206
207
val overrideProperty = PropertySpec.builder("size", Int::class)
208
.addModifiers(KModifier.OVERRIDE)
209
.build()
210
211
// Parameter modifiers
212
val varargParameter = ParameterSpec.builder("items", String::class)
213
.addModifiers(KModifier.VARARG)
214
.build()
215
216
val crossInlineParameter = ParameterSpec.builder("block", LambdaTypeName.get(returnType = UNIT))
217
.addModifiers(KModifier.CROSSINLINE)
218
.build()
219
220
val noinlineParameter = ParameterSpec.builder("callback", LambdaTypeName.get(returnType = UNIT))
221
.addModifiers(KModifier.NOINLINE)
222
.build()
223
224
// Multiplatform modifiers
225
val expectClass = TypeSpec.classBuilder("PlatformSpecific")
226
.addModifiers(KModifier.EXPECT)
227
.build()
228
229
val actualClass = TypeSpec.classBuilder("PlatformSpecific")
230
.addModifiers(KModifier.ACTUAL)
231
.build()
232
233
// External modifier for native interop
234
val externalFunction = FunSpec.builder("nativeFunction")
235
.addModifiers(KModifier.EXTERNAL)
236
.build()
237
```
238
239
### Kotlin Operators
240
241
Enumeration of all Kotlin operators for operator function overloading.
242
243
```kotlin { .api }
244
/**
245
* Kotlin operators for operator functions
246
*/
247
enum class KOperator {
248
// Unary operators
249
UNARY_PLUS, UNARY_MINUS, NOT, INC, DEC,
250
251
// Binary arithmetic operators
252
PLUS, MINUS, TIMES, DIV, REM,
253
254
// Range operator
255
RANGE_TO,
256
257
// Collection operators
258
CONTAINS, GET, SET,
259
260
// Invoke operator
261
INVOKE,
262
263
// Compound assignment operators
264
PLUS_ASSIGN, MINUS_ASSIGN, TIMES_ASSIGN, DIV_ASSIGN, REM_ASSIGN,
265
266
// Comparison operators
267
EQUALS, COMPARE_TO
268
}
269
```
270
271
**Usage Examples:**
272
273
```kotlin
274
// Arithmetic operators
275
val plusOperator = FunSpec.builder("plus")
276
.addModifiers(KModifier.OPERATOR)
277
.receiver(ClassName("", "Vector"))
278
.addParameter("other", ClassName("", "Vector"))
279
.returns(ClassName("", "Vector"))
280
.addStatement("return Vector(x + other.x, y + other.y)")
281
.build()
282
283
val minusOperator = FunSpec.builder("minus")
284
.addModifiers(KModifier.OPERATOR)
285
.receiver(ClassName("", "Vector"))
286
.addParameter("other", ClassName("", "Vector"))
287
.returns(ClassName("", "Vector"))
288
.addStatement("return Vector(x - other.x, y - other.y)")
289
.build()
290
291
// Unary operators
292
val unaryMinusOperator = FunSpec.builder("unaryMinus")
293
.addModifiers(KModifier.OPERATOR)
294
.receiver(ClassName("", "Vector"))
295
.returns(ClassName("", "Vector"))
296
.addStatement("return Vector(-x, -y)")
297
.build()
298
299
val incOperator = FunSpec.builder("inc")
300
.addModifiers(KModifier.OPERATOR)
301
.receiver(ClassName("", "Counter"))
302
.returns(ClassName("", "Counter"))
303
.addStatement("return Counter(value + 1)")
304
.build()
305
306
// Collection access operators
307
val getOperator = FunSpec.builder("get")
308
.addModifiers(KModifier.OPERATOR)
309
.receiver(ClassName("", "Matrix"))
310
.addParameter("row", Int::class)
311
.addParameter("col", Int::class)
312
.returns(Double::class)
313
.addStatement("return data[row * cols + col]")
314
.build()
315
316
val setOperator = FunSpec.builder("set")
317
.addModifiers(KModifier.OPERATOR)
318
.receiver(ClassName("", "Matrix"))
319
.addParameter("row", Int::class)
320
.addParameter("col", Int::class)
321
.addParameter("value", Double::class)
322
.returns(UNIT)
323
.addStatement("data[row * cols + col] = value")
324
.build()
325
326
// Contains operator
327
val containsOperator = FunSpec.builder("contains")
328
.addModifiers(KModifier.OPERATOR)
329
.receiver(ClassName("", "Range"))
330
.addParameter("value", Int::class)
331
.returns(Boolean::class)
332
.addStatement("return value >= start && value <= end")
333
.build()
334
335
// Invoke operator (function-like objects)
336
val invokeOperator = FunSpec.builder("invoke")
337
.addModifiers(KModifier.OPERATOR)
338
.receiver(ClassName("", "Multiplier"))
339
.addParameter("value", Int::class)
340
.returns(Int::class)
341
.addStatement("return value * factor")
342
.build()
343
344
// Compound assignment operators
345
val plusAssignOperator = FunSpec.builder("plusAssign")
346
.addModifiers(KModifier.OPERATOR)
347
.receiver(ClassName("", "MutableVector"))
348
.addParameter("other", ClassName("", "Vector"))
349
.returns(UNIT)
350
.addStatement("x += other.x")
351
.addStatement("y += other.y")
352
.build()
353
354
// Comparison operators
355
val compareToOperator = FunSpec.builder("compareTo")
356
.addModifiers(KModifier.OPERATOR)
357
.receiver(ClassName("", "Version"))
358
.addParameter("other", ClassName("", "Version"))
359
.returns(Int::class)
360
.addStatement("return major.compareTo(other.major)")
361
.build()
362
363
// Range operator
364
val rangeToOperator = FunSpec.builder("rangeTo")
365
.addModifiers(KModifier.OPERATOR)
366
.receiver(ClassName("", "Date"))
367
.addParameter("other", ClassName("", "Date"))
368
.returns(ClassName("", "DateRange"))
369
.addStatement("return DateRange(this, other)")
370
.build()
371
```
372
373
### Platform-Specific Utilities
374
375
Utilities that handle platform differences and provide multiplatform support.
376
377
```kotlin { .api }
378
// Common utilities (available on all platforms)
379
class CodePoint {
380
companion object {
381
fun isISOControl(codePoint: Int): Boolean
382
}
383
}
384
385
// Line wrapping utilities
386
class LineWrapper {
387
// Implementation varies by platform
388
}
389
390
// Platform-specific utility objects
391
object Util {
392
// Common utilities available on all platforms
393
}
394
395
// JVM-specific utilities (only available on JVM)
396
object JvmUtil {
397
// JVM-specific implementation details
398
}
399
```
400
401
**Usage Examples:**
402
403
```kotlin
404
// Unicode handling across platforms
405
val unicodeChecker = FunSpec.builder("isControlCharacter")
406
.addParameter("codePoint", Int::class)
407
.returns(Boolean::class)
408
.addStatement("return %T.isISOControl(codePoint)", CodePoint::class)
409
.build()
410
411
// Platform-specific code generation
412
val platformSpecificFunction = when (targetPlatform) {
413
Platform.JVM -> FunSpec.builder("processFile")
414
.addParameter("file", File::class)
415
.addStatement("// JVM-specific file processing")
416
.build()
417
418
Platform.JS -> FunSpec.builder("processFile")
419
.addParameter("file", Dynamic)
420
.addStatement("// JavaScript-specific file processing")
421
.build()
422
423
Platform.WASM -> FunSpec.builder("processFile")
424
.addParameter("file", String::class)
425
.addStatement("// WebAssembly-specific file processing")
426
.build()
427
}
428
```
429
430
### Helper Interfaces and Abstractions
431
432
Core interfaces that provide common functionality across KotlinPoet specifications.
433
434
```kotlin { .api }
435
/**
436
* Interface for specs that support tags
437
*/
438
interface Taggable {
439
val tags: Map<KClass<*>, Any>
440
}
441
442
/**
443
* Interface for specs that support KDoc documentation
444
*/
445
interface Documentable {
446
val kdoc: CodeBlock
447
}
448
449
/**
450
* Interface for specs that hold references to originating elements (for annotation processing)
451
*/
452
interface OriginatingElementsHolder {
453
val originatingElements: List<Element>
454
}
455
456
/**
457
* Interface for specs that contain member specifications
458
*/
459
interface MemberSpecHolder {
460
// Marker interface for type hierarchy
461
}
462
```
463
464
**Usage Examples:**
465
466
```kotlin
467
// Using tagging for metadata
468
val taggedFunction = FunSpec.builder("processData")
469
.tag(String::class, "user-generated")
470
.tag(Int::class, 42)
471
.build()
472
473
// Retrieve tags later
474
val userTag = taggedFunction.tags[String::class] as? String
475
val numberTag = taggedFunction.tags[Int::class] as? Int
476
477
// Documentation interface usage
478
val documentedClass = TypeSpec.classBuilder("UserService")
479
.addKdoc("""
480
Service for managing user operations.
481
482
This service provides CRUD operations for user entities
483
and handles business logic related to user management.
484
""".trimIndent())
485
.build()
486
487
// Check if a spec is documentable
488
fun addDocumentationIfSupported(spec: Any, doc: String) {
489
if (spec is Documentable && spec.kdoc.isEmpty) {
490
// Add documentation
491
}
492
}
493
```
494
495
### Experimental and Delicate APIs
496
497
Annotations for marking unstable or dangerous APIs.
498
499
```kotlin { .api }
500
/**
501
* Marks delicate KotlinPoet APIs that require careful usage
502
*/
503
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
504
annotation class DelicateKotlinPoetApi
505
506
/**
507
* Marks experimental KotlinPoet APIs
508
*/
509
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
510
annotation class ExperimentalKotlinPoetApi
511
```
512
513
**Usage Examples:**
514
515
```kotlin
516
// Using experimental APIs
517
@OptIn(ExperimentalKotlinPoetApi::class)
518
fun useExperimentalFeature() {
519
// Use experimental KotlinPoet features
520
}
521
522
// Using delicate APIs
523
@OptIn(DelicateKotlinPoetApi::class)
524
fun useDelicateApi() {
525
// Use delicate KotlinPoet APIs that require careful handling
526
}
527
```