Added delegated property through map support + tests.
This commit is contained in:
@@ -619,6 +619,20 @@ task delegatedProperty_delegatedOverride(type: LinkKonanTest) {
|
|||||||
lib = "codegen/delegatedProperty/delegatedOverride_lib.kt"
|
lib = "codegen/delegatedProperty/delegatedOverride_lib.kt"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task delegatedProperty_lazy(type: RunKonanTest) {
|
||||||
|
goldValue = "computed!\nHello\nHello\n"
|
||||||
|
source = "codegen/delegatedProperty/lazy.kt"
|
||||||
|
}
|
||||||
|
|
||||||
|
task delegatedProperty_observable(type: RunKonanTest) {
|
||||||
|
goldValue = "<no name> -> first\nfirst -> second\n"
|
||||||
|
source = "codegen/delegatedProperty/observable.kt"
|
||||||
|
}
|
||||||
|
|
||||||
|
task delegatedProperty_map(type: RunKonanTest) {
|
||||||
|
goldValue = "John Doe\n25\n"
|
||||||
|
source = "codegen/delegatedProperty/map.kt"
|
||||||
|
}
|
||||||
|
|
||||||
task array0(type: RunKonanTest) {
|
task array0(type: RunKonanTest) {
|
||||||
goldValue = "5\n6\n7\n8\n9\n10\n11\n12\n13\n"
|
goldValue = "5\n6\n7\n8\n9\n10\n11\n12\n13\n"
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
val lazyValue: String by lazy {
|
||||||
|
println("computed!")
|
||||||
|
"Hello"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
println(lazyValue)
|
||||||
|
println(lazyValue)
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
class User(val map: Map<String, Any?>) {
|
||||||
|
val name: String by map
|
||||||
|
val age: Int by map
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val user = User(mapOf(
|
||||||
|
"name" to "John Doe",
|
||||||
|
"age" to 25
|
||||||
|
))
|
||||||
|
println(user.name) // Prints "John Doe"
|
||||||
|
println(user.age) // Prints 25
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import kotlin.properties.Delegates
|
||||||
|
|
||||||
|
class User {
|
||||||
|
var name: String by Delegates.observable("<no name>") {
|
||||||
|
prop, old, new ->
|
||||||
|
println("$old -> $new")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val user = User()
|
||||||
|
user.name = "first"
|
||||||
|
user.name = "second"
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package kotlin.collections
|
||||||
|
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
import kotlin.internal.Exact
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value of the property for the given object from this read-only map.
|
||||||
|
* @param thisRef the object for which the value is requested (not used).
|
||||||
|
* @param property the metadata for the property, used to get the name of property and lookup the value corresponding to this name in the map.
|
||||||
|
* @return the property value.
|
||||||
|
*
|
||||||
|
* @throws NoSuchElementException when the map doesn't contain value for the property name and doesn't provide an implicit default (see [withDefault]).
|
||||||
|
*/
|
||||||
|
@kotlin.internal.InlineOnly
|
||||||
|
public inline operator fun <V, V1: V> Map<in String, @Exact V>.getValue(thisRef: Any?, property: KProperty<*>): V1
|
||||||
|
= @Suppress("UNCHECKED_CAST", "NON_PUBLIC_CALL_FROM_PUBLIC_INLINE") (getOrImplicitDefault(property.name) as V1)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value of the property for the given object from this mutable map.
|
||||||
|
* @param thisRef the object for which the value is requested (not used).
|
||||||
|
* @param property the metadata for the property, used to get the name of property and lookup the value corresponding to this name in the map.
|
||||||
|
* @return the property value.
|
||||||
|
*
|
||||||
|
* @throws NoSuchElementException when the map doesn't contain value for the property name and doesn't provide an implicit default (see [withDefault]).
|
||||||
|
*/
|
||||||
|
@kotlin.internal.InlineOnly
|
||||||
|
public inline operator fun <V> MutableMap<in String, in V>.getValue(thisRef: Any?, property: KProperty<*>): V
|
||||||
|
= @Suppress("UNCHECKED_CAST", "NON_PUBLIC_CALL_FROM_PUBLIC_INLINE") (getOrImplicitDefault(property.name) as V)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the value of the property for the given object in this mutable map.
|
||||||
|
* @param thisRef the object for which the value is requested (not used).
|
||||||
|
* @param property the metadata for the property, used to get the name of property and store the value associated with that name in the map.
|
||||||
|
* @param value the value to set.
|
||||||
|
*/
|
||||||
|
@kotlin.internal.InlineOnly
|
||||||
|
public inline operator fun <V> MutableMap<in String, in V>.setValue(thisRef: Any?, property: KProperty<*>, value: V) {
|
||||||
|
this.put(property.name, value)
|
||||||
|
}
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
package kotlin.collections
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value for the given key, or the implicit default value for this map.
|
||||||
|
* By default no implicit value is provided for maps and a [NoSuchElementException] is thrown.
|
||||||
|
* To create a map with implicit default value use [withDefault] method.
|
||||||
|
*
|
||||||
|
* @throws NoSuchElementException when the map doesn't contain a value for the specified key and no implicit default was provided for that map.
|
||||||
|
*/
|
||||||
|
@PublishedApi
|
||||||
|
internal fun <K, V> Map<K, V>.getOrImplicitDefault(key: K): V {
|
||||||
|
if (this is MapWithDefault)
|
||||||
|
return this.getOrImplicitDefault(key)
|
||||||
|
|
||||||
|
return getOrElseNullable(key, { throw NoSuchElementException("Key $key is missing in the map.") })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a wrapper of this read-only map, having the implicit default value provided with the specified function [defaultValue].
|
||||||
|
* This implicit default value is used when properties are delegated to the returned map,
|
||||||
|
* and that map doesn't contain a value for the key specified.
|
||||||
|
*
|
||||||
|
* When this map already has an implicit default value provided with a former call to [withDefault], it is being replaced by this call.
|
||||||
|
*/
|
||||||
|
public fun <K, V> Map<K, V>.withDefault(defaultValue: (key: K) -> V): Map<K, V> =
|
||||||
|
when (this) {
|
||||||
|
is MapWithDefault -> this.map.withDefault(defaultValue)
|
||||||
|
else -> MapWithDefaultImpl(this, defaultValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a wrapper of this mutable map, having the implicit default value provided with the specified function [defaultValue].
|
||||||
|
* This implicit default value is used when properties are delegated to the returned map,
|
||||||
|
* and that map doesn't contain a value for the key specified.
|
||||||
|
*
|
||||||
|
* When this map already has an implicit default value provided with a former call to [withDefault], it is being replaced by this call.
|
||||||
|
*/
|
||||||
|
public fun <K, V> MutableMap<K, V>.withDefault(defaultValue: (key: K) -> V): MutableMap<K, V> =
|
||||||
|
when (this) {
|
||||||
|
is MutableMapWithDefault -> this.map.withDefault(defaultValue)
|
||||||
|
else -> MutableMapWithDefaultImpl(this, defaultValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private interface MapWithDefault<K, out V>: Map<K, V> {
|
||||||
|
public val map: Map<K, V>
|
||||||
|
public fun getOrImplicitDefault(key: K): V
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface MutableMapWithDefault<K, V>: MutableMap<K, V>, MapWithDefault<K, V> {
|
||||||
|
public override val map: MutableMap<K, V>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private class MapWithDefaultImpl<K, out V>(public override val map: Map<K,V>, private val default: (key: K) -> V) : MapWithDefault<K, V> {
|
||||||
|
override fun equals(other: Any?): Boolean = map.equals(other)
|
||||||
|
override fun hashCode(): Int = map.hashCode()
|
||||||
|
override fun toString(): String = map.toString()
|
||||||
|
override val size: Int get() = map.size
|
||||||
|
override fun isEmpty(): Boolean = map.isEmpty()
|
||||||
|
override fun containsKey(key: K): Boolean = map.containsKey(key)
|
||||||
|
override fun containsValue(value: @UnsafeVariance V): Boolean = map.containsValue(value)
|
||||||
|
override fun get(key: K): V? = map.get(key)
|
||||||
|
override val keys: Set<K> get() = map.keys
|
||||||
|
override val values: Collection<V> get() = map.values
|
||||||
|
override val entries: Set<Map.Entry<K, V>> get() = map.entries
|
||||||
|
|
||||||
|
override fun getOrImplicitDefault(key: K): V = map.getOrElseNullable(key, { default(key) })
|
||||||
|
}
|
||||||
|
|
||||||
|
private class MutableMapWithDefaultImpl<K, V>(public override val map: MutableMap<K, V>, private val default: (key: K) -> V): MutableMapWithDefault<K, V> {
|
||||||
|
override fun equals(other: Any?): Boolean = map.equals(other)
|
||||||
|
override fun hashCode(): Int = map.hashCode()
|
||||||
|
override fun toString(): String = map.toString()
|
||||||
|
override val size: Int get() = map.size
|
||||||
|
override fun isEmpty(): Boolean = map.isEmpty()
|
||||||
|
override fun containsKey(key: K): Boolean = map.containsKey(key)
|
||||||
|
override fun containsValue(value: @UnsafeVariance V): Boolean = map.containsValue(value)
|
||||||
|
override fun get(key: K): V? = map.get(key)
|
||||||
|
override val keys: MutableSet<K> get() = map.keys
|
||||||
|
override val values: MutableCollection<V> get() = map.values
|
||||||
|
override val entries: MutableSet<MutableMap.MutableEntry<K, V>> get() = map.entries
|
||||||
|
|
||||||
|
override fun put(key: K, value: V): V? = map.put(key, value)
|
||||||
|
override fun remove(key: K): V? = map.remove(key)
|
||||||
|
override fun putAll(from: Map<out K, V>) = map.putAll(from)
|
||||||
|
override fun clear() = map.clear()
|
||||||
|
|
||||||
|
override fun getOrImplicitDefault(key: K): V = map.getOrElseNullable(key, { default(key) })
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user