Breaking change. Map operations revisited.

This commit is contained in:
Ilya Ryzhenkov
2014-06-09 23:27:42 +04:00
parent 4167359c08
commit ce5f7e9d61
6 changed files with 140 additions and 108 deletions
@@ -61,7 +61,7 @@ public class PseudocodeVariableDataCollector(
// Variables declared in an inner (deeper) scope can't be accessed from an outer scope. // Variables declared in an inner (deeper) scope can't be accessed from an outer scope.
// Thus they can be filtered out upon leaving the inner scope. // Thus they can be filtered out upon leaving the inner scope.
return data.filterKeys { variable -> return data.filterKeys_tmp { variable ->
val lexicalScope = lexicalScopeVariableInfo.declaredIn[variable] val lexicalScope = lexicalScopeVariableInfo.declaredIn[variable]
// '-1' for variables declared outside this pseudocode // '-1' for variables declared outside this pseudocode
val depth = lexicalScope?.depth ?: -1 val depth = lexicalScope?.depth ?: -1
@@ -19,7 +19,8 @@ package org.jetbrains.jet.utils.addToStdlib
import java.util.HashMap import java.util.HashMap
import java.util.Collections import java.util.Collections
fun <K, V> Map<K, V>.filterKeys(predicate: (K)->Boolean): Map<K, V> { deprecated("Replace with filterKeys when bootstrapped")
fun <K, V> Map<K, V>.filterKeys_tmp(predicate: (K)->Boolean): Map<K, V> {
val result = HashMap<K, V>() val result = HashMap<K, V>()
for ((k, v) in this) { for ((k, v) in this) {
if (predicate(k)) { if (predicate(k)) {
@@ -431,19 +431,6 @@ public inline fun <T> Iterable<T>.filter(predicate: (T) -> Boolean): List<T> {
return filterTo(ArrayList<T>(), predicate) return filterTo(ArrayList<T>(), predicate)
} }
/**
* Returns a map containing all key-value pairs matching the given *predicate*
*/
public inline fun <K, V> Map<K, V>.filter(predicate: (Map.Entry<K, V>) -> Boolean): Map<K, V> {
val result = HashMap<K,V>()
for (entry in this) {
if (predicate(entry)) {
result.put(entry.key, entry.value)
}
}
return result
}
/** /**
* Returns a stream containing all elements matching the given *predicate* * Returns a stream containing all elements matching the given *predicate*
*/ */
@@ -528,13 +515,6 @@ public inline fun <T> Iterable<T>.filterNot(predicate: (T) -> Boolean): List<T>
return filterNotTo(ArrayList<T>(), predicate) return filterNotTo(ArrayList<T>(), predicate)
} }
/**
* Returns a list containing all elements not matching the given *predicate*
*/
public inline fun <K, V> Map<K, V>.filterNot(predicate: (Map.Entry<K, V>) -> Boolean): List<Map.Entry<K, V>> {
return filterNotTo(ArrayList<Map.Entry<K, V>>(), predicate)
}
/** /**
* Returns a stream containing all elements not matching the given *predicate* * Returns a stream containing all elements not matching the given *predicate*
*/ */
@@ -674,14 +654,6 @@ public inline fun <T, C : MutableCollection<in T>> Iterable<T>.filterNotTo(desti
return destination return destination
} }
/**
* Appends all elements not matching the given *predicate* to the given *destination*
*/
public inline fun <K, V, C : MutableCollection<in Map.Entry<K, V>>> Map<K, V>.filterNotTo(destination: C, predicate: (Map.Entry<K, V>) -> Boolean): C {
for (element in this) if (!predicate(element)) destination.add(element)
return destination
}
/** /**
* Appends all elements not matching the given *predicate* to the given *destination* * Appends all elements not matching the given *predicate* to the given *destination*
*/ */
@@ -778,14 +750,6 @@ public inline fun <T, C : MutableCollection<in T>> Iterable<T>.filterTo(destinat
return destination return destination
} }
/**
* Appends all elements matching the given *predicate* into the given *destination*
*/
public inline fun <K, V, C : MutableCollection<in Map.Entry<K, V>>> Map<K, V>.filterTo(destination: C, predicate: (Map.Entry<K, V>) -> Boolean): C {
for (element in this) if (predicate(element)) destination.add(element)
return destination
}
/** /**
* Appends all elements matching the given *predicate* into the given *destination* * Appends all elements matching the given *predicate* into the given *destination*
*/ */
+130 -47
View File
@@ -6,37 +6,37 @@ import java.util.HashMap
// Map APIs // Map APIs
/** Returns the size of the map */ /** Returns the size of the map */
public val Map<*,*>.size : Int public val Map<*, *>.size: Int
get() = size() get() = size()
/** Returns true if this map is empty */ /** Returns true if this map is empty */
public val Map<*,*>.empty : Boolean public val Map<*, *>.empty: Boolean
get() = isEmpty() get() = isEmpty()
/** Provides [] access to maps */ /** Provides [] access to maps */
public fun <K, V> MutableMap<K, V>.set(key : K, value : V) : V? = this.put(key, value) public fun <K, V> MutableMap<K, V>.set(key: K, value: V): V? = this.put(key, value)
/** Returns the [[Map]] if its not null otherwise it returns the empty [[Map]] */ /** Returns the [[Map]] if its not null otherwise it returns the empty [[Map]] */
public fun <K,V> Map<K,V>?.orEmpty() : Map<K,V> public fun <K,V> Map<K,V>?.orEmpty() : Map<K,V>
= if (this != null) this else stdlib_emptyMap() = if (this != null) this else stdlib_emptyMap()
public fun <K,V> Map<K,V>.contains(key : K) : Boolean = containsKey(key) public fun <K,V> Map<K,V>.contains(key : K) : Boolean = containsKey(key)
/** Returns the key of the entry */ /** Returns the key of the entry */
public val <K,V> Map.Entry<K,V>.key : K public val <K, V> Map.Entry<K, V>.key: K
get() = getKey() get() = getKey()
/** Returns the value of the entry */ /** Returns the value of the entry */
public val <K,V> Map.Entry<K,V>.value : V public val <K, V> Map.Entry<K, V>.value: V
get() = getValue() get() = getValue()
/** Returns the key of the entry */ /** Returns the key of the entry */
fun <K,V> Map.Entry<K,V>.component1() : K { fun <K, V> Map.Entry<K, V>.component1(): K {
return getKey() return getKey()
} }
/** Returns the value of the entry */ /** Returns the value of the entry */
fun <K,V> Map.Entry<K,V>.component2() : V { fun <K, V> Map.Entry<K, V>.component2(): V {
return getValue() return getValue()
} }
@@ -45,7 +45,7 @@ fun <K,V> Map.Entry<K,V>.component2() : V {
* *
* @includeFunctionBody ../../test/collections/MapTest.kt getOrElse * @includeFunctionBody ../../test/collections/MapTest.kt getOrElse
*/ */
public inline fun <K,V> Map<K,V>.getOrElse(key: K, defaultValue: ()-> V) : V { public inline fun <K, V> Map<K, V>.getOrElse(key: K, defaultValue: () -> V): V {
if (this.containsKey(key)) { if (this.containsKey(key)) {
return this.get(key) as V return this.get(key) as V
} else { } else {
@@ -58,7 +58,7 @@ public inline fun <K,V> Map<K,V>.getOrElse(key: K, defaultValue: ()-> V) : V {
* *
* @includeFunctionBody ../../test/collections/MapTest.kt getOrPut * @includeFunctionBody ../../test/collections/MapTest.kt getOrPut
*/ */
public inline fun <K,V> MutableMap<K,V>.getOrPut(key: K, defaultValue: ()-> V) : V { public inline fun <K, V> MutableMap<K, V>.getOrPut(key: K, defaultValue: () -> V): V {
if (this.containsKey(key)) { if (this.containsKey(key)) {
return this.get(key) as V return this.get(key) as V
} else { } else {
@@ -68,63 +68,54 @@ public inline fun <K,V> MutableMap<K,V>.getOrPut(key: K, defaultValue: ()-> V) :
} }
} }
/** /**
* Returns an [[Iterator]] over the entries in the [[Map]] * Returns an [[Iterator]] over the entries in the [[Map]]
* *
* @includeFunctionBody ../../test/collections/MapTest.kt iterateWithProperties * @includeFunctionBody ../../test/collections/MapTest.kt iterateWithProperties
*/ */
public fun <K,V> Map<K,V>.iterator(): Iterator<Map.Entry<K,V>> { public fun <K, V> Map<K, V>.iterator(): Iterator<Map.Entry<K, V>> {
val entrySet = this.entrySet() val entrySet = this.entrySet()
return entrySet.iterator() return entrySet.iterator()
} }
/** /**
* Populates the given *result* [[Map]] with the value returned by applying the *transform* function on each [[Map.Entry]] in this [[Map]] * Populates the given *destination* [[Map]] with the value returned by applying the *transform* function on each [[Map.Entry]] in this [[Map]]
*/ */
public inline fun <K,V,R,C: MutableMap<K,R>> Map<K,V>.mapValuesTo(result: C, transform : (Map.Entry<K,V>) -> R) : C { public inline fun <K, V, R, C : MutableMap<K, R>> Map<K, V>.mapValuesTo(destination: C, transform: (Map.Entry<K, V>) -> R): C {
for (e in this) { for (e in this) {
val newValue = transform(e) val newValue = transform(e)
result.put(e.key, newValue) destination.put(e.key, newValue)
} }
return result return destination
}
/**
* Populates the given *destination* [[Map]] with the value returned by applying the *transform* function on each [[Map.Entry]] in this [[Map]]
*/
public inline fun <K, V, R, C : MutableMap<R, V>> Map<K, V>.mapKeysTo(destination: C, transform: (Map.Entry<K, V>) -> R): C {
for (e in this) {
val newKey = transform(e)
destination.put(newKey, e.value)
}
return destination
} }
/** /**
* Puts all the entries into this [[MutableMap]] with the first value in the pair being the key and the second the value * Puts all the entries into this [[MutableMap]] with the first value in the pair being the key and the second the value
*/ */
public fun <K,V> MutableMap<K,V>.putAll(vararg values: Pair<K, V>): Unit { public fun <K, V> MutableMap<K, V>.putAll(vararg values: Pair<K, V>): Unit {
for ((key, value) in values) { for ((key, value) in values) {
put(key, value) put(key, value)
} }
} }
/** /**
* Copies the entries in this [[Map]] to the given mutable *map* * Puts all the entries into this [[MutableMap]] with the first value in the pair being the key and the second the value
*/ */
public fun <K,V, C : MutableMap<K, in V>> Map<K,V>.toMap(map: C): C { public fun <K, V> MutableMap<K, V>.putAll(values: Iterable<Pair<K,V>>): Unit {
map.putAll(this) for ((key, value) in values) {
return map put(key, value)
}
/**
* Copies the entries from given iterable of pairs to the given mutable *map*
*/
public fun <K,V, C : MutableMap<K, in V>> Iterable<Pair<K,V>>.toMap(map: C): C {
for((key,value) in this) {
if (map.containsKey(key)) {
throw DuplicateKeyException()
}
map.put(key,value)
} }
return map
}
/**
* Creates map from given iterable of pairs
*/
public fun <K,V> Iterable<Pair<K,V>>.toMap() : Map<K,V> {
return toMap(HashMap<K,V>())
} }
/** /**
@@ -132,6 +123,98 @@ public fun <K,V> Iterable<Pair<K,V>>.toMap() : Map<K,V> {
* *
* @includeFunctionBody ../../test/collections/MapTest.kt mapValues * @includeFunctionBody ../../test/collections/MapTest.kt mapValues
*/ */
public inline fun <K,V,R> Map<K,V>.mapValues(transform : (Map.Entry<K,V>) -> R): Map<K,R> { public inline fun <K, V, R> Map<K, V>.mapValues(transform: (Map.Entry<K, V>) -> R): Map<K, R> {
return mapValuesTo(java.util.HashMap<K,R>(this.size), transform) return mapValuesTo(HashMap<K, R>(this.size), transform)
}
/**
* Returns a new Map containing the results of applying the given *transform* function to each [[Map.Entry]] in this [[Map]]
*
* @includeFunctionBody ../../test/collections/MapTest.kt mapKeys
*/
public inline fun <K, V, R> Map<K, V>.mapKeys(transform: (Map.Entry<K, V>) -> R): Map<R, V> {
return mapKeysTo(HashMap<R, V>(this.size), transform)
}
/**
* Returns a map containing all key-value pairs matching keys with the given *predicate*
*/
public inline fun <K, V> Map<K, V>.filterKeys(predicate: (K) -> Boolean): Map<K, V> {
val result = HashMap<K, V>()
for (entry in this) {
if (predicate(entry.key)) {
result.put(entry.key, entry.value)
}
}
return result
}
/**
* Returns a map containing all key-value pairs matching values with the given *predicate*
*/
public inline fun <K, V> Map<K, V>.filterValues(predicate: (V) -> Boolean): Map<K, V> {
val result = HashMap<K, V>()
for (entry in this) {
if (predicate(entry.value)) {
result.put(entry.key, entry.value)
}
}
return result
}
/**
* Appends all elements matching the given *predicate* into the given *destination*
*/
public inline fun <K, V, C : MutableMap<K, V>> Map<K, V>.filterTo(destination: C, predicate: (Map.Entry<K, V>) -> Boolean): C {
for (element in this) {
if (predicate(element)) {
destination.put(element.key, element.value)
}
}
return destination
}
/**
* Returns a map containing all key-value pairs matching the given *predicate*
*/
public inline fun <K, V> Map<K, V>.filter(predicate: (Map.Entry<K, V>) -> Boolean): Map<K, V> {
return filterTo(HashMap<K, V>(), predicate)
}
/**
* Appends all elements matching the given *predicate* into the given *destination*
*/
public inline fun <K, V, C : MutableMap<K, V>> Map<K, V>.filterNotTo(destination: C, predicate: (Map.Entry<K, V>) -> Boolean): C {
for (element in this) {
if (!predicate(element)) {
destination.put(element.key, element.value)
}
}
return destination
}
/**
* Returns a map containing all key-value pairs matching the given *predicate*
*/
public inline fun <K, V> Map<K, V>.filterNot(predicate: (Map.Entry<K, V>) -> Boolean): Map<K, V> {
return filterNotTo(HashMap<K, V>(), predicate)
}
/**
* Appends given [pair] to the mutable map.
*/
public fun <K, V> MutableMap<K, V>.plusAssign(pair: Pair<K, V>) {
put(pair.first, pair.second)
}
/**
* Returns a map containing all key-value pairs from the given collection
*/
public fun <K, V> Iterable<Pair<K, V>>.toMap(): Map<K, V> {
val result = HashMap<K, V>()
for (element in this) {
result.put(element.first, element.second)
}
return result
} }
@@ -11,14 +11,14 @@ import java.util.Properties
/** /**
* Converts this [[Map]] to a [[LinkedHashMap]] so future insertion orders are maintained * Converts this [[Map]] to a [[LinkedHashMap]] so future insertion orders are maintained
*/ */
public fun <K,V> Map<K,V>.toLinkedMap(): LinkedHashMap<K,V> = toMap(LinkedHashMap<K,V>(size)) public fun <K, V> Map<K, V>.toLinkedMap(): LinkedHashMap<K, V> = LinkedHashMap(this)
/** /**
* Converts this [[Map]] to a [[SortedMap]] so iteration order will be in key order * Converts this [[Map]] to a [[SortedMap]] so iteration order will be in key order
* *
* @includeFunctionBody ../../test/collections/MapTest.kt toSortedMap * @includeFunctionBody ../../test/collections/MapTest.kt toSortedMap
*/ */
public fun <K,V> Map<K,V>.toSortedMap(): SortedMap<K,V> = toMap(TreeMap<K,V>()) public fun <K, V> Map<K, V>.toSortedMap(): SortedMap<K, V> = TreeMap(this)
/** /**
* Converts this [[Map]] to a [[SortedMap]] using the given *comparator* so that iteration order will be in the order * Converts this [[Map]] to a [[SortedMap]] using the given *comparator* so that iteration order will be in the order
@@ -26,8 +26,11 @@ public fun <K,V> Map<K,V>.toSortedMap(): SortedMap<K,V> = toMap(TreeMap<K,V>())
* *
* @includeFunctionBody ../../test/collections/MapTest.kt toSortedMapWithComparator * @includeFunctionBody ../../test/collections/MapTest.kt toSortedMapWithComparator
*/ */
public fun <K,V> Map<K,V>.toSortedMap(comparator: Comparator<K>): SortedMap<K,V> = toMap(TreeMap<K,V>(comparator)) public fun <K, V> Map<K, V>.toSortedMap(comparator: Comparator<K>): SortedMap<K, V> {
val result = TreeMap<K, V>(comparator)
result.putAll(this)
return result
}
/** /**
* Converts this [[Map]] to a [[Properties]] object * Converts this [[Map]] to a [[Properties]] object
@@ -205,21 +205,6 @@ fun filtering(): List<GenericFunction> {
return FilteringStream(this, true, predicate) return FilteringStream(this, true, predicate)
""" """
} }
include(Maps)
doc(Maps) { "Returns a map containing all key-value pairs matching the given *predicate*" }
returns(Maps) { "Map<K, V>" }
body(Maps) {
"""
val result = HashMap<K,V>()
for (entry in this) {
if (predicate(entry)) {
result.put(entry.key, entry.value)
}
}
return result
"""
}
} }
templates add f("filterTo(destination: C, predicate: (T) -> Boolean)") { templates add f("filterTo(destination: C, predicate: (T) -> Boolean)") {
@@ -246,8 +231,6 @@ fun filtering(): List<GenericFunction> {
return destination return destination
""" """
} }
include(Maps)
} }
templates add f("filterNot(predicate: (T) -> Boolean)") { templates add f("filterNot(predicate: (T) -> Boolean)") {
@@ -276,7 +259,6 @@ fun filtering(): List<GenericFunction> {
return FilteringStream(this, false, predicate) return FilteringStream(this, false, predicate)
""" """
} }
include(Maps)
} }
templates add f("filterNotTo(destination: C, predicate: (T) -> Boolean)") { templates add f("filterNotTo(destination: C, predicate: (T) -> Boolean)") {
@@ -300,7 +282,6 @@ fun filtering(): List<GenericFunction> {
return destination return destination
""" """
} }
include(Maps)
} }
templates add f("filterNotNull()") { templates add f("filterNotNull()") {