Update stdlib usages of PropertyMetadata to KProperty<*>

This commit is contained in:
Alexander Udalov
2015-10-14 20:06:37 +03:00
parent 43bb9347c6
commit 556a169a5d
10 changed files with 67 additions and 62 deletions
@@ -16,16 +16,16 @@
package org.jetbrains.kotlin.utils
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty
public class CachedValueProperty<TValue : Any, TTimestamp : Any>(
private val calculator: () -> TValue,
private val timestampCalculator: () -> TTimestamp
) : ReadOnlyProperty<Any?, TValue> {
) {
private var value: TValue? = null
private var timestamp: TTimestamp? = null
public override fun getValue(thisRef: Any?, desc: PropertyMetadata): TValue {
operator fun getValue(thisRef: Any?, property: KProperty<*>): TValue {
val currentTimestamp = timestampCalculator()
if (value == null || timestamp != currentTimestamp) {
value = calculator()
@@ -1,5 +1,5 @@
// "Create class 'Foo'" "true"
// ERROR: <html>Class 'Foo' must be declared abstract or implement abstract member<br/><b>public</b> <b>abstract</b> operator <b>fun</b> getValue(thisRef: A&lt;T&gt;, property: kotlin.PropertyMetadata): B <i>defined in</i> kotlin.properties.ReadOnlyProperty</html>
// ERROR: <html>Class 'Foo' must be declared abstract or implement abstract member<br/><b>public</b> <b>abstract</b> operator <b>fun</b> getValue(thisRef: A&lt;T&gt;, property: kotlin.reflect.KProperty&lt;*&gt;): B <i>defined in</i> kotlin.properties.ReadOnlyProperty</html>
open class B
@@ -1,7 +1,7 @@
import kotlin.properties.ReadOnlyProperty
// "Create class 'Foo'" "true"
// ERROR: <html>Class 'Foo' must be declared abstract or implement abstract member<br/><b>public</b> <b>abstract</b> operator <b>fun</b> getValue(thisRef: A&lt;T&gt;, property: kotlin.PropertyMetadata): B <i>defined in</i> kotlin.properties.ReadOnlyProperty</html>
// ERROR: <html>Class 'Foo' must be declared abstract or implement abstract member<br/><b>public</b> <b>abstract</b> operator <b>fun</b> getValue(thisRef: A&lt;T&gt;, property: kotlin.reflect.KProperty&lt;*&gt;): B <i>defined in</i> kotlin.properties.ReadOnlyProperty</html>
open class B
@@ -2,4 +2,4 @@ import kotlin.properties.Delegates
val x: Int <caret>by Delegates.lazy {1}
// REF: (in kotlin.properties.ReadOnlyProperty).getValue(R,kotlin.PropertyMetadata)
// REF: (in kotlin.properties.ReadOnlyProperty).getValue(R,kotlin.reflect.KProperty<*>)
@@ -3,5 +3,5 @@ import kotlin.properties.Delegates
var x: Int <caret>by Delegates.notNull()
// MULTIRESOLVE
// REF: (in kotlin.properties.ReadWriteProperty).getValue(R,kotlin.PropertyMetadata)
// REF: (in kotlin.properties.ReadWriteProperty).setValue(R,kotlin.PropertyMetadata,T)
// REF: (in kotlin.properties.ReadWriteProperty).getValue(R,kotlin.reflect.KProperty<*>)
// REF: (in kotlin.properties.ReadWriteProperty).setValue(R,kotlin.reflect.KProperty<*>,T)
@@ -1,7 +1,7 @@
package kotlin.properties
import java.util.NoSuchElementException
import kotlin.reflect.KProperty
/**
* Standard property delegates.
@@ -49,9 +49,9 @@ public object Delegates {
* @param onChange the callback which is called after the change of the property is made. The value of the property
* has already been changed when this callback is invoked.
*/
public inline fun observable<T>(initialValue: T, crossinline onChange: (property: PropertyMetadata, oldValue: T, newValue: T) -> Unit):
public inline fun observable<T>(initialValue: T, crossinline onChange: (property: KProperty<*>, oldValue: T, newValue: T) -> Unit):
ReadWriteProperty<Any?, T> = object : ObservableProperty<T>(initialValue) {
override fun afterChange(property: PropertyMetadata, oldValue: T, newValue: T) = onChange(property, oldValue, newValue)
override fun afterChange(property: KProperty<*>, oldValue: T, newValue: T) = onChange(property, oldValue, newValue)
}
/**
@@ -63,9 +63,9 @@ public object Delegates {
* If the callback returns `true` the value of the property is being set to the new value,
* and if the callback returns `false` the new value is discarded and the property remains its old value.
*/
public inline fun vetoable<T>(initialValue: T, crossinline onChange: (property: PropertyMetadata, oldValue: T, newValue: T) -> Boolean):
public inline fun vetoable<T>(initialValue: T, crossinline onChange: (property: KProperty<*>, oldValue: T, newValue: T) -> Boolean):
ReadWriteProperty<Any?, T> = object : ObservableProperty<T>(initialValue) {
override fun beforeChange(property: PropertyMetadata, oldValue: T, newValue: T): Boolean = onChange(property, oldValue, newValue)
override fun beforeChange(property: KProperty<*>, oldValue: T, newValue: T): Boolean = onChange(property, oldValue, newValue)
}
/**
@@ -115,20 +115,20 @@ public object Delegates {
private class NotNullVar<T: Any>() : ReadWriteProperty<Any?, T> {
private var value: T? = null
public override fun getValue(thisRef: Any?, property: PropertyMetadata): T {
public override fun getValue(thisRef: Any?, property: KProperty<*>): T {
return value ?: throw IllegalStateException("Property ${property.name} should be initialized before get.")
}
public override fun setValue(thisRef: Any?, property: PropertyMetadata, value: T) {
public override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
this.value = value
}
}
@Deprecated("Use Delegates.vetoable() instead or construct implementation of abstract ObservableProperty", ReplaceWith("Delegates.vetoable(initialValue, onChange)"))
public fun ObservableProperty<T>(initialValue: T, onChange: (property: PropertyMetadata, oldValue: T, newValue: T) -> Boolean): ObservableProperty<T> =
public fun ObservableProperty<T>(initialValue: T, onChange: (property: KProperty<*>, oldValue: T, newValue: T) -> Boolean): ObservableProperty<T> =
object : ObservableProperty<T>(initialValue) {
override fun beforeChange(property: PropertyMetadata, oldValue: T, newValue: T): Boolean = onChange(property, oldValue, newValue)
override fun beforeChange(property: KProperty<*>, oldValue: T, newValue: T): Boolean = onChange(property, oldValue, newValue)
}
/**
@@ -144,19 +144,19 @@ public abstract class ObservableProperty<T>(initialValue: T) : ReadWriteProperty
* If the callback returns `true` the value of the property is being set to the new value,
* and if the callback returns `false` the new value is discarded and the property remains its old value.
*/
protected open fun beforeChange(property: PropertyMetadata, oldValue: T, newValue: T): Boolean = true
protected open fun beforeChange(property: KProperty<*>, oldValue: T, newValue: T): Boolean = true
/**
* The callback which is called after the change of the property is made. The value of the property
* has already been changed when this callback is invoked.
*/
protected open fun afterChange (property: PropertyMetadata, oldValue: T, newValue: T): Unit {}
protected open fun afterChange (property: KProperty<*>, oldValue: T, newValue: T): Unit {}
public override fun getValue(thisRef: Any?, property: PropertyMetadata): T {
public override fun getValue(thisRef: Any?, property: KProperty<*>): T {
return value
}
public override fun setValue(thisRef: Any?, property: PropertyMetadata, value: T) {
public override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
val oldValue = this.value
if (!beforeChange(property, oldValue, value)) {
return
@@ -179,7 +179,7 @@ private fun unescape(value: Any?): Any? {
private class LazyVal<T>(private val initializer: () -> T) : ReadOnlyProperty<Any?, T> {
private var value: Any? = null
public override fun getValue(thisRef: Any?, property: PropertyMetadata): T {
public override fun getValue(thisRef: Any?, property: KProperty<*>): T {
if (value == null) {
value = escape(initializer())
}
@@ -191,7 +191,7 @@ private class BlockingLazyVal<T>(lock: Any?, private val initializer: () -> T) :
private val lock = lock ?: this
@Volatile private var value: Any? = null
public override fun getValue(thisRef: Any?, property: PropertyMetadata): T {
public override fun getValue(thisRef: Any?, property: KProperty<*>): T {
val _v1 = value
if (_v1 != null) {
return unescape(_v1) as T
@@ -226,20 +226,20 @@ public abstract class MapVal<T, K, out V>() : ReadOnlyProperty<T, V> {
/**
* Returns the map key used to store the values of the given property.
* @param desc the property for which the key is requested.
* @param property the property for which the key is requested.
*/
protected abstract fun key(desc: PropertyMetadata): K
protected abstract fun key(property: KProperty<*>): K
/**
* Returns the property value to be used when the map does not contain the corresponding key.
* @param ref the object instance for which the value was requested.
* @param property the property for which the value was requested.
*/
protected open fun default(ref: T, property: PropertyMetadata): V {
protected open fun default(ref: T, property: KProperty<*>): V {
throw NoSuchElementException("The value for property ${property.name} is missing in $ref.")
}
public override fun getValue(thisRef: T, property: PropertyMetadata) : V {
public override fun getValue(thisRef: T, property: KProperty<*>) : V {
val map = map(thisRef)
val key = key(property)
return map.getOrElse(key, { default(thisRef, property) }) as V
@@ -255,17 +255,17 @@ public abstract class MapVal<T, K, out V>() : ReadOnlyProperty<T, V> {
public abstract class MapVar<T, K, V>() : MapVal<T, K, V>(), ReadWriteProperty<T, V> {
protected abstract override fun map(ref: T): MutableMap<in K, Any?>
public override fun setValue(thisRef: T, property: PropertyMetadata, value: V) {
public override fun setValue(thisRef: T, property: KProperty<*>, value: V) {
val map = map(thisRef)
map.put(key(property), value)
}
override fun getValue(thisRef: T, property: PropertyMetadata): V {
override fun getValue(thisRef: T, property: KProperty<*>): V {
return super<MapVal>.getValue(thisRef, property)
}
}
private val propertyNameSelector: (PropertyMetadata) -> String = {it.name}
private val propertyNameSelector: (KProperty<*>) -> String = {it.name}
private val throwKeyNotFound: (Any?, Any?) -> Nothing = {thisRef, key -> throw NoSuchElementException("The value for key $key is missing from $thisRef.") }
/**
@@ -275,18 +275,20 @@ private val throwKeyNotFound: (Any?, Any?) -> Nothing = {thisRef, key -> throw N
* @param key the function to calculate the map key from a property metadata object.
* @param default the function returning the value of the property for a given object if it's missing from the given map.
*/
public open class FixedMapVal<T, K, out V>(private val map: Map<in K, Any?>,
private val key: (PropertyMetadata) -> K,
private val default: (ref: T, key: K) -> V = throwKeyNotFound) : MapVal<T, K, V>() {
public open class FixedMapVal<T, K, out V>(
private val map: Map<in K, Any?>,
private val key: (KProperty<*>) -> K,
private val default: (ref: T, key: K) -> V = throwKeyNotFound
) : 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 key(property: KProperty<*>): K {
return (key)(property)
}
protected override fun default(ref: T, property: PropertyMetadata): V {
protected override fun default(ref: T, property: KProperty<*>): V {
return (default)(ref, key(property))
}
}
@@ -298,18 +300,20 @@ public open class FixedMapVal<T, K, out V>(private val map: Map<in K, Any?>,
* @param key the function to calculate the map key from a property metadata object.
* @param default the function returning the value of the property for a given object if it's missing from the given map.
*/
public open class FixedMapVar<T, K, V>(private val map: MutableMap<in K, Any?>,
private val key: (PropertyMetadata) -> K,
private val default: (ref: T, key: K) -> V = throwKeyNotFound) : MapVar<T, K, V>() {
public open class FixedMapVar<T, K, V>(
private val map: MutableMap<in K, Any?>,
private val key: (KProperty<*>) -> K,
private val default: (ref: T, key: K) -> V = throwKeyNotFound
) : MapVar<T, K, V>() {
protected override fun map(ref: T): MutableMap<in K, Any?> {
return map
}
protected override fun key(desc: PropertyMetadata): K {
protected override fun key(desc: KProperty<*>): K {
return (key)(desc)
}
protected override fun default(ref: T, property: PropertyMetadata): V {
protected override fun default(ref: T, property: KProperty<*>): V {
return (default)(ref, key(property))
}
}
@@ -1,5 +1,6 @@
package kotlin.properties
import kotlin.reflect.KProperty
/**
* Base interface that can be used for implementing property delegates of read-only properties.
@@ -17,7 +18,7 @@ public interface ReadOnlyProperty<in R, out T> {
* @param property the metadata for the property.
* @return the property value.
*/
public operator fun getValue(thisRef: R, property: PropertyMetadata): T
public operator fun getValue(thisRef: R, property: KProperty<*>): T
}
/**
@@ -36,7 +37,7 @@ public interface ReadWriteProperty<in R, T> {
* @param property the metadata for the property.
* @return the property value.
*/
public operator fun getValue(thisRef: R, property: PropertyMetadata): T
public operator fun getValue(thisRef: R, property: KProperty<*>): T
/**
* Sets the value of the property for the given object.
@@ -44,5 +45,5 @@ public interface ReadWriteProperty<in R, T> {
* @param property the metadata for the property.
* @param value the value to set.
*/
public operator fun setValue(thisRef: R, property: PropertyMetadata, value: T)
public operator fun setValue(thisRef: R, property: KProperty<*>, value: T)
}
@@ -1,7 +1,7 @@
@file:kotlin.jvm.JvmName("MapAccessorsKt")
package kotlin.properties
// extensions for Map and MutableMap
import kotlin.reflect.KProperty
/**
* Returns the value of the property for the given object from this read-only map.
@@ -11,7 +11,7 @@ package kotlin.properties
*
* @throws NoSuchElementException when the map doesn't contain value for the property name and doesn't provide an implicit default (see [withDefault]).
*/
public operator fun <V, V1: V> Map<in String, @Exact V>.getValue(thisRef: Any?, property: PropertyMetadata): V1 = getOrImplicitDefault(property.name) as V1
public operator fun <V, V1: V> Map<in String, @Exact V>.getValue(thisRef: Any?, property: KProperty<*>): V1 = getOrImplicitDefault(property.name) as V1
/**
* Returns the value of the property for the given object from this mutable map.
@@ -22,7 +22,7 @@ public operator fun <V, V1: V> Map<in String, @Exact V>.getValue(thisRef: Any?,
* @throws NoSuchElementException when the map doesn't contain value for the property name and doesn't provide an implicit default (see [withDefault]).
*/
@kotlin.jvm.JvmName("getVar")
public operator fun <V> MutableMap<in String, in V>.getValue(thisRef: Any?, property: PropertyMetadata): V = getOrImplicitDefault(property.name) as V
public operator fun <V> MutableMap<in String, in V>.getValue(thisRef: Any?, property: KProperty<*>): V = getOrImplicitDefault(property.name) as V
/**
* Stores the value of the property for the given object in this mutable map.
@@ -30,6 +30,6 @@ public operator fun <V> MutableMap<in String, in V>.getValue(thisRef: Any?, prop
* @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.
*/
public operator fun <V> MutableMap<in String, in V>.setValue(thisRef: Any?, property: PropertyMetadata, value: V) {
public operator fun <V> MutableMap<in String, in V>.setValue(thisRef: Any?, property: KProperty<*>, value: V) {
this.put(property.name, value)
}
}
+2 -2
View File
@@ -3,7 +3,7 @@
package kotlin
import java.io.Serializable
import kotlin.reflect.KProperty
/**
* Represents a value with lazy initialization.
@@ -74,7 +74,7 @@ public fun lazy<T>(lock: Any?, initializer: () -> T): Lazy<T> = SynchronizedLazy
* This extension allows to use instances of Lazy for property delegation:
* `val property: String by lazy { initializer }`
*/
public operator fun <T> Lazy<T>.getValue(thisRef: Any?, property: PropertyMetadata): T = value
public operator fun <T> Lazy<T>.getValue(thisRef: Any?, property: KProperty<*>): T = value
/**
* Specifies how a [Lazy] instance synchronizes access among multiple threads.
@@ -3,6 +3,7 @@ package test.properties.delegation.map
import org.junit.Test as test
import java.util.HashMap
import kotlin.properties.*
import kotlin.reflect.KProperty
import kotlin.test.*
data class B(val a: Int)
@@ -125,15 +126,14 @@ class MapPropertyFunctionTest() {
}
}
// TODO Remove explicit types when KT-9072 will be fixed
val mapVal: MapVal<MapPropertyCustomTest, String, String> = object: MapVal<MapPropertyCustomTest, String, String>() {
val mapVal = object : MapVal<MapPropertyCustomTest, String, String>() {
override fun map(ref: MapPropertyCustomTest) = ref.map
override fun key(desc: PropertyMetadata) = "${desc.name}Desc"
override fun key(property: KProperty<*>) = "${property.name}Desc"
}
val mapVar: MapVar<MapPropertyCustomTest, String, String> = object : MapVar<MapPropertyCustomTest, String, String>() {
val mapVar = object : MapVar<MapPropertyCustomTest, String, String>() {
override fun map(ref: MapPropertyCustomTest) = ref.map
override fun key(desc: PropertyMetadata) = "${desc.name}Desc"
override fun key(property: KProperty<*>) = "${property.name}Desc"
}
class MapPropertyCustomTest() {
@@ -148,18 +148,18 @@ class MapPropertyCustomTest() {
}
}
val mapValWithDefault: MapVal<MapPropertyCustomWithDefaultTest, String, String> = object : MapVal<MapPropertyCustomWithDefaultTest, String, String>() {
val mapValWithDefault = object : MapVal<MapPropertyCustomWithDefaultTest, String, String>() {
override fun map(ref: MapPropertyCustomWithDefaultTest) = ref.map
override fun key(desc: PropertyMetadata) = desc.name
override fun key(property: KProperty<*>) = property.name
override fun default(ref: MapPropertyCustomWithDefaultTest, key: PropertyMetadata) = "default"
override fun default(ref: MapPropertyCustomWithDefaultTest, key: KProperty<*>) = "default"
}
val mapVarWithDefault: MapVar<MapPropertyCustomWithDefaultTest, String, String> = object : MapVar<MapPropertyCustomWithDefaultTest, String, String>() {
val mapVarWithDefault = object : MapVar<MapPropertyCustomWithDefaultTest, String, String>() {
override fun map(ref: MapPropertyCustomWithDefaultTest) = ref.map
override fun key(desc: PropertyMetadata) = desc.name
override fun key(property: KProperty<*>) = property.name
override fun default(ref: MapPropertyCustomWithDefaultTest, key: PropertyMetadata) = "default"
override fun default(ref: MapPropertyCustomWithDefaultTest, key: KProperty<*>) = "default"
}
class MapPropertyCustomWithDefaultTest() {