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