Skip to content

Commit a5276f0

Browse files
committed
KCallable: call, callBy
1 parent 5dc9c07 commit a5276f0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1556
-130
lines changed

src/main/java/kotlinx/reflect/lite/KCallable.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,14 @@ public interface KCallable<out R> : KAnnotatedElement {
4444
* Throws an exception if the number of specified arguments is not equal to the size of [parameters],
4545
* or if their types do not match the types of the parameters.
4646
*/
47-
private fun call(vararg args: Any?): R = TODO()
47+
public fun call(vararg args: Any?): R
4848

4949
/**
5050
* Calls this callable with the specified mapping of parameters to arguments and returns the result.
5151
* If a parameter is not found in the mapping and is not optional (as per [KParameter.isOptional]),
5252
* or its type does not match the type of the provided value, an exception is thrown.
5353
*/
54-
private fun callBy(args: Map<KParameter, Any?>): R = TODO()
54+
public fun callBy(args: Map<KParameter, Any?>): R
5555

5656
/**
5757
* Visibility of this callable, or `null` if its visibility cannot be represented in Kotlin.

src/main/java/kotlinx/reflect/lite/KProperty.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ public interface KProperty<out V> : KCallable<V> {
2424

2525
/** The getter of this property, used to obtain the value of the property. */
2626
public val getter: Getter<V>
27-
get() = TODO("Not implemented yet")
2827

2928
/**
3029
* Represents a property accessor, which is a `get` or `set` method declared alongside the property.
@@ -75,7 +74,7 @@ public interface KProperty0<out V> : KProperty<V>, () -> V {
7574
* for more information.
7675
*/
7776
@SinceKotlin("1.1")
78-
public fun getDelegate(): Any?
77+
private fun getDelegate(): Any? = TODO()
7978

8079
override val getter: Getter<V>
8180

@@ -140,7 +139,7 @@ public interface KProperty1<T, out V> : KProperty<V>, (T) -> V {
140139
* @see [kotlin.reflect.full.getExtensionDelegate] // [KProperty1.getExtensionDelegate]
141140
*/
142141
@SinceKotlin("1.1")
143-
public fun getDelegate(receiver: T): Any?
142+
private fun getDelegate(receiver: T): Any? = TODO()
144143

145144
override val getter: Getter<T, V>
146145

@@ -211,7 +210,7 @@ public interface KProperty2<D, E, out V> : KProperty<V>, (D, E) -> V {
211210
* @see [kotlin.reflect.full.getExtensionDelegate] // [KProperty2.getExtensionDelegate]
212211
*/
213212
@SinceKotlin("1.1")
214-
public fun getDelegate(receiver1: D, receiver2: E): Any?
213+
private fun getDelegate(receiver1: D, receiver2: E): Any? = TODO()
215214

216215
override val getter: Getter<D, E, V>
217216

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package kotlinx.reflect.lite.builtins
2+
3+
object JvmAbi {
4+
fun getterName(name: String): String = "get" + name.capitalize()
5+
6+
const val INSTANCE_FIELD = "INSTANCE"
7+
const val DEFAULT_PARAMS_IMPL_SUFFIX = "\$default"
8+
const val DEFAULT_IMPLS_CLASS_NAME = "DefaultImpls"
9+
const val DEFAULT_IMPLS_SUFFIX = "$$DEFAULT_IMPLS_CLASS_NAME"
10+
const val IMPL_SUFFIX_FOR_INLINE_CLASS_MEMBERS = "-impl"
11+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copy of: https://github.com/JetBrains/kotlin/blob/master/core/reflection.jvm/src/kotlin/reflect/jvm/internal/calls/Caller.kt
2+
package kotlinx.reflect.lite.calls
3+
4+
import java.lang.reflect.Member
5+
import java.lang.reflect.Type
6+
7+
internal interface Caller<out M : Member?> {
8+
val member: M
9+
10+
val returnType: Type
11+
12+
val parameterTypes: List<Type>
13+
14+
fun checkArguments(args: Array<*>) {
15+
if (arity != args.size) {
16+
throw IllegalArgumentException("Callable expects $arity arguments, but ${args.size} were provided.")
17+
}
18+
}
19+
20+
fun call(args: Array<*>): Any?
21+
}
22+
23+
internal val Caller<*>.arity: Int
24+
get() = parameterTypes.size
25+
26+
/**
27+
* A marker interface that signifies that this caller has a "bound receiver" object which should be used as the dispatch receiver instance.
28+
*/
29+
interface BoundCaller
Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
// Copy of: https://github.com/JetBrains/kotlin/blob/master/core/reflection.jvm/src/kotlin/reflect/jvm/internal/calls/CallerImpl.kt
2+
package kotlinx.reflect.lite.calls
3+
4+
import java.lang.reflect.Member
5+
import java.lang.reflect.Modifier
6+
import java.lang.reflect.Type
7+
import java.lang.reflect.Constructor as ReflectConstructor
8+
import java.lang.reflect.Field as ReflectField
9+
import java.lang.reflect.Method as ReflectMethod
10+
11+
internal sealed class CallerImpl<out M : Member>(
12+
final override val member: M,
13+
final override val returnType: Type,
14+
val instanceClass: Class<*>?,
15+
valueParameterTypes: Array<Type>
16+
) : Caller<M> {
17+
override val parameterTypes: List<Type> =
18+
instanceClass?.let { listOf(it, *valueParameterTypes) } ?: valueParameterTypes.toList()
19+
20+
protected fun checkObjectInstance(obj: Any?) {
21+
if (obj == null || !member.declaringClass.isInstance(obj)) {
22+
throw IllegalArgumentException("An object member requires the object instance passed as the first argument.")
23+
}
24+
}
25+
26+
class Constructor(constructor: ReflectConstructor<*>) : CallerImpl<ReflectConstructor<*>>(
27+
constructor,
28+
constructor.declaringClass,
29+
constructor.declaringClass.let { klass ->
30+
val outerClass = klass.declaringClass
31+
if (outerClass != null && !Modifier.isStatic(klass.modifiers)) outerClass else null
32+
},
33+
constructor.genericParameterTypes
34+
) {
35+
override fun call(args: Array<*>): Any? {
36+
checkArguments(args)
37+
return member.newInstance(*args)
38+
}
39+
}
40+
41+
// TODO fix 'callBy' for bound (and non-bound) inner class constructor references
42+
// See https://youtrack.jetbrains.com/issue/KT-14990
43+
class BoundConstructor(constructor: ReflectConstructor<*>, private val boundReceiver: Any?) : BoundCaller,
44+
CallerImpl<ReflectConstructor<*>>(
45+
constructor, constructor.declaringClass, null,
46+
constructor.genericParameterTypes
47+
) {
48+
override fun call(args: Array<*>): Any? {
49+
checkArguments(args)
50+
return member.newInstance(boundReceiver, *args)
51+
}
52+
}
53+
54+
class AccessorForHiddenConstructor(
55+
constructor: ReflectConstructor<*>
56+
) : CallerImpl<ReflectConstructor<*>>(
57+
constructor, constructor.declaringClass, null,
58+
constructor.genericParameterTypes.dropLast()
59+
) {
60+
override fun call(args: Array<*>): Any? {
61+
checkArguments(args)
62+
return member.newInstance(*args, null)
63+
}
64+
}
65+
66+
class AccessorForHiddenBoundConstructor(
67+
constructor: ReflectConstructor<*>,
68+
private val boundReceiver: Any?
69+
) : CallerImpl<ReflectConstructor<*>>(
70+
constructor, constructor.declaringClass,
71+
null,
72+
constructor.genericParameterTypes.dropFirstAndLast()
73+
), BoundCaller {
74+
override fun call(args: Array<*>): Any? {
75+
checkArguments(args)
76+
return member.newInstance(boundReceiver, *args, null)
77+
}
78+
}
79+
80+
sealed class Method(
81+
method: ReflectMethod,
82+
requiresInstance: Boolean = !Modifier.isStatic(method.modifiers),
83+
parameterTypes: Array<Type> = method.genericParameterTypes
84+
) : CallerImpl<ReflectMethod>(
85+
method,
86+
method.genericReturnType,
87+
if (requiresInstance) method.declaringClass else null,
88+
parameterTypes
89+
) {
90+
private val isVoidMethod = returnType == Void.TYPE
91+
92+
protected fun callMethod(instance: Any?, args: Array<*>): Any? {
93+
val result = member.invoke(instance, *args)
94+
95+
// If this is a Unit function, the method returns void, Method#invoke returns null, while we should return Unit
96+
return if (isVoidMethod) Unit else result
97+
}
98+
99+
class Static(method: ReflectMethod) : Method(method) {
100+
override fun call(args: Array<*>): Any? {
101+
checkArguments(args)
102+
return callMethod(null, args)
103+
}
104+
}
105+
106+
class Instance(method: ReflectMethod) : Method(method) {
107+
override fun call(args: Array<*>): Any? {
108+
checkArguments(args)
109+
return callMethod(args[0], args.dropFirst())
110+
}
111+
}
112+
113+
class JvmStaticInObject(method: ReflectMethod) : Method(method, requiresInstance = true) {
114+
override fun call(args: Array<*>): Any? {
115+
checkArguments(args)
116+
checkObjectInstance(args.firstOrNull())
117+
return callMethod(null, args.dropFirst())
118+
}
119+
}
120+
121+
class BoundStatic(method: ReflectMethod, private val boundReceiver: Any?) : BoundCaller, Method(
122+
method, requiresInstance = false, parameterTypes = method.genericParameterTypes.dropFirst()
123+
) {
124+
override fun call(args: Array<*>): Any? {
125+
checkArguments(args)
126+
return callMethod(null, arrayOf(boundReceiver, *args))
127+
}
128+
}
129+
130+
class BoundInstance(method: ReflectMethod, private val boundReceiver: Any?) : BoundCaller,
131+
Method(method, requiresInstance = false) {
132+
override fun call(args: Array<*>): Any? {
133+
checkArguments(args)
134+
return callMethod(boundReceiver, args)
135+
}
136+
}
137+
138+
class BoundJvmStaticInObject(method: ReflectMethod) : BoundCaller, Method(method, requiresInstance = false) {
139+
override fun call(args: Array<*>): Any? {
140+
checkArguments(args)
141+
return callMethod(null, args)
142+
}
143+
}
144+
}
145+
146+
sealed class FieldGetter(
147+
field: ReflectField,
148+
requiresInstance: Boolean
149+
) : CallerImpl<ReflectField>(
150+
field,
151+
field.genericType,
152+
if (requiresInstance) field.declaringClass else null,
153+
emptyArray()
154+
) {
155+
override fun call(args: Array<*>): Any? {
156+
checkArguments(args)
157+
return member.get(if (instanceClass != null) args.first() else null)
158+
}
159+
160+
class Static(field: ReflectField) : FieldGetter(field, requiresInstance = false)
161+
162+
class Instance(field: ReflectField) : FieldGetter(field, requiresInstance = true)
163+
164+
class JvmStaticInObject(field: ReflectField) : FieldGetter(field, requiresInstance = true) {
165+
override fun checkArguments(args: Array<*>) {
166+
super.checkArguments(args)
167+
checkObjectInstance(args.firstOrNull())
168+
}
169+
}
170+
171+
class BoundInstance(field: ReflectField, private val boundReceiver: Any?) : BoundCaller,
172+
FieldGetter(field, requiresInstance = false) {
173+
override fun call(args: Array<*>): Any? {
174+
checkArguments(args)
175+
return member.get(boundReceiver)
176+
}
177+
}
178+
179+
class BoundJvmStaticInObject(field: ReflectField) : BoundCaller, FieldGetter(field, requiresInstance = false)
180+
}
181+
182+
sealed class FieldSetter(
183+
field: ReflectField,
184+
private val notNull: Boolean,
185+
requiresInstance: Boolean
186+
) : CallerImpl<ReflectField>(
187+
field,
188+
Void.TYPE,
189+
if (requiresInstance) field.declaringClass else null,
190+
arrayOf(field.genericType)
191+
) {
192+
override fun checkArguments(args: Array<*>) {
193+
super.checkArguments(args)
194+
if (notNull && args.last() == null) {
195+
throw IllegalArgumentException("null is not allowed as a value for this property.")
196+
}
197+
}
198+
199+
override fun call(args: Array<*>): Any? {
200+
checkArguments(args)
201+
return member.set(if (instanceClass != null) args.first() else null, args.last())
202+
}
203+
204+
class Static(field: ReflectField, notNull: Boolean) : FieldSetter(field, notNull, requiresInstance = false)
205+
206+
class Instance(field: ReflectField, notNull: Boolean) : FieldSetter(field, notNull, requiresInstance = true)
207+
208+
class JvmStaticInObject(field: ReflectField, notNull: Boolean) : FieldSetter(field, notNull, requiresInstance = true) {
209+
override fun checkArguments(args: Array<*>) {
210+
super.checkArguments(args)
211+
checkObjectInstance(args.firstOrNull())
212+
}
213+
}
214+
215+
class BoundInstance(field: ReflectField, notNull: Boolean, private val boundReceiver: Any?) : BoundCaller,
216+
FieldSetter(field, notNull, requiresInstance = false) {
217+
override fun call(args: Array<*>): Any {
218+
checkArguments(args)
219+
return member.set(boundReceiver, args.first())
220+
}
221+
}
222+
223+
class BoundJvmStaticInObject(field: ReflectField, notNull: Boolean) : BoundCaller,
224+
FieldSetter(field, notNull, requiresInstance = false) {
225+
override fun call(args: Array<*>): Any {
226+
checkArguments(args)
227+
return member.set(null, args.last())
228+
}
229+
}
230+
}
231+
232+
companion object {
233+
@Suppress("UNCHECKED_CAST")
234+
inline fun <reified T> Array<out T>.dropFirst(): Array<T> =
235+
if (size <= 1) emptyArray() else copyOfRange(1, size) as Array<T>
236+
237+
@Suppress("UNCHECKED_CAST")
238+
inline fun <reified T> Array<out T>.dropLast(): Array<T> =
239+
if (size <= 1) emptyArray() else copyOfRange(0, size - 1) as Array<T>
240+
241+
@Suppress("UNCHECKED_CAST")
242+
inline fun <reified T> Array<out T>.dropFirstAndLast(): Array<T> =
243+
if (size <= 2) emptyArray() else copyOfRange(1, size - 1) as Array<T>
244+
}
245+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copy of: https://github.com/JetBrains/kotlin/blob/master/core/reflection.jvm/src/kotlin/reflect/jvm/internal/calls/ThrowingCaller.kt
2+
package kotlinx.reflect.lite.calls
3+
4+
import java.lang.reflect.Type
5+
6+
internal object ThrowingCaller : Caller<Nothing?> {
7+
override val member: Nothing?
8+
get() = null
9+
10+
override val parameterTypes: List<Type>
11+
get() = emptyList()
12+
13+
override val returnType: Type
14+
get() = Void.TYPE
15+
16+
override fun call(args: Array<*>): Any? {
17+
throw UnsupportedOperationException("call/callBy are not supported for this declaration.")
18+
}
19+
}

0 commit comments

Comments
 (0)