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.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>
/**