From 3e79bd2b0e7ab09ea68cf77aa0611ff1907439d7 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Mon, 27 Aug 2018 19:44:48 +0200 Subject: [PATCH] Make CallerImpl with subclasses a sealed hierarchy --- .../reflect/jvm/internal/KFunctionImpl.kt | 6 +- .../reflect/jvm/internal/KPropertyImpl.kt | 40 ++-- .../reflect/jvm/internal/calls/CallerImpl.kt | 178 +++++++++--------- 3 files changed, 108 insertions(+), 116 deletions(-) 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 b82d5f95573..cdbeec1fa29 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KFunctionImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KFunctionImpl.kt @@ -133,13 +133,13 @@ internal class KFunctionImpl private constructor( } private fun createStaticMethodCaller(member: Method) = - if (isBound) CallerImpl.BoundStaticMethod(member, boundReceiver) else CallerImpl.StaticMethod(member) + if (isBound) CallerImpl.Method.BoundStatic(member, boundReceiver) else CallerImpl.Method.Static(member) private fun createJvmStaticInObjectCaller(member: Method) = - if (isBound) CallerImpl.BoundJvmStaticInObject(member) else CallerImpl.JvmStaticInObject(member) + if (isBound) CallerImpl.Method.BoundJvmStaticInObject(member) else CallerImpl.Method.JvmStaticInObject(member) private fun createInstanceMethodCaller(member: Method) = - if (isBound) CallerImpl.BoundInstanceMethod(member, boundReceiver) else CallerImpl.InstanceMethod(member) + if (isBound) CallerImpl.Method.BoundInstance(member, boundReceiver) else CallerImpl.Method.Instance(member) private fun createConstructorCaller(member: Constructor<*>) = if (isBound) CallerImpl.BoundConstructor(member, boundReceiver) else CallerImpl.Constructor(member) 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 aa36f8bbf55..fa8cdb4e317 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KPropertyImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KPropertyImpl.kt @@ -188,21 +188,21 @@ private fun KPropertyImpl.Accessor<*, *>.computeCallerForAccessor(isGetter: Bool fun computeFieldCaller(field: Field): Caller = when { property.descriptor.isJvmFieldPropertyInCompanionObject() || !Modifier.isStatic(field.modifiers) -> if (isGetter) - if (isBound) CallerImpl.BoundInstanceFieldGetter(field, property.boundReceiver) - else CallerImpl.InstanceFieldGetter(field) + if (isBound) CallerImpl.FieldGetter.BoundInstance(field, property.boundReceiver) + else CallerImpl.FieldGetter.Instance(field) else - if (isBound) CallerImpl.BoundInstanceFieldSetter(field, isNotNullProperty(), property.boundReceiver) - else CallerImpl.InstanceFieldSetter(field, isNotNullProperty()) + if (isBound) CallerImpl.FieldSetter.BoundInstance(field, isNotNullProperty(), property.boundReceiver) + else CallerImpl.FieldSetter.Instance(field, isNotNullProperty()) isJvmStaticProperty() -> if (isGetter) - if (isBound) CallerImpl.BoundJvmStaticInObjectFieldGetter(field) - else CallerImpl.JvmStaticInObjectFieldGetter(field) + if (isBound) CallerImpl.FieldGetter.BoundJvmStaticInObject(field) + else CallerImpl.FieldGetter.JvmStaticInObject(field) else - if (isBound) CallerImpl.BoundJvmStaticInObjectFieldSetter(field, isNotNullProperty()) - else CallerImpl.JvmStaticInObjectFieldSetter(field, isNotNullProperty()) + if (isBound) CallerImpl.FieldSetter.BoundJvmStaticInObject(field, isNotNullProperty()) + else CallerImpl.FieldSetter.JvmStaticInObject(field, isNotNullProperty()) else -> - if (isGetter) CallerImpl.StaticFieldGetter(field) - else CallerImpl.StaticFieldSetter(field, isNotNullProperty()) + if (isGetter) CallerImpl.FieldGetter.Static(field) + else CallerImpl.FieldSetter.Static(field, isNotNullProperty()) } val jvmSignature = RuntimeTypeMapper.mapPropertySignature(property.descriptor) @@ -228,14 +228,14 @@ private fun KPropertyImpl.Accessor<*, *>.computeCallerForAccessor(isGetter: Bool property.javaField ?: throw KotlinReflectionInternalError("No accessors or field is found for property $property") ) !Modifier.isStatic(accessor.modifiers) -> - if (isBound) CallerImpl.BoundInstanceMethod(accessor, property.boundReceiver) - else CallerImpl.InstanceMethod(accessor) + if (isBound) CallerImpl.Method.BoundInstance(accessor, property.boundReceiver) + else CallerImpl.Method.Instance(accessor) isJvmStaticProperty() -> - if (isBound) CallerImpl.BoundJvmStaticInObject(accessor) - else CallerImpl.JvmStaticInObject(accessor) + if (isBound) CallerImpl.Method.BoundJvmStaticInObject(accessor) + else CallerImpl.Method.JvmStaticInObject(accessor) else -> - if (isBound) CallerImpl.BoundStaticMethod(accessor, property.boundReceiver) - else CallerImpl.StaticMethod(accessor) + if (isBound) CallerImpl.Method.BoundStatic(accessor, property.boundReceiver) + else CallerImpl.Method.Static(accessor) } } is JavaField -> { @@ -247,8 +247,8 @@ private fun KPropertyImpl.Accessor<*, *>.computeCallerForAccessor(isGetter: Bool else jvmSignature.setterMethod ?: throw KotlinReflectionInternalError( "No source found for setter of Java method property: ${jvmSignature.getterMethod}" ) - if (isBound) CallerImpl.BoundInstanceMethod(method, property.boundReceiver) - else CallerImpl.InstanceMethod(method) + if (isBound) CallerImpl.Method.BoundInstance(method, property.boundReceiver) + else CallerImpl.Method.Instance(method) } is MappedKotlinProperty -> { val signature = @@ -260,8 +260,8 @@ private fun KPropertyImpl.Accessor<*, *>.computeCallerForAccessor(isGetter: Bool assert(!Modifier.isStatic(accessor.modifiers)) { "Mapped property cannot have a static accessor: $property" } - return if (isBound) CallerImpl.BoundInstanceMethod(accessor, property.boundReceiver) - else CallerImpl.InstanceMethod(accessor) + return if (isBound) CallerImpl.Method.BoundInstance(accessor, property.boundReceiver) + else CallerImpl.Method.Instance(accessor) } } } diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/calls/CallerImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/calls/CallerImpl.kt index e3a25c1179a..e7953f8cc8e 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/calls/CallerImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/calls/CallerImpl.kt @@ -12,7 +12,7 @@ import java.lang.reflect.Constructor as ReflectConstructor import java.lang.reflect.Field as ReflectField import java.lang.reflect.Method as ReflectMethod -internal abstract class CallerImpl( +internal sealed class CallerImpl( final override val member: M, final override val returnType: Type, val instanceClass: Class<*>?, @@ -27,8 +27,6 @@ internal abstract class CallerImpl( } } - // Constructors - class Constructor(constructor: ReflectConstructor<*>) : CallerImpl>( constructor, constructor.declaringClass, @@ -57,9 +55,7 @@ internal abstract class CallerImpl( } } - // Methods - - abstract class Method( + sealed class Method( method: ReflectMethod, requiresInstance: Boolean = !Modifier.isStatic(method.modifiers), parameterTypes: Array = method.genericParameterTypes @@ -77,56 +73,54 @@ internal abstract class CallerImpl( // 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) { - override fun call(args: Array<*>): Any? { - checkArguments(args) - return callMethod(null, args) + class Static(method: ReflectMethod) : Method(method) { + override fun call(args: Array<*>): Any? { + checkArguments(args) + return callMethod(null, args) + } + } + + class Instance(method: ReflectMethod) : Method(method) { + override fun call(args: Array<*>): Any? { + checkArguments(args) + return callMethod(args[0], args.dropFirst()) + } + } + + class JvmStaticInObject(method: ReflectMethod) : Method(method, requiresInstance = true) { + override fun call(args: Array<*>): Any? { + checkArguments(args) + checkObjectInstance(args.firstOrNull()) + return callMethod(null, args.dropFirst()) + } + } + + class BoundStatic(method: ReflectMethod, private val boundReceiver: Any?) : Method( + method, requiresInstance = false, parameterTypes = method.genericParameterTypes.dropFirst() + ) { + override fun call(args: Array<*>): Any? { + checkArguments(args) + return callMethod(null, arrayOf(boundReceiver, *args)) + } + } + + class BoundInstance(method: ReflectMethod, private val boundReceiver: Any?) : Method(method, requiresInstance = false) { + override fun call(args: Array<*>): Any? { + checkArguments(args) + return callMethod(boundReceiver, args) + } + } + + class BoundJvmStaticInObject(method: ReflectMethod) : Method(method, requiresInstance = false) { + override fun call(args: Array<*>): Any? { + checkArguments(args) + return callMethod(null, args) + } } } - class InstanceMethod(method: ReflectMethod) : Method(method) { - override fun call(args: Array<*>): Any? { - checkArguments(args) - return callMethod(args[0], args.dropFirst()) - } - } - - class JvmStaticInObject(method: ReflectMethod) : Method(method, requiresInstance = true) { - override fun call(args: Array<*>): Any? { - checkArguments(args) - checkObjectInstance(args.firstOrNull()) - return callMethod(null, args.dropFirst()) - } - } - - class BoundStaticMethod(method: ReflectMethod, private val boundReceiver: Any?) : Method( - method, requiresInstance = false, parameterTypes = method.genericParameterTypes.dropFirst() - ) { - override fun call(args: Array<*>): Any? { - checkArguments(args) - return callMethod(null, arrayOf(boundReceiver, *args)) - } - } - - class BoundInstanceMethod(method: ReflectMethod, private val boundReceiver: Any?) : Method(method, requiresInstance = false) { - override fun call(args: Array<*>): Any? { - checkArguments(args) - return callMethod(boundReceiver, args) - } - } - - class BoundJvmStaticInObject(method: ReflectMethod) : Method(method, requiresInstance = false) { - override fun call(args: Array<*>): Any? { - checkArguments(args) - return callMethod(null, args) - } - } - - // Field accessors - - abstract class FieldGetter( + sealed class FieldGetter( field: ReflectField, requiresInstance: Boolean ) : CallerImpl( @@ -139,9 +133,29 @@ internal abstract class CallerImpl( checkArguments(args) return member.get(if (instanceClass != null) args.first() else null) } + + class Static(field: ReflectField) : FieldGetter(field, requiresInstance = false) + + class Instance(field: ReflectField) : FieldGetter(field, requiresInstance = true) + + class JvmStaticInObject(field: ReflectField) : FieldGetter(field, requiresInstance = true) { + override fun checkArguments(args: Array<*>) { + super.checkArguments(args) + checkObjectInstance(args.firstOrNull()) + } + } + + class BoundInstance(field: ReflectField, private val boundReceiver: Any?) : FieldGetter(field, requiresInstance = false) { + override fun call(args: Array<*>): Any? { + checkArguments(args) + return member.get(boundReceiver) + } + } + + class BoundJvmStaticInObject(field: ReflectField) : FieldGetter(field, requiresInstance = false) } - abstract class FieldSetter( + sealed class FieldSetter( field: ReflectField, private val notNull: Boolean, requiresInstance: Boolean @@ -162,53 +176,31 @@ internal abstract class CallerImpl( checkArguments(args) return member.set(if (instanceClass != null) args.first() else null, args.last()) } - } - class StaticFieldGetter(field: ReflectField) : FieldGetter(field, requiresInstance = false) + class Static(field: ReflectField, notNull: Boolean) : FieldSetter(field, notNull, requiresInstance = false) - class InstanceFieldGetter(field: ReflectField) : FieldGetter(field, requiresInstance = true) + class Instance(field: ReflectField, notNull: Boolean) : FieldSetter(field, notNull, requiresInstance = true) - class JvmStaticInObjectFieldGetter(field: ReflectField) : FieldGetter(field, requiresInstance = true) { - override fun checkArguments(args: Array<*>) { - super.checkArguments(args) - checkObjectInstance(args.firstOrNull()) + class JvmStaticInObject(field: ReflectField, notNull: Boolean) : FieldSetter(field, notNull, requiresInstance = true) { + override fun checkArguments(args: Array<*>) { + super.checkArguments(args) + checkObjectInstance(args.firstOrNull()) + } } - } - class BoundInstanceFieldGetter(field: ReflectField, private val boundReceiver: Any?) : FieldGetter(field, requiresInstance = false) { - override fun call(args: Array<*>): Any? { - checkArguments(args) - return member.get(boundReceiver) + class BoundInstance(field: ReflectField, notNull: Boolean, private val boundReceiver: Any?) : + FieldSetter(field, notNull, requiresInstance = false) { + override fun call(args: Array<*>): Any? { + checkArguments(args) + return member.set(boundReceiver, args.first()) + } } - } - class BoundJvmStaticInObjectFieldGetter(field: ReflectField) : FieldGetter(field, requiresInstance = false) - - class StaticFieldSetter(field: ReflectField, notNull: Boolean) : FieldSetter(field, notNull, requiresInstance = false) - - class InstanceFieldSetter(field: ReflectField, notNull: Boolean) : FieldSetter(field, notNull, requiresInstance = true) - - class JvmStaticInObjectFieldSetter(field: ReflectField, notNull: Boolean) : FieldSetter(field, notNull, requiresInstance = true) { - override fun checkArguments(args: Array<*>) { - super.checkArguments(args) - checkObjectInstance(args.firstOrNull()) - } - } - - class BoundInstanceFieldSetter(field: ReflectField, notNull: Boolean, private val boundReceiver: Any?) : - FieldSetter(field, notNull, requiresInstance = false) { - override fun call(args: Array<*>): Any? { - checkArguments(args) - return member.set(boundReceiver, args.first()) - } - } - - class BoundJvmStaticInObjectFieldSetter(field: ReflectField, notNull: Boolean) : FieldSetter( - field, notNull, requiresInstance = false - ) { - override fun call(args: Array<*>): Any? { - checkArguments(args) - return member.set(null, args.last()) + class BoundJvmStaticInObject(field: ReflectField, notNull: Boolean) : FieldSetter(field, notNull, requiresInstance = false) { + override fun call(args: Array<*>): Any? { + checkArguments(args) + return member.set(null, args.last()) + } } }