From 0d0ccfef8c47753ecdf4e739f4477f38be6f205c Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 6 Aug 2015 17:29:55 +0300 Subject: [PATCH] Refactor and simplify FunctionCaller --- .../reflect/jvm/internal/FunctionCaller.kt | 107 +++++++++--------- .../reflect/jvm/internal/KCallableImpl.kt | 2 +- .../reflect/jvm/internal/KFunctionImpl.kt | 2 +- .../reflect/jvm/internal/KPropertyImpl.kt | 10 +- .../src/kotlin/reflect/jvm/mapping.kt | 10 +- 5 files changed, 63 insertions(+), 68 deletions(-) diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/FunctionCaller.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/FunctionCaller.kt index 03b7a3c41d3..480afec8429 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/FunctionCaller.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/FunctionCaller.kt @@ -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 +internal abstract class FunctionCaller( + internal val member: M, + internal val returnType: Type, + internal val instanceClass: Class<*>?, + valueParameterTypes: Array +) { + internal val parameterTypes: List = + 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>( + 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( + 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( + 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( + 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<*>) { diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KCallableImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KCallableImpl.kt index 77f71e9edc7..03d121bb512 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KCallableImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KCallableImpl.kt @@ -26,7 +26,7 @@ import kotlin.reflect.KType interface KCallableImpl : KCallable, KAnnotatedElementImpl { val descriptor: CallableMemberDescriptor - val caller: FunctionCaller + val caller: FunctionCaller<*> override val annotated: Annotated get() = descriptor diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KFunctionImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KFunctionImpl.kt index eb78526b947..5aa59294790 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KFunctionImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KFunctionImpl.kt @@ -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 -> diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KPropertyImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KPropertyImpl.kt index b8e5657961b..2ef2cd340a4 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KPropertyImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KPropertyImpl.kt @@ -35,7 +35,7 @@ interface KPropertyImpl : KProperty, KCallableImpl { 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 : KProperty.Accessor { abstract override val property: KPropertyImpl @@ -51,7 +51,7 @@ interface KPropertyImpl : KProperty, KCallableImpl { 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 : KMutableProperty, KPropertyImpl { 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 = when { !Modifier.isStatic(field.modifiers) -> if (isGetter) FunctionCaller.InstanceFieldGetter(field) else FunctionCaller.InstanceFieldSetter(field, isNotNullProperty()) diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/mapping.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/mapping.kt index b6e2118fab0..7cff63ad92e 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/mapping.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/mapping.kt @@ -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 KFunction.javaConstructor: Constructor? - get() = when (this) { - is KFunctionImpl -> (caller as? FunctionCaller.Constructor)?.constructor as? Constructor - else -> null - } + get() = (this as? KCallableImpl)?.caller?.member as? Constructor /**