JVM: use $delegate methods in KProperty[0-2].getDelegate
#KT-39055 Fixed
This commit is contained in:
@@ -34,9 +34,9 @@ internal open class KProperty0Impl<out V> : KProperty0<V>, KPropertyImpl<V> {
|
|||||||
|
|
||||||
override fun get(): V = getter.call()
|
override fun get(): V = getter.call()
|
||||||
|
|
||||||
private val delegateFieldValue = lazy(PUBLICATION) { getDelegate(computeDelegateField(), boundReceiver) }
|
private val delegateValue = lazy(PUBLICATION) { getDelegateImpl(computeDelegateSource(), null, null) }
|
||||||
|
|
||||||
override fun getDelegate(): Any? = delegateFieldValue.value
|
override fun getDelegate(): Any? = delegateValue.value
|
||||||
|
|
||||||
override fun invoke(): V = get()
|
override fun invoke(): V = get()
|
||||||
|
|
||||||
|
|||||||
@@ -34,9 +34,9 @@ internal open class KProperty1Impl<T, out V> : KProperty1<T, V>, KPropertyImpl<V
|
|||||||
|
|
||||||
override fun get(receiver: T): V = getter.call(receiver)
|
override fun get(receiver: T): V = getter.call(receiver)
|
||||||
|
|
||||||
private val delegateField = lazy(PUBLICATION) { computeDelegateField() }
|
private val delegateSource = lazy(PUBLICATION) { computeDelegateSource() }
|
||||||
|
|
||||||
override fun getDelegate(receiver: T): Any? = getDelegate(delegateField.value, receiver)
|
override fun getDelegate(receiver: T): Any? = getDelegateImpl(delegateSource.value, receiver, null)
|
||||||
|
|
||||||
override fun invoke(receiver: T): V = get(receiver)
|
override fun invoke(receiver: T): V = get(receiver)
|
||||||
|
|
||||||
|
|||||||
@@ -35,9 +35,9 @@ internal open class KProperty2Impl<D, E, out V> : KProperty2<D, E, V>, KProperty
|
|||||||
|
|
||||||
override fun get(receiver1: D, receiver2: E): V = getter.call(receiver1, receiver2)
|
override fun get(receiver1: D, receiver2: E): V = getter.call(receiver1, receiver2)
|
||||||
|
|
||||||
private val delegateField = lazy(PUBLICATION) { computeDelegateField() }
|
private val delegateSource = lazy(PUBLICATION) { computeDelegateSource() }
|
||||||
|
|
||||||
override fun getDelegate(receiver1: D, receiver2: E): Any? = getDelegate(delegateField.value, receiver1)
|
override fun getDelegate(receiver1: D, receiver2: E): Any? = getDelegateImpl(delegateSource.value, receiver1, receiver2)
|
||||||
|
|
||||||
override fun invoke(receiver1: D, receiver2: E): V = get(receiver1, receiver2)
|
override fun invoke(receiver1: D, receiver2: E): V = get(receiver1, receiver2)
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ import org.jetbrains.kotlin.resolve.isUnderlyingPropertyOfInlineClass
|
|||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
|
||||||
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.Member
|
||||||
|
import java.lang.reflect.Method
|
||||||
import java.lang.reflect.Modifier
|
import java.lang.reflect.Modifier
|
||||||
import kotlin.jvm.internal.CallableReference
|
import kotlin.jvm.internal.CallableReference
|
||||||
import kotlin.reflect.KFunction
|
import kotlin.reflect.KFunction
|
||||||
@@ -77,12 +79,22 @@ internal abstract class KPropertyImpl<out V> private constructor(
|
|||||||
|
|
||||||
val javaField: Field? get() = _javaField()
|
val javaField: Field? get() = _javaField()
|
||||||
|
|
||||||
protected fun computeDelegateField(): Field? =
|
protected fun computeDelegateSource(): Member? {
|
||||||
if (descriptor.isDelegated) javaField else null
|
if (!descriptor.isDelegated) return null
|
||||||
|
val jvmSignature = RuntimeTypeMapper.mapPropertySignature(descriptor)
|
||||||
|
if (jvmSignature is KotlinProperty && jvmSignature.signature.hasDelegateMethod()) {
|
||||||
|
val method = jvmSignature.signature.delegateMethod
|
||||||
|
if (!method.hasName() || !method.hasDesc()) return null
|
||||||
|
val name = jvmSignature.nameResolver.getString(method.name)
|
||||||
|
val desc = jvmSignature.nameResolver.getString(method.desc)
|
||||||
|
return container.findMethodBySignature(name, desc)
|
||||||
|
}
|
||||||
|
return javaField
|
||||||
|
}
|
||||||
|
|
||||||
protected fun getDelegate(field: Field?, receiver: Any?): Any? =
|
protected fun getDelegateImpl(fieldOrMethod: Member?, receiver1: Any?, receiver2: Any?): Any? =
|
||||||
try {
|
try {
|
||||||
if (receiver === EXTENSION_PROPERTY_DELEGATE) {
|
if (receiver1 === EXTENSION_PROPERTY_DELEGATE || receiver2 === EXTENSION_PROPERTY_DELEGATE) {
|
||||||
if (descriptor.extensionReceiverParameter == null) {
|
if (descriptor.extensionReceiverParameter == null) {
|
||||||
throw RuntimeException(
|
throw RuntimeException(
|
||||||
"'$this' is not an extension property and thus getExtensionDelegate() " +
|
"'$this' is not an extension property and thus getExtensionDelegate() " +
|
||||||
@@ -90,7 +102,20 @@ internal abstract class KPropertyImpl<out V> private constructor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
field?.get(receiver)
|
|
||||||
|
val realReceiver1 = (if (isBound) boundReceiver else receiver1).takeIf { it !== EXTENSION_PROPERTY_DELEGATE }
|
||||||
|
val realReceiver2 = (if (isBound) receiver1 else receiver2).takeIf { it !== EXTENSION_PROPERTY_DELEGATE }
|
||||||
|
when (fieldOrMethod) {
|
||||||
|
null -> null
|
||||||
|
is Field -> fieldOrMethod.get(realReceiver1)
|
||||||
|
is Method -> when (fieldOrMethod.parameterTypes.size) {
|
||||||
|
0 -> fieldOrMethod.invoke(null)
|
||||||
|
1 -> fieldOrMethod.invoke(null, realReceiver1 ?: defaultPrimitiveValue(fieldOrMethod.parameterTypes[0]))
|
||||||
|
2 -> fieldOrMethod.invoke(null, realReceiver1, realReceiver2 ?: defaultPrimitiveValue(fieldOrMethod.parameterTypes[1]))
|
||||||
|
else -> throw AssertionError("delegate method $fieldOrMethod should take 0, 1, or 2 parameters")
|
||||||
|
}
|
||||||
|
else -> throw AssertionError("delegate field/method $fieldOrMethod neither field nor method")
|
||||||
|
}
|
||||||
} catch (e: IllegalAccessException) {
|
} catch (e: IllegalAccessException) {
|
||||||
throw IllegalPropertyDelegateAccessException(e)
|
throw IllegalPropertyDelegateAccessException(e)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user