Support reflection on @JvmField properties inside class companion
This commit is contained in:
@@ -158,6 +158,21 @@ internal abstract class FunctionCaller<out M : Member>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ClassCompanionFieldGetter(
|
||||||
|
field: ReflectField,
|
||||||
|
klass: Class<*>
|
||||||
|
) : FunctionCaller<ReflectField>(
|
||||||
|
field,
|
||||||
|
field.genericType,
|
||||||
|
klass,
|
||||||
|
emptyArray()
|
||||||
|
) {
|
||||||
|
override fun call(args: Array<*>): Any? {
|
||||||
|
checkArguments(args)
|
||||||
|
return member.get(args.first())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class StaticFieldSetter(field: ReflectField, notNull: Boolean) : FieldSetter(field, notNull)
|
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)
|
||||||
@@ -168,4 +183,19 @@ internal abstract class FunctionCaller<out M : Member>(
|
|||||||
checkObjectInstance(args.firstOrNull())
|
checkObjectInstance(args.firstOrNull())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ClassCompanionFieldSetter(
|
||||||
|
field: ReflectField,
|
||||||
|
klass: Class<*>
|
||||||
|
) : FunctionCaller<ReflectField>(
|
||||||
|
field,
|
||||||
|
Void.TYPE,
|
||||||
|
klass,
|
||||||
|
arrayOf(field.genericType)
|
||||||
|
) {
|
||||||
|
override fun call(args: Array<*>): Any? {
|
||||||
|
checkArguments(args)
|
||||||
|
return member.set(instanceClass, args.last())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,10 @@ package kotlin.reflect.jvm.internal
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
|
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement
|
||||||
|
import org.jetbrains.kotlin.load.kotlin.reflect.ReflectKotlinClass
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorFactory
|
import org.jetbrains.kotlin.resolve.DescriptorFactory
|
||||||
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
import java.lang.reflect.Field
|
import java.lang.reflect.Field
|
||||||
import java.lang.reflect.Modifier
|
import java.lang.reflect.Modifier
|
||||||
@@ -86,14 +89,29 @@ internal interface KMutablePropertyImpl<R> : KMutableProperty<R>, KPropertyImpl<
|
|||||||
|
|
||||||
|
|
||||||
private fun KPropertyImpl.Accessor<*>.computeCallerForAccessor(isGetter: Boolean): FunctionCaller<*> {
|
private fun KPropertyImpl.Accessor<*>.computeCallerForAccessor(isGetter: Boolean): FunctionCaller<*> {
|
||||||
|
fun isInsideClassCompanionObject(): Boolean {
|
||||||
|
val possibleCompanionObject = property.descriptor.containingDeclaration
|
||||||
|
if (DescriptorUtils.isCompanionObject(possibleCompanionObject) && !DescriptorUtils.isInterface(possibleCompanionObject.containingDeclaration)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
fun isJvmStaticProperty() =
|
fun isJvmStaticProperty() =
|
||||||
property.descriptor.annotations.findAnnotation(PLATFORM_STATIC) != null ||
|
property.descriptor.annotations.findAnnotation(PLATFORM_STATIC) != null ||
|
||||||
property.descriptor.annotations.findAnnotation(JVM_STATIC) != null
|
property.descriptor.annotations.findAnnotation(JVM_STATIC) != null
|
||||||
|
|
||||||
|
|
||||||
fun isNotNullProperty() =
|
fun isNotNullProperty() =
|
||||||
!TypeUtils.isNullableType(property.descriptor.type)
|
!TypeUtils.isNullableType(property.descriptor.type)
|
||||||
|
|
||||||
fun computeFieldCaller(field: Field): FunctionCaller<Field> = when {
|
fun computeFieldCaller(field: Field): FunctionCaller<Field> = when {
|
||||||
|
isInsideClassCompanionObject() -> {
|
||||||
|
val containingDeclaration = descriptor.containingDeclaration as ClassDescriptor
|
||||||
|
val sourceElement = containingDeclaration.source as KotlinJvmBinarySourceElement
|
||||||
|
val klass = (sourceElement.binaryClass as ReflectKotlinClass).klass
|
||||||
|
if (isGetter) FunctionCaller.ClassCompanionFieldGetter(field, klass)
|
||||||
|
else FunctionCaller.ClassCompanionFieldSetter(field, klass)
|
||||||
|
}
|
||||||
!Modifier.isStatic(field.modifiers) ->
|
!Modifier.isStatic(field.modifiers) ->
|
||||||
if (isGetter) FunctionCaller.InstanceFieldGetter(field)
|
if (isGetter) FunctionCaller.InstanceFieldGetter(field)
|
||||||
else FunctionCaller.InstanceFieldSetter(field, isNotNullProperty())
|
else FunctionCaller.InstanceFieldSetter(field, isNotNullProperty())
|
||||||
|
|||||||
Reference in New Issue
Block a user