Allow delegating val properties to out-projected MutableMap
Change generic signature of MutableMap.getValue, use 'out @Exact V' and `V1: V` types instead of single `in V`. Fix affected IR generation tests. #KT-18789 Fixed
This commit is contained in:
@@ -113,8 +113,9 @@ FILE /classLevelProperties.kt
|
|||||||
$this: VALUE_PARAMETER this@C: C
|
$this: VALUE_PARAMETER this@C: C
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='<get-test8>(): Int'
|
RETURN type=kotlin.Nothing from='<get-test8>(): Int'
|
||||||
CALL 'getValue(Any?, KProperty<*>) on MutableMap<in String, in Int>: Int' type=kotlin.Int origin=null
|
CALL 'getValue(Any?, KProperty<*>) on MutableMap<in String, out Int>: Int' type=kotlin.Int origin=null
|
||||||
<V>: Int
|
<V>: Int
|
||||||
|
<V1 : V>: Int
|
||||||
$receiver: GET_FIELD '`test8$delegate`: HashMap<String, Int> /* = HashMap<String, Int> */' type=kotlin.collections.HashMap<kotlin.String, kotlin.Int> /* = java.util.HashMap<kotlin.String, kotlin.Int> */ origin=null
|
$receiver: GET_FIELD '`test8$delegate`: HashMap<String, Int> /* = HashMap<String, Int> */' type=kotlin.collections.HashMap<kotlin.String, kotlin.Int> /* = java.util.HashMap<kotlin.String, kotlin.Int> */ origin=null
|
||||||
receiver: GET_VAR 'this@C: C' type=C origin=null
|
receiver: GET_VAR 'this@C: C' type=C origin=null
|
||||||
thisRef: GET_VAR 'this@C: C' type=C origin=null
|
thisRef: GET_VAR 'this@C: C' type=C origin=null
|
||||||
|
|||||||
@@ -65,8 +65,9 @@ FILE /delegatedProperties.kt
|
|||||||
$this: VALUE_PARAMETER this@C: C
|
$this: VALUE_PARAMETER this@C: C
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='<get-test3>(): Any'
|
RETURN type=kotlin.Nothing from='<get-test3>(): Any'
|
||||||
CALL 'getValue(Any?, KProperty<*>) on MutableMap<in String, in Any>: Any' type=kotlin.Any origin=null
|
CALL 'getValue(Any?, KProperty<*>) on MutableMap<in String, out Any>: Any' type=kotlin.Any origin=null
|
||||||
<V>: Any
|
<V>: Any
|
||||||
|
<V1 : V>: Any
|
||||||
$receiver: GET_FIELD '`test3$delegate`: MutableMap<String, Any>' type=kotlin.collections.MutableMap<kotlin.String, kotlin.Any> origin=null
|
$receiver: GET_FIELD '`test3$delegate`: MutableMap<String, Any>' type=kotlin.collections.MutableMap<kotlin.String, kotlin.Any> origin=null
|
||||||
receiver: GET_VAR 'this@C: C' type=C origin=null
|
receiver: GET_VAR 'this@C: C' type=C origin=null
|
||||||
thisRef: GET_VAR 'this@C: C' type=C origin=null
|
thisRef: GET_VAR 'this@C: C' type=C origin=null
|
||||||
@@ -99,8 +100,9 @@ FILE /delegatedProperties.kt
|
|||||||
FUN DELEGATED_PROPERTY_ACCESSOR public fun <get-test4>(): kotlin.Any
|
FUN DELEGATED_PROPERTY_ACCESSOR public fun <get-test4>(): kotlin.Any
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='<get-test4>(): Any'
|
RETURN type=kotlin.Nothing from='<get-test4>(): Any'
|
||||||
CALL 'getValue(Any?, KProperty<*>) on MutableMap<in String, in Any>: Any' type=kotlin.Any origin=null
|
CALL 'getValue(Any?, KProperty<*>) on MutableMap<in String, out Any>: Any' type=kotlin.Any origin=null
|
||||||
<V>: Any
|
<V>: Any
|
||||||
|
<V1 : V>: Any
|
||||||
$receiver: GET_FIELD '`test4$delegate`: HashMap<String, Any> /* = HashMap<String, Any> */' type=kotlin.collections.HashMap<kotlin.String, kotlin.Any> /* = java.util.HashMap<kotlin.String, kotlin.Any> */ origin=null
|
$receiver: GET_FIELD '`test4$delegate`: HashMap<String, Any> /* = HashMap<String, Any> */' type=kotlin.collections.HashMap<kotlin.String, kotlin.Any> /* = java.util.HashMap<kotlin.String, kotlin.Any> */ origin=null
|
||||||
thisRef: CONST Null type=kotlin.Nothing? value='null'
|
thisRef: CONST Null type=kotlin.Nothing? value='null'
|
||||||
property: PROPERTY_REFERENCE 'test4: Any' field=null getter='<get-test4>(): Any' setter='<set-test4>(Any): Unit' type=kotlin.reflect.KMutableProperty0<kotlin.Any> origin=PROPERTY_REFERENCE_FOR_DELEGATE
|
property: PROPERTY_REFERENCE 'test4: Any' field=null getter='<get-test4>(): Any' setter='<set-test4>(Any): Unit' type=kotlin.reflect.KMutableProperty0<kotlin.Any> origin=PROPERTY_REFERENCE_FOR_DELEGATE
|
||||||
|
|||||||
@@ -31,8 +31,9 @@ FILE /localDelegatedProperties.kt
|
|||||||
FUN DELEGATED_PROPERTY_ACCESSOR local final fun <get-x>(): kotlin.Int
|
FUN DELEGATED_PROPERTY_ACCESSOR local final fun <get-x>(): kotlin.Int
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='<get-x>(): Int'
|
RETURN type=kotlin.Nothing from='<get-x>(): Int'
|
||||||
CALL 'getValue(Any?, KProperty<*>) on MutableMap<in String, in Int>: Int' type=kotlin.Int origin=null
|
CALL 'getValue(Any?, KProperty<*>) on MutableMap<in String, out Int>: Int' type=kotlin.Int origin=null
|
||||||
<V>: Int
|
<V>: Int
|
||||||
|
<V1 : V>: Int
|
||||||
$receiver: GET_VAR '`x$delegate`: HashMap<String, Int> /* = HashMap<String, Int> */' type=kotlin.collections.HashMap<kotlin.String, kotlin.Int> /* = java.util.HashMap<kotlin.String, kotlin.Int> */ origin=null
|
$receiver: GET_VAR '`x$delegate`: HashMap<String, Int> /* = HashMap<String, Int> */' type=kotlin.collections.HashMap<kotlin.String, kotlin.Int> /* = java.util.HashMap<kotlin.String, kotlin.Int> */ origin=null
|
||||||
thisRef: CONST Null type=kotlin.Nothing? value='null'
|
thisRef: CONST Null type=kotlin.Nothing? value='null'
|
||||||
property: LOCAL_DELEGATED_PROPERTY_REFERENCE 'x: Int' delegate='`x$delegate`: HashMap<String, Int> /* = HashMap<String, Int> */' getter='<get-x>(): Int' setter='<set-x>(Int): Unit' type=kotlin.reflect.KMutableProperty0<kotlin.Int> origin=PROPERTY_REFERENCE_FOR_DELEGATE
|
property: LOCAL_DELEGATED_PROPERTY_REFERENCE 'x: Int' delegate='`x$delegate`: HashMap<String, Int> /* = HashMap<String, Int> */' getter='<get-x>(): Int' setter='<set-x>(Int): Unit' type=kotlin.reflect.KMutableProperty0<kotlin.Int> origin=PROPERTY_REFERENCE_FOR_DELEGATE
|
||||||
|
|||||||
@@ -87,8 +87,9 @@ FILE /packageLevelProperties.kt
|
|||||||
FUN DELEGATED_PROPERTY_ACCESSOR public fun <get-test8>(): kotlin.Int
|
FUN DELEGATED_PROPERTY_ACCESSOR public fun <get-test8>(): kotlin.Int
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='<get-test8>(): Int'
|
RETURN type=kotlin.Nothing from='<get-test8>(): Int'
|
||||||
CALL 'getValue(Any?, KProperty<*>) on MutableMap<in String, in Int>: Int' type=kotlin.Int origin=null
|
CALL 'getValue(Any?, KProperty<*>) on MutableMap<in String, out Int>: Int' type=kotlin.Int origin=null
|
||||||
<V>: Int
|
<V>: Int
|
||||||
|
<V1 : V>: Int
|
||||||
$receiver: GET_FIELD '`test8$delegate`: HashMap<String, Int> /* = HashMap<String, Int> */' type=kotlin.collections.HashMap<kotlin.String, kotlin.Int> /* = java.util.HashMap<kotlin.String, kotlin.Int> */ origin=null
|
$receiver: GET_FIELD '`test8$delegate`: HashMap<String, Int> /* = HashMap<String, Int> */' type=kotlin.collections.HashMap<kotlin.String, kotlin.Int> /* = java.util.HashMap<kotlin.String, kotlin.Int> */ origin=null
|
||||||
thisRef: CONST Null type=kotlin.Nothing? value='null'
|
thisRef: CONST Null type=kotlin.Nothing? value='null'
|
||||||
property: PROPERTY_REFERENCE 'test8: Int' field=null getter='<get-test8>(): Int' setter='<set-test8>(Int): Unit' type=kotlin.reflect.KMutableProperty0<kotlin.Int> origin=PROPERTY_REFERENCE_FOR_DELEGATE
|
property: PROPERTY_REFERENCE 'test8: Int' field=null getter='<get-test8>(): Int' setter='<set-test8>(Int): Unit' type=kotlin.reflect.KMutableProperty0<kotlin.Int> origin=PROPERTY_REFERENCE_FOR_DELEGATE
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ public inline operator fun <V, V1: V> Map<in String, @Exact V>.getValue(thisRef:
|
|||||||
*/
|
*/
|
||||||
@kotlin.jvm.JvmName("getVar")
|
@kotlin.jvm.JvmName("getVar")
|
||||||
@kotlin.internal.InlineOnly
|
@kotlin.internal.InlineOnly
|
||||||
public inline operator fun <V> MutableMap<in String, in V>.getValue(thisRef: Any?, property: KProperty<*>): V
|
public inline operator fun <V, V1: V> MutableMap<in String, out @Exact V>.getValue(thisRef: Any?, property: KProperty<*>): V1
|
||||||
= @Suppress("UNCHECKED_CAST") (getOrImplicitDefault(property.name) as V)
|
= @Suppress("UNCHECKED_CAST") (getOrImplicitDefault(property.name) as V1)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores the value of the property for the given object in this mutable map.
|
* Stores the value of the property for the given object in this mutable map.
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import kotlin.test.*
|
|||||||
class ValByMapExtensionsTest {
|
class ValByMapExtensionsTest {
|
||||||
val map: Map<String, String> = hashMapOf("a" to "all", "b" to "bar", "c" to "code")
|
val map: Map<String, String> = hashMapOf("a" to "all", "b" to "bar", "c" to "code")
|
||||||
val genericMap = mapOf<String, Any?>("i" to 1, "x" to 1.0)
|
val genericMap = mapOf<String, Any?>("i" to 1, "x" to 1.0)
|
||||||
|
val mmapOut: MutableMap<String, out String> = mutableMapOf("g" to "out", "g1" to "in")
|
||||||
|
val genericMmapOut: MutableMap<String, out Any?> = mmapOut
|
||||||
|
|
||||||
val a by map
|
val a by map
|
||||||
val b: String by map
|
val b: String by map
|
||||||
@@ -12,6 +14,8 @@ class ValByMapExtensionsTest {
|
|||||||
val d: String? by map
|
val d: String? by map
|
||||||
val e: String by map.withDefault { "default" }
|
val e: String by map.withDefault { "default" }
|
||||||
val f: String? by map.withDefault { null }
|
val f: String? by map.withDefault { null }
|
||||||
|
val g: String by mmapOut
|
||||||
|
val g1: String by genericMmapOut
|
||||||
// val n: Int by map // prohibited by type system
|
// val n: Int by map // prohibited by type system
|
||||||
val i: Int by genericMap
|
val i: Int by genericMap
|
||||||
val x: Double by genericMap
|
val x: Double by genericMap
|
||||||
@@ -23,6 +27,8 @@ class ValByMapExtensionsTest {
|
|||||||
assertEquals("code", c)
|
assertEquals("code", c)
|
||||||
assertEquals("default", e)
|
assertEquals("default", e)
|
||||||
assertEquals(null, f)
|
assertEquals(null, f)
|
||||||
|
assertEquals("out", g)
|
||||||
|
assertEquals("in", g1)
|
||||||
assertEquals(1, i)
|
assertEquals(1, i)
|
||||||
assertEquals(1.0, x)
|
assertEquals(1.0, x)
|
||||||
assertFailsWith<NoSuchElementException> { d }
|
assertFailsWith<NoSuchElementException> { d }
|
||||||
|
|||||||
Reference in New Issue
Block a user