or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

console-io.mdexceptions.mdindex.mdrandom.mdreflection.mdtime.mduuid.md

reflection.mddocs/

0

# Reflection Capabilities

1

2

## Overview

3

4

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.

5

6

## API Reference

7

8

### Type Reflection Functions

9

10

```kotlin { .api }

11

/**

12

* Returns the runtime representation of the given type T.

13

* Uses compile-time type information to create KType instances.

14

* @return KType representing the type T

15

*/

16

inline fun <reified T> typeOf(): KType

17

18

/**

19

* Returns the runtime representation of the given type T with lazy initialization.

20

* Optimized version that delays KType creation until first access.

21

* @return KType representing the type T

22

*/

23

inline fun <reified T> typeOfLazyInit(): KType

24

```

25

26

### KType Interface

27

28

```kotlin { .api }

29

/**

30

* Represents a type in the Kotlin type system.

31

*/

32

interface KType {

33

/**

34

* The classifier of this type, typically a KClass.

35

*/

36

val classifier: KClassifier?

37

38

/**

39

* Type arguments for generic types.

40

*/

41

val arguments: List<KTypeProjection>

42

43

/**

44

* Whether this type is marked as nullable.

45

*/

46

val isMarkedNullable: Boolean

47

}

48

```

49

50

## Usage Examples

51

52

### Basic Type Reflection

53

54

```kotlin

55

// Get type information for primitive types

56

val stringType = typeOf<String>()

57

val intType = typeOf<Int>()

58

val booleanType = typeOf<Boolean>()

59

60

println("String type: $stringType")

61

println("Int type: $intType")

62

println("Boolean type: $booleanType")

63

64

// Check type properties

65

println("String is nullable: ${stringType.isMarkedNullable}") // false

66

println("String classifier: ${stringType.classifier}")

67

```

68

69

### Nullable Type Reflection

70

71

```kotlin

72

// Compare nullable and non-nullable types

73

val nonNullableString = typeOf<String>()

74

val nullableString = typeOf<String?>()

75

76

println("Non-nullable: $nonNullableString")

77

println("Nullable: $nullableString")

78

println("Nullable marked: ${nullableString.isMarkedNullable}") // true

79

println("Types equal: ${nonNullableString == nullableString}") // false

80

```

81

82

### Generic Type Reflection

83

84

```kotlin

85

// Reflect on generic types

86

val listOfStrings = typeOf<List<String>>()

87

val mapOfStringToInt = typeOf<Map<String, Int>>()

88

val setOfNullableInts = typeOf<Set<Int?>>()

89

90

println("List<String>: $listOfStrings")

91

println("Map<String, Int>: $mapOfStringToInt")

92

println("Set<Int?>: $setOfNullableInts")

93

94

// Access type arguments

95

val listArgs = listOfStrings.arguments

96

println("List type arguments: $listArgs")

97

if (listArgs.isNotEmpty()) {

98

val elementType = listArgs[0].type

99

println("List element type: $elementType")

100

}

101

```

102

103

### Collection Type Analysis

104

105

```kotlin

106

// Analyze collection types

107

fun analyzeCollectionType(type: KType) {

108

when (type.classifier) {

109

List::class -> {

110

println("This is a List type")

111

val elementType = type.arguments.firstOrNull()?.type

112

println("Element type: $elementType")

113

}

114

Set::class -> {

115

println("This is a Set type")

116

val elementType = type.arguments.firstOrNull()?.type

117

println("Element type: $elementType")

118

}

119

Map::class -> {

120

println("This is a Map type")

121

val keyType = type.arguments.getOrNull(0)?.type

122

val valueType = type.arguments.getOrNull(1)?.type

123

println("Key type: $keyType")

124

println("Value type: $valueType")

125

}

126

else -> {

127

println("Unknown collection type: ${type.classifier}")

128

}

129

}

130

}

131

132

// Usage

133

analyzeCollectionType(typeOf<List<String>>())

134

analyzeCollectionType(typeOf<Map<String, Int>>())

135

analyzeCollectionType(typeOf<Set<Double>>())

136

```

137

138

### Type-Safe Configuration

139

140

```kotlin

141

// Type-safe configuration system using reflection

142

class ConfigurationManager {

143

private val values = mutableMapOf<KType, Any?>()

144

145

inline fun <reified T> set(value: T) {

146

values[typeOf<T>()] = value

147

}

148

149

inline fun <reified T> get(): T? {

150

@Suppress("UNCHECKED_CAST")

151

return values[typeOf<T>()] as? T

152

}

153

154

inline fun <reified T> getOrDefault(defaultValue: T): T {

155

return get<T>() ?: defaultValue

156

}

157

158

inline fun <reified T> has(): Boolean {

159

return typeOf<T>() in values

160

}

161

}

162

163

// Usage

164

val config = ConfigurationManager()

165

166

config.set("localhost")

167

config.set(8080)

168

config.set(true)

169

170

val host: String? = config.get<String>()

171

val port: Int = config.getOrDefault(3000)

172

val debug: Boolean = config.getOrDefault(false)

173

174

println("Host: $host")

175

println("Port: $port")

176

println("Debug: $debug")

177

```

178

179

### Serialization Support

180

181

```kotlin

182

// Type-aware serialization helper

183

object TypedSerializer {

184

private val serializers = mutableMapOf<KType, (Any?) -> String>()

185

private val deserializers = mutableMapOf<KType, (String) -> Any?>()

186

187

inline fun <reified T> registerSerializer(

188

noinline serializer: (T?) -> String,

189

noinline deserializer: (String) -> T?

190

) {

191

val type = typeOf<T>()

192

@Suppress("UNCHECKED_CAST")

193

serializers[type] = serializer as (Any?) -> String

194

@Suppress("UNCHECKED_CAST")

195

deserializers[type] = deserializer as (String) -> Any?

196

}

197

198

inline fun <reified T> serialize(value: T?): String? {

199

val type = typeOf<T>()

200

return serializers[type]?.invoke(value)

201

}

202

203

inline fun <reified T> deserialize(data: String): T? {

204

val type = typeOf<T>()

205

@Suppress("UNCHECKED_CAST")

206

return deserializers[type]?.invoke(data) as? T

207

}

208

}

209

210

// Register serializers

211

TypedSerializer.registerSerializer<String>(

212

{ it ?: "null" },

213

{ if (it == "null") null else it }

214

)

215

216

TypedSerializer.registerSerializer<Int>(

217

{ it?.toString() ?: "null" },

218

{ if (it == "null") null else it.toIntOrNull() }

219

)

220

221

// Use type-safe serialization

222

val serialized = TypedSerializer.serialize("Hello")

223

val deserialized: String? = TypedSerializer.deserialize(serialized ?: "")

224

println("Serialized: $serialized")

225

println("Deserialized: $deserialized")

226

```

227

228

### Generic Function Utilities

229

230

```kotlin

231

// Type-safe generic utilities

232

object TypeUtils {

233

inline fun <reified T> typeName(): String {

234

return typeOf<T>().toString()

235

}

236

237

inline fun <reified T> isNullable(): Boolean {

238

return typeOf<T>().isMarkedNullable

239

}

240

241

inline fun <reified T> isList(): Boolean {

242

return typeOf<T>().classifier == List::class

243

}

244

245

inline fun <reified T> isMap(): Boolean {

246

return typeOf<T>().classifier == Map::class

247

}

248

249

inline fun <reified Collection> getElementType(): KType? {

250

val type = typeOf<Collection>()

251

return type.arguments.firstOrNull()?.type

252

}

253

}

254

255

// Usage examples

256

println("String name: ${TypeUtils.typeName<String>()}")

257

println("String? nullable: ${TypeUtils.isNullable<String?>()}")

258

println("List<Int> is list: ${TypeUtils.isList<List<Int>>()}")

259

println("Map<String, Int> is map: ${TypeUtils.isMap<Map<String, Int>>()}")

260

261

val elementType = TypeUtils.getElementType<List<String>>()

262

println("List<String> element type: $elementType")

263

```

264

265

### Lazy Type Initialization

266

267

```kotlin

268

// Use lazy type initialization for performance

269

class TypeRegistry {

270

private val lazyTypes = mutableMapOf<String, Lazy<KType>>()

271

272

inline fun <reified T> registerLazy(name: String) {

273

lazyTypes[name] = lazy { typeOfLazyInit<T>() }

274

}

275

276

fun getType(name: String): KType? {

277

return lazyTypes[name]?.value

278

}

279

280

fun hasType(name: String): Boolean {

281

return name in lazyTypes

282

}

283

}

284

285

// Register types lazily

286

val registry = TypeRegistry()

287

registry.registerLazy<String>("string")

288

registry.registerLazy<List<Int>>("intList")

289

registry.registerLazy<Map<String, Any?>>("stringMap")

290

291

// Access types only when needed

292

val stringType = registry.getType("string")

293

println("Retrieved string type: $stringType")

294

```

295

296

## Implementation Details

297

298

### Compile-Time Type Resolution

299

300

The WASI reflection implementation uses compile-time type resolution:

301

302

- **Reified Generics**: Type parameters are resolved at compile time

303

- **No Runtime Class Loading**: No dynamic class loading or bytecode analysis

304

- **Static Type Information**: All type information is embedded at compile time

305

306

### Memory Efficiency

307

308

- **Lazy Initialization**: `typeOfLazyInit` delays KType creation until first access

309

- **Type Caching**: Identical types may be cached to reduce memory usage

310

- **Minimal Overhead**: No heavy reflection infrastructure in WASI environment

311

312

### Limitations

313

314

#### No Runtime Class Analysis

315

316

```kotlin

317

// NOT SUPPORTED: Runtime class introspection

318

// val methods = SomeClass::class.members // Not available

319

// val properties = SomeClass::class.memberProperties // Not available

320

321

// SUPPORTED: Compile-time type information only

322

val type = typeOf<SomeClass>()

323

val classifier = type.classifier

324

```

325

326

#### No Dynamic Method Invocation

327

328

```kotlin

329

// NOT SUPPORTED: Dynamic method calls

330

// val method = SomeClass::class.functions.find { it.name == "someMethod" }

331

// method?.call(instance, args) // Not available

332

333

// SUPPORTED: Static type checking only

334

fun processType(type: KType) {

335

when (type.classifier) {

336

String::class -> println("Processing string type")

337

Int::class -> println("Processing int type")

338

}

339

}

340

```

341

342

## Performance Considerations

343

344

### Type Comparison Performance

345

346

```kotlin

347

// Type comparison is efficient

348

val type1 = typeOf<String>()

349

val type2 = typeOf<String>()

350

val equal = type1 == type2 // Fast comparison

351

352

// Cache types for repeated use

353

class TypeCache {

354

private val stringType = typeOf<String>()

355

private val intType = typeOf<Int>()

356

357

fun isString(type: KType) = type == stringType

358

fun isInt(type: KType) = type == intType

359

}

360

```

361

362

### Lazy Initialization Benefits

363

364

```kotlin

365

// Use lazy initialization for large type hierarchies

366

object SchemaTypes {

367

val userType by lazy { typeOfLazyInit<User>() }

368

val productType by lazy { typeOfLazyInit<Product>() }

369

val orderType by lazy { typeOfLazyInit<Order>() }

370

// Types are only created when first accessed

371

}

372

```

373

374

## Best Practices

375

376

### Type Safety

377

378

```kotlin

379

// DO: Use reified generics for type safety

380

inline fun <reified T> processTypedValue(value: Any?): T? {

381

val expectedType = typeOf<T>()

382

// Use type information for safe casting

383

return value as? T

384

}

385

386

// DON'T: Rely on runtime class checking (not available)

387

// fun processValue(value: Any, clazz: Class<*>) // Not supported in WASI

388

```

389

390

### Performance Optimization

391

392

```kotlin

393

// DO: Cache frequently used types

394

object CommonTypes {

395

val STRING = typeOf<String>()

396

val INT = typeOf<Int>()

397

val BOOLEAN = typeOf<Boolean>()

398

}

399

400

// DO: Use lazy initialization for expensive type hierarchies

401

val complexType by lazy { typeOfLazyInit<ComplexGenericType<List<Map<String, Any?>>>>() }

402

403

// AVOID: Repeated type creation in hot paths

404

// Bad:

405

repeat(1000) {

406

val type = typeOf<String>() // Creates type object each time

407

}

408

409

// Better:

410

val cachedType = typeOf<String>()

411

repeat(1000) {

412

// Use cachedType

413

}

414

```

415

416

### Type Registry Pattern

417

418

```kotlin

419

// Recommended pattern for managing multiple types

420

class ApplicationTypes {

421

companion object {

422

private val types = mapOf(

423

"user" to typeOf<User>(),

424

"product" to typeOf<Product>(),

425

"order" to typeOf<Order>()

426

)

427

428

fun getType(name: String): KType? = types[name]

429

fun hasType(name: String): Boolean = name in types

430

}

431

}

432

```