From a6b7857d5710bc0fb4b3f4b3eff74c7009adb643 Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Fri, 19 Jun 2015 17:52:35 +0300 Subject: [PATCH] Drop complicated MapAccessors. Deprecate simple cases of Delegates.mapVar and Delegates.mapVal in favor of direct delegation without wrappers. --- .../src/kotlin/properties/Delegation.kt | 24 +++++- .../src/kotlin/properties/MapAccessors.kt | 74 ------------------- .../properties/delegation/MapAccessorsTest.kt | 45 ----------- 3 files changed, 22 insertions(+), 121 deletions(-) diff --git a/libraries/stdlib/src/kotlin/properties/Delegation.kt b/libraries/stdlib/src/kotlin/properties/Delegation.kt index 847a2296780..9fac18e408a 100644 --- a/libraries/stdlib/src/kotlin/properties/Delegation.kt +++ b/libraries/stdlib/src/kotlin/properties/Delegation.kt @@ -54,6 +54,16 @@ public object Delegates { return ObservableProperty(initial, onChange) } + /** + * Returns a property delegate for a read/write property that stores its value in a map, using the property name + * as a key. + * @param map the map where the property values are stored. + */ + deprecated("Delegate property to the map itself without creating a wrapper.", ReplaceWith("map")) + public fun mapVar(map: MutableMap): ReadWriteProperty { + return FixedMapVar(map, propertyNameSelector, throwKeyNotFound) + } + /** * Returns a property delegate for a read/write property that stores its value in a map, using the property name * as a key. @@ -61,10 +71,20 @@ public object Delegates { * @param default the function returning the value of the property for a given object if it's missing from the given map. */ public fun mapVar(map: MutableMap, - default: (thisRef: Any?, desc: String) -> T = throwKeyNotFound): ReadWriteProperty { + default: (thisRef: Any?, desc: String) -> T): ReadWriteProperty { return FixedMapVar(map, propertyNameSelector, default) } + /** + * Returns a property delegate for a read-only property that takes its value from a map, using the property name + * as a key. + * @param map the map where the property values are stored. + */ + deprecated("Delegate property to the map itself without creating a wrapper.", ReplaceWith("map")) + public fun mapVal(map: Map): ReadOnlyProperty { + return FixedMapVal(map, propertyNameSelector, throwKeyNotFound) + } + /** * Returns a property delegate for a read-only property that takes its value from a map, using the property name * as a key. @@ -72,7 +92,7 @@ public object Delegates { * @param default the function returning the value of the property for a given object if it's missing from the given map. */ public fun mapVal(map: Map, - default: (thisRef: Any?, desc: String) -> T = throwKeyNotFound): ReadOnlyProperty { + default: (thisRef: Any?, desc: String) -> T): ReadOnlyProperty { return FixedMapVal(map, propertyNameSelector, default) } } diff --git a/libraries/stdlib/src/kotlin/properties/MapAccessors.kt b/libraries/stdlib/src/kotlin/properties/MapAccessors.kt index 6269cbc762c..2de12707e05 100644 --- a/libraries/stdlib/src/kotlin/properties/MapAccessors.kt +++ b/libraries/stdlib/src/kotlin/properties/MapAccessors.kt @@ -35,77 +35,3 @@ public fun MutableMap.get(thisRef: Any?, property: Property public fun MutableMap.set(thisRef: Any?, property: PropertyMetadata, value: V) { this.put(property.name, value) } - - - - - -// Map accessors - -public interface MapAccessor -{ - public val map: Map - - /** Returns `true` if the map contains the specified [key]. */ - public fun containsKey(key: KAccess): Boolean - - /** Returns the value corresponding to the given [key], or the default value if such a key is not present in the map. */ - public fun getOrDefault(key: KAccess): V - - public open fun withDefault(default: (KMap) -> V): MapAccessor -} - -public interface MutableMapAccessor: MapAccessor { - public override val map: MutableMap - /** Associates the specified [value] with the specified [key] in the map. */ - public fun put(key: KAccess, value: V): V? - - public override fun withDefault(default: (KMap) -> V): MutableMapAccessor -} - - -public fun Map.forProperties(): MapAccessor = MapAccessorImpl(this, propertyNameSelector) - -// todo: inline keyselector into anonymous object -public fun Map.forProperties(keySelector: (PropertyMetadata) -> K): MapAccessor = MapAccessorImpl(this, keySelector) - -public fun MutableMap.forProperties(): MutableMapAccessor = MutableMapAccessorImpl(this, propertyNameSelector) - -// todo: inline keyselector into anonymous object -public fun MutableMap.forProperties(keySelector: (PropertyMetadata) -> K): MutableMapAccessor = MutableMapAccessorImpl(this, keySelector) - - -// extensions to delegate properties to MapAccessors - -public fun MapAccessor.get(thisRef: Any?, property: PropertyMetadata): V = this.getOrDefault(property) - -platformName("getVar") -public fun MutableMapAccessor.get(thisRef: Any?, property: PropertyMetadata): V = this.getOrDefault(property) as V - -public fun MutableMapAccessor.set(thisRef: Any?, property: PropertyMetadata, value: V) { - this.put(property, value) -} - - - -// MapAccessor implementations - -private open class MapAccessorImpl(public override val map: Map, public val transform: (KAccess) -> KMap, public val default: (KMap) -> V = { key -> throwKeyNotFound(map, key) }) -: MapAccessor { - - override fun containsKey(key: KAccess): Boolean = map.containsKey(transform(key)) - - override fun getOrDefault(key: KAccess): V = transform(key).let { map.getOrElse(it, { default(it) }) } - - override fun withDefault(default: (KMap) -> V): MapAccessor = MapAccessorImpl(map as Map, transform, default) -} - - -private class MutableMapAccessorImpl(public override val map: MutableMap, transform: (KAccess) -> KMap, default: (KMap) -> V = { key -> throwKeyNotFound(map, key) }) -: MapAccessorImpl(map, transform, default), MutableMapAccessor { - - - override fun put(key: KAccess, value: V): V? = map.put(transform(key), value) - - override fun withDefault(default: (KMap) -> V): MutableMapAccessor = MutableMapAccessorImpl(map as MutableMap, transform, default) -} diff --git a/libraries/stdlib/test/properties/delegation/MapAccessorsTest.kt b/libraries/stdlib/test/properties/delegation/MapAccessorsTest.kt index 948265ae9fc..b96bfadb5cf 100644 --- a/libraries/stdlib/test/properties/delegation/MapAccessorsTest.kt +++ b/libraries/stdlib/test/properties/delegation/MapAccessorsTest.kt @@ -64,48 +64,3 @@ class VarByMapExtensionsTest { assertEquals(null, d) } } - -class ValByMapAccessorExtensionsTest { - val map: Map = mapOf("a" to "all", "b" to "bar", "c" to "code") - val genericMap = mapOf("i" to 1, "x" to 1.0) - - val mapAccessor = map.forProperties { it.name.take(1) } - val genericMapAccessor = genericMap.forProperties { it.name.take(1) } - - val cProperty by mapAccessor - val xProperty by genericMapAccessor - val zNoDefault by genericMapAccessor - val zProperty by genericMapAccessor.withDefault { 1 } - - test fun doTest() { - assertEquals("code", cProperty) - assertEquals(1.0, xProperty) - assertEquals(1, zProperty) - fails { zNoDefault } - } -} - -class VarByMapAccessorExtensionsTest { - val map = hashMapOf("xProperty" to 1.0) - - val mapAccessor = map.forProperties { it.name + "Property" } - - var x: Double by mapAccessor.withDefault { 2.0 } - var z: Int by mapAccessor - var s: String by mapAccessor - - test fun doTest() { - assertEquals(1.0, x) - - map.remove("xProperty") - assertEquals(2.0, x) - - z = 2 - assertEquals(2, z) - assertEquals(2, map["zProperty"]) - - fails { s } - map["sProperty"] = null - s // fails { s } // does not fail due to KT-8135 - } -}