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) =
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)
@@ -188,21 +188,21 @@ private fun KPropertyImpl.Accessor<*, *>.computeCallerForAccessor(isGetter: Bool
fun computeFieldCaller(field: Field): Caller<Field> = 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)
}
}
}
@@ -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<out M : Member>(
internal sealed class CallerImpl<out M : Member>(
final override val member: M,
final override val returnType: Type,
val instanceClass: Class<*>?,
@@ -27,8 +27,6 @@ internal abstract class CallerImpl<out M : Member>(
}
}
// Constructors
class Constructor(constructor: ReflectConstructor<*>) : CallerImpl<ReflectConstructor<*>>(
constructor,
constructor.declaringClass,
@@ -57,9 +55,7 @@ internal abstract class CallerImpl<out M : Member>(
}
}
// Methods
abstract class Method(
sealed class Method(
method: ReflectMethod,
requiresInstance: Boolean = !Modifier.isStatic(method.modifiers),
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
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<ReflectField>(
@@ -139,9 +133,29 @@ internal abstract class CallerImpl<out M : Member>(
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<out M : Member>(
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())
}
}
}