Remove unneeded CallerImpl implementations

Also fix a bug where nullability of the assigned value was not checked
in ClassCompanionFieldSetter because it wasn't a subclass of FieldSetter
where this check occurred
This commit is contained in:
Alexander Udalov
2018-08-27 19:43:56 +02:00
parent 356b02cb91
commit 8c8f0639f8
3 changed files with 47 additions and 80 deletions
@@ -23,6 +23,14 @@ class CounterTest<T>(t: T) {
private var generic: T = t
}
class C {
companion object {
private var z: String = ""
fun getBoundZ() = this::z
}
}
fun box(): String {
val p = A::class.memberProperties.single() as KMutableProperty1<A, String?>
p.isAccessible = true
@@ -47,5 +55,19 @@ fun box(): String {
d.isAccessible = true
d.setter.call(CounterTest(""), null) // Also should not fail, because we can't be sure about nullability of 'generic'
val z = C.Companion::class.memberProperties.single { it.name == "z" } as KMutableProperty1<C.Companion, String?>
z.isAccessible = true
try {
z.setter.call(C, null)
return "Fail: exception should have been thrown"
} catch (e: IllegalArgumentException) {}
val zz = C.getBoundZ() as KMutableProperty0<String?>
zz.isAccessible = true
try {
zz.setter.call(null)
return "Fail: exception should have been thrown"
} catch (e: IllegalArgumentException) {}
return "OK"
}
@@ -179,42 +179,14 @@ private fun KPropertyImpl.Accessor<*, *>.computeCallerForAccessor(isGetter: Bool
return ThrowingCaller
}
fun isInsideClassCompanionObject(): Boolean {
val possibleCompanionObject = property.descriptor.containingDeclaration
return DescriptorUtils.isCompanionObject(possibleCompanionObject) &&
!DescriptorUtils.isInterface(possibleCompanionObject.containingDeclaration)
}
fun isJvmStaticProperty(): Boolean =
property.descriptor.annotations.hasAnnotation(JVM_STATIC)
fun isInsideJvmInterfaceCompanionObject(): Boolean {
val possibleCompanionObject = property.descriptor.containingDeclaration
return DescriptorUtils.isCompanionObject(possibleCompanionObject) &&
(DescriptorUtils.isInterface(possibleCompanionObject.containingDeclaration) ||
DescriptorUtils.isAnnotationClass(possibleCompanionObject.containingDeclaration))
}
fun isInsideInterfaceCompanionObjectWithJvmField(): Boolean {
val propertyDescriptor = property.descriptor
if (propertyDescriptor !is DeserializedPropertyDescriptor || !isInsideJvmInterfaceCompanionObject()) return false
return JvmProtoBufUtil.isMovedFromInterfaceCompanion(propertyDescriptor.proto)
}
fun isJvmStaticProperty() =
property.descriptor.annotations.findAnnotation(JVM_STATIC) != null
fun isNotNullProperty() =
fun isNotNullProperty(): Boolean =
!TypeUtils.isNullableType(property.descriptor.type)
fun computeFieldCaller(field: Field): Caller<Field> = when {
isInsideClassCompanionObject() || isInsideInterfaceCompanionObjectWithJvmField() -> {
val klass = (descriptor.containingDeclaration as ClassDescriptor).toJavaClass()!!
if (isGetter)
if (isBound) CallerImpl.BoundClassCompanionFieldGetter(field, klass)
else CallerImpl.ClassCompanionFieldGetter(field, klass)
else
if (isBound) CallerImpl.BoundClassCompanionFieldSetter(field, klass)
else CallerImpl.ClassCompanionFieldSetter(field, klass)
}
!Modifier.isStatic(field.modifiers) ->
property.descriptor.isJvmFieldPropertyInCompanionObject() || !Modifier.isStatic(field.modifiers) ->
if (isGetter)
if (isBound) CallerImpl.BoundInstanceFieldGetter(field, property.boundReceiver)
else CallerImpl.InstanceFieldGetter(field)
@@ -293,3 +265,15 @@ private fun KPropertyImpl.Accessor<*, *>.computeCallerForAccessor(isGetter: Bool
}
}
}
private fun PropertyDescriptor.isJvmFieldPropertyInCompanionObject(): Boolean {
val container = containingDeclaration
if (!DescriptorUtils.isCompanionObject(container)) return false
val outerClass = container.containingDeclaration
return when {
DescriptorUtils.isInterface(outerClass) || DescriptorUtils.isAnnotationClass(outerClass) ->
this is DeserializedPropertyDescriptor && JvmProtoBufUtil.isMovedFromInterfaceCompanion(proto)
else -> true
}
}
@@ -128,7 +128,7 @@ internal abstract class CallerImpl<out M : Member>(
abstract class FieldGetter(
field: ReflectField,
requiresInstance: Boolean = !Modifier.isStatic(field.modifiers)
requiresInstance: Boolean
) : CallerImpl<ReflectField>(
field,
field.genericType,
@@ -144,7 +144,7 @@ internal abstract class CallerImpl<out M : Member>(
abstract class FieldSetter(
field: ReflectField,
private val notNull: Boolean,
requiresInstance: Boolean = !Modifier.isStatic(field.modifiers)
requiresInstance: Boolean
) : CallerImpl<ReflectField>(
field,
Void.TYPE,
@@ -164,9 +164,9 @@ internal abstract class CallerImpl<out M : Member>(
}
}
class StaticFieldGetter(field: ReflectField) : FieldGetter(field)
class StaticFieldGetter(field: ReflectField) : FieldGetter(field, requiresInstance = false)
class InstanceFieldGetter(field: ReflectField) : FieldGetter(field)
class InstanceFieldGetter(field: ReflectField) : FieldGetter(field, requiresInstance = true)
class JvmStaticInObjectFieldGetter(field: ReflectField) : FieldGetter(field, requiresInstance = true) {
override fun checkArguments(args: Array<*>) {
@@ -175,18 +175,7 @@ internal abstract class CallerImpl<out M : Member>(
}
}
class ClassCompanionFieldGetter(field: ReflectField, klass: Class<*>) : CallerImpl<ReflectField>(
field, field.genericType, klass, emptyArray()
) {
override fun call(args: Array<*>): Any? {
checkArguments(args)
return member.get(args.first())
}
}
class BoundInstanceFieldGetter(field: ReflectField, private val boundReceiver: Any?) : FieldGetter(
field, requiresInstance = false
) {
class BoundInstanceFieldGetter(field: ReflectField, private val boundReceiver: Any?) : FieldGetter(field, requiresInstance = false) {
override fun call(args: Array<*>): Any? {
checkArguments(args)
return member.get(boundReceiver)
@@ -195,18 +184,9 @@ internal abstract class CallerImpl<out M : Member>(
class BoundJvmStaticInObjectFieldGetter(field: ReflectField) : FieldGetter(field, requiresInstance = false)
class BoundClassCompanionFieldGetter(field: ReflectField, private val boundReceiver: Any?) : FieldGetter(
field, requiresInstance = false
) {
override fun call(args: Array<*>): Any? {
checkArguments(args)
return member.get(boundReceiver)
}
}
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)
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<*>) {
@@ -215,18 +195,8 @@ internal abstract class CallerImpl<out M : Member>(
}
}
class ClassCompanionFieldSetter(field: ReflectField, klass: Class<*>) : CallerImpl<ReflectField>(
field, Void.TYPE, klass, arrayOf(field.genericType)
) {
override fun call(args: Array<*>): Any? {
checkArguments(args)
return member.set(null, args.last())
}
}
class BoundInstanceFieldSetter(field: ReflectField, notNull: Boolean, private val boundReceiver: Any?) : FieldSetter(
field, notNull, false
) {
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())
@@ -242,15 +212,6 @@ internal abstract class CallerImpl<out M : Member>(
}
}
class BoundClassCompanionFieldSetter(field: ReflectField, klass: Class<*>) : CallerImpl<ReflectField>(
field, Void.TYPE, klass, arrayOf(field.genericType)
) {
override fun call(args: Array<*>): Any? {
checkArguments(args)
return member.set(null, args.last())
}
}
companion object {
@Suppress("UNCHECKED_CAST")
inline fun <reified T> Array<out T>.dropFirst(): Array<T> =