Refactor and simplify FunctionCaller

This commit is contained in:
Alexander Udalov
2015-08-06 17:29:55 +03:00
parent d3e39812cb
commit 0d0ccfef8c
5 changed files with 63 additions and 68 deletions
@@ -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
}
/** /**