From 2db8714fc59726c0c3632366cbc39732ab726454 Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Mon, 17 Apr 2017 21:03:04 +0300 Subject: [PATCH] Fix null values being treated as missing in 'put' method of a specialized string-keyed map --- .../src/core/collections/InternalStringMap.kt | 8 +++++++- libraries/stdlib/test/js/MapJsTest.kt | 16 +++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/js/js.libraries/src/core/collections/InternalStringMap.kt b/js/js.libraries/src/core/collections/InternalStringMap.kt index f144e066857..a10c870f4fd 100644 --- a/js/js.libraries/src/core/collections/InternalStringMap.kt +++ b/js/js.libraries/src/core/collections/InternalStringMap.kt @@ -23,6 +23,10 @@ import kotlin.collections.MutableMap.MutableEntry /** * A simple wrapper around JavaScript Map for key type is string. + * + * Though this map is instantiated only with K=String, the K type is not fixed to String statically, + * because we want to have it erased to Any? in order not to generate type-safe override bridges for + * [get], [contains], [remove] etc, if they ever are generated. */ internal class InternalStringMap(override val equality: EqualityComparator) : InternalMap { @@ -55,7 +59,7 @@ internal class InternalStringMap(override val equality: EqualityComparator val oldValue = backingMap[key] backingMap[key] = value - if (oldValue == undefined) { + if (oldValue === undefined) { size++ // structureChanged(host) return null @@ -99,10 +103,12 @@ internal class InternalStringMap(override val equality: EqualityComparator override fun next(): MutableEntry { val key = iterator.next() lastKey = key + @Suppress("UNCHECKED_CAST") return newMapEntry(key as K) } override fun remove() { + @Suppress("UNCHECKED_CAST") this@InternalStringMap.remove(checkNotNull(lastKey) as K) } } diff --git a/libraries/stdlib/test/js/MapJsTest.kt b/libraries/stdlib/test/js/MapJsTest.kt index dfbe22e5f7d..703d1db273f 100644 --- a/libraries/stdlib/test/js/MapJsTest.kt +++ b/libraries/stdlib/test/js/MapJsTest.kt @@ -45,7 +45,7 @@ class PrimitiveMapJsTest : MapJsTest() { override fun emptyMutableMapWithNullableKeyValue(): MutableMap = HashMap() @Test fun compareBehavior() { - val specialJsStringMap = HashMap() + val specialJsStringMap = stringMapOf() specialJsStringMap.put("k1", "v1") compare(genericHashMapOf("k1" to "v1"), specialJsStringMap) { mapBehavior() } @@ -53,6 +53,20 @@ class PrimitiveMapJsTest : MapJsTest() { specialJsNumberMap.put(5, "v5") compare(genericHashMapOf(5 to "v5"), specialJsNumberMap) { mapBehavior() } } + + @Test fun putNull() { + val map = stringMapOf("k" to null) + assertEquals(1, map.size) + + map.put("k", null) + assertEquals(1, map.size) + + map["k"] = null + assertEquals(1, map.size) + + map.remove("k") + assertEquals(0, map.size) + } } class LinkedHashMapJsTest : MapJsTest() {