Delegate properties stdlib, take 2.
This commit is contained in:
@@ -0,0 +1,175 @@
|
||||
package kotlin.properties
|
||||
|
||||
public trait ReadOnlyProperty<in R, out T> {
|
||||
public fun get(thisRef: R, desc: PropertyMetadata): T
|
||||
}
|
||||
|
||||
public trait ReadWriteProperty<in R, T> {
|
||||
public fun get(thisRef: R, desc: PropertyMetadata): T
|
||||
public fun set(thisRef: R, desc: PropertyMetadata, value: T)
|
||||
}
|
||||
|
||||
public object Delegates {
|
||||
public fun notNull<T: Any>(): ReadWriteProperty<Any?, T> = NotNullVar()
|
||||
|
||||
public fun lazy<T>(initializer: () -> T): ReadOnlyProperty<Any?, T> = LazyVal(initializer)
|
||||
public fun blockingLazy<T>(lock: Any? = null, initializer: () -> T): ReadOnlyProperty<Any?, T> = BlockingLazyVal(lock, initializer)
|
||||
|
||||
public fun observable<T>(initial: T, onChange: (desc: PropertyMetadata, oldValue: T, newValue: T) -> Unit): ReadWriteProperty<Any?, T> {
|
||||
return ObservableProperty<T>(initial) { (desc, old, new) ->
|
||||
onChange(desc, old, new)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
public fun vetoable<T>(initial: T, onChange: (desc: PropertyMetadata, oldValue: T, newValue: T) -> Boolean): ReadWriteProperty<Any?, T> {
|
||||
return ObservableProperty<T>(initial, onChange)
|
||||
}
|
||||
|
||||
public fun mapVar<T>(map: MutableMap<in String, Any?>,
|
||||
default: (thisRef: Any?, desc: String) -> T = defaultValueProvider): ReadWriteProperty<Any?, T> {
|
||||
return FixedMapVar<Any?, String, T>(map, defaultKeyProvider, default)
|
||||
}
|
||||
|
||||
public fun mapVal<T>(map: Map<in String, Any?>,
|
||||
default: (thisRef: Any?, desc: String) -> T = defaultValueProvider): ReadOnlyProperty<Any?, T> {
|
||||
return FixedMapVal<Any?, String, T>(map, defaultKeyProvider, default)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class NotNullVar<T: Any>() : ReadWriteProperty<Any?, T> {
|
||||
private var value: T? = null
|
||||
|
||||
public override fun get(thisRef: Any?, desc: PropertyMetadata): T {
|
||||
return value ?: throw IllegalStateException("Property ${desc.name} should be initialized before get")
|
||||
}
|
||||
|
||||
public override fun set(thisRef: Any?, desc: PropertyMetadata, value: T) {
|
||||
this.value = value
|
||||
}
|
||||
}
|
||||
|
||||
class ObservableProperty<T>(initialValue: T, val onChange: (name: jet.PropertyMetadata, oldValue: T, newValue: T) -> Boolean): ReadWriteProperty<Any?, T> {
|
||||
private var value = initialValue
|
||||
|
||||
public override fun get(thisRef: Any?, desc: PropertyMetadata): T {
|
||||
return value
|
||||
}
|
||||
|
||||
public override fun set(thisRef: Any?, desc: PropertyMetadata, value: T) {
|
||||
if (onChange(desc, this.value, value)) {
|
||||
this.value = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val NULL_VALUE: Any = Any()
|
||||
|
||||
private fun escape(value: Any?): Any {
|
||||
return value ?: NULL_VALUE
|
||||
}
|
||||
|
||||
private fun unescape(value: Any?): Any? {
|
||||
return if (value == NULL_VALUE) null else value
|
||||
}
|
||||
|
||||
private class LazyVal<T>(private val initializer: () -> T) : ReadOnlyProperty<Any?, T> {
|
||||
private var value: Any? = null
|
||||
|
||||
public override fun get(thisRef: Any?, desc: PropertyMetadata): T {
|
||||
if (value == null) {
|
||||
value = escape(initializer())
|
||||
}
|
||||
return unescape(value) as T
|
||||
}
|
||||
}
|
||||
|
||||
private class BlockingLazyVal<T>(lock: Any?, private val initializer: () -> T) : ReadOnlyProperty<Any?, T> {
|
||||
private val lock = lock ?: this
|
||||
private volatile var value: Any? = null
|
||||
|
||||
public override fun get(thisRef: Any?, desc: PropertyMetadata): T {
|
||||
val _v1 = value
|
||||
if (_v1 != null) {
|
||||
return unescape(_v1) as T
|
||||
}
|
||||
|
||||
return synchronized(lock) {
|
||||
val _v2 = value
|
||||
if (_v2 != null) {
|
||||
unescape(_v2) as T
|
||||
}
|
||||
else {
|
||||
val typedValue = initializer()
|
||||
value = escape(typedValue)
|
||||
typedValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class KeyMissingException(message: String): RuntimeException(message)
|
||||
|
||||
public abstract class MapVal<T, in K, out V>() : ReadOnlyProperty<T, V> {
|
||||
protected abstract fun map(ref: T): Map<in K, Any?>
|
||||
protected abstract fun key(desc: PropertyMetadata): K
|
||||
|
||||
protected open fun default(ref: T, desc: PropertyMetadata): V {
|
||||
throw KeyMissingException("Key $desc is missing in $ref")
|
||||
}
|
||||
|
||||
public override fun get(thisRef: T, desc: PropertyMetadata) : V {
|
||||
val map = map(thisRef)
|
||||
val key = key(desc)
|
||||
if (!map.containsKey(key)) {
|
||||
return default(thisRef, desc)
|
||||
}
|
||||
|
||||
return map[key] as V
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class MapVar<T, in K, V>() : MapVal<T, K, V>(), ReadWriteProperty<T, V> {
|
||||
protected abstract override fun map(ref: T): MutableMap<in K, Any?>
|
||||
|
||||
public override fun set(thisRef: T, desc: PropertyMetadata, value: V) {
|
||||
val map = map(thisRef)
|
||||
map.put(key(desc), value)
|
||||
}
|
||||
}
|
||||
|
||||
private val defaultKeyProvider:(PropertyMetadata) -> String = {it.name}
|
||||
private val defaultValueProvider:(Any?, Any?) -> Nothing = {(thisRef, key) -> throw KeyMissingException("$key is missing from $thisRef")}
|
||||
|
||||
public open class FixedMapVal<T, in K, out V>(private val map: Map<in K, Any?>,
|
||||
private val key: (PropertyMetadata) -> K,
|
||||
private val default: (ref: T, key: K) -> V = defaultValueProvider) : MapVal<T, K, V>() {
|
||||
protected override fun map(ref: T): Map<in K, Any?> {
|
||||
return map
|
||||
}
|
||||
|
||||
protected override fun key(desc: PropertyMetadata): K {
|
||||
return (key)(desc)
|
||||
}
|
||||
|
||||
protected override fun default(ref: T, desc: PropertyMetadata): V {
|
||||
return (default)(ref, key(desc))
|
||||
}
|
||||
}
|
||||
|
||||
public open class FixedMapVar<T, in K, V>(private val map: MutableMap<in K, Any?>,
|
||||
private val key: (PropertyMetadata) -> K,
|
||||
private val default: (ref: T, key: K) -> V = defaultValueProvider) : MapVar<T, K, V>() {
|
||||
protected override fun map(ref: T): MutableMap<in K, Any?> {
|
||||
return map
|
||||
}
|
||||
|
||||
protected override fun key(desc: PropertyMetadata): K {
|
||||
return (key)(desc)
|
||||
}
|
||||
|
||||
protected override fun default(ref: T, desc: PropertyMetadata): V {
|
||||
return (default)(ref, key(desc))
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package kotlin.properties
|
||||
|
||||
import java.util.HashMap
|
||||
import java.util.ArrayList
|
||||
import kotlin.properties.delegation.ObservableProperty
|
||||
|
||||
public class ChangeEvent(val source: Any, val name: String, val oldValue: Any?, val newValue: Any?) {
|
||||
var propogationId: Any? = null
|
||||
@@ -65,8 +64,8 @@ public abstract class ChangeSupport {
|
||||
}
|
||||
}
|
||||
|
||||
protected fun property<T>(init: T): ObservableProperty<T> {
|
||||
return ObservableProperty(init) { name, oldValue, newValue -> changeProperty(name, oldValue, newValue) }
|
||||
protected fun property<T>(init: T): ReadWriteProperty<Any?, T> {
|
||||
return Delegates.observable(init) { desc, oldValue, newValue -> changeProperty(desc.name, oldValue, newValue) }
|
||||
}
|
||||
|
||||
public fun onPropertyChange(fn: (ChangeEvent) -> Unit) {
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
package kotlin.properties.delegation
|
||||
|
||||
import kotlin.properties.ChangeSupport
|
||||
|
||||
public class NotNullVar<T: Any> {
|
||||
private var value: T? = null
|
||||
|
||||
public fun get(thisRef: Any?, desc: PropertyMetadata): T {
|
||||
return value ?: throw IllegalStateException("Property ${desc.name} should be initialized before get")
|
||||
}
|
||||
|
||||
public fun set(thisRef: Any?, desc: PropertyMetadata, value: T) {
|
||||
this.value = value
|
||||
}
|
||||
}
|
||||
|
||||
public class SynchronizedVar<T>(private val initValue: T, private val lock: Any) {
|
||||
private var value: T = initValue
|
||||
|
||||
public fun get(thisRef: Any?, desc: PropertyMetadata): T {
|
||||
return synchronized(lock) { value }
|
||||
}
|
||||
|
||||
public fun set(thisRef: Any?, desc: PropertyMetadata, newValue: T) {
|
||||
synchronized(lock) {
|
||||
value = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ObservableProperty<T>(initialValue: T, val changeSupport: (name: String, oldValue: T, newValue: T) -> Unit) {
|
||||
private var value = initialValue
|
||||
|
||||
public fun get(thisRef: Any?, desc: PropertyMetadata): T {
|
||||
return value
|
||||
}
|
||||
|
||||
public fun set(thisRef: Any?, desc: PropertyMetadata, newValue: T) {
|
||||
changeSupport(desc.name, value, newValue)
|
||||
value = newValue
|
||||
}
|
||||
}
|
||||
|
||||
public class KeyMissingException(message: String): RuntimeException(message)
|
||||
|
||||
public abstract class MapVal<T, V> {
|
||||
public abstract fun getMap(thisRef: T): Map<*, *>
|
||||
public abstract fun getKey(desc: PropertyMetadata): Any?
|
||||
|
||||
public open fun getDefaultValue(desc: PropertyMetadata, key: Any?): V {
|
||||
throw KeyMissingException("Key $key is missing")
|
||||
}
|
||||
|
||||
public fun get(thisRef: T, desc: PropertyMetadata): V {
|
||||
val key = getKey(desc)
|
||||
val map = getMap(thisRef)
|
||||
if (!map.containsKey(key)) {
|
||||
return getDefaultValue(desc, key)
|
||||
}
|
||||
return map[key] as V
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class MapVar<T, V>: MapVal<T, V>() {
|
||||
|
||||
public fun set(thisRef: T, desc: PropertyMetadata, newValue: V) {
|
||||
val map = getMap(thisRef) as MutableMap<Any?, Any?>
|
||||
map[getKey(desc)] = newValue
|
||||
}
|
||||
}
|
||||
|
||||
public fun <V> Map<String, *>.readOnlyProperty(default: (() -> V)? = null): MapVal<Any?, V> {
|
||||
return object: MapVal<Any?, V>() {
|
||||
override fun getMap(thisRef: Any?) = this@readOnlyProperty
|
||||
override fun getKey(desc: PropertyMetadata) = desc.name
|
||||
override fun getDefaultValue(desc: PropertyMetadata, key: Any?) = if (default == null) super.getDefaultValue(desc, key) else default()
|
||||
}
|
||||
}
|
||||
|
||||
public fun <V> Map<*, *>.readOnlyProperty(default: (() -> V)? = null, key: Any?): MapVal<Any?, V> {
|
||||
return object: MapVal<Any?, V>() {
|
||||
override fun getMap(thisRef: Any?) = this@readOnlyProperty
|
||||
override fun getKey(desc: PropertyMetadata) = key
|
||||
override fun getDefaultValue(desc: PropertyMetadata, key: Any?) = if (default == null) super.getDefaultValue(desc, key) else default()
|
||||
}
|
||||
}
|
||||
|
||||
public fun <V> Map<*, *>.readOnlyProperty(default: (() -> V)? = null, key: (desc: PropertyMetadata) -> Any?): MapVal<Any?, V> {
|
||||
return object: MapVal<Any?, V>() {
|
||||
override fun getMap(thisRef: Any?) = this@readOnlyProperty
|
||||
override fun getKey(desc: PropertyMetadata) = key(desc)
|
||||
override fun getDefaultValue(desc: PropertyMetadata, key: Any?) = if (default == null) super.getDefaultValue(desc, key) else default()
|
||||
}
|
||||
}
|
||||
|
||||
public fun <V> MutableMap<String, *>.property(default: (() -> V)? = null): MapVar<Any?, V> {
|
||||
return object: MapVar<Any?, V>() {
|
||||
override fun getMap(thisRef: Any?) = this@property
|
||||
override fun getKey(desc: PropertyMetadata) = desc.name
|
||||
override fun getDefaultValue(desc: PropertyMetadata, key: Any?) = if (default == null) super.getDefaultValue(desc, key) else default()
|
||||
}
|
||||
}
|
||||
|
||||
public fun <V> MutableMap<*, *>.property(default: (() -> V)? = null, key: Any?): MapVar<Any?, V> {
|
||||
return object: MapVar<Any?, V>() {
|
||||
override fun getMap(thisRef: Any?) = this@property
|
||||
override fun getKey(desc: PropertyMetadata) = key
|
||||
override fun getDefaultValue(desc: PropertyMetadata, key: Any?) = if (default == null) super.getDefaultValue(desc, key) else default()
|
||||
}
|
||||
}
|
||||
|
||||
public fun <V> MutableMap<*, *>.property(default: (() -> V)? = null, key: (desc: PropertyMetadata) -> Any?): MapVar<Any?, V> {
|
||||
return object: MapVar<Any?, V>() {
|
||||
override fun getMap(thisRef: Any?) = this@property
|
||||
override fun getKey(desc: PropertyMetadata) = key(desc)
|
||||
override fun getDefaultValue(desc: PropertyMetadata, key: Any?) = if (default == null) super.getDefaultValue(desc, key) else default()
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
package kotlin.properties.delegation.lazy
|
||||
|
||||
private val NULL_VALUE: Any = Any()
|
||||
|
||||
private fun <T> escape(value: T): Any {
|
||||
return if (value == null) NULL_VALUE else value
|
||||
}
|
||||
|
||||
private fun <T: Any> unescape(value: Any): T? {
|
||||
return if (value == NULL_VALUE) null else value as T
|
||||
}
|
||||
|
||||
public open class LazyVal<T: Any>(initializer: () -> T): NullableLazyVal<T>(initializer) {
|
||||
override fun get(thisRef: Any?, desc: PropertyMetadata): T {
|
||||
return super.get(thisRef, desc)!!
|
||||
}
|
||||
}
|
||||
|
||||
public open class NullableLazyVal<T: Any>(private val initializer: () -> T?) {
|
||||
private var value: Any? = null
|
||||
|
||||
public open fun get(thisRef: Any?, desc: PropertyMetadata): T? {
|
||||
if (value == null) {
|
||||
value = escape(initializer())
|
||||
}
|
||||
return unescape(value!!)
|
||||
}
|
||||
}
|
||||
|
||||
public open class VolatileLazyVal<T: Any>(initializer: () -> T): VolatileNullableLazyVal<T>(initializer) {
|
||||
override fun get(thisRef: Any?, desc: PropertyMetadata): T {
|
||||
return super.get(thisRef, desc)!!
|
||||
}
|
||||
}
|
||||
|
||||
public open class VolatileNullableLazyVal<T: Any>(private val initializer: () -> T?) {
|
||||
private volatile var value: Any? = null
|
||||
|
||||
public open fun get(thisRef: Any?, desc: PropertyMetadata): T? {
|
||||
if (value == null) {
|
||||
value = escape(initializer())
|
||||
}
|
||||
return unescape(value!!)
|
||||
}
|
||||
}
|
||||
|
||||
public open class AtomicLazyVal<T: Any>(lock: Any? = null, initializer: () -> T): AtomicNullableLazyVal<T>(lock, initializer) {
|
||||
override fun get(thisRef: Any?, desc: PropertyMetadata): T {
|
||||
return super.get(thisRef, desc)!!
|
||||
}
|
||||
}
|
||||
|
||||
public open class AtomicNullableLazyVal<T: Any>(lock: Any? = null, private val initializer: () -> T?) {
|
||||
private val lock = lock ?: this
|
||||
private volatile var value: Any? = null
|
||||
|
||||
public open fun get(thisRef: Any?, desc: PropertyMetadata): T? {
|
||||
val _v1 = value
|
||||
if (_v1 != null) {
|
||||
return unescape(_v1)
|
||||
}
|
||||
|
||||
return synchronized(lock) {
|
||||
val _v2 = value
|
||||
if (_v2 != null) {
|
||||
unescape<T>(_v2)
|
||||
}
|
||||
else {
|
||||
val typedValue = initializer()
|
||||
value = escape(typedValue)
|
||||
typedValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,6 @@ package test.properties.delegation
|
||||
import junit.framework.TestCase
|
||||
import kotlin.test.*
|
||||
import kotlin.properties.*
|
||||
import kotlin.properties.delegation.*
|
||||
import kotlin.properties.delegation.lazy.*
|
||||
|
||||
trait WithBox {
|
||||
fun box(): String
|
||||
@@ -27,8 +25,8 @@ class DelegationTest(): DelegationTestBase() {
|
||||
}
|
||||
|
||||
public class TestNotNullVar<T>(val a1: String, val b1: T): WithBox {
|
||||
var a: String by NotNullVar<String>()
|
||||
var b by NotNullVar<T>()
|
||||
var a: String by Delegates.notNull<String>()
|
||||
var b by Delegates.notNull<T>()
|
||||
|
||||
override fun box(): String {
|
||||
a = a1
|
||||
@@ -61,4 +59,4 @@ class TestObservableProperty: WithBox, ChangeSupport() {
|
||||
if (!result) return "fail: result should be true"
|
||||
return "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package test.properties.delegation
|
||||
|
||||
import java.util.HashMap
|
||||
import kotlin.properties.delegation.*
|
||||
import kotlin.properties.*
|
||||
|
||||
class MapDelegationTest(): DelegationTestBase() {
|
||||
|
||||
@@ -48,10 +48,10 @@ class MapDelegationTest(): DelegationTestBase() {
|
||||
|
||||
class TestMapValWithDifferentTypes(): WithBox {
|
||||
val map = hashMapOf("a" to "a", "b" to 1, "c" to A(1), "d" to null)
|
||||
val a by map.readOnlyProperty<String>()
|
||||
val b by map.readOnlyProperty<Int>()
|
||||
val c by map.readOnlyProperty<Any>()
|
||||
val d by map.readOnlyProperty<Int?>()
|
||||
val a by Delegates.mapVal<String>(map)
|
||||
val b by Delegates.mapVal<Int>(map)
|
||||
val c by Delegates.mapVal<Any>(map)
|
||||
val d by Delegates.mapVal<Int?>(map)
|
||||
|
||||
override fun box(): String {
|
||||
if (a != "a") return "fail at 'a'"
|
||||
@@ -66,10 +66,10 @@ class TestMapValWithDifferentTypes(): WithBox {
|
||||
|
||||
class TestMapVarWithDifferentTypes(): WithBox {
|
||||
val map: HashMap<String, Any?> = hashMapOf("a" to "a", "b" to 1, "c" to A(1), "d" to "d")
|
||||
var a by map.property<String>()
|
||||
var b by map.property<Int>()
|
||||
var c by map.property<Any>()
|
||||
var d by map.property<String?>()
|
||||
var a by Delegates.mapVar<String>(map)
|
||||
var b by Delegates.mapVar<Int>(map)
|
||||
var c by Delegates.mapVar<Any>(map)
|
||||
var d by Delegates.mapVar<String?>(map)
|
||||
|
||||
override fun box(): String {
|
||||
a = "aa"
|
||||
@@ -87,8 +87,8 @@ class TestMapVarWithDifferentTypes(): WithBox {
|
||||
}
|
||||
|
||||
class TestNullableKey: WithBox {
|
||||
val map = hashMapOf(null to "null")
|
||||
var a by map.property<String?> { desc -> null }
|
||||
val map = hashMapOf(null:Any? to "null": Any?)
|
||||
var a by FixedMapVar<Any?, Any?, Any?>(map, key = { desc -> null }, default = {ref, desc -> null})
|
||||
|
||||
override fun box(): String {
|
||||
if (a != "null") return "fail at 'a'"
|
||||
@@ -99,10 +99,10 @@ class TestNullableKey: WithBox {
|
||||
}
|
||||
|
||||
class TestMapPropertyString(): WithBox {
|
||||
val map = hashMapOf("a" to "a", "b" to "b", "c" to "c")
|
||||
val a by map.readOnlyProperty<String>()
|
||||
var b by map.property<String>()
|
||||
val c by map.property<String>()
|
||||
val map = hashMapOf("a" to "a", "b" to "b", "c" to "c":Any?)
|
||||
val a by Delegates.mapVal<String>(map)
|
||||
var b by Delegates.mapVar<String>(map)
|
||||
val c by Delegates.mapVal<String>(map)
|
||||
|
||||
override fun box(): String {
|
||||
b = "newB"
|
||||
@@ -115,9 +115,9 @@ class TestMapPropertyString(): WithBox {
|
||||
|
||||
class TestMapValWithDefault(): WithBox {
|
||||
val map = hashMapOf<String, String>()
|
||||
val a by map.readOnlyProperty<String>(default = { "aDefault" })
|
||||
val b by map.readOnlyProperty<String>(default = { "bDefault" }, key = "b")
|
||||
val c by map.readOnlyProperty<String>(default = { "cDefault" }, key = { desc -> desc.name })
|
||||
val a by Delegates.mapVal<String>(map, default = { ref, desc -> "aDefault" })
|
||||
val b by FixedMapVal<TestMapValWithDefault, String, String>(map, default = { ref, desc -> "bDefault" }, key = {"b"})
|
||||
val c by FixedMapVal<TestMapValWithDefault, String, String>(map, default = { ref, desc -> "cDefault" }, key = { desc -> desc.name })
|
||||
|
||||
override fun box(): String {
|
||||
if (a != "aDefault") return "fail at 'a'"
|
||||
@@ -128,10 +128,10 @@ class TestMapValWithDefault(): WithBox {
|
||||
}
|
||||
|
||||
class TestMapVarWithDefault(): WithBox {
|
||||
val map = hashMapOf<String, String>()
|
||||
var a by map.property<String>(default = { "aDefault" })
|
||||
var b by map.property<String>(default = { "bDefault" }, key = "b")
|
||||
var c by map.property<String>(default = { "cDefault" }, key = { desc -> desc.name })
|
||||
val map = hashMapOf<String, Any?>()
|
||||
var a: String by Delegates.mapVar(map, default = {ref, desc -> "aDefault" })
|
||||
var b: String by FixedMapVar<Any?, String, String>(map, default = {ref, desc -> "bDefault" }, key = {"b"})
|
||||
var c: String by FixedMapVar<Any?, String, String>(map, default = {ref, desc -> "cDefault" }, key = { desc -> desc.name })
|
||||
|
||||
override fun box(): String {
|
||||
if (a != "aDefault") return "fail at 'a'"
|
||||
@@ -148,9 +148,9 @@ class TestMapVarWithDefault(): WithBox {
|
||||
}
|
||||
|
||||
class TestMapPropertyKey(): WithBox {
|
||||
val map = hashMapOf("a" to "a", "b" to "b")
|
||||
val a by map.readOnlyProperty<String>(key = "a")
|
||||
var b by map.property<String>(key = "b")
|
||||
val map = hashMapOf("a" to "a", "b" to "b" : Any?)
|
||||
val a by FixedMapVal<Any?, String, String>(map, key = {"a"})
|
||||
var b by FixedMapVar<Any?, String, String>(map, key = {"b"})
|
||||
|
||||
override fun box(): String {
|
||||
b = "c"
|
||||
@@ -161,9 +161,9 @@ class TestMapPropertyKey(): WithBox {
|
||||
}
|
||||
|
||||
class TestMapPropertyFunction(): WithBox {
|
||||
val map = hashMapOf("aDesc" to "a", "bDesc" to "b")
|
||||
val a by map.readOnlyProperty<String> { desc -> "${desc.name}Desc" }
|
||||
var b by map.property<String> { desc -> "${desc.name}Desc" }
|
||||
val map = hashMapOf("aDesc" to "a", "bDesc" to "b": Any?)
|
||||
val a by FixedMapVal<Any?, String, String>(map, { desc -> "${desc.name}Desc" })
|
||||
var b by FixedMapVar<Any?, String, String>(map, { desc -> "${desc.name}Desc" })
|
||||
|
||||
override fun box(): String {
|
||||
b = "c"
|
||||
@@ -173,17 +173,18 @@ class TestMapPropertyFunction(): WithBox {
|
||||
}
|
||||
}
|
||||
|
||||
val mapVal = object : MapVal<TestMapPropertyCustom, String>() {
|
||||
override fun getMap(thisRef: TestMapPropertyCustom) = thisRef.map
|
||||
override fun getKey(desc: PropertyMetadata) = "${desc.name}Desc"
|
||||
val mapVal = object: MapVal<TestMapPropertyCustom, String, String>() {
|
||||
override fun map(ref: TestMapPropertyCustom) = ref.map
|
||||
override fun key(desc: PropertyMetadata) = "${desc.name}Desc"
|
||||
}
|
||||
val mapVar = object : MapVar<TestMapPropertyCustom, String>() {
|
||||
override fun getMap(thisRef: TestMapPropertyCustom) = thisRef.map
|
||||
override fun getKey(desc: PropertyMetadata) = "${desc.name}Desc"
|
||||
|
||||
val mapVar = object : MapVar<TestMapPropertyCustom, String, String>() {
|
||||
override fun map(ref: TestMapPropertyCustom) = ref.map
|
||||
override fun key(desc: PropertyMetadata) = "${desc.name}Desc"
|
||||
}
|
||||
|
||||
class TestMapPropertyCustom(): WithBox {
|
||||
val map = hashMapOf("aDesc" to "a", "bDesc" to "b")
|
||||
val map = hashMapOf("aDesc" to "a", "bDesc" to "b":Any?)
|
||||
val a by mapVal
|
||||
var b by mapVar
|
||||
|
||||
@@ -195,22 +196,22 @@ class TestMapPropertyCustom(): WithBox {
|
||||
}
|
||||
}
|
||||
|
||||
val mapValWithDefault = object : MapVal<TestMapPropertyCustomWithDefault, String>() {
|
||||
override fun getMap(thisRef: TestMapPropertyCustomWithDefault) = thisRef.map
|
||||
override fun getKey(desc: PropertyMetadata) = desc.name
|
||||
val mapValWithDefault = object : MapVal<TestMapPropertyCustomWithDefault, String, String>() {
|
||||
override fun map(ref: TestMapPropertyCustomWithDefault) = ref.map
|
||||
override fun key(desc: PropertyMetadata) = desc.name
|
||||
|
||||
override fun getDefaultValue(desc: PropertyMetadata, key: Any?) = "default"
|
||||
override fun default(ref: TestMapPropertyCustomWithDefault, key: PropertyMetadata) = "default"
|
||||
}
|
||||
|
||||
val mapVarWithDefault = object : MapVar<TestMapPropertyCustomWithDefault, String>() {
|
||||
override fun getMap(thisRef: TestMapPropertyCustomWithDefault) = thisRef.map
|
||||
override fun getKey(desc: PropertyMetadata) = desc.name
|
||||
val mapVarWithDefault = object : MapVar<TestMapPropertyCustomWithDefault, String, String>() {
|
||||
override fun map(ref: TestMapPropertyCustomWithDefault) = ref.map
|
||||
override fun key(desc: PropertyMetadata) = desc.name
|
||||
|
||||
override fun getDefaultValue(desc: PropertyMetadata, key: Any?) = "default"
|
||||
override fun default(ref: TestMapPropertyCustomWithDefault, key: PropertyMetadata) = "default"
|
||||
}
|
||||
|
||||
class TestMapPropertyCustomWithDefault(): WithBox {
|
||||
val map = hashMapOf<String, String>()
|
||||
val map = hashMapOf<String, Any?>()
|
||||
val a by mapValWithDefault
|
||||
var b by mapVarWithDefault
|
||||
|
||||
@@ -221,4 +222,4 @@ class TestMapPropertyCustomWithDefault(): WithBox {
|
||||
if (b != "c") return "fail at 'b' after set"
|
||||
return "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package test.properties.delegation.lazy
|
||||
|
||||
import kotlin.properties.delegation.lazy.*
|
||||
import test.properties.delegation.WithBox
|
||||
import test.properties.delegation.DelegationTestBase
|
||||
import kotlin.properties.*
|
||||
|
||||
class LazyValuesTest(): DelegationTestBase() {
|
||||
|
||||
@@ -33,7 +33,7 @@ class LazyValuesTest(): DelegationTestBase() {
|
||||
|
||||
class TestLazyVal: WithBox {
|
||||
var result = 0
|
||||
val a by LazyVal {
|
||||
val a by Delegates.lazy {
|
||||
++result
|
||||
}
|
||||
|
||||
@@ -48,8 +48,8 @@ class TestNullableLazyVal: WithBox {
|
||||
var resultA = 0
|
||||
var resultB = 0
|
||||
|
||||
val a: Int? by NullableLazyVal { resultA++; null}
|
||||
val b by NullableLazyVal { foo() }
|
||||
val a: Int? by Delegates.lazy { resultA++; null}
|
||||
val b by Delegates.lazy { foo() }
|
||||
|
||||
override fun box(): String {
|
||||
a
|
||||
@@ -70,7 +70,7 @@ class TestNullableLazyVal: WithBox {
|
||||
|
||||
class TestAtomicLazyVal: WithBox {
|
||||
var result = 0
|
||||
val a by AtomicLazyVal {
|
||||
val a by Delegates.blockingLazy {
|
||||
++result
|
||||
}
|
||||
|
||||
@@ -85,8 +85,8 @@ class TestVolatileNullableLazyVal: WithBox {
|
||||
var resultA = 0
|
||||
var resultB = 0
|
||||
|
||||
val a: Int? by VolatileNullableLazyVal { resultA++; null}
|
||||
val b by VolatileNullableLazyVal { foo() }
|
||||
val a: Int? by Delegates.blockingLazy { resultA++; null}
|
||||
val b by Delegates.blockingLazy { foo() }
|
||||
|
||||
override fun box(): String {
|
||||
a
|
||||
@@ -107,7 +107,7 @@ class TestVolatileNullableLazyVal: WithBox {
|
||||
|
||||
class TestVolatileLazyVal: WithBox {
|
||||
var result = 0
|
||||
val a by VolatileLazyVal {
|
||||
val a by Delegates.blockingLazy {
|
||||
++result
|
||||
}
|
||||
|
||||
@@ -122,8 +122,8 @@ class TestAtomicNullableLazyVal: WithBox {
|
||||
var resultA = 0
|
||||
var resultB = 0
|
||||
|
||||
val a: Int? by AtomicNullableLazyVal { resultA++; null}
|
||||
val b by AtomicNullableLazyVal { foo() }
|
||||
val a: Int? by Delegates.blockingLazy { resultA++; null}
|
||||
val b by Delegates.blockingLazy { foo() }
|
||||
|
||||
override fun box(): String {
|
||||
a
|
||||
|
||||
Reference in New Issue
Block a user