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
|
private var generic: T = t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class C {
|
||||||
|
companion object {
|
||||||
|
private var z: String = ""
|
||||||
|
|
||||||
|
fun getBoundZ() = this::z
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
val p = A::class.memberProperties.single() as KMutableProperty1<A, String?>
|
val p = A::class.memberProperties.single() as KMutableProperty1<A, String?>
|
||||||
p.isAccessible = true
|
p.isAccessible = true
|
||||||
@@ -47,5 +55,19 @@ fun box(): String {
|
|||||||
d.isAccessible = true
|
d.isAccessible = true
|
||||||
d.setter.call(CounterTest(""), null) // Also should not fail, because we can't be sure about nullability of 'generic'
|
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"
|
return "OK"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -179,42 +179,14 @@ private fun KPropertyImpl.Accessor<*, *>.computeCallerForAccessor(isGetter: Bool
|
|||||||
return ThrowingCaller
|
return ThrowingCaller
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isInsideClassCompanionObject(): Boolean {
|
fun isJvmStaticProperty(): Boolean =
|
||||||
val possibleCompanionObject = property.descriptor.containingDeclaration
|
property.descriptor.annotations.hasAnnotation(JVM_STATIC)
|
||||||
return DescriptorUtils.isCompanionObject(possibleCompanionObject) &&
|
|
||||||
!DescriptorUtils.isInterface(possibleCompanionObject.containingDeclaration)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun isInsideJvmInterfaceCompanionObject(): Boolean {
|
fun isNotNullProperty(): 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() =
|
|
||||||
!TypeUtils.isNullableType(property.descriptor.type)
|
!TypeUtils.isNullableType(property.descriptor.type)
|
||||||
|
|
||||||
fun computeFieldCaller(field: Field): Caller<Field> = when {
|
fun computeFieldCaller(field: Field): Caller<Field> = when {
|
||||||
isInsideClassCompanionObject() || isInsideInterfaceCompanionObjectWithJvmField() -> {
|
property.descriptor.isJvmFieldPropertyInCompanionObject() || !Modifier.isStatic(field.modifiers) ->
|
||||||
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) ->
|
|
||||||
if (isGetter)
|
if (isGetter)
|
||||||
if (isBound) CallerImpl.BoundInstanceFieldGetter(field, property.boundReceiver)
|
if (isBound) CallerImpl.BoundInstanceFieldGetter(field, property.boundReceiver)
|
||||||
else CallerImpl.InstanceFieldGetter(field)
|
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(
|
abstract class FieldGetter(
|
||||||
field: ReflectField,
|
field: ReflectField,
|
||||||
requiresInstance: Boolean = !Modifier.isStatic(field.modifiers)
|
requiresInstance: Boolean
|
||||||
) : CallerImpl<ReflectField>(
|
) : CallerImpl<ReflectField>(
|
||||||
field,
|
field,
|
||||||
field.genericType,
|
field.genericType,
|
||||||
@@ -144,7 +144,7 @@ internal abstract class CallerImpl<out M : Member>(
|
|||||||
abstract class FieldSetter(
|
abstract class FieldSetter(
|
||||||
field: ReflectField,
|
field: ReflectField,
|
||||||
private val notNull: Boolean,
|
private val notNull: Boolean,
|
||||||
requiresInstance: Boolean = !Modifier.isStatic(field.modifiers)
|
requiresInstance: Boolean
|
||||||
) : CallerImpl<ReflectField>(
|
) : CallerImpl<ReflectField>(
|
||||||
field,
|
field,
|
||||||
Void.TYPE,
|
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) {
|
class JvmStaticInObjectFieldGetter(field: ReflectField) : FieldGetter(field, requiresInstance = true) {
|
||||||
override fun checkArguments(args: Array<*>) {
|
override fun checkArguments(args: Array<*>) {
|
||||||
@@ -175,18 +175,7 @@ internal abstract class CallerImpl<out M : Member>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ClassCompanionFieldGetter(field: ReflectField, klass: Class<*>) : CallerImpl<ReflectField>(
|
class BoundInstanceFieldGetter(field: ReflectField, private val boundReceiver: Any?) : FieldGetter(field, requiresInstance = false) {
|
||||||
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
|
|
||||||
) {
|
|
||||||
override fun call(args: Array<*>): Any? {
|
override fun call(args: Array<*>): Any? {
|
||||||
checkArguments(args)
|
checkArguments(args)
|
||||||
return member.get(boundReceiver)
|
return member.get(boundReceiver)
|
||||||
@@ -195,18 +184,9 @@ internal abstract class CallerImpl<out M : Member>(
|
|||||||
|
|
||||||
class BoundJvmStaticInObjectFieldGetter(field: ReflectField) : FieldGetter(field, requiresInstance = false)
|
class BoundJvmStaticInObjectFieldGetter(field: ReflectField) : FieldGetter(field, requiresInstance = false)
|
||||||
|
|
||||||
class BoundClassCompanionFieldGetter(field: ReflectField, private val boundReceiver: Any?) : FieldGetter(
|
class StaticFieldSetter(field: ReflectField, notNull: Boolean) : FieldSetter(field, notNull, requiresInstance = false)
|
||||||
field, requiresInstance = false
|
|
||||||
) {
|
|
||||||
override fun call(args: Array<*>): Any? {
|
|
||||||
checkArguments(args)
|
|
||||||
return member.get(boundReceiver)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class StaticFieldSetter(field: ReflectField, notNull: Boolean) : FieldSetter(field, notNull)
|
class InstanceFieldSetter(field: ReflectField, notNull: Boolean) : FieldSetter(field, notNull, requiresInstance = true)
|
||||||
|
|
||||||
class InstanceFieldSetter(field: ReflectField, notNull: Boolean) : FieldSetter(field, notNull)
|
|
||||||
|
|
||||||
class JvmStaticInObjectFieldSetter(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<*>) {
|
override fun checkArguments(args: Array<*>) {
|
||||||
@@ -215,18 +195,8 @@ internal abstract class CallerImpl<out M : Member>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ClassCompanionFieldSetter(field: ReflectField, klass: Class<*>) : CallerImpl<ReflectField>(
|
class BoundInstanceFieldSetter(field: ReflectField, notNull: Boolean, private val boundReceiver: Any?) :
|
||||||
field, Void.TYPE, klass, arrayOf(field.genericType)
|
FieldSetter(field, notNull, requiresInstance = false) {
|
||||||
) {
|
|
||||||
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
|
|
||||||
) {
|
|
||||||
override fun call(args: Array<*>): Any? {
|
override fun call(args: Array<*>): Any? {
|
||||||
checkArguments(args)
|
checkArguments(args)
|
||||||
return member.set(boundReceiver, args.first())
|
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 {
|
companion object {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
inline fun <reified T> Array<out T>.dropFirst(): Array<T> =
|
inline fun <reified T> Array<out T>.dropFirst(): Array<T> =
|
||||||
|
|||||||
Reference in New Issue
Block a user