diff --git a/compiler/testData/resolvedCalls/arguments/realExamples/emptyList.kt b/compiler/testData/resolvedCalls/arguments/realExamples/emptyList.kt index efbcfff5fd4..cbac1d85aee 100644 --- a/compiler/testData/resolvedCalls/arguments/realExamples/emptyList.kt +++ b/compiler/testData/resolvedCalls/arguments/realExamples/emptyList.kt @@ -2,8 +2,8 @@ class A {} fun foo(t: T) {} -fun emptyList(): List = throw Exception() +fun someList(): List = throw Exception() fun bar() { - foo(emptyList()) + foo(someList()) } \ No newline at end of file diff --git a/compiler/testData/resolvedCalls/arguments/realExamples/emptyList.txt b/compiler/testData/resolvedCalls/arguments/realExamples/emptyList.txt index 5f789485d03..24203fd1e26 100644 --- a/compiler/testData/resolvedCalls/arguments/realExamples/emptyList.txt +++ b/compiler/testData/resolvedCalls/arguments/realExamples/emptyList.txt @@ -2,10 +2,10 @@ class A {} fun foo(t: T) {} -fun emptyList(): List = throw Exception() +fun someList(): List = throw Exception() fun bar() { - foo(emptyList()) + 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() diff --git a/compiler/testData/resolvedCalls/arguments/realExamples/emptyMutableList.kt b/compiler/testData/resolvedCalls/arguments/realExamples/emptyMutableList.kt index 2fdc1eba65f..06b616cdf3c 100644 --- a/compiler/testData/resolvedCalls/arguments/realExamples/emptyMutableList.kt +++ b/compiler/testData/resolvedCalls/arguments/realExamples/emptyMutableList.kt @@ -2,8 +2,8 @@ class A {} fun foo(t: T) {} -fun emptyList(): MutableList = throw Exception() +fun someList(): MutableList = throw Exception() fun bar() { - foo(emptyList()) + foo(someList()) } \ No newline at end of file diff --git a/compiler/testData/resolvedCalls/arguments/realExamples/emptyMutableList.txt b/compiler/testData/resolvedCalls/arguments/realExamples/emptyMutableList.txt index 222dd13a0c7..6537d71ccba 100644 --- a/compiler/testData/resolvedCalls/arguments/realExamples/emptyMutableList.txt +++ b/compiler/testData/resolvedCalls/arguments/realExamples/emptyMutableList.txt @@ -2,10 +2,10 @@ class A {} fun foo(t: T) {} -fun emptyList(): MutableList = throw Exception() +fun someList(): MutableList = throw Exception() fun bar() { - foo(emptyList()) + 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() diff --git a/compiler/testData/resolvedCalls/resolve/mostSpecificUninferredParam.kt b/compiler/testData/resolvedCalls/resolve/mostSpecificUninferredParam.kt index 1bee99680d1..49f4f0d6465 100644 --- a/compiler/testData/resolvedCalls/resolve/mostSpecificUninferredParam.kt +++ b/compiler/testData/resolvedCalls/resolve/mostSpecificUninferredParam.kt @@ -1,8 +1,8 @@ -fun emptyList(): List = throw Exception() +fun someList(): List = throw Exception() fun doSmth(l: List) {} fun doSmth(a: Any) {} fun bar() { - doSmth(emptyList()) + doSmth(someList()) } \ No newline at end of file diff --git a/compiler/testData/resolvedCalls/resolve/mostSpecificUninferredParam.txt b/compiler/testData/resolvedCalls/resolve/mostSpecificUninferredParam.txt index 40c5b409ad3..8f00c409342 100644 --- a/compiler/testData/resolvedCalls/resolve/mostSpecificUninferredParam.txt +++ b/compiler/testData/resolvedCalls/resolve/mostSpecificUninferredParam.txt @@ -1,10 +1,10 @@ -fun emptyList(): List = throw Exception() +fun someList(): List = throw Exception() fun doSmth(l: List) {} fun doSmth(a: Any) {} fun bar() { - doSmth(emptyList()) + 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() diff --git a/j2k/tests/testData/fileOrElement/methodCallExpression/collectionsMethods2.kt b/j2k/tests/testData/fileOrElement/methodCallExpression/collectionsMethods2.kt index ccc9c1635e0..71ff9210fb1 100644 --- a/j2k/tests/testData/fileOrElement/methodCallExpression/collectionsMethods2.kt +++ b/j2k/tests/testData/fileOrElement/methodCallExpression/collectionsMethods2.kt @@ -1,5 +1,5 @@ // ERROR: Too many arguments for public fun listOf(): kotlin.List defined in kotlin -// ERROR: Null can not be a value of a non-null type kotlin.String +// ERROR: Too many arguments for public fun setOf(): kotlin.Set defined in kotlin import java.util.* class A { diff --git a/libraries/stdlib/src/kotlin/Deprecated.kt b/libraries/stdlib/src/kotlin/Deprecated.kt index e8f0328af0f..e823aa72140 100644 --- a/libraries/stdlib/src/kotlin/Deprecated.kt +++ b/libraries/stdlib/src/kotlin/Deprecated.kt @@ -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() diff --git a/libraries/stdlib/src/kotlin/collections/JUtil.kt b/libraries/stdlib/src/kotlin/collections/JUtil.kt index 148820a3380..b1b9a57a97f 100644 --- a/libraries/stdlib/src/kotlin/collections/JUtil.kt +++ b/libraries/stdlib/src/kotlin/collections/JUtil.kt @@ -2,28 +2,52 @@ package kotlin import java.util.* -private class stdlib_emptyListClass : List by ArrayList() {} -private val stdlib_emptyList : List = stdlib_emptyListClass() -private fun stdlib_emptyList() = stdlib_emptyList as List +private object EmptyList : List { + private val list = ArrayList() -private class stdlib_emptyMapClass : Map by HashMap() {} -private val stdlib_emptyMap : Map = stdlib_emptyMapClass() -private fun stdlib_emptyMap() = stdlib_emptyMap as Map + override fun contains(o: Any?): Boolean = list.contains(o) + override fun containsAll(c: Collection): 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 = list.iterator() + override fun lastIndexOf(o: Any?): Int = list.lastIndexOf(o) + override fun listIterator(): ListIterator = list.listIterator() + override fun listIterator(index: Int): ListIterator =list.listIterator(index) + override fun size(): Int = list.size() + override fun subList(fromIndex: Int, toIndex: Int): List = 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 { + private val set = HashSet() + + override fun contains(o: Any?): Boolean = set.contains(o) + override fun containsAll(c: Collection): Boolean = set.containsAll(c) + override fun isEmpty(): Boolean = set.isEmpty() + override fun iterator(): Iterator = 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(): List = EmptyList as List +public fun emptySet(): Set = EmptySet as Set /** Returns a new read-only list of given elements */ -public fun listOf(vararg values: T): List = if (values.size() == 0) stdlib_emptyList() else arrayListOf(*values) +public fun listOf(vararg values: T): List = if (values.size() == 0) emptyList() else arrayListOf(*values) -/** Returns an empty list */ -public fun listOf(): List = stdlib_emptyList() +/** Returns an empty read-only list */ +public fun listOf(): List = 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(vararg values: Pair): Map = if (values.size() == 0) stdlib_emptyMap() else linkedMapOf(*values) +/** Returns a new read-only ordered set of given elements */ +public fun setOf(vararg values: T): Set = if (values.size() == 0) emptySet() else values.toCollection(LinkedHashSet()) -/** Returns an empty read-only map */ -public fun mapOf(): Map = stdlib_emptyMap() - -/** Returns a new read-only set of given elements */ -public fun setOf(vararg values: T): Set = values.toCollection(LinkedHashSet()) +/** Returns an empty read-only set */ +public fun setOf(): Set = emptySet() /** Returns a new LinkedList with a variable number of initial elements */ public fun linkedListOf(vararg values: T): LinkedList = values.toCollection(LinkedList()) @@ -34,30 +58,8 @@ public fun arrayListOf(vararg values: T): ArrayList = values.toCollection( /** Returns a new HashSet with a variable number of initial elements */ public fun hashSetOf(vararg values: T): HashSet = 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 hashMapOf(vararg values: Pair): HashMap { - val answer = HashMap(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 linkedMapOf(vararg values: Pair): LinkedHashMap { - val answer = LinkedHashMap(values.size()) - answer.putAll(*values) - return answer -} +/** Returns a new LinkedHashSet with a variable number of initial elements */ +public fun linkedSetOf(vararg values: T): HashSet = 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 List.lastIndex: Int get() = this.size() - 1 - /** Returns true if the collection is not empty */ -public fun Collection.isNotEmpty(): Boolean = !this.isEmpty() - -/** Returns true if this collection is not empty */ -public val Collection<*>.notEmpty: Boolean - get() = isNotEmpty() +public fun Collection.isNotEmpty(): Boolean = !isEmpty() /** Returns the Collection if its not null otherwise it returns the empty list */ -public fun Collection?.orEmpty(): Collection = this ?: stdlib_emptyList() - -// List APIs +public fun Collection?.orEmpty(): Collection = this ?: emptyList() /** Returns the List if its not null otherwise returns the empty list */ -public fun List?.orEmpty(): List = this ?: stdlib_emptyList() +public fun List?.orEmpty(): List = this ?: emptyList() + +/** Returns the List if its not null otherwise returns the empty list */ +public fun Set?.orEmpty(): Set = this ?: emptySet() diff --git a/libraries/stdlib/src/kotlin/collections/JUtilJVM.kt b/libraries/stdlib/src/kotlin/collections/JUtilJVM.kt index 8245598c8d3..9a235628fef 100644 --- a/libraries/stdlib/src/kotlin/collections/JUtilJVM.kt +++ b/libraries/stdlib/src/kotlin/collections/JUtilJVM.kt @@ -12,29 +12,6 @@ public fun sortedSetOf(vararg values: T): TreeSet = values.toCollection(Tr */ public fun sortedSetOf(comparator: Comparator, vararg values: T): TreeSet = values.toCollection(TreeSet(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 sortedMapOf(vararg values: Pair): SortedMap { - val answer = TreeMap() - /** - 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 Set?.orEmpty(): Set - = if (this != null) this else Collections.EMPTY_SET as Set - - /** * Returns a list containing the elements returned by the * specified enumeration in the order they are returned by the diff --git a/libraries/stdlib/src/kotlin/collections/Maps.kt b/libraries/stdlib/src/kotlin/collections/Maps.kt index 2fa56f12e56..5e60312bba3 100644 --- a/libraries/stdlib/src/kotlin/collections/Maps.kt +++ b/libraries/stdlib/src/kotlin/collections/Maps.kt @@ -2,11 +2,59 @@ package kotlin import java.util.* -// Map APIs +private object EmptyMap : Map { + private val map = HashMap() + + override fun containsKey(key: Any?): Boolean = map.containsKey(key) + override fun containsValue(value: Any?): Boolean = map.containsValue(value) + override fun entrySet(): Set> = map.entrySet() + override fun get(key: Any?): Any? = map.get(key) + override fun keySet(): Set = map.keySet() + override fun values(): Collection = 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(): Map = EmptyMap as Map + +/** Returns a new read-only map of given pairs, where the first value is the key, and the second is value */ +public fun mapOf(vararg values: Pair): Map = if (values.size() == 0) emptyMap() else linkedMapOf(*values) + +/** Returns an empty read-only map */ +public fun mapOf(): Map = 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 hashMapOf(vararg values: Pair): HashMap { + val answer = HashMap(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 linkedMapOf(vararg values: Pair): LinkedHashMap { + val answer = LinkedHashMap(values.size()) + answer.putAll(*values) + return answer +} /** Returns the [[Map]] if its not null otherwise it returns the empty [[Map]] */ public fun Map?.orEmpty() : Map - = if (this != null) this else stdlib_emptyMap() + = if (this != null) this else emptyMap() public fun Map.contains(key : K) : Boolean = containsKey(key) @@ -39,8 +87,8 @@ public fun Map.Entry.toPair(): Pair { * @includeFunctionBody ../../test/collections/MapTest.kt getOrElse */ public inline fun Map.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 Map.getOrElse(key: K, defaultValue: () -> V): V { * @includeFunctionBody ../../test/collections/MapTest.kt getOrPut */ public inline fun MutableMap.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 MutableMap.getOrPut(key: K, defaultValue: () -> V * @includeFunctionBody ../../test/collections/MapTest.kt iterateWithProperties */ public fun Map.iterator(): Iterator> { - val entrySet = this.entrySet() + val entrySet = entrySet() return entrySet.iterator() } @@ -117,7 +165,7 @@ public fun MutableMap.putAll(values: Iterable>): Unit { * @includeFunctionBody ../../test/collections/MapTest.kt mapValues */ public inline fun Map.mapValues(transform: (Map.Entry) -> R): Map { - return mapValuesTo(LinkedHashMap(this.size), transform) + return mapValuesTo(LinkedHashMap(size()), transform) } /** @@ -126,7 +174,7 @@ public inline fun Map.mapValues(transform: (Map.Entry) -> * @includeFunctionBody ../../test/collections/MapTest.kt mapKeys */ public inline fun Map.mapKeys(transform: (Map.Entry) -> R): Map { - return mapKeysTo(LinkedHashMap(this.size), transform) + return mapKeysTo(LinkedHashMap(size()), transform) } /** @@ -211,3 +259,8 @@ public fun Iterable>.toMap(): Map { } return result } + +/** + * Converts this [Map] to a [LinkedHashMap] so future insertion orders are maintained + */ +public fun Map.toLinkedMap(): MutableMap = LinkedHashMap(this) diff --git a/libraries/stdlib/src/kotlin/collections/MapsJVM.kt b/libraries/stdlib/src/kotlin/collections/MapsJVM.kt index f4ae05cd51f..41fad88f2bd 100644 --- a/libraries/stdlib/src/kotlin/collections/MapsJVM.kt +++ b/libraries/stdlib/src/kotlin/collections/MapsJVM.kt @@ -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 MutableMap.set(key: K, value: V): V? = this.put(key, value) - -/** - * Converts this [[Map]] to a [[LinkedHashMap]] so future insertion orders are maintained - */ -public fun Map.toLinkedMap(): LinkedHashMap = LinkedHashMap(this) +/** Provides indexed write access to mutable maps */ +// this code is JVM-specific, because JS has native set function +public fun MutableMap.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 Map.toSortedMap(comparator: Comparator): SortedMap sortedMapOf(vararg values: Pair): SortedMap { + val answer = TreeMap() + /** + 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 * diff --git a/libraries/stdlib/test/collections/ArraysTest.kt b/libraries/stdlib/test/collections/ArraysTest.kt index c05ecf1d6cd..9687f90ae3a 100644 --- a/libraries/stdlib/test/collections/ArraysTest.kt +++ b/libraries/stdlib/test/collections/ArraysTest.kt @@ -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().slice(5..4).none()) - assertTrue(array(1, 2, 3).slice(5..1).none()) + assertEquals(listOf(), array().slice(5..4)) + assertEquals(listOf(), 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))