Make CallerImpl with subclasses a sealed hierarchy

This commit is contained in:
Alexander Udalov
2018-08-27 19:44:48 +02:00
parent 8c8f0639f8
commit 3e79bd2b0e
3 changed files with 108 additions and 116 deletions
@@ -133,13 +133,13 @@ internal class KFunctionImpl private constructor(
} }
private fun createStaticMethodCaller(member: Method) = 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) = 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) = 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<*>) = private fun createConstructorCaller(member: Constructor<*>) =
if (isBound) CallerImpl.BoundConstructor(member, boundReceiver) else CallerImpl.Constructor(member) if (isBound) CallerImpl.BoundConstructor(member, boundReceiver) else CallerImpl.Constructor(member)
@@ -188,21 +188,21 @@ private fun KPropertyImpl.Accessor<*, *>.computeCallerForAccessor(isGetter: Bool
fun computeFieldCaller(field: Field): Caller<Field> = when { fun computeFieldCaller(field: Field): Caller<Field> = when {
property.descriptor.isJvmFieldPropertyInCompanionObject() || !Modifier.isStatic(field.modifiers) -> property.descriptor.isJvmFieldPropertyInCompanionObject() || !Modifier.isStatic(field.modifiers) ->
if (isGetter) if (isGetter)
if (isBound) CallerImpl.BoundInstanceFieldGetter(field, property.boundReceiver) if (isBound) CallerImpl.FieldGetter.BoundInstance(field, property.boundReceiver)
else CallerImpl.InstanceFieldGetter(field) else CallerImpl.FieldGetter.Instance(field)
else else
if (isBound) CallerImpl.BoundInstanceFieldSetter(field, isNotNullProperty(), property.boundReceiver) if (isBound) CallerImpl.FieldSetter.BoundInstance(field, isNotNullProperty(), property.boundReceiver)
else CallerImpl.InstanceFieldSetter(field, isNotNullProperty()) else CallerImpl.FieldSetter.Instance(field, isNotNullProperty())
isJvmStaticProperty() -> isJvmStaticProperty() ->
if (isGetter) if (isGetter)
if (isBound) CallerImpl.BoundJvmStaticInObjectFieldGetter(field) if (isBound) CallerImpl.FieldGetter.BoundJvmStaticInObject(field)
else CallerImpl.JvmStaticInObjectFieldGetter(field) else CallerImpl.FieldGetter.JvmStaticInObject(field)
else else
if (isBound) CallerImpl.BoundJvmStaticInObjectFieldSetter(field, isNotNullProperty()) if (isBound) CallerImpl.FieldSetter.BoundJvmStaticInObject(field, isNotNullProperty())
else CallerImpl.JvmStaticInObjectFieldSetter(field, isNotNullProperty()) else CallerImpl.FieldSetter.JvmStaticInObject(field, isNotNullProperty())
else -> else ->
if (isGetter) CallerImpl.StaticFieldGetter(field) if (isGetter) CallerImpl.FieldGetter.Static(field)
else CallerImpl.StaticFieldSetter(field, isNotNullProperty()) else CallerImpl.FieldSetter.Static(field, isNotNullProperty())
} }
val jvmSignature = RuntimeTypeMapper.mapPropertySignature(property.descriptor) 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") property.javaField ?: throw KotlinReflectionInternalError("No accessors or field is found for property $property")
) )
!Modifier.isStatic(accessor.modifiers) -> !Modifier.isStatic(accessor.modifiers) ->
if (isBound) CallerImpl.BoundInstanceMethod(accessor, property.boundReceiver) if (isBound) CallerImpl.Method.BoundInstance(accessor, property.boundReceiver)
else CallerImpl.InstanceMethod(accessor) else CallerImpl.Method.Instance(accessor)
isJvmStaticProperty() -> isJvmStaticProperty() ->
if (isBound) CallerImpl.BoundJvmStaticInObject(accessor) if (isBound) CallerImpl.Method.BoundJvmStaticInObject(accessor)
else CallerImpl.JvmStaticInObject(accessor) else CallerImpl.Method.JvmStaticInObject(accessor)
else -> else ->
if (isBound) CallerImpl.BoundStaticMethod(accessor, property.boundReceiver) if (isBound) CallerImpl.Method.BoundStatic(accessor, property.boundReceiver)
else CallerImpl.StaticMethod(accessor) else CallerImpl.Method.Static(accessor)
} }
} }
is JavaField -> { is JavaField -> {
@@ -247,8 +247,8 @@ private fun KPropertyImpl.Accessor<*, *>.computeCallerForAccessor(isGetter: Bool
else jvmSignature.setterMethod ?: throw KotlinReflectionInternalError( else jvmSignature.setterMethod ?: throw KotlinReflectionInternalError(
"No source found for setter of Java method property: ${jvmSignature.getterMethod}" "No source found for setter of Java method property: ${jvmSignature.getterMethod}"
) )
if (isBound) CallerImpl.BoundInstanceMethod(method, property.boundReceiver) if (isBound) CallerImpl.Method.BoundInstance(method, property.boundReceiver)
else CallerImpl.InstanceMethod(method) else CallerImpl.Method.Instance(method)
} }
is MappedKotlinProperty -> { is MappedKotlinProperty -> {
val signature = 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" } assert(!Modifier.isStatic(accessor.modifiers)) { "Mapped property cannot have a static accessor: $property" }
return if (isBound) CallerImpl.BoundInstanceMethod(accessor, property.boundReceiver) return if (isBound) CallerImpl.Method.BoundInstance(accessor, property.boundReceiver)
else CallerImpl.InstanceMethod(accessor) else CallerImpl.Method.Instance(accessor)
} }
} }
} }
@@ -12,7 +12,7 @@ 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 CallerImpl<out M : Member>( internal sealed class CallerImpl<out M : Member>(
final override val member: M, final override val member: M,
final override val returnType: Type, final override val returnType: Type,
val instanceClass: Class<*>?, val instanceClass: Class<*>?,
@@ -27,8 +27,6 @@ internal abstract class CallerImpl<out M : Member>(
} }
} }
// Constructors
class Constructor(constructor: ReflectConstructor<*>) : CallerImpl<ReflectConstructor<*>>( class Constructor(constructor: ReflectConstructor<*>) : CallerImpl<ReflectConstructor<*>>(
constructor, constructor,
constructor.declaringClass, constructor.declaringClass,
@@ -57,9 +55,7 @@ internal abstract class CallerImpl<out M : Member>(
} }
} }
// Methods sealed class Method(
abstract class Method(
method: ReflectMethod, method: ReflectMethod,
requiresInstance: Boolean = !Modifier.isStatic(method.modifiers), requiresInstance: Boolean = !Modifier.isStatic(method.modifiers),
parameterTypes: Array<Type> = method.genericParameterTypes parameterTypes: Array<Type> = method.genericParameterTypes
@@ -77,56 +73,54 @@ internal abstract class CallerImpl<out M : Member>(
// 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) { class Static(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 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) { sealed class FieldGetter(
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(
field: ReflectField, field: ReflectField,
requiresInstance: Boolean requiresInstance: Boolean
) : CallerImpl<ReflectField>( ) : CallerImpl<ReflectField>(
@@ -139,9 +133,29 @@ internal abstract class CallerImpl<out M : Member>(
checkArguments(args) checkArguments(args)
return member.get(if (instanceClass != null) args.first() else null) 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, field: ReflectField,
private val notNull: Boolean, private val notNull: Boolean,
requiresInstance: Boolean requiresInstance: Boolean
@@ -162,53 +176,31 @@ internal abstract class CallerImpl<out M : Member>(
checkArguments(args) checkArguments(args)
return member.set(if (instanceClass != null) 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 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) { class JvmStaticInObject(field: ReflectField, notNull: Boolean) : FieldSetter(field, notNull, requiresInstance = true) {
override fun checkArguments(args: Array<*>) { override fun checkArguments(args: Array<*>) {
super.checkArguments(args) super.checkArguments(args)
checkObjectInstance(args.firstOrNull()) checkObjectInstance(args.firstOrNull())
}
} }
}
class BoundInstanceFieldGetter(field: ReflectField, private val boundReceiver: Any?) : FieldGetter(field, requiresInstance = false) { class BoundInstance(field: ReflectField, notNull: Boolean, private val boundReceiver: Any?) :
override fun call(args: Array<*>): Any? { FieldSetter(field, notNull, requiresInstance = false) {
checkArguments(args) override fun call(args: Array<*>): Any? {
return member.get(boundReceiver) checkArguments(args)
return member.set(boundReceiver, args.first())
}
} }
}
class BoundJvmStaticInObjectFieldGetter(field: ReflectField) : FieldGetter(field, requiresInstance = false) class BoundJvmStaticInObject(field: ReflectField, notNull: Boolean) : FieldSetter(field, notNull, requiresInstance = false) {
override fun call(args: Array<*>): Any? {
class StaticFieldSetter(field: ReflectField, notNull: Boolean) : FieldSetter(field, notNull, requiresInstance = false) checkArguments(args)
return member.set(null, args.last())
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())
} }
} }