From fb99919c590fa170ddfbe5740397cd930a72f8ff Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Tue, 2 Aug 2016 22:26:46 +0300 Subject: [PATCH] Accept maps out-projected by key where possible. --- libraries/stdlib/src/generated/_Maps.kt | 42 +++++++++---------- .../stdlib/src/kotlin/collections/Maps.kt | 26 ++++++------ libraries/stdlib/test/collections/MapTest.kt | 8 ++-- .../src/templates/engine/Engine.kt | 2 +- 4 files changed, 39 insertions(+), 39 deletions(-) diff --git a/libraries/stdlib/src/generated/_Maps.kt b/libraries/stdlib/src/generated/_Maps.kt index 03eac7565f3..cea3e6dd4a7 100644 --- a/libraries/stdlib/src/generated/_Maps.kt +++ b/libraries/stdlib/src/generated/_Maps.kt @@ -16,7 +16,7 @@ import java.util.Collections // TODO: it's temporary while we have java.util.Col /** * Returns a [List] containing all key-value pairs. */ -public fun Map.toList(): List> { +public fun Map.toList(): List> { if (size == 0) return emptyList() val iterator = entries.iterator() @@ -36,14 +36,14 @@ public fun Map.toList(): List> { /** * Returns a single list of all elements yielded from results of [transform] function being invoked on each entry of original map. */ -public inline fun Map.flatMap(transform: (Map.Entry) -> Iterable): List { +public inline fun Map.flatMap(transform: (Map.Entry) -> Iterable): List { return flatMapTo(ArrayList(), transform) } /** * Appends all elements yielded from results of [transform] function being invoked on each entry of original map, to the given [destination]. */ -public inline fun > Map.flatMapTo(destination: C, transform: (Map.Entry) -> Iterable): C { +public inline fun > Map.flatMapTo(destination: C, transform: (Map.Entry) -> Iterable): C { for (element in this) { val list = transform(element) destination.addAll(list) @@ -55,7 +55,7 @@ public inline fun > Map.flatMapTo(des * Returns a list containing the results of applying the given [transform] function * to each entry in the original map. */ -public inline fun Map.map(transform: (Map.Entry) -> R): List { +public inline fun Map.map(transform: (Map.Entry) -> R): List { return mapTo(ArrayList(size), transform) } @@ -63,7 +63,7 @@ public inline fun Map.map(transform: (Map.Entry) -> R): Li * Returns a list containing only the non-null results of applying the given [transform] function * to each entry in the original map. */ -public inline fun Map.mapNotNull(transform: (Map.Entry) -> R?): List { +public inline fun Map.mapNotNull(transform: (Map.Entry) -> R?): List { return mapNotNullTo(ArrayList(), transform) } @@ -71,7 +71,7 @@ public inline fun Map.mapNotNull(transform: (Map.Entry> Map.mapNotNullTo(destination: C, transform: (Map.Entry) -> R?): C { +public inline fun > Map.mapNotNullTo(destination: C, transform: (Map.Entry) -> R?): C { forEach { element -> transform(element)?.let { destination.add(it) } } return destination } @@ -80,7 +80,7 @@ public inline fun > Map.mapNotN * Applies the given [transform] function to each entry of the original map * and appends the results to the given [destination]. */ -public inline fun > Map.mapTo(destination: C, transform: (Map.Entry) -> R): C { +public inline fun > Map.mapTo(destination: C, transform: (Map.Entry) -> R): C { for (item in this) destination.add(transform(item)) return destination @@ -89,7 +89,7 @@ public inline fun > Map.mapTo(destina /** * Returns `true` if all entries match the given [predicate]. */ -public inline fun Map.all(predicate: (Map.Entry) -> Boolean): Boolean { +public inline fun Map.all(predicate: (Map.Entry) -> Boolean): Boolean { for (element in this) if (!predicate(element)) return false return true } @@ -97,7 +97,7 @@ public inline fun Map.all(predicate: (Map.Entry) -> Boolean): /** * Returns `true` if map has at least one entry. */ -public fun Map.any(): Boolean { +public fun Map.any(): Boolean { for (element in this) return true return false } @@ -105,7 +105,7 @@ public fun Map.any(): Boolean { /** * Returns `true` if at least one entry matches the given [predicate]. */ -public inline fun Map.any(predicate: (Map.Entry) -> Boolean): Boolean { +public inline fun Map.any(predicate: (Map.Entry) -> Boolean): Boolean { for (element in this) if (predicate(element)) return true return false } @@ -114,14 +114,14 @@ public inline fun Map.any(predicate: (Map.Entry) -> Boolean): * Returns the number of entries in this map. */ @kotlin.internal.InlineOnly -public inline fun Map.count(): Int { +public inline fun Map.count(): Int { return size } /** * Returns the number of entries matching the given [predicate]. */ -public inline fun Map.count(predicate: (Map.Entry) -> Boolean): Int { +public inline fun Map.count(predicate: (Map.Entry) -> Boolean): Int { var count = 0 for (element in this) if (predicate(element)) count++ return count @@ -131,7 +131,7 @@ public inline fun Map.count(predicate: (Map.Entry) -> Boolean * Performs the given [action] on each entry. */ @kotlin.internal.HidesMembers -public inline fun Map.forEach(action: (Map.Entry) -> Unit): Unit { +public inline fun Map.forEach(action: (Map.Entry) -> Unit): Unit { for (element in this) action(element) } @@ -139,7 +139,7 @@ public inline fun Map.forEach(action: (Map.Entry) -> Unit): U * Returns the first entry yielding the largest value of the given function or `null` if there are no entries. */ @kotlin.internal.InlineOnly -public inline fun > Map.maxBy(selector: (Map.Entry) -> R): Map.Entry? { +public inline fun > Map.maxBy(selector: (Map.Entry) -> R): Map.Entry? { return entries.maxBy(selector) } @@ -147,28 +147,28 @@ public inline fun > Map.maxBy(selector: (Map.Entry * Returns the first entry having the largest value according to the provided [comparator] or `null` if there are no entries. */ @kotlin.internal.InlineOnly -public inline fun Map.maxWith(comparator: Comparator>): Map.Entry? { +public inline fun Map.maxWith(comparator: Comparator>): Map.Entry? { return entries.maxWith(comparator) } /** * Returns the first entry yielding the smallest value of the given function or `null` if there are no entries. */ -public inline fun > Map.minBy(selector: (Map.Entry) -> R): Map.Entry? { +public inline fun > Map.minBy(selector: (Map.Entry) -> R): Map.Entry? { return entries.minBy(selector) } /** * Returns the first entry having the smallest value according to the provided [comparator] or `null` if there are no entries. */ -public fun Map.minWith(comparator: Comparator>): Map.Entry? { +public fun Map.minWith(comparator: Comparator>): Map.Entry? { return entries.minWith(comparator) } /** * Returns `true` if the map has no entries. */ -public fun Map.none(): Boolean { +public fun Map.none(): Boolean { for (element in this) return false return true } @@ -176,7 +176,7 @@ public fun Map.none(): Boolean { /** * Returns `true` if no entries match the given [predicate]. */ -public inline fun Map.none(predicate: (Map.Entry) -> Boolean): Boolean { +public inline fun Map.none(predicate: (Map.Entry) -> Boolean): Boolean { for (element in this) if (predicate(element)) return false return true } @@ -185,14 +185,14 @@ public inline fun Map.none(predicate: (Map.Entry) -> Boolean) * Creates an [Iterable] instance that wraps the original map returning its entries when being iterated. */ @kotlin.internal.InlineOnly -public inline fun Map.asIterable(): Iterable> { +public inline fun Map.asIterable(): Iterable> { return entries } /** * Creates a [Sequence] instance that wraps the original map returning its entries when being iterated. */ -public fun Map.asSequence(): Sequence> { +public fun Map.asSequence(): Sequence> { return Sequence { this.iterator() } } diff --git a/libraries/stdlib/src/kotlin/collections/Maps.kt b/libraries/stdlib/src/kotlin/collections/Maps.kt index f095cb72a22..76e67ceffe5 100644 --- a/libraries/stdlib/src/kotlin/collections/Maps.kt +++ b/libraries/stdlib/src/kotlin/collections/Maps.kt @@ -98,13 +98,13 @@ private const val INT_MAX_POWER_OF_TWO: Int = Int.MAX_VALUE / 2 + 1 /** Returns `true` if this map is not empty. */ @kotlin.internal.InlineOnly -public inline fun Map.isNotEmpty(): Boolean = !isEmpty() +public inline fun Map.isNotEmpty(): Boolean = !isEmpty() /** * Returns the [Map] if its not `null`, or the empty [Map] otherwise. */ @kotlin.internal.InlineOnly -public inline fun Map?.orEmpty() : Map = this ?: emptyMap() +public inline fun Map?.orEmpty() : Map = this ?: emptyMap() /** * Checks if the map contains the given key. This method allows to use the `x in map` syntax for checking @@ -223,7 +223,7 @@ public inline fun MutableMap.getOrPut(key: K, defaultValue: () -> V * @sample test.collections.MapTest.iterateWithProperties */ @kotlin.internal.InlineOnly -public inline operator fun Map.iterator(): Iterator> = entries.iterator() +public inline operator fun Map.iterator(): Iterator> = entries.iterator() /** * Returns a [MutableIterator] over the mutable entries in the [MutableMap]. @@ -238,7 +238,7 @@ public inline operator fun MutableMap.iterator(): MutableIterator> Map.mapValuesTo(destination: C, transform: (Map.Entry) -> R): C { +public inline fun > Map.mapValuesTo(destination: C, transform: (Map.Entry) -> R): C { return entries.associateByTo(destination, { it.key }, transform) } @@ -249,7 +249,7 @@ public inline fun > Map.mapValuesTo(de * In case if any two entries are mapped to the equal keys, the value of the latter one will overwrite * the value associated with the former one. */ -public inline fun > Map.mapKeysTo(destination: C, transform: (Map.Entry) -> R): C { +public inline fun > Map.mapKeysTo(destination: C, transform: (Map.Entry) -> R): C { return entries.associateByTo(destination, transform, { it.value }) } @@ -289,7 +289,7 @@ public fun MutableMap.putAll(pairs: Sequence>): Uni * @sample test.collections.MapTest.mapValues */ @Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE") -public inline fun Map.mapValues(transform: (Map.Entry) -> R): Map { +public inline fun Map.mapValues(transform: (Map.Entry) -> R): Map { return mapValuesTo(LinkedHashMap(mapCapacity(size)), transform) // .optimizeReadOnlyMap() } @@ -305,7 +305,7 @@ public inline fun Map.mapValues(transform: (Map.Entry) -> * @sample test.collections.MapTest.mapKeys */ @Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE") -public inline fun Map.mapKeys(transform: (Map.Entry) -> R): Map { +public inline fun Map.mapKeys(transform: (Map.Entry) -> R): Map { return mapKeysTo(LinkedHashMap(mapCapacity(size)), transform) // .optimizeReadOnlyMap() } @@ -314,7 +314,7 @@ public inline fun Map.mapKeys(transform: (Map.Entry) -> R) * * The returned map preserves the entry iteration order of the original map. */ -public inline fun Map.filterKeys(predicate: (K) -> Boolean): Map { +public inline fun Map.filterKeys(predicate: (K) -> Boolean): Map { val result = LinkedHashMap() for (entry in this) { if (predicate(entry.key)) { @@ -329,7 +329,7 @@ public inline fun Map.filterKeys(predicate: (K) -> Boolean): Map Map.filterValues(predicate: (V) -> Boolean): Map { +public inline fun Map.filterValues(predicate: (V) -> Boolean): Map { val result = LinkedHashMap() for (entry in this) { if (predicate(entry.value)) { @@ -345,7 +345,7 @@ public inline fun Map.filterValues(predicate: (V) -> Boolean): Map< * * @return the destination map. */ -public inline fun > Map.filterTo(destination: C, predicate: (Map.Entry) -> Boolean): C { +public inline fun > Map.filterTo(destination: C, predicate: (Map.Entry) -> Boolean): C { for (element in this) { if (predicate(element)) { destination.put(element.key, element.value) @@ -359,7 +359,7 @@ public inline fun > Map.filterTo(destinat * * The returned map preserves the entry iteration order of the original map. */ -public inline fun Map.filter(predicate: (Map.Entry) -> Boolean): Map { +public inline fun Map.filter(predicate: (Map.Entry) -> Boolean): Map { return filterTo(LinkedHashMap(), predicate) } @@ -368,7 +368,7 @@ public inline fun Map.filter(predicate: (Map.Entry) -> Boolea * * @return the destination map. */ -public inline fun > Map.filterNotTo(destination: C, predicate: (Map.Entry) -> Boolean): C { +public inline fun > Map.filterNotTo(destination: C, predicate: (Map.Entry) -> Boolean): C { for (element in this) { if (!predicate(element)) { destination.put(element.key, element.value) @@ -382,7 +382,7 @@ public inline fun > Map.filterNotTo(desti * * The returned map preserves the entry iteration order of the original map. */ -public inline fun Map.filterNot(predicate: (Map.Entry) -> Boolean): Map { +public inline fun Map.filterNot(predicate: (Map.Entry) -> Boolean): Map { return filterNotTo(LinkedHashMap(), predicate) } diff --git a/libraries/stdlib/test/collections/MapTest.kt b/libraries/stdlib/test/collections/MapTest.kt index 0ebde237b62..cf568575da0 100644 --- a/libraries/stdlib/test/collections/MapTest.kt +++ b/libraries/stdlib/test/collections/MapTest.kt @@ -252,12 +252,12 @@ class MapTest { } @test fun filter() { - val map = mapOf(Pair("b", 3), Pair("c", 2), Pair("a", 2)) - val filteredByKey = map.filter { it.key == "b" } + val map: Map = mapOf(Pair("b", 3), Pair("c", 2), Pair("a", 2)) + val filteredByKey = map.filter { it.key[0] == 'b' } assertEquals(1, filteredByKey.size) assertEquals(3, filteredByKey["b"]) - val filteredByKey2 = map.filterKeys { it == "b" } + val filteredByKey2 = map.filterKeys { it[0] == 'b' } assertEquals(1, filteredByKey2.size) assertEquals(3, filteredByKey2["b"]) @@ -267,7 +267,7 @@ class MapTest { assertEquals(2, filteredByValue["c"]) assertEquals(2, filteredByValue["a"]) - val filteredByValue2 = map.filterValues { it == 2 } + val filteredByValue2 = map.filterValues { it % 2 == 0 } assertEquals(2, filteredByValue2.size) assertEquals(null, filteredByValue2["b"]) assertEquals(2, filteredByValue2["c"]) diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/engine/Engine.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/engine/Engine.kt index 194a1ba200a..9baa43e068b 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/engine/Engine.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/engine/Engine.kt @@ -327,7 +327,7 @@ class GenericFunction(val signature: String, val keyword: String = "fun") { Iterables -> "Iterable<$isAsteriskOrT>" Collections -> "Collection<$isAsteriskOrT>" Lists -> "List<$isAsteriskOrT>" - Maps -> "Map" + Maps -> "Map" Sets -> "Set<$isAsteriskOrT>" Sequences -> "Sequence<$isAsteriskOrT>" InvariantArraysOfObjects -> "Array"