From 7efaa7cabcb18972836ec391a02b1c4d8702f775 Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Sat, 1 Jul 2017 17:00:16 +0300 Subject: [PATCH] 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 --- .../ir/irText/declarations/classLevelProperties.txt | 3 ++- .../testData/ir/irText/declarations/delegatedProperties.txt | 6 ++++-- .../ir/irText/declarations/localDelegatedProperties.txt | 3 ++- .../ir/irText/declarations/packageLevelProperties.txt | 3 ++- libraries/stdlib/src/kotlin/collections/MapAccessors.kt | 4 ++-- .../stdlib/test/properties/delegation/MapAccessorsTest.kt | 6 ++++++ 6 files changed, 18 insertions(+), 7 deletions(-) diff --git a/compiler/testData/ir/irText/declarations/classLevelProperties.txt b/compiler/testData/ir/irText/declarations/classLevelProperties.txt index 2c62eb529e3..76df61fdbb3 100644 --- a/compiler/testData/ir/irText/declarations/classLevelProperties.txt +++ b/compiler/testData/ir/irText/declarations/classLevelProperties.txt @@ -113,8 +113,9 @@ FILE /classLevelProperties.kt $this: VALUE_PARAMETER this@C: C BLOCK_BODY RETURN type=kotlin.Nothing from='(): Int' - CALL 'getValue(Any?, KProperty<*>) on MutableMap: Int' type=kotlin.Int origin=null + CALL 'getValue(Any?, KProperty<*>) on MutableMap: Int' type=kotlin.Int origin=null : Int + : Int $receiver: GET_FIELD '`test8$delegate`: HashMap /* = HashMap */' type=kotlin.collections.HashMap /* = java.util.HashMap */ origin=null receiver: GET_VAR 'this@C: C' type=C origin=null thisRef: GET_VAR 'this@C: C' type=C origin=null diff --git a/compiler/testData/ir/irText/declarations/delegatedProperties.txt b/compiler/testData/ir/irText/declarations/delegatedProperties.txt index 7e925261483..02e7fd5fe25 100644 --- a/compiler/testData/ir/irText/declarations/delegatedProperties.txt +++ b/compiler/testData/ir/irText/declarations/delegatedProperties.txt @@ -65,8 +65,9 @@ FILE /delegatedProperties.kt $this: VALUE_PARAMETER this@C: C BLOCK_BODY RETURN type=kotlin.Nothing from='(): Any' - CALL 'getValue(Any?, KProperty<*>) on MutableMap: Any' type=kotlin.Any origin=null + CALL 'getValue(Any?, KProperty<*>) on MutableMap: Any' type=kotlin.Any origin=null : Any + : Any $receiver: GET_FIELD '`test3$delegate`: MutableMap' type=kotlin.collections.MutableMap origin=null receiver: 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 (): kotlin.Any BLOCK_BODY RETURN type=kotlin.Nothing from='(): Any' - CALL 'getValue(Any?, KProperty<*>) on MutableMap: Any' type=kotlin.Any origin=null + CALL 'getValue(Any?, KProperty<*>) on MutableMap: Any' type=kotlin.Any origin=null : Any + : Any $receiver: GET_FIELD '`test4$delegate`: HashMap /* = HashMap */' type=kotlin.collections.HashMap /* = java.util.HashMap */ origin=null thisRef: CONST Null type=kotlin.Nothing? value='null' property: PROPERTY_REFERENCE 'test4: Any' field=null getter='(): Any' setter='(Any): Unit' type=kotlin.reflect.KMutableProperty0 origin=PROPERTY_REFERENCE_FOR_DELEGATE diff --git a/compiler/testData/ir/irText/declarations/localDelegatedProperties.txt b/compiler/testData/ir/irText/declarations/localDelegatedProperties.txt index 0e8fd4e24ab..612350304ab 100644 --- a/compiler/testData/ir/irText/declarations/localDelegatedProperties.txt +++ b/compiler/testData/ir/irText/declarations/localDelegatedProperties.txt @@ -31,8 +31,9 @@ FILE /localDelegatedProperties.kt FUN DELEGATED_PROPERTY_ACCESSOR local final fun (): kotlin.Int BLOCK_BODY RETURN type=kotlin.Nothing from='(): Int' - CALL 'getValue(Any?, KProperty<*>) on MutableMap: Int' type=kotlin.Int origin=null + CALL 'getValue(Any?, KProperty<*>) on MutableMap: Int' type=kotlin.Int origin=null : Int + : Int $receiver: GET_VAR '`x$delegate`: HashMap /* = HashMap */' type=kotlin.collections.HashMap /* = java.util.HashMap */ origin=null thisRef: CONST Null type=kotlin.Nothing? value='null' property: LOCAL_DELEGATED_PROPERTY_REFERENCE 'x: Int' delegate='`x$delegate`: HashMap /* = HashMap */' getter='(): Int' setter='(Int): Unit' type=kotlin.reflect.KMutableProperty0 origin=PROPERTY_REFERENCE_FOR_DELEGATE diff --git a/compiler/testData/ir/irText/declarations/packageLevelProperties.txt b/compiler/testData/ir/irText/declarations/packageLevelProperties.txt index f73cbe6ad61..b50fbbbb0a0 100644 --- a/compiler/testData/ir/irText/declarations/packageLevelProperties.txt +++ b/compiler/testData/ir/irText/declarations/packageLevelProperties.txt @@ -87,8 +87,9 @@ FILE /packageLevelProperties.kt FUN DELEGATED_PROPERTY_ACCESSOR public fun (): kotlin.Int BLOCK_BODY RETURN type=kotlin.Nothing from='(): Int' - CALL 'getValue(Any?, KProperty<*>) on MutableMap: Int' type=kotlin.Int origin=null + CALL 'getValue(Any?, KProperty<*>) on MutableMap: Int' type=kotlin.Int origin=null : Int + : Int $receiver: GET_FIELD '`test8$delegate`: HashMap /* = HashMap */' type=kotlin.collections.HashMap /* = java.util.HashMap */ origin=null thisRef: CONST Null type=kotlin.Nothing? value='null' property: PROPERTY_REFERENCE 'test8: Int' field=null getter='(): Int' setter='(Int): Unit' type=kotlin.reflect.KMutableProperty0 origin=PROPERTY_REFERENCE_FOR_DELEGATE diff --git a/libraries/stdlib/src/kotlin/collections/MapAccessors.kt b/libraries/stdlib/src/kotlin/collections/MapAccessors.kt index 7c2b8d66f73..157762278c0 100644 --- a/libraries/stdlib/src/kotlin/collections/MapAccessors.kt +++ b/libraries/stdlib/src/kotlin/collections/MapAccessors.kt @@ -26,8 +26,8 @@ public inline operator fun Map.getValue(thisRef: */ @kotlin.jvm.JvmName("getVar") @kotlin.internal.InlineOnly -public inline operator fun MutableMap.getValue(thisRef: Any?, property: KProperty<*>): V - = @Suppress("UNCHECKED_CAST") (getOrImplicitDefault(property.name) as V) +public inline operator fun MutableMap.getValue(thisRef: Any?, property: KProperty<*>): V1 + = @Suppress("UNCHECKED_CAST") (getOrImplicitDefault(property.name) as V1) /** * Stores the value of the property for the given object in this mutable map. diff --git a/libraries/stdlib/test/properties/delegation/MapAccessorsTest.kt b/libraries/stdlib/test/properties/delegation/MapAccessorsTest.kt index 12c0b3ff78a..7e724498a0a 100644 --- a/libraries/stdlib/test/properties/delegation/MapAccessorsTest.kt +++ b/libraries/stdlib/test/properties/delegation/MapAccessorsTest.kt @@ -5,6 +5,8 @@ import kotlin.test.* class ValByMapExtensionsTest { val map: Map = hashMapOf("a" to "all", "b" to "bar", "c" to "code") val genericMap = mapOf("i" to 1, "x" to 1.0) + val mmapOut: MutableMap = mutableMapOf("g" to "out", "g1" to "in") + val genericMmapOut: MutableMap = mmapOut val a by map val b: String by map @@ -12,6 +14,8 @@ class ValByMapExtensionsTest { val d: String? by map val e: String by map.withDefault { "default" } 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 i: Int by genericMap val x: Double by genericMap @@ -23,6 +27,8 @@ class ValByMapExtensionsTest { assertEquals("code", c) assertEquals("default", e) assertEquals(null, f) + assertEquals("out", g) + assertEquals("in", g1) assertEquals(1, i) assertEquals(1.0, x) assertFailsWith { d }