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()
|
||||
|
||||
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()
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
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)
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@ import org.jetbrains.kotlin.resolve.isUnderlyingPropertyOfInlineClass
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import java.lang.reflect.Field
|
||||
import java.lang.reflect.Member
|
||||
import java.lang.reflect.Method
|
||||
import java.lang.reflect.Modifier
|
||||
import kotlin.jvm.internal.CallableReference
|
||||
import kotlin.reflect.KFunction
|
||||
@@ -77,12 +79,22 @@ internal abstract class KPropertyImpl<out V> private constructor(
|
||||
|
||||
val javaField: Field? get() = _javaField()
|
||||
|
||||
protected fun computeDelegateField(): Field? =
|
||||
if (descriptor.isDelegated) javaField else null
|
||||
protected fun computeDelegateSource(): Member? {
|
||||
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 {
|
||||
if (receiver === EXTENSION_PROPERTY_DELEGATE) {
|
||||
if (receiver1 === EXTENSION_PROPERTY_DELEGATE || receiver2 === EXTENSION_PROPERTY_DELEGATE) {
|
||||
if (descriptor.extensionReceiverParameter == null) {
|
||||
throw RuntimeException(
|
||||
"'$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) {
|
||||
throw IllegalPropertyDelegateAccessException(e)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user