Refactor and simplify FunctionCaller
This commit is contained in:
@@ -23,11 +23,15 @@ import java.lang.reflect.Constructor as ReflectConstructor
|
||||
import java.lang.reflect.Field as ReflectField
|
||||
import java.lang.reflect.Method as ReflectMethod
|
||||
|
||||
internal abstract class FunctionCaller {
|
||||
abstract val member: Member
|
||||
|
||||
abstract val returnType: Type
|
||||
abstract val parameterTypes: List<Type>
|
||||
internal abstract class FunctionCaller<out M : Member>(
|
||||
internal val member: M,
|
||||
internal val returnType: Type,
|
||||
internal val instanceClass: Class<*>?,
|
||||
valueParameterTypes: Array<Type>
|
||||
) {
|
||||
internal val parameterTypes: List<Type> =
|
||||
instanceClass?.let { listOf(it, *valueParameterTypes) } ?:
|
||||
valueParameterTypes.toList()
|
||||
|
||||
abstract fun call(args: Array<*>): Any?
|
||||
|
||||
@@ -43,52 +47,52 @@ internal abstract class FunctionCaller {
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
// Constructors
|
||||
|
||||
class Constructor(constructor: ReflectConstructor<*>) : FunctionCaller<ReflectConstructor<*>>(
|
||||
constructor,
|
||||
constructor.declaringClass,
|
||||
constructor.declaringClass.let { klass ->
|
||||
val outerClass = klass.declaringClass
|
||||
if (outerClass != null && !Modifier.isStatic(klass.modifiers)) outerClass else null
|
||||
},
|
||||
constructor.genericParameterTypes
|
||||
) {
|
||||
override fun call(args: Array<*>): Any? {
|
||||
checkArguments(args)
|
||||
return constructor.newInstance(*args)
|
||||
return member.newInstance(*args)
|
||||
}
|
||||
}
|
||||
|
||||
// Methods
|
||||
|
||||
abstract class Method(
|
||||
val method: ReflectMethod,
|
||||
private val requiresInstance: Boolean
|
||||
) : FunctionCaller() {
|
||||
override val member: Member get() = method
|
||||
|
||||
override val returnType = method.genericReturnType
|
||||
|
||||
override val parameterTypes =
|
||||
if (requiresInstance) listOf(method.declaringClass, *method.genericParameterTypes)
|
||||
else method.genericParameterTypes.toList()
|
||||
|
||||
method: ReflectMethod,
|
||||
requiresInstance: Boolean = !Modifier.isStatic(method.modifiers)
|
||||
) : FunctionCaller<ReflectMethod>(
|
||||
method,
|
||||
method.genericReturnType,
|
||||
if (requiresInstance) method.declaringClass else null,
|
||||
method.genericParameterTypes
|
||||
) {
|
||||
private val isVoidMethod = returnType == Void.TYPE
|
||||
|
||||
protected fun callMethod(instance: Any?, args: Array<*>): Any? {
|
||||
val result = method.invoke(instance, *args)
|
||||
val result = member.invoke(instance, *args)
|
||||
|
||||
// If this is a Unit function, the method returns void, Method#invoke returns null, while we should return Unit
|
||||
return if (isVoidMethod) Unit else result
|
||||
}
|
||||
}
|
||||
|
||||
class StaticMethod(method: ReflectMethod) : Method(method, requiresInstance = false) {
|
||||
class StaticMethod(method: ReflectMethod) : Method(method) {
|
||||
override fun call(args: Array<*>): Any? {
|
||||
checkArguments(args)
|
||||
return callMethod(null, args)
|
||||
}
|
||||
}
|
||||
|
||||
class InstanceMethod(method: ReflectMethod) : Method(method, requiresInstance = true) {
|
||||
class InstanceMethod(method: ReflectMethod) : Method(method) {
|
||||
override fun call(args: Array<*>): Any? {
|
||||
checkArguments(args)
|
||||
return callMethod(args[0], args.asList().subList(1, args.size()).toTypedArray())
|
||||
@@ -103,36 +107,33 @@ internal abstract class FunctionCaller {
|
||||
}
|
||||
}
|
||||
|
||||
abstract class FieldAccessor(val field: ReflectField) : FunctionCaller() {
|
||||
override val member: Member get() = field
|
||||
}
|
||||
// Field accessors
|
||||
|
||||
abstract class FieldGetter(
|
||||
field: ReflectField,
|
||||
private val requiresInstance: Boolean
|
||||
) : FieldAccessor(field) {
|
||||
override val returnType = field.genericType
|
||||
|
||||
override val parameterTypes =
|
||||
if (requiresInstance) listOf(field.declaringClass) else listOf()
|
||||
|
||||
requiresInstance: Boolean = !Modifier.isStatic(field.modifiers)
|
||||
) : FunctionCaller<ReflectField>(
|
||||
field,
|
||||
field.genericType,
|
||||
if (requiresInstance) field.declaringClass else null,
|
||||
emptyArray()
|
||||
) {
|
||||
override fun call(args: Array<*>): Any? {
|
||||
checkArguments(args)
|
||||
return field.get(if (requiresInstance) args.first() else null)
|
||||
return member.get(if (instanceClass != null) args.first() else null)
|
||||
}
|
||||
}
|
||||
|
||||
abstract class FieldSetter(
|
||||
field: ReflectField,
|
||||
private val notNull: Boolean,
|
||||
private val requiresInstance: Boolean
|
||||
) : FieldAccessor(field) {
|
||||
override val returnType: Type get() = Void.TYPE
|
||||
|
||||
override val parameterTypes =
|
||||
if (requiresInstance) listOf(field.declaringClass, field.genericType)
|
||||
else listOf(field.genericType)
|
||||
|
||||
requiresInstance: Boolean = !Modifier.isStatic(field.modifiers)
|
||||
) : FunctionCaller<ReflectField>(
|
||||
field,
|
||||
Void.TYPE,
|
||||
if (requiresInstance) field.declaringClass else null,
|
||||
arrayOf(field.genericType)
|
||||
) {
|
||||
override fun checkArguments(args: Array<*>) {
|
||||
super.checkArguments(args)
|
||||
if (notNull && args.last() == null) {
|
||||
@@ -142,13 +143,13 @@ internal abstract class FunctionCaller {
|
||||
|
||||
override fun call(args: Array<*>): Any? {
|
||||
checkArguments(args)
|
||||
return field.set(if (requiresInstance) args.first() else null, args.last())
|
||||
return member.set(if (instanceClass != null) args.first() else null, args.last())
|
||||
}
|
||||
}
|
||||
|
||||
class StaticFieldGetter(field: ReflectField) : FieldGetter(field, requiresInstance = false)
|
||||
class StaticFieldGetter(field: ReflectField) : FieldGetter(field)
|
||||
|
||||
class InstanceFieldGetter(field: ReflectField) : FieldGetter(field, requiresInstance = true)
|
||||
class InstanceFieldGetter(field: ReflectField) : FieldGetter(field)
|
||||
|
||||
class PlatformStaticInObjectFieldGetter(field: ReflectField) : FieldGetter(field, requiresInstance = true) {
|
||||
override fun checkArguments(args: Array<*>) {
|
||||
@@ -157,9 +158,9 @@ internal abstract class FunctionCaller {
|
||||
}
|
||||
}
|
||||
|
||||
class StaticFieldSetter(field: ReflectField, notNull: Boolean) : FieldSetter(field, notNull, requiresInstance = false)
|
||||
class StaticFieldSetter(field: ReflectField, notNull: Boolean) : FieldSetter(field, notNull)
|
||||
|
||||
class InstanceFieldSetter(field: ReflectField, notNull: Boolean) : FieldSetter(field, notNull, requiresInstance = true)
|
||||
class InstanceFieldSetter(field: ReflectField, notNull: Boolean) : FieldSetter(field, notNull)
|
||||
|
||||
class PlatformStaticInObjectFieldSetter(field: ReflectField, notNull: Boolean) : FieldSetter(field, notNull, requiresInstance = true) {
|
||||
override fun checkArguments(args: Array<*>) {
|
||||
|
||||
@@ -26,7 +26,7 @@ import kotlin.reflect.KType
|
||||
interface KCallableImpl<out R> : KCallable<R>, KAnnotatedElementImpl {
|
||||
val descriptor: CallableMemberDescriptor
|
||||
|
||||
val caller: FunctionCaller
|
||||
val caller: FunctionCaller<*>
|
||||
|
||||
override val annotated: Annotated get() = descriptor
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ open class KFunctionImpl protected constructor(
|
||||
|
||||
override val name: String get() = descriptor.name.asString()
|
||||
|
||||
override val caller: FunctionCaller by ReflectProperties.lazySoft {
|
||||
override val caller: FunctionCaller<*> by ReflectProperties.lazySoft {
|
||||
val jvmSignature = RuntimeTypeMapper.mapSignature(descriptor)
|
||||
val member: Member? = when (jvmSignature) {
|
||||
is KotlinFunction ->
|
||||
|
||||
@@ -35,7 +35,7 @@ interface KPropertyImpl<out R> : KProperty<R>, KCallableImpl<R> {
|
||||
|
||||
override val name: String get() = descriptor.name.asString()
|
||||
|
||||
override val caller: FunctionCaller get() = getter.caller
|
||||
override val caller: FunctionCaller<*> get() = getter.caller
|
||||
|
||||
abstract class Accessor<out R> : KProperty.Accessor<R> {
|
||||
abstract override val property: KPropertyImpl<R>
|
||||
@@ -51,7 +51,7 @@ interface KPropertyImpl<out R> : KProperty<R>, KCallableImpl<R> {
|
||||
property.descriptor.getter ?: DescriptorFactory.createDefaultGetter(property.descriptor)
|
||||
}
|
||||
|
||||
override val caller: FunctionCaller by ReflectProperties.lazySoft {
|
||||
override val caller: FunctionCaller<*> by ReflectProperties.lazySoft {
|
||||
computeCallerForAccessor(isGetter = true)
|
||||
}
|
||||
}
|
||||
@@ -71,21 +71,21 @@ interface KMutablePropertyImpl<R> : KMutableProperty<R>, KPropertyImpl<R> {
|
||||
property.descriptor.setter ?: DescriptorFactory.createDefaultSetter(property.descriptor)
|
||||
}
|
||||
|
||||
override val caller: FunctionCaller by ReflectProperties.lazySoft {
|
||||
override val caller: FunctionCaller<*> by ReflectProperties.lazySoft {
|
||||
computeCallerForAccessor(isGetter = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun KPropertyImpl.Accessor<*>.computeCallerForAccessor(isGetter: Boolean): FunctionCaller {
|
||||
private fun KPropertyImpl.Accessor<*>.computeCallerForAccessor(isGetter: Boolean): FunctionCaller<*> {
|
||||
fun isPlatformStaticProperty() =
|
||||
property.descriptor.annotations.findAnnotation(PLATFORM_STATIC) != null
|
||||
|
||||
fun isNotNullProperty() =
|
||||
!TypeUtils.isNullableType(property.descriptor.type)
|
||||
|
||||
fun computeFieldCaller(field: Field): FunctionCaller.FieldAccessor = when {
|
||||
fun computeFieldCaller(field: Field): FunctionCaller<Field> = when {
|
||||
!Modifier.isStatic(field.modifiers) ->
|
||||
if (isGetter) FunctionCaller.InstanceFieldGetter(field)
|
||||
else FunctionCaller.InstanceFieldSetter(field, isNotNullProperty())
|
||||
|
||||
@@ -67,10 +67,7 @@ public val KMutableProperty<*>.javaSetter: Method?
|
||||
* or `null` if this function is a constructor or cannot be represented by a Java [Method].
|
||||
*/
|
||||
public val KFunction<*>.javaMethod: Method?
|
||||
get() = when (this) {
|
||||
is KCallableImpl<*> -> (caller as? FunctionCaller.Method)?.method
|
||||
else -> null
|
||||
}
|
||||
get() = (this as? KCallableImpl<*>)?.caller?.member as? Method
|
||||
|
||||
/**
|
||||
* Returns a Java [Constructor] instance corresponding to the given Kotlin function,
|
||||
@@ -78,10 +75,7 @@ public val KFunction<*>.javaMethod: Method?
|
||||
*/
|
||||
@suppress("UNCHECKED_CAST")
|
||||
public val <T> KFunction<T>.javaConstructor: Constructor<T>?
|
||||
get() = when (this) {
|
||||
is KFunctionImpl -> (caller as? FunctionCaller.Constructor)?.constructor as? Constructor<T>
|
||||
else -> null
|
||||
}
|
||||
get() = (this as? KCallableImpl<T>)?.caller?.member as? Constructor<T>
|
||||
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user