[kotlin-tooling-core] Implement ExtrasLazyProperty

^KT-55289 Verification Pending
This commit is contained in:
Sebastian Sellmair
2022-12-07 09:50:26 +01:00
committed by Space Team
parent bd229584e4
commit 764a57f126
3 changed files with 63 additions and 1 deletions
@@ -83,17 +83,27 @@ public abstract interface class org/jetbrains/kotlin/tooling/core/ExtrasFactoryP
public fun setValue (Lorg/jetbrains/kotlin/tooling/core/HasMutableExtras;Lkotlin/reflect/KProperty;Ljava/lang/Object;)V
}
public abstract interface class org/jetbrains/kotlin/tooling/core/ExtrasLazyProperty : kotlin/properties/ReadWriteProperty, org/jetbrains/kotlin/tooling/core/ExtrasProperty {
public abstract fun getFactory ()Lkotlin/jvm/functions/Function1;
public synthetic fun getValue (Ljava/lang/Object;Lkotlin/reflect/KProperty;)Ljava/lang/Object;
public fun getValue (Lorg/jetbrains/kotlin/tooling/core/HasMutableExtras;Lkotlin/reflect/KProperty;)Ljava/lang/Object;
public synthetic fun setValue (Ljava/lang/Object;Lkotlin/reflect/KProperty;Ljava/lang/Object;)V
public fun setValue (Lorg/jetbrains/kotlin/tooling/core/HasMutableExtras;Lkotlin/reflect/KProperty;Ljava/lang/Object;)V
}
public abstract interface class org/jetbrains/kotlin/tooling/core/ExtrasProperty {
public abstract fun getKey ()Lorg/jetbrains/kotlin/tooling/core/Extras$Key;
}
public final class org/jetbrains/kotlin/tooling/core/ExtrasPropertyKt {
public static final fun extrasFactoryProperty (Lorg/jetbrains/kotlin/tooling/core/Extras$Key;Lkotlin/jvm/functions/Function0;)Lorg/jetbrains/kotlin/tooling/core/ExtrasFactoryProperty;
public static final fun extrasLazyProperty (Lorg/jetbrains/kotlin/tooling/core/Extras$Key;Lkotlin/jvm/functions/Function1;)Lorg/jetbrains/kotlin/tooling/core/ExtrasLazyProperty;
public static final fun extrasReadProperty (Lorg/jetbrains/kotlin/tooling/core/Extras$Key;)Lorg/jetbrains/kotlin/tooling/core/ExtrasReadOnlyProperty;
public static final fun extrasReadWriteProperty (Lorg/jetbrains/kotlin/tooling/core/Extras$Key;)Lorg/jetbrains/kotlin/tooling/core/ExtrasReadWriteProperty;
public static final fun factoryProperty (Lorg/jetbrains/kotlin/tooling/core/Extras$Key;Lkotlin/jvm/functions/Function0;)Lorg/jetbrains/kotlin/tooling/core/ExtrasFactoryProperty;
public static final fun getReadProperty (Lorg/jetbrains/kotlin/tooling/core/Extras$Key;)Lorg/jetbrains/kotlin/tooling/core/ExtrasReadOnlyProperty;
public static final fun getReadWriteProperty (Lorg/jetbrains/kotlin/tooling/core/Extras$Key;)Lorg/jetbrains/kotlin/tooling/core/ExtrasReadWriteProperty;
public static final fun lazyProperty (Lorg/jetbrains/kotlin/tooling/core/Extras$Key;Lkotlin/jvm/functions/Function1;)Lorg/jetbrains/kotlin/tooling/core/ExtrasLazyProperty;
}
public abstract interface class org/jetbrains/kotlin/tooling/core/ExtrasReadOnlyProperty : kotlin/properties/ReadOnlyProperty, org/jetbrains/kotlin/tooling/core/ExtrasProperty {
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.tooling.core
import javax.sound.midi.Receiver
import kotlin.properties.ReadOnlyProperty
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
@@ -19,6 +20,8 @@ val <T : Any> Extras.Key<T>.readWriteProperty get() = extrasReadWriteProperty(th
fun <T : Any> Extras.Key<T>.factoryProperty(factory: () -> T) = extrasFactoryProperty(this, factory)
fun <Receiver : HasMutableExtras, T : Any> Extras.Key<T>.lazyProperty(factory: Receiver.() -> T) = extrasLazyProperty(this, factory)
fun <T : Any> extrasReadProperty(key: Extras.Key<T>): ExtrasReadOnlyProperty<T> = object : ExtrasReadOnlyProperty<T> {
override val key: Extras.Key<T> = key
}
@@ -32,6 +35,14 @@ fun <T : Any> extrasFactoryProperty(key: Extras.Key<T>, factory: () -> T) = obje
override val factory: () -> T = factory
}
fun <Receiver : HasMutableExtras, T : Any> extrasLazyProperty(
key: Extras.Key<T>, factory: Receiver.() -> T
): ExtrasLazyProperty<Receiver, T> =
object : ExtrasLazyProperty<Receiver, T> {
override val key: Extras.Key<T> = key
override val factory: Receiver.() -> T = factory
}
inline fun <reified T : Any> extrasReadWriteProperty(name: String? = null) =
extrasReadWriteProperty(extrasKeyOf<T>(name))
@@ -39,7 +50,10 @@ inline fun <reified T : Any> extrasReadProperty(name: String? = null) =
extrasReadProperty(extrasKeyOf<T>(name))
inline fun <reified T : Any> extrasFactoryProperty(name: String? = null, noinline factory: () -> T) =
extrasFactoryProperty(extrasKeyOf<T>(name), factory)
extrasFactoryProperty(extrasKeyOf(name), factory)
inline fun <Receiver : HasMutableExtras, reified T : Any> extrasLazyProperty(name: String? = null, noinline factory: Receiver.() -> T) =
extrasLazyProperty(extrasKeyOf(name), factory)
interface ExtrasReadOnlyProperty<T : Any> : ExtrasProperty<T>, ReadOnlyProperty<HasExtras, T?> {
override fun getValue(thisRef: HasExtras, property: KProperty<*>): T? {
@@ -99,3 +113,15 @@ interface ExtrasFactoryProperty<T : Any> : ExtrasProperty<T>, ReadWriteProperty<
thisRef.extras[key] = value
}
}
interface ExtrasLazyProperty<Receiver : HasMutableExtras, T : Any> : ExtrasProperty<T>, ReadWriteProperty<Receiver, T> {
val factory: Receiver.() -> T
override fun getValue(thisRef: Receiver, property: KProperty<*>): T {
return thisRef.extras.getOrPut(key) { thisRef.factory() }
}
override fun setValue(thisRef: Receiver, property: KProperty<*>, value: T) {
thisRef.extras[key] = value
}
}
@@ -34,6 +34,9 @@ class ExtrasPropertyTest {
private val keyList = extrasKeyOf<MutableList<Dummy>>()
private val Subject.factoryList: MutableList<Dummy> by keyList.factoryProperty { mutableListOf() }
private val keySubjectList = extrasKeyOf<MutableList<Subject>>()
private val Subject.lazyList: MutableList<Subject> by keySubjectList.lazyProperty { mutableListOf(this) }
@Test
fun `test - readOnlyProperty`() {
val subject = Subject()
@@ -110,4 +113,27 @@ class ExtrasPropertyTest {
assertSame(list, subject.factoryList)
}
}
@Test
fun `test - lazyProperty`() {
run {
val subject = Subject()
assertNotNull(subject.lazyList)
assertSame(subject.lazyList, subject.lazyList)
assertSame(subject.extras[keySubjectList], subject.lazyList)
assertSame(subject, subject.lazyList.firstOrNull())
val subject2 = Subject()
assertSame(subject2, subject2.lazyList.firstOrNull())
assertNotSame(subject.lazyList.firstOrNull(), subject2.lazyList.firstOrNull())
}
run {
val subject = Subject()
val list = mutableListOf<Subject>()
subject.extras[keySubjectList] = list
assertSame(list, subject.lazyList)
}
}
}