Support mapping of KType to j.l.reflect.Type
This commit is contained in:
@@ -17,20 +17,23 @@
|
||||
package kotlin.reflect.jvm.internal
|
||||
|
||||
import java.lang.reflect.Member
|
||||
import java.lang.reflect.Modifier
|
||||
import java.lang.reflect.Type
|
||||
import java.lang.reflect.Constructor as ReflectConstructor
|
||||
import java.lang.reflect.Field as ReflectField
|
||||
import java.lang.reflect.Method as ReflectMethod
|
||||
|
||||
internal sealed class FunctionCaller(
|
||||
private val expectedArgumentNumber: Int
|
||||
) {
|
||||
internal abstract class FunctionCaller {
|
||||
abstract val member: Member
|
||||
|
||||
abstract val returnType: Type
|
||||
abstract val parameterTypes: List<Type>
|
||||
|
||||
abstract fun call(args: Array<*>): Any?
|
||||
|
||||
protected open fun checkArguments(args: Array<*>) {
|
||||
if (expectedArgumentNumber != args.size()) {
|
||||
throw IllegalArgumentException("Callable expects $expectedArgumentNumber arguments, but ${args.size()} were provided.")
|
||||
if (parameterTypes.size() != args.size()) {
|
||||
throw IllegalArgumentException("Callable expects ${parameterTypes.size()} arguments, but ${args.size()} were provided.")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,9 +43,16 @@ internal sealed class FunctionCaller(
|
||||
}
|
||||
}
|
||||
|
||||
class Constructor(val constructor: ReflectConstructor<*>) : FunctionCaller(constructor.parameterTypes.size()) {
|
||||
class Constructor(val constructor: ReflectConstructor<*>) : FunctionCaller() {
|
||||
override val member: Member get() = constructor
|
||||
|
||||
override val returnType = constructor.declaringClass
|
||||
|
||||
override val parameterTypes =
|
||||
if (returnType.declaringClass == null || Modifier.isStatic(returnType.modifiers))
|
||||
constructor.genericParameterTypes.toList()
|
||||
else listOf(returnType.declaringClass, *constructor.genericParameterTypes)
|
||||
|
||||
override fun call(args: Array<*>): Any? {
|
||||
checkArguments(args)
|
||||
return constructor.newInstance(*args)
|
||||
@@ -51,10 +61,17 @@ internal sealed class FunctionCaller(
|
||||
|
||||
abstract class Method(
|
||||
val method: ReflectMethod,
|
||||
requiresInstance: Boolean
|
||||
) : FunctionCaller(method.parameterTypes.size() + (if (requiresInstance) 1 else 0)) {
|
||||
private val requiresInstance: Boolean
|
||||
) : FunctionCaller() {
|
||||
override val member: Member get() = method
|
||||
private val isVoidMethod = method.returnType == Void.TYPE
|
||||
|
||||
override val returnType = method.genericReturnType
|
||||
|
||||
override val parameterTypes =
|
||||
if (requiresInstance) listOf(method.declaringClass, *method.genericParameterTypes)
|
||||
else method.genericParameterTypes.toList()
|
||||
|
||||
private val isVoidMethod = returnType == Void.TYPE
|
||||
|
||||
protected fun callMethod(instance: Any?, args: Array<*>): Any? {
|
||||
val result = method.invoke(instance, *args)
|
||||
@@ -86,14 +103,19 @@ internal sealed class FunctionCaller(
|
||||
}
|
||||
}
|
||||
|
||||
abstract class FieldAccessor(val field: ReflectField, expectedArgumentNumber: Int) : FunctionCaller(expectedArgumentNumber) {
|
||||
abstract class FieldAccessor(val field: ReflectField) : FunctionCaller() {
|
||||
override val member: Member get() = field
|
||||
}
|
||||
|
||||
abstract class FieldGetter(
|
||||
field: ReflectField,
|
||||
private val requiresInstance: Boolean
|
||||
) : FieldAccessor(field, if (requiresInstance) 1 else 0) {
|
||||
) : FieldAccessor(field) {
|
||||
override val returnType = field.genericType
|
||||
|
||||
override val parameterTypes =
|
||||
if (requiresInstance) listOf(field.declaringClass) else listOf()
|
||||
|
||||
override fun call(args: Array<*>): Any? {
|
||||
checkArguments(args)
|
||||
return field.get(if (requiresInstance) args.first() else null)
|
||||
@@ -104,7 +126,13 @@ internal sealed class FunctionCaller(
|
||||
field: ReflectField,
|
||||
private val notNull: Boolean,
|
||||
private val requiresInstance: Boolean
|
||||
) : FieldAccessor(field, if (requiresInstance) 2 else 1) {
|
||||
) : FieldAccessor(field) {
|
||||
override val returnType: Type get() = Void.TYPE
|
||||
|
||||
override val parameterTypes =
|
||||
if (requiresInstance) listOf(field.declaringClass, field.genericType)
|
||||
else listOf(field.genericType)
|
||||
|
||||
override fun checkArguments(args: Array<*>) {
|
||||
super.checkArguments(args)
|
||||
if (notNull && args.last() == null) {
|
||||
|
||||
@@ -36,15 +36,15 @@ interface KCallableImpl<out R> : KCallable<R>, KAnnotatedElementImpl {
|
||||
var index = 0
|
||||
|
||||
if (descriptor.dispatchReceiverParameter != null) {
|
||||
result.add(KParameterImpl(index++) { descriptor.dispatchReceiverParameter!! })
|
||||
result.add(KParameterImpl(this, index++) { descriptor.dispatchReceiverParameter!! })
|
||||
}
|
||||
|
||||
if (descriptor.extensionReceiverParameter != null) {
|
||||
result.add(KParameterImpl(index++) { descriptor.extensionReceiverParameter!! })
|
||||
result.add(KParameterImpl(this, index++) { descriptor.extensionReceiverParameter!! })
|
||||
}
|
||||
|
||||
for (i in descriptor.valueParameters.indices) {
|
||||
result.add(KParameterImpl(index++) { descriptor.valueParameters[i] })
|
||||
result.add(KParameterImpl(this, index++) { descriptor.valueParameters[i] })
|
||||
}
|
||||
|
||||
result.trimToSize()
|
||||
@@ -52,7 +52,7 @@ interface KCallableImpl<out R> : KCallable<R>, KAnnotatedElementImpl {
|
||||
}
|
||||
|
||||
override val returnType: KType
|
||||
get() = KTypeImpl(descriptor.returnType!!)
|
||||
get() = KTypeImpl(descriptor.returnType!!) { caller.returnType }
|
||||
|
||||
@suppress("UNCHECKED_CAST")
|
||||
override fun call(vararg args: Any?): R = reflectionCall {
|
||||
|
||||
@@ -23,8 +23,9 @@ import kotlin.reflect.KParameter
|
||||
import kotlin.reflect.KType
|
||||
|
||||
class KParameterImpl(
|
||||
val callable: KCallableImpl<*>,
|
||||
override val index: Int,
|
||||
private val computeDescriptor: () -> ParameterDescriptor
|
||||
computeDescriptor: () -> ParameterDescriptor
|
||||
) : KParameter, KAnnotatedElementImpl {
|
||||
private val descriptor: ParameterDescriptor by ReflectProperties.lazySoft(computeDescriptor)
|
||||
|
||||
@@ -38,5 +39,5 @@ class KParameterImpl(
|
||||
}
|
||||
|
||||
override val type: KType
|
||||
get() = KTypeImpl(descriptor.getType())
|
||||
get() = KTypeImpl(descriptor.type) { callable.caller.parameterTypes[index] }
|
||||
}
|
||||
|
||||
@@ -17,9 +17,15 @@
|
||||
package kotlin.reflect.jvm.internal
|
||||
|
||||
import org.jetbrains.kotlin.types.JetType
|
||||
import java.lang.reflect.Type
|
||||
import kotlin.reflect.KType
|
||||
|
||||
class KTypeImpl(val type: JetType) : KType {
|
||||
class KTypeImpl(
|
||||
val type: JetType,
|
||||
computeJavaType: () -> Type
|
||||
) : KType {
|
||||
internal val javaType: Type by ReflectProperties.lazySoft(computeJavaType)
|
||||
|
||||
override val isMarkedNullable: Boolean
|
||||
get() = type.isMarkedNullable
|
||||
}
|
||||
|
||||
@@ -16,10 +16,7 @@
|
||||
|
||||
package kotlin.reflect.jvm
|
||||
|
||||
import java.lang.reflect.Constructor
|
||||
import java.lang.reflect.Field
|
||||
import java.lang.reflect.Method
|
||||
import java.lang.reflect.Modifier
|
||||
import java.lang.reflect.*
|
||||
import kotlin.jvm.internal.Intrinsic
|
||||
import kotlin.reflect.*
|
||||
import kotlin.reflect.jvm.internal.*
|
||||
@@ -87,6 +84,15 @@ public val <T> KFunction<T>.javaConstructor: Constructor<T>?
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a Java [Type] instance corresponding to the given Kotlin type.
|
||||
* Note that one Kotlin type may correspond to different JVM types depending on where it appears. For example, [Unit] corresponds to
|
||||
* the JVM class [Unit] when it's the type of a parameter, or to `void` when it's the return type of a function.
|
||||
*/
|
||||
public val KType.javaType: Type
|
||||
get() = (this as KTypeImpl).javaType
|
||||
|
||||
|
||||
|
||||
// Java reflection -> Kotlin reflection
|
||||
|
||||
|
||||
Reference in New Issue
Block a user