Introduce KProperty{0,1,2}.getDelegate
#KT-8384 In Progress
This commit is contained in:
@@ -88,6 +88,14 @@ public interface KProperty0<out R> : KProperty<R>, () -> R {
|
||||
*/
|
||||
public fun get(): R
|
||||
|
||||
/**
|
||||
* Returns the value of the delegate if this is a delegated property, or `null` if this property is not delegated.
|
||||
* See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/delegated-properties.html)
|
||||
* for more information.
|
||||
*/
|
||||
@SinceKotlin("1.1")
|
||||
public fun getDelegate(): Any?
|
||||
|
||||
override val getter: Getter<R>
|
||||
|
||||
public interface Getter<out R> : KProperty.Getter<R>, () -> R
|
||||
@@ -126,6 +134,21 @@ public interface KProperty1<T, out R> : KProperty<R>, (T) -> R {
|
||||
*/
|
||||
public fun get(receiver: T): R
|
||||
|
||||
/**
|
||||
* Returns the value of the delegate if this is a delegated property, or `null` if this property is not delegated.
|
||||
* See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/delegated-properties.html)
|
||||
* for more information.
|
||||
*
|
||||
* Note that for a top level **extension** property, the delegate is the same for all extension receivers,
|
||||
* so the actual [receiver] instance passed in is not going to make any difference, it must only be a value of [T].
|
||||
*
|
||||
* @param receiver the receiver which is used to obtain the value of the property delegate.
|
||||
* For example, it should be a class instance if this is a member property of that class,
|
||||
* or an extension receiver if this is a top level extension property.
|
||||
*/
|
||||
@SinceKotlin("1.1")
|
||||
public fun getDelegate(receiver: T): Any?
|
||||
|
||||
override val getter: Getter<T, R>
|
||||
|
||||
public interface Getter<T, out R> : KProperty.Getter<R>, (T) -> R
|
||||
@@ -171,6 +194,20 @@ public interface KProperty2<D, E, out R> : KProperty<R>, (D, E) -> R {
|
||||
*/
|
||||
public fun get(receiver1: D, receiver2: E): R
|
||||
|
||||
/**
|
||||
* Returns the value of the delegate if this is a delegated property, or `null` if this property is not delegated.
|
||||
* See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/delegated-properties.html)
|
||||
* for more information.
|
||||
*
|
||||
* In case of the extension property in a class, the instance of the class should be passed first
|
||||
* and the instance of the extension receiver second.
|
||||
*
|
||||
* @param receiver1 the instance of the first receiver.
|
||||
* @param receiver2 the instance of the second receiver.
|
||||
*/
|
||||
@SinceKotlin("1.1")
|
||||
public fun getDelegate(receiver1: D, receiver2: E): Any?
|
||||
|
||||
override val getter: Getter<D, E, R>
|
||||
|
||||
public interface Getter<D, E, out R> : KProperty.Getter<R>, (D, E) -> R
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package kotlin.reflect.full
|
||||
|
||||
import kotlin.reflect.KProperty
|
||||
import kotlin.reflect.jvm.isAccessible
|
||||
|
||||
/**
|
||||
* An exception that is thrown when `call` is invoked on a callable or `get` or `set` is invoked on a property
|
||||
@@ -27,6 +29,20 @@ package kotlin.reflect.full
|
||||
*/
|
||||
class IllegalCallableAccessException(cause: IllegalAccessException) : kotlin.reflect.IllegalCallableAccessException(cause)
|
||||
|
||||
/**
|
||||
* An exception that is thrown when `getDelegate` is invoked on a [KProperty] object that was not made accessible
|
||||
* with [isAccessible].
|
||||
*
|
||||
* @see [kotlin.reflect.KProperty0.getDelegate]
|
||||
* @see [kotlin.reflect.KProperty1.getDelegate]
|
||||
* @see [kotlin.reflect.KProperty2.getDelegate]
|
||||
* @see [kotlin.reflect.jvm.isAccessible]
|
||||
*/
|
||||
class IllegalPropertyDelegateAccessException(cause: IllegalAccessException) : Exception(
|
||||
"Cannot obtain the delegate of a non-accessible property. Use \"isAccessible = true\" to make the property accessible",
|
||||
cause
|
||||
)
|
||||
|
||||
/**
|
||||
* An exception that is thrown when the code tries to introspect a property of a class or a package
|
||||
* and that class or the package no longer has that property.
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package kotlin.reflect.jvm.internal
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import kotlin.LazyThreadSafetyMode.PUBLICATION
|
||||
import kotlin.reflect.KMutableProperty0
|
||||
import kotlin.reflect.KProperty0
|
||||
|
||||
@@ -31,6 +32,10 @@ internal open class KProperty0Impl<out R> : KProperty0<R>, KPropertyImpl<R> {
|
||||
|
||||
override fun get(): R = getter.call()
|
||||
|
||||
private val delegateFieldValue = lazy(PUBLICATION) { getDelegate(computeDelegateField(), boundReceiver) }
|
||||
|
||||
override fun getDelegate(): Any? = delegateFieldValue.value
|
||||
|
||||
override fun invoke(): R = get()
|
||||
|
||||
class Getter<out R>(override val property: KProperty0Impl<R>) : KPropertyImpl.Getter<R>(), KProperty0.Getter<R> {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package kotlin.reflect.jvm.internal
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import kotlin.LazyThreadSafetyMode.PUBLICATION
|
||||
import kotlin.reflect.KMutableProperty1
|
||||
import kotlin.reflect.KProperty1
|
||||
|
||||
@@ -31,6 +32,10 @@ internal open class KProperty1Impl<T, out R> : KProperty1<T, R>, KPropertyImpl<R
|
||||
|
||||
override fun get(receiver: T): R = getter.call(receiver)
|
||||
|
||||
private val delegateField = lazy(PUBLICATION) { computeDelegateField() }
|
||||
|
||||
override fun getDelegate(receiver: T): Any? = getDelegate(delegateField.value, receiver)
|
||||
|
||||
override fun invoke(receiver: T): R = get(receiver)
|
||||
|
||||
class Getter<T, out R>(override val property: KProperty1Impl<T, R>) : KPropertyImpl.Getter<R>(), KProperty1.Getter<T, R> {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package kotlin.reflect.jvm.internal
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import kotlin.LazyThreadSafetyMode.PUBLICATION
|
||||
import kotlin.jvm.internal.CallableReference
|
||||
import kotlin.reflect.KMutableProperty2
|
||||
import kotlin.reflect.KProperty2
|
||||
@@ -32,6 +33,10 @@ internal open class KProperty2Impl<D, E, out R> : KProperty2<D, E, R>, KProperty
|
||||
|
||||
override fun get(receiver1: D, receiver2: E): R = getter.call(receiver1, receiver2)
|
||||
|
||||
private val delegateField = lazy(PUBLICATION) { computeDelegateField() }
|
||||
|
||||
override fun getDelegate(receiver1: D, receiver2: E): Any? = getDelegate(delegateField.value, receiver1)
|
||||
|
||||
override fun invoke(receiver1: D, receiver2: E): R = get(receiver1, receiver2)
|
||||
|
||||
class Getter<D, E, out R>(override val property: KProperty2Impl<D, E, R>) : KPropertyImpl.Getter<R>(), KProperty2.Getter<D, E, R> {
|
||||
|
||||
@@ -29,6 +29,7 @@ import kotlin.jvm.internal.CallableReference
|
||||
import kotlin.reflect.KFunction
|
||||
import kotlin.reflect.KMutableProperty
|
||||
import kotlin.reflect.KProperty
|
||||
import kotlin.reflect.full.IllegalPropertyDelegateAccessException
|
||||
import kotlin.reflect.jvm.internal.JvmPropertySignature.*
|
||||
|
||||
internal abstract class KPropertyImpl<out R> private constructor(
|
||||
@@ -81,6 +82,17 @@ internal abstract class KPropertyImpl<out R> private constructor(
|
||||
|
||||
val javaField: Field? get() = javaField_()
|
||||
|
||||
protected fun computeDelegateField(): Field? =
|
||||
if (@Suppress("DEPRECATION") descriptor.isDelegated) javaField else null
|
||||
|
||||
protected fun getDelegate(field: Field?, receiver: Any?): Any? =
|
||||
try {
|
||||
field?.get(receiver)
|
||||
}
|
||||
catch (e: IllegalAccessException) {
|
||||
throw IllegalPropertyDelegateAccessException(e)
|
||||
}
|
||||
|
||||
override abstract val getter: Getter<R>
|
||||
|
||||
private val descriptor_ = ReflectProperties.lazySoft(descriptorInitialValue) {
|
||||
|
||||
@@ -47,4 +47,9 @@ public abstract class MutablePropertyReference0 extends MutablePropertyReference
|
||||
public KMutableProperty0.Setter getSetter() {
|
||||
return ((KMutableProperty0) getReflected()).getSetter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getDelegate() {
|
||||
return ((KMutableProperty0) getReflected()).getDelegate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,4 +47,9 @@ public abstract class MutablePropertyReference1 extends MutablePropertyReference
|
||||
public KMutableProperty1.Setter getSetter() {
|
||||
return ((KMutableProperty1) getReflected()).getSetter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getDelegate(Object receiver) {
|
||||
return ((KMutableProperty1) getReflected()).getDelegate(receiver);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,4 +40,9 @@ public abstract class MutablePropertyReference2 extends MutablePropertyReference
|
||||
public KMutableProperty2.Setter getSetter() {
|
||||
return ((KMutableProperty2) getReflected()).getSetter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getDelegate(Object receiver1, Object receiver2) {
|
||||
return ((KMutableProperty2) getReflected()).getDelegate(receiver1, receiver2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,4 +42,9 @@ public abstract class PropertyReference0 extends PropertyReference implements KP
|
||||
public KProperty0.Getter getGetter() {
|
||||
return ((KProperty0) getReflected()).getGetter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getDelegate() {
|
||||
return ((KProperty0) getReflected()).getDelegate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,4 +41,9 @@ public abstract class PropertyReference1 extends PropertyReference implements KP
|
||||
public KProperty1.Getter getGetter() {
|
||||
return ((KProperty1) getReflected()).getGetter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getDelegate(Object receiver) {
|
||||
return ((KProperty1) getReflected()).getDelegate(receiver);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,4 +34,9 @@ public abstract class PropertyReference2 extends PropertyReference implements KP
|
||||
public KProperty2.Getter getGetter() {
|
||||
return ((KProperty2) getReflected()).getGetter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getDelegate(Object receiver1, Object receiver2) {
|
||||
return ((KProperty2) getReflected()).getDelegate(receiver1, receiver2);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user