Sort collections/map APIs, improve empty implementations.
This commit is contained in:
@@ -2,8 +2,8 @@ class A {}
|
||||
|
||||
fun <T> foo(t: T) {}
|
||||
|
||||
fun <T> emptyList(): List<T> = throw Exception()
|
||||
fun <T> someList(): List<T> = throw Exception()
|
||||
|
||||
fun bar() {
|
||||
<caret>foo(emptyList())
|
||||
<caret>foo(someList())
|
||||
}
|
||||
@@ -2,10 +2,10 @@ class A {}
|
||||
|
||||
fun <T> foo(t: T) {}
|
||||
|
||||
fun <T> emptyList(): List<T> = throw Exception()
|
||||
fun <T> someList(): List<T> = throw Exception()
|
||||
|
||||
fun bar() {
|
||||
<caret>foo(emptyList())
|
||||
<caret>foo(someList())
|
||||
}
|
||||
|
||||
|
||||
@@ -20,4 +20,4 @@ Extension receiver = NO_RECEIVER
|
||||
|
||||
Value arguments mapping:
|
||||
|
||||
MATCH_MODULO_UNINFERRED_TYPES t : List<???> = emptyList()
|
||||
MATCH_MODULO_UNINFERRED_TYPES t : List<???> = someList()
|
||||
|
||||
@@ -2,8 +2,8 @@ class A {}
|
||||
|
||||
fun <T> foo(t: T) {}
|
||||
|
||||
fun <T> emptyList(): MutableList<T> = throw Exception()
|
||||
fun <T> someList(): MutableList<T> = throw Exception()
|
||||
|
||||
fun bar() {
|
||||
<caret>foo(emptyList())
|
||||
<caret>foo(someList())
|
||||
}
|
||||
@@ -2,10 +2,10 @@ class A {}
|
||||
|
||||
fun <T> foo(t: T) {}
|
||||
|
||||
fun <T> emptyList(): MutableList<T> = throw Exception()
|
||||
fun <T> someList(): MutableList<T> = throw Exception()
|
||||
|
||||
fun bar() {
|
||||
<caret>foo(emptyList())
|
||||
<caret>foo(someList())
|
||||
}
|
||||
|
||||
|
||||
@@ -20,4 +20,4 @@ Extension receiver = NO_RECEIVER
|
||||
|
||||
Value arguments mapping:
|
||||
|
||||
MATCH_MODULO_UNINFERRED_TYPES t : MutableList<???> = emptyList()
|
||||
MATCH_MODULO_UNINFERRED_TYPES t : MutableList<???> = someList()
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
fun <T> emptyList(): List<T> = throw Exception()
|
||||
fun <T> someList(): List<T> = throw Exception()
|
||||
|
||||
fun <T> doSmth(l: List<T>) {}
|
||||
fun doSmth(a: Any) {}
|
||||
|
||||
fun bar() {
|
||||
<caret>doSmth(emptyList())
|
||||
<caret>doSmth(someList())
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
fun <T> emptyList(): List<T> = throw Exception()
|
||||
fun <T> someList(): List<T> = throw Exception()
|
||||
|
||||
fun <T> doSmth(l: List<T>) {}
|
||||
fun doSmth(a: Any) {}
|
||||
|
||||
fun bar() {
|
||||
<caret>doSmth(emptyList())
|
||||
<caret>doSmth(someList())
|
||||
}
|
||||
|
||||
|
||||
@@ -19,4 +19,4 @@ Extension receiver = NO_RECEIVER
|
||||
|
||||
Value arguments mapping:
|
||||
|
||||
MATCH_MODULO_UNINFERRED_TYPES l : List<???> = emptyList()
|
||||
MATCH_MODULO_UNINFERRED_TYPES l : List<???> = someList()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// ERROR: Too many arguments for public fun <T> listOf(): kotlin.List<T> defined in kotlin
|
||||
// ERROR: Null can not be a value of a non-null type kotlin.String
|
||||
// ERROR: Too many arguments for public fun <T> setOf(): kotlin.Set<T> defined in kotlin
|
||||
import java.util.*
|
||||
|
||||
class A {
|
||||
|
||||
@@ -144,3 +144,8 @@ public val Map<*, *>.size: Int
|
||||
deprecated("Use isEmpty() function call instead")
|
||||
public val Map<*, *>.empty: Boolean
|
||||
get() = isEmpty()
|
||||
|
||||
/** Returns true if this collection is not empty */
|
||||
deprecated("Use isNotEmpty() function call instead")
|
||||
public val Collection<*>.notEmpty: Boolean
|
||||
get() = isNotEmpty()
|
||||
|
||||
@@ -2,28 +2,52 @@ package kotlin
|
||||
|
||||
import java.util.*
|
||||
|
||||
private class stdlib_emptyListClass : List<Any> by ArrayList<Any>() {}
|
||||
private val stdlib_emptyList : List<Any> = stdlib_emptyListClass()
|
||||
private fun stdlib_emptyList<T>() = stdlib_emptyList as List<T>
|
||||
private object EmptyList : List<Any> {
|
||||
private val list = ArrayList<Any>()
|
||||
|
||||
private class stdlib_emptyMapClass : Map<Any, Any> by HashMap<Any, Any>() {}
|
||||
private val stdlib_emptyMap : Map<Any, Any> = stdlib_emptyMapClass()
|
||||
private fun stdlib_emptyMap<K,V>() = stdlib_emptyMap as Map<K,V>
|
||||
override fun contains(o: Any?): Boolean = list.contains(o)
|
||||
override fun containsAll(c: Collection<Any?>): Boolean = list.containsAll(c)
|
||||
override fun get(index: Int): Any = list.get(index)
|
||||
override fun indexOf(o: Any?): Int = list.indexOf(o)
|
||||
override fun isEmpty(): Boolean = list.isEmpty()
|
||||
override fun iterator(): Iterator<Any> = list.iterator()
|
||||
override fun lastIndexOf(o: Any?): Int = list.lastIndexOf(o)
|
||||
override fun listIterator(): ListIterator<Any> = list.listIterator()
|
||||
override fun listIterator(index: Int): ListIterator<Any> =list.listIterator(index)
|
||||
override fun size(): Int = list.size()
|
||||
override fun subList(fromIndex: Int, toIndex: Int): List<Any> = list.subList(fromIndex, toIndex)
|
||||
override fun equals(other: Any?): Boolean = list.equals(other)
|
||||
override fun hashCode(): Int = list.hashCode()
|
||||
override fun toString(): String = list.toString()
|
||||
}
|
||||
|
||||
private object EmptySet : Set<Any> {
|
||||
private val set = HashSet<Any>()
|
||||
|
||||
override fun contains(o: Any?): Boolean = set.contains(o)
|
||||
override fun containsAll(c: Collection<Any?>): Boolean = set.containsAll(c)
|
||||
override fun isEmpty(): Boolean = set.isEmpty()
|
||||
override fun iterator(): Iterator<Any> = set.iterator()
|
||||
override fun size(): Int = set.size()
|
||||
override fun equals(other: Any?): Boolean = set.equals(other)
|
||||
override fun hashCode(): Int = set.hashCode()
|
||||
override fun toString(): String = set.toString()
|
||||
}
|
||||
|
||||
public fun emptyList<T>(): List<T> = EmptyList as List<T>
|
||||
public fun emptySet<T>(): Set<T> = EmptySet as Set<T>
|
||||
|
||||
/** Returns a new read-only list of given elements */
|
||||
public fun listOf<T>(vararg values: T): List<T> = if (values.size() == 0) stdlib_emptyList() else arrayListOf(*values)
|
||||
public fun listOf<T>(vararg values: T): List<T> = if (values.size() == 0) emptyList() else arrayListOf(*values)
|
||||
|
||||
/** Returns an empty list */
|
||||
public fun listOf<T>(): List<T> = stdlib_emptyList()
|
||||
/** Returns an empty read-only list */
|
||||
public fun listOf<T>(): List<T> = emptyList()
|
||||
|
||||
/** Returns a new read-only map of given pairs, where the first value is the key, and the second is value */
|
||||
public fun mapOf<K, V>(vararg values: Pair<K, V>): Map<K, V> = if (values.size() == 0) stdlib_emptyMap() else linkedMapOf(*values)
|
||||
/** Returns a new read-only ordered set of given elements */
|
||||
public fun setOf<T>(vararg values: T): Set<T> = if (values.size() == 0) emptySet() else values.toCollection(LinkedHashSet<T>())
|
||||
|
||||
/** Returns an empty read-only map */
|
||||
public fun mapOf<K, V>(): Map<K, V> = stdlib_emptyMap()
|
||||
|
||||
/** Returns a new read-only set of given elements */
|
||||
public fun setOf<T>(vararg values: T): Set<T> = values.toCollection(LinkedHashSet<T>())
|
||||
/** Returns an empty read-only set */
|
||||
public fun setOf<T>(): Set<T> = emptySet()
|
||||
|
||||
/** Returns a new LinkedList with a variable number of initial elements */
|
||||
public fun linkedListOf<T>(vararg values: T): LinkedList<T> = values.toCollection(LinkedList<T>())
|
||||
@@ -34,30 +58,8 @@ public fun arrayListOf<T>(vararg values: T): ArrayList<T> = values.toCollection(
|
||||
/** Returns a new HashSet with a variable number of initial elements */
|
||||
public fun hashSetOf<T>(vararg values: T): HashSet<T> = values.toCollection(HashSet(values.size()))
|
||||
|
||||
/**
|
||||
* Returns a new [[HashMap]] populated with the given pairs where the first value in each pair
|
||||
* is the key and the second value is the value
|
||||
*
|
||||
* @includeFunctionBody ../../test/collections/MapTest.kt createUsingPairs
|
||||
*/
|
||||
public fun <K, V> hashMapOf(vararg values: Pair<K, V>): HashMap<K, V> {
|
||||
val answer = HashMap<K, V>(values.size())
|
||||
answer.putAll(*values)
|
||||
return answer
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new [[LinkedHashMap]] populated with the given pairs where the first value in each pair
|
||||
* is the key and the second value is the value. This map preserves insertion order so iterating through
|
||||
* the map's entries will be in the same order
|
||||
*
|
||||
* @includeFunctionBody ../../test/collections/MapTest.kt createLinkedMap
|
||||
*/
|
||||
public fun <K, V> linkedMapOf(vararg values: Pair<K, V>): LinkedHashMap<K, V> {
|
||||
val answer = LinkedHashMap<K, V>(values.size())
|
||||
answer.putAll(*values)
|
||||
return answer
|
||||
}
|
||||
/** Returns a new LinkedHashSet with a variable number of initial elements */
|
||||
public fun linkedSetOf<T>(vararg values: T): HashSet<T> = values.toCollection(LinkedHashSet(values.size()))
|
||||
|
||||
public val Collection<*>.indices: IntRange
|
||||
get() = 0..size() - 1
|
||||
@@ -73,18 +75,14 @@ public val Int.indices: IntRange
|
||||
public val <T> List<T>.lastIndex: Int
|
||||
get() = this.size() - 1
|
||||
|
||||
|
||||
/** Returns true if the collection is not empty */
|
||||
public fun <T> Collection<T>.isNotEmpty(): Boolean = !this.isEmpty()
|
||||
|
||||
/** Returns true if this collection is not empty */
|
||||
public val Collection<*>.notEmpty: Boolean
|
||||
get() = isNotEmpty()
|
||||
public fun <T> Collection<T>.isNotEmpty(): Boolean = !isEmpty()
|
||||
|
||||
/** Returns the Collection if its not null otherwise it returns the empty list */
|
||||
public fun <T> Collection<T>?.orEmpty(): Collection<T> = this ?: stdlib_emptyList()
|
||||
|
||||
// List APIs
|
||||
public fun <T> Collection<T>?.orEmpty(): Collection<T> = this ?: emptyList()
|
||||
|
||||
/** Returns the List if its not null otherwise returns the empty list */
|
||||
public fun <T> List<T>?.orEmpty(): List<T> = this ?: stdlib_emptyList()
|
||||
public fun <T> List<T>?.orEmpty(): List<T> = this ?: emptyList()
|
||||
|
||||
/** Returns the List if its not null otherwise returns the empty list */
|
||||
public fun <T> Set<T>?.orEmpty(): Set<T> = this ?: emptySet()
|
||||
|
||||
@@ -12,29 +12,6 @@ public fun sortedSetOf<T>(vararg values: T): TreeSet<T> = values.toCollection(Tr
|
||||
*/
|
||||
public fun sortedSetOf<T>(comparator: Comparator<T>, vararg values: T): TreeSet<T> = values.toCollection(TreeSet<T>(comparator))
|
||||
|
||||
/**
|
||||
* Returns a new [[SortedMap]] populated with the given pairs where the first value in each pair
|
||||
* is the key and the second value is the value
|
||||
*
|
||||
* @includeFunctionBody ../../test/collections/MapTest.kt createSortedMap
|
||||
*/
|
||||
public fun <K, V> sortedMapOf(vararg values: Pair<K, V>): SortedMap<K, V> {
|
||||
val answer = TreeMap<K, V>()
|
||||
/**
|
||||
TODO replace by this simpler call when we can pass vararg values into other methods
|
||||
answer.putAll(values)
|
||||
*/
|
||||
for (v in values) {
|
||||
answer.put(v.first, v.second)
|
||||
}
|
||||
return answer
|
||||
}
|
||||
|
||||
/** Returns the Set if its not null otherwise returns the empty set */
|
||||
public fun <T> Set<T>?.orEmpty(): Set<T>
|
||||
= if (this != null) this else Collections.EMPTY_SET as Set<T>
|
||||
|
||||
|
||||
/**
|
||||
* Returns a list containing the elements returned by the
|
||||
* specified enumeration in the order they are returned by the
|
||||
|
||||
@@ -2,11 +2,59 @@ package kotlin
|
||||
|
||||
import java.util.*
|
||||
|
||||
// Map APIs
|
||||
private object EmptyMap : Map<Any, Any> {
|
||||
private val map = HashMap<Any, Any>()
|
||||
|
||||
override fun containsKey(key: Any?): Boolean = map.containsKey(key)
|
||||
override fun containsValue(value: Any?): Boolean = map.containsValue(value)
|
||||
override fun entrySet(): Set<Map.Entry<Any, Any>> = map.entrySet()
|
||||
override fun get(key: Any?): Any? = map.get(key)
|
||||
override fun keySet(): Set<Any> = map.keySet()
|
||||
override fun values(): Collection<Any> = map.values()
|
||||
override fun isEmpty(): Boolean = map.isEmpty()
|
||||
override fun size(): Int = map.size()
|
||||
override fun equals(other: Any?): Boolean = map.equals(other)
|
||||
override fun hashCode(): Int = map.hashCode()
|
||||
override fun toString(): String = map.toString()
|
||||
}
|
||||
|
||||
/** Returns an empty read-only map of specified type */
|
||||
public fun emptyMap<K, V>(): Map<K, V> = EmptyMap as Map<K, V>
|
||||
|
||||
/** Returns a new read-only map of given pairs, where the first value is the key, and the second is value */
|
||||
public fun mapOf<K, V>(vararg values: Pair<K, V>): Map<K, V> = if (values.size() == 0) emptyMap() else linkedMapOf(*values)
|
||||
|
||||
/** Returns an empty read-only map */
|
||||
public fun mapOf<K, V>(): Map<K, V> = emptyMap()
|
||||
|
||||
/**
|
||||
* Returns a new [[HashMap]] populated with the given pairs where the first value in each pair
|
||||
* is the key and the second value is the value
|
||||
*
|
||||
* @includeFunctionBody ../../test/collections/MapTest.kt createUsingPairs
|
||||
*/
|
||||
public fun <K, V> hashMapOf(vararg values: Pair<K, V>): HashMap<K, V> {
|
||||
val answer = HashMap<K, V>(values.size())
|
||||
answer.putAll(*values)
|
||||
return answer
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new [[LinkedHashMap]] populated with the given pairs where the first value in each pair
|
||||
* is the key and the second value is the value. This map preserves insertion order so iterating through
|
||||
* the map's entries will be in the same order
|
||||
*
|
||||
* @includeFunctionBody ../../test/collections/MapTest.kt createLinkedMap
|
||||
*/
|
||||
public fun <K, V> linkedMapOf(vararg values: Pair<K, V>): LinkedHashMap<K, V> {
|
||||
val answer = LinkedHashMap<K, V>(values.size())
|
||||
answer.putAll(*values)
|
||||
return answer
|
||||
}
|
||||
|
||||
/** Returns the [[Map]] if its not null otherwise it returns the empty [[Map]] */
|
||||
public fun <K,V> Map<K,V>?.orEmpty() : Map<K,V>
|
||||
= if (this != null) this else stdlib_emptyMap()
|
||||
= if (this != null) this else emptyMap()
|
||||
|
||||
public fun <K,V> Map<K,V>.contains(key : K) : Boolean = containsKey(key)
|
||||
|
||||
@@ -39,8 +87,8 @@ public fun <K, V> Map.Entry<K, V>.toPair(): Pair<K, V> {
|
||||
* @includeFunctionBody ../../test/collections/MapTest.kt getOrElse
|
||||
*/
|
||||
public inline fun <K, V> Map<K, V>.getOrElse(key: K, defaultValue: () -> V): V {
|
||||
if (this.containsKey(key)) {
|
||||
return this.get(key) as V
|
||||
if (containsKey(key)) {
|
||||
return get(key) as V
|
||||
} else {
|
||||
return defaultValue()
|
||||
}
|
||||
@@ -52,11 +100,11 @@ public inline fun <K, V> Map<K, V>.getOrElse(key: K, defaultValue: () -> V): V {
|
||||
* @includeFunctionBody ../../test/collections/MapTest.kt getOrPut
|
||||
*/
|
||||
public inline fun <K, V> MutableMap<K, V>.getOrPut(key: K, defaultValue: () -> V): V {
|
||||
if (this.containsKey(key)) {
|
||||
return this.get(key) as V
|
||||
if (containsKey(key)) {
|
||||
return get(key) as V
|
||||
} else {
|
||||
val answer = defaultValue()
|
||||
this.put(key, answer)
|
||||
put(key, answer)
|
||||
return answer
|
||||
}
|
||||
}
|
||||
@@ -67,7 +115,7 @@ public inline fun <K, V> MutableMap<K, V>.getOrPut(key: K, defaultValue: () -> V
|
||||
* @includeFunctionBody ../../test/collections/MapTest.kt iterateWithProperties
|
||||
*/
|
||||
public fun <K, V> Map<K, V>.iterator(): Iterator<Map.Entry<K, V>> {
|
||||
val entrySet = this.entrySet()
|
||||
val entrySet = entrySet()
|
||||
return entrySet.iterator()
|
||||
}
|
||||
|
||||
@@ -117,7 +165,7 @@ public fun <K, V> MutableMap<K, V>.putAll(values: Iterable<Pair<K,V>>): Unit {
|
||||
* @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> {
|
||||
return mapValuesTo(LinkedHashMap<K, R>(this.size), transform)
|
||||
return mapValuesTo(LinkedHashMap<K, R>(size()), transform)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -126,7 +174,7 @@ public inline fun <K, V, R> Map<K, V>.mapValues(transform: (Map.Entry<K, V>) ->
|
||||
* @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(LinkedHashMap<R, V>(this.size), transform)
|
||||
return mapKeysTo(LinkedHashMap<R, V>(size()), transform)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -211,3 +259,8 @@ public fun <K, V> Iterable<Pair<K, V>>.toMap(): Map<K, V> {
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts this [Map] to a [LinkedHashMap] so future insertion orders are maintained
|
||||
*/
|
||||
public fun <K, V> Map<K, V>.toLinkedMap(): MutableMap<K, V> = LinkedHashMap(this)
|
||||
|
||||
@@ -6,16 +6,9 @@ import java.util.SortedMap
|
||||
import java.util.TreeMap
|
||||
import java.util.Properties
|
||||
|
||||
// Map APIs
|
||||
|
||||
// Move back to Maps.kt after KT-2093 will be fixed
|
||||
/** Provides [] access to maps */
|
||||
public fun <K, V> MutableMap<K, V>.set(key: K, value: V): V? = this.put(key, value)
|
||||
|
||||
/**
|
||||
* Converts this [[Map]] to a [[LinkedHashMap]] so future insertion orders are maintained
|
||||
*/
|
||||
public fun <K, V> Map<K, V>.toLinkedMap(): LinkedHashMap<K, V> = LinkedHashMap(this)
|
||||
/** Provides indexed write access to mutable maps */
|
||||
// this code is JVM-specific, because JS has native set function
|
||||
public fun <K, V> MutableMap<K, V>.set(key: K, value: V): V? = put(key, value)
|
||||
|
||||
/**
|
||||
* Converts this [[Map]] to a [[SortedMap]] so iteration order will be in key order
|
||||
@@ -36,6 +29,25 @@ public fun <K, V> Map<K, V>.toSortedMap(comparator: Comparator<K>): SortedMap<K,
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new [[SortedMap]] populated with the given pairs where the first value in each pair
|
||||
* is the key and the second value is the value
|
||||
*
|
||||
* @includeFunctionBody ../../test/collections/MapTest.kt createSortedMap
|
||||
*/
|
||||
public fun <K, V> sortedMapOf(vararg values: Pair<K, V>): SortedMap<K, V> {
|
||||
val answer = TreeMap<K, V>()
|
||||
/**
|
||||
TODO replace by this simpler call when we can pass vararg values into other methods
|
||||
answer.putAll(values)
|
||||
*/
|
||||
for (v in values) {
|
||||
answer.put(v.first, v.second)
|
||||
}
|
||||
return answer
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts this [[Map]] to a [[Properties]] object
|
||||
*
|
||||
|
||||
@@ -192,8 +192,8 @@ class ArraysTest {
|
||||
assertEquals(listOf("B"), array("A", "B", "C").slice(1..1))
|
||||
assertEquals(listOf('E', 'B', 'C'), array('A', 'B', 'C', 'E').slice(iter))
|
||||
|
||||
assertTrue(array<Int>().slice(5..4).none())
|
||||
assertTrue(array(1, 2, 3).slice(5..1).none())
|
||||
assertEquals(listOf<Int>(), array<Int>().slice(5..4))
|
||||
assertEquals(listOf<Int>(), array(1, 2, 3).slice(5..1))
|
||||
assertEquals(listOf(2, 3, 9), array(2, 3, 9, 2, 3, 9).slice(iter))
|
||||
assertEquals(listOf(2.0, 3.0), array(2.0, 3.0, 9.0).slice(0..1))
|
||||
assertEquals(listOf(2f, 3f), array(2f, 3f, 9f).slice(0..1))
|
||||
|
||||
Reference in New Issue
Block a user