0
# Callable System
1
2
Function and property reflection with dynamic invocation capabilities, parameter inspection, suspend function support, and extension handling for comprehensive callable manipulation.
3
4
## Capabilities
5
6
### Property Reflection
7
8
Access and manipulate properties of different receiver types with full type safety.
9
10
```kotlin { .api }
11
/**
12
* Represents a property without any kind of receiver
13
*/
14
interface KProperty0<out V> : KProperty<V>, () -> V {
15
/** Returns the current value of the property */
16
fun get(): V
17
}
18
19
/**
20
* Represents a var-property without any kind of receiver
21
*/
22
interface KMutableProperty0<V> : KProperty0<V>, KMutableProperty<V> {
23
/** Modifies the value of the property */
24
fun set(value: V)
25
}
26
27
/**
28
* Represents a property with one receiver
29
*/
30
interface KProperty1<T, out V> : KProperty<V>, (T) -> V {
31
/** Returns the current value of the property */
32
fun get(receiver: T): V
33
}
34
35
/**
36
* Represents a var-property with one receiver
37
*/
38
interface KMutableProperty1<T, V> : KProperty1<T, V>, KMutableProperty<V> {
39
/** Modifies the value of the property */
40
fun set(receiver: T, value: V)
41
}
42
```
43
44
**Usage Examples:**
45
46
```kotlin
47
class Person(var name: String, val age: Int)
48
49
val person = Person("Alice", 30)
50
51
// Access member properties
52
val nameProperty = Person::name
53
val ageProperty = Person::age
54
55
// Get property values
56
println(nameProperty.get(person)) // "Alice"
57
println(ageProperty.get(person)) // 30
58
59
// Set mutable property value
60
if (nameProperty is KMutableProperty1<Person, String>) {
61
nameProperty.set(person, "Bob")
62
println(person.name) // "Bob"
63
}
64
65
// Top-level property access
66
var globalCounter = 0
67
val counterProperty = ::globalCounter
68
69
// Access top-level property
70
println(counterProperty.get()) // 0
71
if (counterProperty is KMutableProperty0<Int>) {
72
counterProperty.set(42)
73
println(globalCounter) // 42
74
}
75
```
76
77
### Function Invocation
78
79
Dynamic function calling with parameter mapping and suspend function support.
80
81
```kotlin { .api }
82
/**
83
* Calls this callable with the specified arguments
84
*/
85
fun <R> KCallable<R>.call(vararg args: Any?): R
86
87
/**
88
* Calls this callable with arguments provided in a map
89
*/
90
fun <R> KCallable<R>.callBy(args: Map<KParameter, Any?>): R
91
92
/**
93
* Calls a callable in the current suspend context
94
*/
95
suspend fun <R> KCallable<R>.callSuspend(vararg args: Any?): R
96
97
/**
98
* Calls a callable in the current suspend context with named arguments
99
*/
100
suspend fun <R> KCallable<R>.callSuspendBy(args: Map<KParameter, Any?>): R
101
```
102
103
**Usage Examples:**
104
105
```kotlin
106
class Calculator {
107
fun add(a: Int, b: Int): Int = a + b
108
suspend fun asyncAdd(a: Int, b: Int): Int {
109
delay(100)
110
return a + b
111
}
112
}
113
114
val calc = Calculator()
115
val addFunction = Calculator::add
116
val asyncAddFunction = Calculator::asyncAdd
117
118
// Call function with positional arguments
119
val result1 = addFunction.call(calc, 5, 3) // 8
120
121
// Call function with named arguments
122
val params = addFunction.parameters
123
val argMap = mapOf(
124
params[0] to calc, // receiver
125
params[1] to 10, // first parameter
126
params[2] to 20 // second parameter
127
)
128
val result2 = addFunction.callBy(argMap) // 30
129
130
// Call suspend function
131
runBlocking {
132
val asyncResult = asyncAddFunction.callSuspend(calc, 7, 13) // 20
133
}
134
```
135
136
### Parameter Inspection
137
138
Access detailed information about function and property parameters.
139
140
```kotlin { .api }
141
/**
142
* Represents a parameter of a function or property
143
*/
144
interface KParameter {
145
/** Name of the parameter, or null if not available */
146
val name: String?
147
/** Type of the parameter */
148
val type: KType
149
/** Kind of the parameter */
150
val kind: Kind
151
/** Whether the parameter is optional (has default value) */
152
val isOptional: Boolean
153
/** Whether the parameter is vararg */
154
val isVararg: Boolean
155
156
enum class Kind {
157
INSTANCE, // 'this' instance
158
EXTENSION_RECEIVER, // extension receiver
159
VALUE, // regular parameter
160
CONTEXT // context parameter
161
}
162
}
163
164
/** Returns a parameter representing the 'this' instance */
165
val KCallable<*>.instanceParameter: KParameter?
166
167
/** Returns a parameter representing the extension receiver */
168
val KCallable<*>.extensionReceiverParameter: KParameter?
169
170
/** Returns parameters excluding 'this' and extension receiver */
171
val KCallable<*>.valueParameters: List<KParameter>
172
173
/** Returns context parameters of this callable */
174
@ExperimentalContextParameters
175
val KCallable<*>.contextParameters: List<KParameter>
176
```
177
178
**Usage Examples:**
179
180
```kotlin
181
class Example {
182
fun method(required: String, optional: Int = 42, vararg extras: String): String {
183
return "$required-$optional-${extras.joinToString()}"
184
}
185
}
186
187
fun String.extensionFunction(param: Int): String = "$this:$param"
188
189
// Inspect regular method parameters
190
val method = Example::method
191
val parameters = method.parameters
192
193
println("Total parameters: ${parameters.size}") // 4 (including receiver)
194
195
val instanceParam = method.instanceParameter
196
println("Instance parameter: ${instanceParam?.kind}") // INSTANCE
197
198
val valueParams = method.valueParameters
199
valueParams.forEach { param ->
200
println("${param.name}: ${param.type}, optional: ${param.isOptional}, vararg: ${param.isVararg}")
201
}
202
// required: kotlin.String, optional: false, vararg: false
203
// optional: kotlin.Int, optional: true, vararg: false
204
// extras: kotlin.Array<out kotlin.String>, optional: false, vararg: true
205
206
// Inspect extension function parameters
207
val extensionFunc = String::extensionFunction
208
val extReceiver = extensionFunc.extensionReceiverParameter
209
println("Extension receiver: ${extReceiver?.type}") // kotlin.String
210
```
211
212
### Parameter Lookup
213
214
Find parameters by name and build argument mappings dynamically.
215
216
```kotlin { .api }
217
/**
218
* Returns the parameter with the given name, or null if not found
219
*/
220
fun KCallable<*>.findParameterByName(name: String): KParameter?
221
```
222
223
**Usage Examples:**
224
225
```kotlin
226
fun exampleFunction(first: String, second: Int, third: Boolean = true): String {
227
return "$first-$second-$third"
228
}
229
230
val function = ::exampleFunction
231
232
// Find parameters by name
233
val firstParam = function.findParameterByName("first")
234
val secondParam = function.findParameterByName("second")
235
val thirdParam = function.findParameterByName("third")
236
237
// Build argument map dynamically
238
val args = buildMap<KParameter, Any?> {
239
firstParam?.let { put(it, "hello") }
240
secondParam?.let { put(it, 42) }
241
// third parameter omitted - will use default value
242
}
243
244
val result = function.callBy(args) // "hello-42-true"
245
```
246
247
### Property Delegation
248
249
Access property delegates for delegated properties inspection.
250
251
```kotlin { .api }
252
/**
253
* Returns the instance of a delegated extension property, or null if not delegated
254
*/
255
fun KProperty1<*, *>.getExtensionDelegate(): Any?
256
257
/**
258
* Returns the instance of a delegated member extension property, or null if not delegated
259
*/
260
fun <D> KProperty2<D, *, *>.getExtensionDelegate(receiver: D): Any?
261
262
/**
263
* Returns the delegate of this property, or null if it is not delegated
264
*/
265
fun KProperty0<*>.getDelegate(): Any?
266
fun <T> KProperty1<T, *>.getDelegate(receiver: T): Any?
267
```
268
269
**Usage Examples:**
270
271
```kotlin
272
class MyDelegate {
273
operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
274
return "delegated value"
275
}
276
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
277
println("Setting $value")
278
}
279
}
280
281
class Example {
282
var delegatedProperty: String by MyDelegate()
283
}
284
285
val example = Example()
286
val property = Example::delegatedProperty
287
288
// Access the delegate
289
val delegate = property.getDelegate(example)
290
println(delegate::class.simpleName) // "MyDelegate"
291
292
// Check if property is delegated
293
val hasDelegate = property.getDelegate(example) != null
294
println("Is delegated: $hasDelegate") // true
295
```
296
297
### Experimental Features
298
299
Context parameters are an experimental feature that allows functions to have implicit context receivers.
300
301
```kotlin { .api }
302
/**
303
* Marks an API related to Kotlin's context parameters experimental feature
304
*/
305
@RequiresOptIn(level = RequiresOptIn.Level.ERROR)
306
@Retention(AnnotationRetention.BINARY)
307
@MustBeDocumented
308
annotation class ExperimentalContextParameters
309
```