Kotlin Standard Library implementation for WebAssembly System Interface (WASI) platform providing essential I/O, time, random, UUID, and reflection capabilities.
—
The Reflection capabilities provide type introspection support for WASI applications. The implementation focuses on compile-time type reflection using Kotlin's reified generics, enabling applications to obtain runtime type information for generic type parameters.
/**
* Returns the runtime representation of the given type T.
* Uses compile-time type information to create KType instances.
* @return KType representing the type T
*/
inline fun <reified T> typeOf(): KType
/**
* Returns the runtime representation of the given type T with lazy initialization.
* Optimized version that delays KType creation until first access.
* @return KType representing the type T
*/
inline fun <reified T> typeOfLazyInit(): KType/**
* Represents a type in the Kotlin type system.
*/
interface KType {
/**
* The classifier of this type, typically a KClass.
*/
val classifier: KClassifier?
/**
* Type arguments for generic types.
*/
val arguments: List<KTypeProjection>
/**
* Whether this type is marked as nullable.
*/
val isMarkedNullable: Boolean
}// Get type information for primitive types
val stringType = typeOf<String>()
val intType = typeOf<Int>()
val booleanType = typeOf<Boolean>()
println("String type: $stringType")
println("Int type: $intType")
println("Boolean type: $booleanType")
// Check type properties
println("String is nullable: ${stringType.isMarkedNullable}") // false
println("String classifier: ${stringType.classifier}")// Compare nullable and non-nullable types
val nonNullableString = typeOf<String>()
val nullableString = typeOf<String?>()
println("Non-nullable: $nonNullableString")
println("Nullable: $nullableString")
println("Nullable marked: ${nullableString.isMarkedNullable}") // true
println("Types equal: ${nonNullableString == nullableString}") // false// Reflect on generic types
val listOfStrings = typeOf<List<String>>()
val mapOfStringToInt = typeOf<Map<String, Int>>()
val setOfNullableInts = typeOf<Set<Int?>>()
println("List<String>: $listOfStrings")
println("Map<String, Int>: $mapOfStringToInt")
println("Set<Int?>: $setOfNullableInts")
// Access type arguments
val listArgs = listOfStrings.arguments
println("List type arguments: $listArgs")
if (listArgs.isNotEmpty()) {
val elementType = listArgs[0].type
println("List element type: $elementType")
}// Analyze collection types
fun analyzeCollectionType(type: KType) {
when (type.classifier) {
List::class -> {
println("This is a List type")
val elementType = type.arguments.firstOrNull()?.type
println("Element type: $elementType")
}
Set::class -> {
println("This is a Set type")
val elementType = type.arguments.firstOrNull()?.type
println("Element type: $elementType")
}
Map::class -> {
println("This is a Map type")
val keyType = type.arguments.getOrNull(0)?.type
val valueType = type.arguments.getOrNull(1)?.type
println("Key type: $keyType")
println("Value type: $valueType")
}
else -> {
println("Unknown collection type: ${type.classifier}")
}
}
}
// Usage
analyzeCollectionType(typeOf<List<String>>())
analyzeCollectionType(typeOf<Map<String, Int>>())
analyzeCollectionType(typeOf<Set<Double>>())// Type-safe configuration system using reflection
class ConfigurationManager {
private val values = mutableMapOf<KType, Any?>()
inline fun <reified T> set(value: T) {
values[typeOf<T>()] = value
}
inline fun <reified T> get(): T? {
@Suppress("UNCHECKED_CAST")
return values[typeOf<T>()] as? T
}
inline fun <reified T> getOrDefault(defaultValue: T): T {
return get<T>() ?: defaultValue
}
inline fun <reified T> has(): Boolean {
return typeOf<T>() in values
}
}
// Usage
val config = ConfigurationManager()
config.set("localhost")
config.set(8080)
config.set(true)
val host: String? = config.get<String>()
val port: Int = config.getOrDefault(3000)
val debug: Boolean = config.getOrDefault(false)
println("Host: $host")
println("Port: $port")
println("Debug: $debug")// Type-aware serialization helper
object TypedSerializer {
private val serializers = mutableMapOf<KType, (Any?) -> String>()
private val deserializers = mutableMapOf<KType, (String) -> Any?>()
inline fun <reified T> registerSerializer(
noinline serializer: (T?) -> String,
noinline deserializer: (String) -> T?
) {
val type = typeOf<T>()
@Suppress("UNCHECKED_CAST")
serializers[type] = serializer as (Any?) -> String
@Suppress("UNCHECKED_CAST")
deserializers[type] = deserializer as (String) -> Any?
}
inline fun <reified T> serialize(value: T?): String? {
val type = typeOf<T>()
return serializers[type]?.invoke(value)
}
inline fun <reified T> deserialize(data: String): T? {
val type = typeOf<T>()
@Suppress("UNCHECKED_CAST")
return deserializers[type]?.invoke(data) as? T
}
}
// Register serializers
TypedSerializer.registerSerializer<String>(
{ it ?: "null" },
{ if (it == "null") null else it }
)
TypedSerializer.registerSerializer<Int>(
{ it?.toString() ?: "null" },
{ if (it == "null") null else it.toIntOrNull() }
)
// Use type-safe serialization
val serialized = TypedSerializer.serialize("Hello")
val deserialized: String? = TypedSerializer.deserialize(serialized ?: "")
println("Serialized: $serialized")
println("Deserialized: $deserialized")// Type-safe generic utilities
object TypeUtils {
inline fun <reified T> typeName(): String {
return typeOf<T>().toString()
}
inline fun <reified T> isNullable(): Boolean {
return typeOf<T>().isMarkedNullable
}
inline fun <reified T> isList(): Boolean {
return typeOf<T>().classifier == List::class
}
inline fun <reified T> isMap(): Boolean {
return typeOf<T>().classifier == Map::class
}
inline fun <reified Collection> getElementType(): KType? {
val type = typeOf<Collection>()
return type.arguments.firstOrNull()?.type
}
}
// Usage examples
println("String name: ${TypeUtils.typeName<String>()}")
println("String? nullable: ${TypeUtils.isNullable<String?>()}")
println("List<Int> is list: ${TypeUtils.isList<List<Int>>()}")
println("Map<String, Int> is map: ${TypeUtils.isMap<Map<String, Int>>()}")
val elementType = TypeUtils.getElementType<List<String>>()
println("List<String> element type: $elementType")// Use lazy type initialization for performance
class TypeRegistry {
private val lazyTypes = mutableMapOf<String, Lazy<KType>>()
inline fun <reified T> registerLazy(name: String) {
lazyTypes[name] = lazy { typeOfLazyInit<T>() }
}
fun getType(name: String): KType? {
return lazyTypes[name]?.value
}
fun hasType(name: String): Boolean {
return name in lazyTypes
}
}
// Register types lazily
val registry = TypeRegistry()
registry.registerLazy<String>("string")
registry.registerLazy<List<Int>>("intList")
registry.registerLazy<Map<String, Any?>>("stringMap")
// Access types only when needed
val stringType = registry.getType("string")
println("Retrieved string type: $stringType")The WASI reflection implementation uses compile-time type resolution:
typeOfLazyInit delays KType creation until first access// NOT SUPPORTED: Runtime class introspection
// val methods = SomeClass::class.members // Not available
// val properties = SomeClass::class.memberProperties // Not available
// SUPPORTED: Compile-time type information only
val type = typeOf<SomeClass>()
val classifier = type.classifier// NOT SUPPORTED: Dynamic method calls
// val method = SomeClass::class.functions.find { it.name == "someMethod" }
// method?.call(instance, args) // Not available
// SUPPORTED: Static type checking only
fun processType(type: KType) {
when (type.classifier) {
String::class -> println("Processing string type")
Int::class -> println("Processing int type")
}
}// Type comparison is efficient
val type1 = typeOf<String>()
val type2 = typeOf<String>()
val equal = type1 == type2 // Fast comparison
// Cache types for repeated use
class TypeCache {
private val stringType = typeOf<String>()
private val intType = typeOf<Int>()
fun isString(type: KType) = type == stringType
fun isInt(type: KType) = type == intType
}// Use lazy initialization for large type hierarchies
object SchemaTypes {
val userType by lazy { typeOfLazyInit<User>() }
val productType by lazy { typeOfLazyInit<Product>() }
val orderType by lazy { typeOfLazyInit<Order>() }
// Types are only created when first accessed
}// DO: Use reified generics for type safety
inline fun <reified T> processTypedValue(value: Any?): T? {
val expectedType = typeOf<T>()
// Use type information for safe casting
return value as? T
}
// DON'T: Rely on runtime class checking (not available)
// fun processValue(value: Any, clazz: Class<*>) // Not supported in WASI// DO: Cache frequently used types
object CommonTypes {
val STRING = typeOf<String>()
val INT = typeOf<Int>()
val BOOLEAN = typeOf<Boolean>()
}
// DO: Use lazy initialization for expensive type hierarchies
val complexType by lazy { typeOfLazyInit<ComplexGenericType<List<Map<String, Any?>>>>() }
// AVOID: Repeated type creation in hot paths
// Bad:
repeat(1000) {
val type = typeOf<String>() // Creates type object each time
}
// Better:
val cachedType = typeOf<String>()
repeat(1000) {
// Use cachedType
}// Recommended pattern for managing multiple types
class ApplicationTypes {
companion object {
private val types = mapOf(
"user" to typeOf<User>(),
"product" to typeOf<Product>(),
"order" to typeOf<Order>()
)
fun getType(name: String): KType? = types[name]
fun hasType(name: String): Boolean = name in types
}
}Install with Tessl CLI
npx tessl i tessl/maven-org-jetbrains-kotlin--kotlin-stdlib-wasm-wasi