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:
+22
@@ -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> =
|
||||
|
||||
Reference in New Issue
Block a user