0
# Type System Integration
1
2
Type representation and handling for Kotlin types within the scripting system. Provides utilities for working with Kotlin type information in a scripting context, including type creation, nullability handling, and type conversions.
3
4
## Capabilities
5
6
### KotlinType Class
7
8
Primary class for representing Kotlin types with support for nullability and class-based type creation.
9
10
```kotlin { .api }
11
/**
12
* Represents a Kotlin type within the scripting system
13
*/
14
class KotlinType private constructor(
15
/** String representation of the type name */
16
val typeName: String,
17
/** Source KClass if created from a class (marked as @Transient) */
18
@Transient val fromClass: KClass<*>?,
19
/** Whether this type is nullable */
20
val isNullable: Boolean
21
) : Serializable {
22
/**
23
* Constructs KotlinType from fully-qualified type name
24
* @param qualifiedTypeName Dot-separated type name (e.g. "org.acme.Outer.Inner")
25
* @param isNullable Whether the type should be nullable
26
*/
27
@JvmOverloads
28
constructor(qualifiedTypeName: String, isNullable: Boolean = false) :
29
this(qualifiedTypeName.removeSuffix("?"), null, isNullable = isNullable || qualifiedTypeName.endsWith('?'))
30
31
/**
32
* Constructs KotlinType from reflected KClass
33
* @param kclass The Kotlin class to create type from
34
* @param isNullable Whether the type should be nullable
35
*/
36
@JvmOverloads
37
constructor(kclass: KClass<*>, isNullable: Boolean = false) :
38
this(kclass.qualifiedName ?: error("Cannot use class $kclass as a KotlinType"), kclass, isNullable)
39
40
/**
41
* Constructs KotlinType from reflected KType
42
* @param type The Kotlin type to convert
43
*/
44
constructor(type: KType) : this(type.classifier as KClass<*>, type.isMarkedNullable)
45
46
/**
47
* Create a new KotlinType with different nullability
48
* @param isNullable Whether the new type should be nullable
49
* @return New KotlinType with specified nullability
50
*/
51
fun withNullability(isNullable: Boolean): KotlinType
52
53
override fun toString(): String
54
override fun equals(other: Any?): Boolean
55
override fun hashCode(): Int
56
}
57
```
58
59
### Type Creation Utilities
60
61
Convenient functions and extensions for creating KotlinType instances.
62
63
```kotlin { .api }
64
/**
65
* Create KotlinType from reified type parameter
66
*/
67
inline fun <reified T> kotlinType(isNullable: Boolean = false): KotlinType {
68
return KotlinType.from(T::class, isNullable)
69
}
70
71
/**
72
* Extension function to convert KClass to KotlinType
73
*/
74
fun KClass<*>.toKotlinType(isNullable: Boolean = false): KotlinType {
75
return KotlinType.from(this, isNullable)
76
}
77
78
/**
79
* Extension function to convert KType to KotlinType
80
*/
81
fun KType.toKotlinType(): KotlinType {
82
return KotlinType.from(this)
83
}
84
```
85
86
**Usage Examples:**
87
88
```kotlin
89
import kotlin.script.experimental.api.*
90
import kotlin.reflect.full.*
91
92
// Create types from classes
93
val stringType = KotlinType(String::class)
94
val nullableStringType = KotlinType(String::class, isNullable = true)
95
val intType = KotlinType(Int::class)
96
val listType = KotlinType(List::class)
97
98
// Create types from type names
99
val stringTypeFromName = KotlinType("kotlin.String")
100
val nullableIntFromName = KotlinType("kotlin.Int", isNullable = true)
101
102
// Create types from KType
103
val functionType = KotlinType(typeOf<(String) -> Int>())
104
val suspendFunctionType = KotlinType(typeOf<suspend (String) -> Int>())
105
106
// Work with nullability
107
val originalType = KotlinType(String::class, isNullable = false)
108
val nullableVersion = originalType.withNullability(true)
109
val nonNullableVersion = nullableVersion.withNullability(false)
110
111
println("Original: $originalType") // String
112
println("Nullable: $nullableVersion") // String?
113
println("Non-nullable: $nonNullableVersion") // String
114
115
// Check properties
116
println("Is nullable: ${nullableVersion.isNullable}") // true
117
println("Type name: ${originalType.typeName}") // kotlin.String
118
println("From class: ${originalType.fromClass}") // class kotlin.String
119
```
120
121
### Type Usage in Script Configuration
122
123
```kotlin
124
// Using KotlinType in script compilation configuration
125
val compilationConfig = ScriptCompilationConfiguration {
126
// Set base class for scripts
127
baseClass(KotlinType(Any::class))
128
129
// Add implicit receivers
130
implicitReceivers(
131
KotlinType(File::class),
132
KotlinType(Properties::class)
133
)
134
135
// Provide properties with specific types
136
providedProperties(mapOf(
137
"logger" to KotlinType(Logger::class),
138
"config" to KotlinType(Configuration::class),
139
"args" to KotlinType(Array<String>::class),
140
"optionalValue" to KotlinType(String::class, isNullable = true)
141
))
142
143
// Add dependencies with type information
144
dependencies.append(JvmDependency("org.slf4j:slf4j-api:1.7.36"))
145
}
146
147
// Using KotlinType in script evaluation configuration
148
val evaluationConfig = ScriptEvaluationConfiguration {
149
// Provide implicit receivers as actual objects
150
implicitReceivers(
151
File(System.getProperty("user.dir")),
152
System.getProperties()
153
)
154
155
// Context variables with type safety
156
contextVariables(mapOf(
157
"database" to getDatabaseConnection(), // Type inferred
158
"timeout" to Duration.ofSeconds(30) // Type inferred
159
))
160
}
161
```
162
163
### Advanced Type Operations
164
165
```kotlin
166
// Complex type creation and manipulation
167
class TypeManager {
168
private val typeCache = mutableMapOf<String, KotlinType>()
169
170
fun getOrCreateType(className: String, isNullable: Boolean = false): KotlinType? {
171
val cacheKey = "$className:$isNullable"
172
return typeCache.getOrPut(cacheKey) {
173
try {
174
val kClass = Class.forName(className).kotlin
175
KotlinType.from(kClass, isNullable)
176
} catch (e: ClassNotFoundException) {
177
return null
178
}
179
}
180
}
181
182
fun createGenericType(baseClassName: String, typeArguments: List<KotlinType>): KotlinType? {
183
// This would require more complex type construction
184
// For demonstration purposes, simplified
185
return getOrCreateType(baseClassName)
186
}
187
}
188
189
// Using type manager
190
val typeManager = TypeManager()
191
val stringType = typeManager.getOrCreateType("kotlin.String")
192
val nullableIntType = typeManager.getOrCreateType("kotlin.Int", isNullable = true)
193
```
194
195
### Type Validation and Conversion
196
197
```kotlin
198
// Type validation utilities
199
object TypeValidator {
200
fun isAssignableFrom(target: KotlinType, source: KotlinType): Boolean {
201
// Simplified validation logic
202
if (target.typeName == source.typeName) {
203
return !target.isNullable || source.isNullable
204
}
205
206
// Check if source can be assigned to target
207
val targetClass = target.fromClass
208
val sourceClass = source.fromClass
209
210
return if (targetClass != null && sourceClass != null) {
211
targetClass.isInstance(sourceClass) || sourceClass.isSubclassOf(targetClass)
212
} else {
213
false
214
}
215
}
216
217
fun canBeNull(type: KotlinType): Boolean = type.isNullable
218
219
fun makeNullable(type: KotlinType): KotlinType = type.withNullability(true)
220
fun makeNonNull(type: KotlinType): KotlinType = type.withNullability(false)
221
}
222
223
// Type conversion utilities
224
object TypeConverter {
225
fun convertValue(value: Any?, targetType: KotlinType): Any? {
226
if (value == null) {
227
return if (targetType.isNullable) null
228
else throw IllegalArgumentException("Cannot assign null to non-nullable type")
229
}
230
231
// Simplified conversion logic
232
return when (targetType.typeName) {
233
"kotlin.String" -> value.toString()
234
"kotlin.Int" -> when (value) {
235
is Number -> value.toInt()
236
is String -> value.toIntOrNull()
237
else -> null
238
}
239
"kotlin.Boolean" -> when (value) {
240
is Boolean -> value
241
is String -> value.toBooleanStrictOrNull()
242
else -> null
243
}
244
else -> value
245
}
246
}
247
}
248
```
249
250
### Collection Type Handling
251
252
```kotlin
253
// Working with collection types
254
fun createCollectionTypes(): Map<String, KotlinType> {
255
return mapOf(
256
"stringList" to kotlinType<List<String>>(),
257
"nullableStringList" to kotlinType<List<String?>>(),
258
"stringToIntMap" to kotlinType<Map<String, Int>>(),
259
"mutableIntSet" to kotlinType<MutableSet<Int>>(),
260
"arrayOfStrings" to kotlinType<Array<String>>(),
261
"intArray" to kotlinType<IntArray>()
262
)
263
}
264
265
// Function type handling
266
fun createFunctionTypes(): Map<String, KotlinType> {
267
return mapOf(
268
"stringTransform" to typeOf<(String) -> String>().toKotlinType(),
269
"suspendStringTransform" to typeOf<suspend (String) -> String>().toKotlinType(),
270
"predicate" to typeOf<(String) -> Boolean>().toKotlinType(),
271
"callback" to typeOf<(Result<String>) -> Unit>().toKotlinType(),
272
"supplier" to typeOf<() -> String>().toKotlinType()
273
)
274
}
275
276
// Using collection and function types in configuration
277
val advancedConfig = ScriptCompilationConfiguration {
278
providedProperties(mapOf(
279
"items" to kotlinType<List<String>>(),
280
"processor" to typeOf<(String) -> String>().toKotlinType(),
281
"validator" to typeOf<(String) -> Boolean>().toKotlinType(),
282
"results" to kotlinType<MutableMap<String, Any?>>(),
283
"callback" to typeOf<suspend (Result<Any>) -> Unit>().toKotlinType()
284
))
285
}
286
```
287
288
### Integration with Reflection
289
290
```kotlin
291
// Type reflection utilities
292
object TypeReflectionUtils {
293
fun getTypeInfo(type: KotlinType): TypeInfo {
294
val kClass = type.fromClass
295
return TypeInfo(
296
typeName = type.typeName,
297
isNullable = type.isNullable,
298
isInterface = kClass?.isData == true,
299
isData = kClass?.isData == true,
300
isSealed = kClass?.isSealed == true,
301
constructors = kClass?.constructors?.size ?: 0,
302
properties = kClass?.memberProperties?.size ?: 0,
303
functions = kClass?.memberFunctions?.size ?: 0
304
)
305
}
306
307
fun validateTypeUsage(type: KotlinType, value: Any?): ValidationResult {
308
if (value == null) {
309
return if (type.isNullable) {
310
ValidationResult.Success
311
} else {
312
ValidationResult.Error("Null value for non-nullable type ${type.typeName}")
313
}
314
}
315
316
val valueClass = value::class
317
val targetClass = type.fromClass
318
319
return if (targetClass != null && targetClass.isInstance(value)) {
320
ValidationResult.Success
321
} else {
322
ValidationResult.Error("Value of type ${valueClass.simpleName} cannot be assigned to ${type.typeName}")
323
}
324
}
325
}
326
327
data class TypeInfo(
328
val typeName: String,
329
val isNullable: Boolean,
330
val isInterface: Boolean,
331
val isData: Boolean,
332
val isSealed: Boolean,
333
val constructors: Int,
334
val properties: Int,
335
val functions: Int
336
)
337
338
sealed class ValidationResult {
339
object Success : ValidationResult()
340
data class Error(val message: String) : ValidationResult()
341
}
342
```