diff --git a/libraries/stdlib/src/generated/_Strings.kt b/libraries/stdlib/src/generated/_Strings.kt index f6dd7054999..2913ca4a837 100644 --- a/libraries/stdlib/src/generated/_Strings.kt +++ b/libraries/stdlib/src/generated/_Strings.kt @@ -19,6 +19,14 @@ public fun CharSequence.elementAt(index: Int): Char { return get(index) } +/** + * Returns an element at the given [index] or throws an [IndexOutOfBoundsException] if the [index] is out of bounds of this collection. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public fun String.elementAt(index: Int): Char { + return get(index) +} + /** * Returns an element at the given [index] or the result of calling the [defaultValue] function if the [index] is out of bounds of this collection. */ @@ -26,6 +34,14 @@ public inline fun CharSequence.elementAtOrElse(index: Int, defaultValue: (Int) - return if (index >= 0 && index <= lastIndex) get(index) else defaultValue(index) } +/** + * Returns an element at the given [index] or the result of calling the [defaultValue] function if the [index] is out of bounds of this collection. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.elementAtOrElse(index: Int, defaultValue: (Int) -> Char): Char { + return if (index >= 0 && index <= lastIndex) get(index) else defaultValue(index) +} + /** * Returns an element at the given [index] or `null` if the [index] is out of bounds of this collection. */ @@ -33,6 +49,14 @@ public fun CharSequence.elementAtOrNull(index: Int): Char? { return if (index >= 0 && index <= lastIndex) get(index) else null } +/** + * Returns an element at the given [index] or `null` if the [index] is out of bounds of this collection. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public fun String.elementAtOrNull(index: Int): Char? { + return if (index >= 0 && index <= lastIndex) get(index) else null +} + /** * Returns the first character matching the given [predicate], or `null` if character was not found. */ @@ -40,6 +64,14 @@ public inline fun CharSequence.find(predicate: (Char) -> Boolean): Char? { return firstOrNull(predicate) } +/** + * Returns the first element matching the given [predicate], or `null` if element was not found. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.find(predicate: (Char) -> Boolean): Char? { + return firstOrNull(predicate) +} + /** * Returns the last character matching the given [predicate], or `null` if no such character was found. */ @@ -47,6 +79,14 @@ public inline fun CharSequence.findLast(predicate: (Char) -> Boolean): Char? { return lastOrNull(predicate) } +/** + * Returns the last element matching the given [predicate], or `null` if no such element was found. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.findLast(predicate: (Char) -> Boolean): Char? { + return lastOrNull(predicate) +} + /** * Returns first character. * @throws [NoSuchElementException] if the CharSequence is empty. @@ -57,6 +97,17 @@ public fun CharSequence.first(): Char { return this[0] } +/** + * Returns first element. + * @throws [NoSuchElementException] if the collection is empty. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public fun String.first(): Char { + if (isEmpty()) + throw NoSuchElementException("Collection is empty.") + return this[0] +} + /** * Returns the first character matching the given [predicate]. * @throws [NoSuchElementException] if no such character is found. @@ -66,6 +117,16 @@ public inline fun CharSequence.first(predicate: (Char) -> Boolean): Char { throw NoSuchElementException("No element matching predicate was found.") } +/** + * Returns the first element matching the given [predicate]. + * @throws [NoSuchElementException] if no such element is found. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.first(predicate: (Char) -> Boolean): Char { + for (element in this) if (predicate(element)) return element + throw NoSuchElementException("No element matching predicate was found.") +} + /** * Returns the first character, or `null` if CharSequence is empty. */ @@ -73,6 +134,14 @@ public fun CharSequence.firstOrNull(): Char? { return if (isEmpty()) null else this[0] } +/** + * Returns the first element, or `null` if the collection is empty. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public fun String.firstOrNull(): Char? { + return if (isEmpty()) null else this[0] +} + /** * Returns the first character matching the given [predicate], or `null` if character was not found. */ @@ -81,6 +150,15 @@ public inline fun CharSequence.firstOrNull(predicate: (Char) -> Boolean): Char? return null } +/** + * Returns the first element matching the given [predicate], or `null` if element was not found. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.firstOrNull(predicate: (Char) -> Boolean): Char? { + for (element in this) if (predicate(element)) return element + return null +} + /** * Returns an element at the given [index] or the result of calling the [defaultValue] function if the [index] is out of bounds of this collection. */ @@ -88,6 +166,14 @@ public inline fun CharSequence.getOrElse(index: Int, defaultValue: (Int) -> Char return if (index >= 0 && index <= lastIndex) get(index) else defaultValue(index) } +/** + * Returns an element at the given [index] or the result of calling the [defaultValue] function if the [index] is out of bounds of this collection. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.getOrElse(index: Int, defaultValue: (Int) -> Char): Char { + return if (index >= 0 && index <= lastIndex) get(index) else defaultValue(index) +} + /** * Returns an element at the given [index] or `null` if the [index] is out of bounds of this collection. */ @@ -95,6 +181,14 @@ public fun CharSequence.getOrNull(index: Int): Char? { return if (index >= 0 && index <= lastIndex) get(index) else null } +/** + * Returns an element at the given [index] or `null` if the [index] is out of bounds of this collection. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public fun String.getOrNull(index: Int): Char? { + return if (index >= 0 && index <= lastIndex) get(index) else null +} + /** * Returns index of the first element matching the given [predicate], or -1 if the collection does not contain such element. */ @@ -107,6 +201,19 @@ public inline fun CharSequence.indexOfFirst(predicate: (Char) -> Boolean): Int { return -1 } +/** + * Returns index of the first element matching the given [predicate], or -1 if the collection does not contain such element. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.indexOfFirst(predicate: (Char) -> Boolean): Int { + for (index in indices) { + if (predicate(this[index])) { + return index + } + } + return -1 +} + /** * Returns index of the last element matching the given [predicate], or -1 if the collection does not contain such element. */ @@ -119,6 +226,19 @@ public inline fun CharSequence.indexOfLast(predicate: (Char) -> Boolean): Int { return -1 } +/** + * Returns index of the last element matching the given [predicate], or -1 if the collection does not contain such element. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.indexOfLast(predicate: (Char) -> Boolean): Int { + for (index in indices.reversed()) { + if (predicate(this[index])) { + return index + } + } + return -1 +} + /** * "Returns the last character. * @throws [NoSuchElementException] if the string is empty. @@ -129,6 +249,17 @@ public fun CharSequence.last(): Char { return this[lastIndex] } +/** + * Returns the last element. + * @throws [NoSuchElementException] if the collection is empty. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public fun String.last(): Char { + if (isEmpty()) + throw NoSuchElementException("Collection is empty.") + return this[lastIndex] +} + /** * "Returns the last character matching the given [predicate]. * @throws [NoSuchElementException] if no such character is found. @@ -146,6 +277,24 @@ public inline fun CharSequence.last(predicate: (Char) -> Boolean): Char { return last as Char } +/** + * Returns the last element matching the given [predicate]. + * @throws [NoSuchElementException] if no such element is found. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.last(predicate: (Char) -> Boolean): Char { + var last: Char? = null + var found = false + for (element in this) { + if (predicate(element)) { + last = element + found = true + } + } + if (!found) throw NoSuchElementException("Collection doesn't contain any element matching the predicate.") + return last as Char +} + /** * Returns the last character, or `null` if the string is empty. */ @@ -153,6 +302,14 @@ public fun CharSequence.lastOrNull(): Char? { return if (isEmpty()) null else this[length() - 1] } +/** + * Returns the last element, or `null` if the collection is empty. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public fun String.lastOrNull(): Char? { + return if (isEmpty()) null else this[length() - 1] +} + /** * Returns the last character matching the given [predicate], or `null` if no such character was found. */ @@ -166,6 +323,20 @@ public inline fun CharSequence.lastOrNull(predicate: (Char) -> Boolean): Char? { return last } +/** + * Returns the last element matching the given [predicate], or `null` if no such element was found. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.lastOrNull(predicate: (Char) -> Boolean): Char? { + var last: Char? = null + for (element in this) { + if (predicate(element)) { + last = element + } + } + return last +} + /** * Returns the single character, or throws an exception if the string is empty or has more than one character. */ @@ -177,6 +348,18 @@ public fun CharSequence.single(): Char { } } +/** + * Returns the single element, or throws an exception if the collection is empty or has more than one element. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public fun String.single(): Char { + return when (length()) { + 0 -> throw NoSuchElementException("Collection is empty.") + 1 -> this[0] + else -> throw IllegalArgumentException("Collection has more than one element.") + } +} + /** * Returns the single character matching the given [predicate], or throws exception if there is no or more than one matching character. */ @@ -194,6 +377,24 @@ public inline fun CharSequence.single(predicate: (Char) -> Boolean): Char { return single as Char } +/** + * Returns the single element matching the given [predicate], or throws exception if there is no or more than one matching element. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.single(predicate: (Char) -> Boolean): Char { + var single: Char? = null + var found = false + for (element in this) { + if (predicate(element)) { + if (found) throw IllegalArgumentException("Collection contains more than one matching element.") + single = element + found = true + } + } + if (!found) throw NoSuchElementException("Collection doesn't contain any element matching predicate.") + return single as Char +} + /** * Returns the single character, or `null` if the string is empty or has more than one character. */ @@ -201,6 +402,14 @@ public fun CharSequence.singleOrNull(): Char? { return if (length() == 1) this[0] else null } +/** + * Returns single element, or `null` if the collection is empty or has more than one element. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public fun String.singleOrNull(): Char? { + return if (length() == 1) this[0] else null +} + /** * Returns the single character matching the given [predicate], or `null` if character was not found or more than one character was found. */ @@ -218,6 +427,24 @@ public inline fun CharSequence.singleOrNull(predicate: (Char) -> Boolean): Char? return single } +/** + * Returns the single element matching the given [predicate], or `null` if element was not found or more than one element was found. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.singleOrNull(predicate: (Char) -> Boolean): Char? { + var single: Char? = null + var found = false + for (element in this) { + if (predicate(element)) { + if (found) return null + single = element + found = true + } + } + if (!found) return null + return single +} + /** * Returns a string with the first [n] characters removed. */ @@ -225,6 +452,14 @@ public fun CharSequence.drop(n: Int): String { return substring(Math.min(n, length())) } +/** + * Returns a list containing all elements except first [n] elements. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public fun String.drop(n: Int): String { + return substring(Math.min(n, length())) +} + /** * Returns a string with the last [n] characters removed. */ @@ -233,6 +468,15 @@ public fun CharSequence.dropLast(n: Int): String { return take((length() - n).coerceAtLeast(0)) } +/** + * Returns a list containing all elements except last [n] elements. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public fun String.dropLast(n: Int): String { + require(n >= 0, { "Requested character count $n is less than zero." }) + return take((length() - n).coerceAtLeast(0)) +} + /** * Returns a string containing all characters except last characters that satisfy the given [predicate]. */ @@ -240,6 +484,14 @@ public inline fun CharSequence.dropLastWhile(predicate: (Char) -> Boolean): Stri return trimEnd(predicate) } +/** + * Returns a list containing all elements except last elements that satisfy the given [predicate]. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.dropLastWhile(predicate: (Char) -> Boolean): String { + return trimEnd(predicate) +} + /** * Returns a string containing all characters except first characters that satisfy the given [predicate]. */ @@ -247,6 +499,14 @@ public inline fun CharSequence.dropWhile(predicate: (Char) -> Boolean): String { return trimStart(predicate) } +/** + * Returns a list containing all elements except first elements that satisfy the given [predicate]. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.dropWhile(predicate: (Char) -> Boolean): String { + return trimStart(predicate) +} + /** * Returns a string containing only those characters from the original string that match the given [predicate]. */ @@ -254,6 +514,14 @@ public inline fun CharSequence.filter(predicate: (Char) -> Boolean): String { return filterTo(StringBuilder(), predicate).toString() } +/** + * Returns a list containing all elements matching the given [predicate]. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.filter(predicate: (Char) -> Boolean): String { + return filterTo(StringBuilder(), predicate).toString() +} + /** * Returns a string containing only those characters from the original string that do not match the given [predicate]. */ @@ -261,6 +529,14 @@ public inline fun CharSequence.filterNot(predicate: (Char) -> Boolean): String { return filterNotTo(StringBuilder(), predicate).toString() } +/** + * Returns a list containing all elements not matching the given [predicate]. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.filterNot(predicate: (Char) -> Boolean): String { + return filterNotTo(StringBuilder(), predicate).toString() +} + /** * Appends all characters not matching the given [predicate] to the given [destination]. */ @@ -269,6 +545,15 @@ public inline fun CharSequence.filterNotTo(destination: C, pred return destination } +/** + * Appends all elements not matching the given [predicate] to the given [destination]. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.filterNotTo(destination: C, predicate: (Char) -> Boolean): C { + for (element in this) if (!predicate(element)) destination.append(element) + return destination +} + /** * Appends all characters matching the given [predicate] to the given [destination]. */ @@ -280,6 +565,18 @@ public inline fun CharSequence.filterTo(destination: C, predica return destination } +/** + * Appends all elements matching the given [predicate] into the given [destination]. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.filterTo(destination: C, predicate: (Char) -> Boolean): C { + for (index in 0..length() - 1) { + val element = get(index) + if (predicate(element)) destination.append(element) + } + return destination +} + /** * Returns a string containing characters at indices at the specified [indices]. */ @@ -309,6 +606,15 @@ public fun CharSequence.take(n: Int): String { return substring(0, Math.min(n, length())) } +/** + * Returns a list containing first [n] elements. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public fun String.take(n: Int): String { + require(n >= 0, { "Requested character count $n is less than zero." }) + return substring(0, Math.min(n, length())) +} + /** * Returns a string containing the last [n] characters from this string, or the entire string if this string is shorter. */ @@ -318,6 +624,16 @@ public fun CharSequence.takeLast(n: Int): String { return substring(length - Math.min(n, length), length) } +/** + * Returns a list containing last [n] elements. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public fun String.takeLast(n: Int): String { + require(n >= 0, { "Requested character count $n is less than zero." }) + val length = length() + return substring(length - Math.min(n, length), length) +} + /** * Returns a string containing last characters that satisfy the given [predicate]. */ @@ -330,6 +646,19 @@ public inline fun CharSequence.takeLastWhile(predicate: (Char) -> Boolean): Stri return this.toString() } +/** + * Returns a list containing last elements satisfying the given [predicate]. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.takeLastWhile(predicate: (Char) -> Boolean): String { + for (index in lastIndex downTo 0) { + if (!predicate(this[index])) { + return substring(index + 1) + } + } + return this.toString() +} + /** * Returns a string containing the first characters that satisfy the given [predicate]. */ @@ -341,6 +670,18 @@ public inline fun CharSequence.takeWhile(predicate: (Char) -> Boolean): String { return this.toString() } +/** + * Returns a list containing first elements satisfying the given [predicate]. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.takeWhile(predicate: (Char) -> Boolean): String { + for (index in 0..length() - 1) + if (!predicate(get(index))) { + return substring(0, index) + } + return this.toString() +} + /** * Returns a string with characters in reversed order. */ @@ -348,6 +689,14 @@ public fun CharSequence.reversed(): String { return StringBuilder().append(this).reverse().toString() } +/** + * Returns a list with elements in reversed order. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public fun String.reversed(): String { + return StringBuilder().append(this).reverse().toString() +} + /** * Returns an [ArrayList] of all elements. */ @@ -355,6 +704,14 @@ public fun CharSequence.toArrayList(): ArrayList { return toCollection(ArrayList(length())) } +/** + * Returns an [ArrayList] of all elements. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public fun String.toArrayList(): ArrayList { + return toCollection(ArrayList(length())) +} + /** * Appends all elements to the given [collection]. */ @@ -365,6 +722,17 @@ public fun > CharSequence.toCollection(collection return collection } +/** + * Appends all elements to the given [collection]. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public fun > String.toCollection(collection: C): C { + for (item in this) { + collection.add(item) + } + return collection +} + /** * Returns a [HashSet] of all elements. */ @@ -372,6 +740,14 @@ public fun CharSequence.toHashSet(): HashSet { return toCollection(HashSet(mapCapacity(length()))) } +/** + * Returns a [HashSet] of all elements. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public fun String.toHashSet(): HashSet { + return toCollection(HashSet(mapCapacity(length()))) +} + /** * Returns a [LinkedList] containing all elements. */ @@ -387,11 +763,24 @@ public fun CharSequence.toList(): List { return this.toArrayList() } +/** + * Returns a [List] containing all elements. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public fun String.toList(): List { + return this.toArrayList() +} + @Deprecated("Use toMapBy instead.", ReplaceWith("toMapBy(selector)")) public inline fun CharSequence.toMap(selector: (Char) -> K): Map { return toMapBy(selector) } +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.toMap(selector: (Char) -> K): Map { + return toMapBy(selector) +} + /** * Returns Map containing the values provided by [transform] and indexed by [selector] from the given collection. * If any two elements would have the same key returned by [selector] the last one gets added to the map. @@ -405,6 +794,20 @@ public inline fun CharSequence.toMap(selector: (Char) -> K, transform: (C return result } +/** + * Returns Map containing the values provided by [transform] and indexed by [selector] from the given collection. + * If any two elements would have the same key returned by [selector] the last one gets added to the map. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.toMap(selector: (Char) -> K, transform: (Char) -> V): Map { + val capacity = (length()/.75f) + 1 + val result = LinkedHashMap(Math.max(capacity.toInt(), 16)) + for (element in this) { + result.put(selector(element), transform(element)) + } + return result +} + /** * Returns Map containing the values from the given collection indexed by [selector]. * If any two elements would have the same key returned by [selector] the last one gets added to the map. @@ -418,6 +821,20 @@ public inline fun CharSequence.toMapBy(selector: (Char) -> K): Map return result } +/** + * Returns Map containing the values from the given collection indexed by [selector]. + * If any two elements would have the same key returned by [selector] the last one gets added to the map. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.toMapBy(selector: (Char) -> K): Map { + val capacity = (length()/.75f) + 1 + val result = LinkedHashMap(Math.max(capacity.toInt(), 16)) + for (element in this) { + result.put(selector(element), element) + } + return result +} + /** * Returns a [Set] of all elements. */ @@ -425,6 +842,14 @@ public fun CharSequence.toSet(): Set { return toCollection(LinkedHashSet(mapCapacity(length()))) } +/** + * Returns a [Set] of all elements. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public fun String.toSet(): Set { + return toCollection(LinkedHashSet(mapCapacity(length()))) +} + /** * Returns a [SortedSet] of all elements. */ @@ -432,6 +857,14 @@ public fun CharSequence.toSortedSet(): SortedSet { return toCollection(TreeSet()) } +/** + * Returns a [SortedSet] of all elements. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public fun String.toSortedSet(): SortedSet { + return toCollection(TreeSet()) +} + /** * Returns a single list of all elements yielded from results of [transform] function being invoked on each element of original collection. */ @@ -439,6 +872,14 @@ public inline fun CharSequence.flatMap(transform: (Char) -> Iterable): Li return flatMapTo(ArrayList(), transform) } +/** + * Returns a single list of all elements yielded from results of [transform] function being invoked on each element of original collection. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.flatMap(transform: (Char) -> Iterable): List { + return flatMapTo(ArrayList(), transform) +} + /** * Appends all elements yielded from results of [transform] function being invoked on each element of original collection, to the given [destination]. */ @@ -450,6 +891,18 @@ public inline fun > CharSequence.flatMapTo(destin return destination } +/** + * Appends all elements yielded from results of [transform] function being invoked on each element of original collection, to the given [destination]. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun > String.flatMapTo(destination: C, transform: (Char) -> Iterable): C { + for (element in this) { + val list = transform(element) + destination.addAll(list) + } + return destination +} + /** * Returns a map of the elements in original collection grouped by the result of given [toKey] function. */ @@ -457,6 +910,14 @@ public inline fun CharSequence.groupBy(toKey: (Char) -> K): Map>(), toKey) } +/** + * Returns a map of the elements in original collection grouped by the result of given [toKey] function. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.groupBy(toKey: (Char) -> K): Map> { + return groupByTo(LinkedHashMap>(), toKey) +} + /** * Appends elements from original collection grouped by the result of given [toKey] function to the given [map]. */ @@ -469,6 +930,19 @@ public inline fun CharSequence.groupByTo(map: MutableMap String.groupByTo(map: MutableMap>, toKey: (Char) -> K): Map> { + for (element in this) { + val key = toKey(element) + val list = map.getOrPut(key) { ArrayList() } + list.add(element) + } + return map +} + /** * Returns a list containing the results of applying the given [transform] function to each element of the original collection. */ @@ -476,6 +950,14 @@ public inline fun CharSequence.map(transform: (Char) -> R): List { return mapTo(ArrayList(length()), transform) } +/** + * Returns a list containing the results of applying the given [transform] function to each element of the original collection. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.map(transform: (Char) -> R): List { + return mapTo(ArrayList(length()), transform) +} + /** * Returns a list containing the results of applying the given [transform] function to each element and its index of the original collection. */ @@ -483,6 +965,14 @@ public inline fun CharSequence.mapIndexed(transform: (Int, Char) -> R): List return mapIndexedTo(ArrayList(length()), transform) } +/** + * Returns a list containing the results of applying the given [transform] function to each element and its index of the original collection. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.mapIndexed(transform: (Int, Char) -> R): List { + return mapIndexedTo(ArrayList(length()), transform) +} + /** * Appends transformed elements and their indices of the original collection using the given [transform] function * to the given [destination]. @@ -494,6 +984,18 @@ public inline fun > CharSequence.mapIndexedTo(des return destination } +/** + * Appends transformed elements and their indices of the original collection using the given [transform] function + * to the given [destination]. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun > String.mapIndexedTo(destination: C, transform: (Int, Char) -> R): C { + var index = 0 + for (item in this) + destination.add(transform(index++, item)) + return destination +} + /** * Appends transformed elements of the original collection using the given [transform] function * to the given [destination]. @@ -504,6 +1006,17 @@ public inline fun > CharSequence.mapTo(destinatio return destination } +/** + * Appends transformed elements of the original collection using the given [transform] function + * to the given [destination]. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun > String.mapTo(destination: C, transform: (Char) -> R): C { + for (item in this) + destination.add(transform(item)) + return destination +} + /** * Returns a lazy [Iterable] of [IndexedValue] for each element of the original collection. */ @@ -511,6 +1024,14 @@ public fun CharSequence.withIndex(): Iterable> { return IndexingIterable { iterator() } } +/** + * Returns a lazy [Iterable] of [IndexedValue] for each element of the original collection. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public fun String.withIndex(): Iterable> { + return IndexingIterable { iterator() } +} + /** * Returns `true` if all elements match the given [predicate]. */ @@ -519,6 +1040,15 @@ public inline fun CharSequence.all(predicate: (Char) -> Boolean): Boolean { return true } +/** + * Returns `true` if all elements match the given [predicate]. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.all(predicate: (Char) -> Boolean): Boolean { + for (element in this) if (!predicate(element)) return false + return true +} + /** * Returns `true` if collection has at least one element. */ @@ -527,6 +1057,15 @@ public fun CharSequence.any(): Boolean { return false } +/** + * Returns `true` if collection has at least one element. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public fun String.any(): Boolean { + for (element in this) return true + return false +} + /** * Returns `true` if at least one element matches the given [predicate]. */ @@ -535,6 +1074,15 @@ public inline fun CharSequence.any(predicate: (Char) -> Boolean): Boolean { return false } +/** + * Returns `true` if at least one element matches the given [predicate]. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.any(predicate: (Char) -> Boolean): Boolean { + for (element in this) if (predicate(element)) return true + return false +} + /** * Returns the length of this string. */ @@ -542,6 +1090,14 @@ public fun CharSequence.count(): Int { return length() } +/** + * Returns the number of elements in this collection. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public fun String.count(): Int { + return length() +} + /** * Returns the number of elements matching the given [predicate]. */ @@ -551,6 +1107,16 @@ public inline fun CharSequence.count(predicate: (Char) -> Boolean): Int { return count } +/** + * Returns the number of elements matching the given [predicate]. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.count(predicate: (Char) -> Boolean): Int { + var count = 0 + for (element in this) if (predicate(element)) count++ + return count +} + /** * Accumulates value starting with [initial] value and applying [operation] from left to right to current accumulator value and each element. */ @@ -560,6 +1126,16 @@ public inline fun CharSequence.fold(initial: R, operation: (R, Char) -> R): return accumulator } +/** + * Accumulates value starting with [initial] value and applying [operation] from left to right to current accumulator value and each element. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.fold(initial: R, operation: (R, Char) -> R): R { + var accumulator = initial + for (element in this) accumulator = operation(accumulator, element) + return accumulator +} + /** * Accumulates value starting with [initial] value and applying [operation] from right to left to each element and current accumulator value. */ @@ -572,6 +1148,19 @@ public inline fun CharSequence.foldRight(initial: R, operation: (Char, R) -> return accumulator } +/** + * Accumulates value starting with [initial] value and applying [operation] from right to left to each element and current accumulator value. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.foldRight(initial: R, operation: (Char, R) -> R): R { + var index = lastIndex + var accumulator = initial + while (index >= 0) { + accumulator = operation(get(index--), accumulator) + } + return accumulator +} + /** * Performs the given [operation] on each element. */ @@ -579,6 +1168,14 @@ public inline fun CharSequence.forEach(operation: (Char) -> Unit): Unit { for (element in this) operation(element) } +/** + * Performs the given [operation] on each element. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.forEach(operation: (Char) -> Unit): Unit { + for (element in this) operation(element) +} + /** * Performs the given [operation] on each element, providing sequential index with the element. */ @@ -587,6 +1184,15 @@ public inline fun CharSequence.forEachIndexed(operation: (Int, Char) -> Unit): U for (item in this) operation(index++, item) } +/** + * Performs the given [operation] on each element, providing sequential index with the element. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.forEachIndexed(operation: (Int, Char) -> Unit): Unit { + var index = 0 + for (item in this) operation(index++, item) +} + /** * Returns the largest element or `null` if there are no elements. */ @@ -600,6 +1206,20 @@ public fun CharSequence.max(): Char? { return max } +/** + * Returns the largest element or `null` if there are no elements. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public fun String.max(): Char? { + if (isEmpty()) return null + var max = this[0] + for (i in 1..lastIndex) { + val e = this[i] + if (max < e) max = e + } + return max +} + /** * Returns the first element yielding the largest value of the given function or `null` if there are no elements. */ @@ -618,6 +1238,25 @@ public inline fun > CharSequence.maxBy(f: (Char) -> R): Char? return maxElem } +/** + * Returns the first element yielding the largest value of the given function or `null` if there are no elements. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun > String.maxBy(f: (Char) -> R): Char? { + if (isEmpty()) return null + var maxElem = this[0] + var maxValue = f(maxElem) + for (i in 1..lastIndex) { + val e = this[i] + val v = f(e) + if (maxValue < v) { + maxElem = e + maxValue = v + } + } + return maxElem +} + /** * Returns the smallest element or `null` if there are no elements. */ @@ -631,6 +1270,20 @@ public fun CharSequence.min(): Char? { return min } +/** + * Returns the smallest element or `null` if there are no elements. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public fun String.min(): Char? { + if (isEmpty()) return null + var min = this[0] + for (i in 1..lastIndex) { + val e = this[i] + if (min > e) min = e + } + return min +} + /** * Returns the first element yielding the smallest value of the given function or `null` if there are no elements. */ @@ -649,6 +1302,25 @@ public inline fun > CharSequence.minBy(f: (Char) -> R): Char? return minElem } +/** + * Returns the first element yielding the smallest value of the given function or `null` if there are no elements. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun > String.minBy(f: (Char) -> R): Char? { + if (isEmpty()) return null + var minElem = this[0] + var minValue = f(minElem) + for (i in 1..lastIndex) { + val e = this[i] + val v = f(e) + if (minValue > v) { + minElem = e + minValue = v + } + } + return minElem +} + /** * Returns `true` if collection has no elements. */ @@ -657,6 +1329,15 @@ public fun CharSequence.none(): Boolean { return true } +/** + * Returns `true` if collection has no elements. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public fun String.none(): Boolean { + for (element in this) return false + return true +} + /** * Returns `true` if no elements match the given [predicate]. */ @@ -665,6 +1346,15 @@ public inline fun CharSequence.none(predicate: (Char) -> Boolean): Boolean { return true } +/** + * Returns `true` if no elements match the given [predicate]. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.none(predicate: (Char) -> Boolean): Boolean { + for (element in this) if (predicate(element)) return false + return true +} + /** * Accumulates value starting with the first element and applying [operation] from left to right to current accumulator value and each element. */ @@ -678,6 +1368,20 @@ public inline fun CharSequence.reduce(operation: (Char, Char) -> Char): Char { return accumulator } +/** + * Accumulates value starting with the first element and applying [operation] from left to right to current accumulator value and each element. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.reduce(operation: (Char, Char) -> Char): Char { + val iterator = this.iterator() + if (!iterator.hasNext()) throw UnsupportedOperationException("Empty iterable can't be reduced.") + var accumulator = iterator.next() + while (iterator.hasNext()) { + accumulator = operation(accumulator, iterator.next()) + } + return accumulator +} + /** * Accumulates value starting with last element and applying [operation] from right to left to each element and current accumulator value. */ @@ -691,6 +1395,20 @@ public inline fun CharSequence.reduceRight(operation: (Char, Char) -> Char): Cha return accumulator } +/** + * Accumulates value starting with last element and applying [operation] from right to left to each element and current accumulator value. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.reduceRight(operation: (Char, Char) -> Char): Char { + var index = lastIndex + if (index < 0) throw UnsupportedOperationException("Empty iterable can't be reduced.") + var accumulator = get(index--) + while (index >= 0) { + accumulator = operation(get(index--), accumulator) + } + return accumulator +} + /** * Returns the sum of all values produced by [transform] function from characters in the string. */ @@ -702,6 +1420,18 @@ public inline fun CharSequence.sumBy(transform: (Char) -> Int): Int { return sum } +/** + * Returns the sum of all values produced by [transform] function from elements in the collection. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.sumBy(transform: (Char) -> Int): Int { + var sum: Int = 0 + for (element in this) { + sum += transform(element) + } + return sum +} + /** * Returns the sum of all values produced by [transform] function from characters in the string. */ @@ -713,6 +1443,18 @@ public inline fun CharSequence.sumByDouble(transform: (Char) -> Double): Double return sum } +/** + * Returns the sum of all values produced by [transform] function from elements in the collection. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.sumByDouble(transform: (Char) -> Double): Double { + var sum: Double = 0.0 + for (element in this) { + sum += transform(element) + } + return sum +} + /** * Splits the original string into pair of strings, * where *first* string contains characters for which [predicate] yielded `true`, @@ -731,6 +1473,25 @@ public inline fun CharSequence.partition(predicate: (Char) -> Boolean): Pair Boolean): Pair { + val first = StringBuilder() + val second = StringBuilder() + for (element in this) { + if (predicate(element)) { + first.append(element) + } else { + second.append(element) + } + } + return Pair(first.toString(), second.toString()) +} + /** * Returns a list of pairs built from characters of both strings with same indexes. List has length of shortest collection. */ @@ -738,6 +1499,14 @@ public fun CharSequence.zip(other: String): List> { return zip(other) { c1, c2 -> c1 to c2 } } +/** + * Returns a list of pairs built from characters of both strings with same indexes. List has length of shortest collection. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public fun String.zip(other: String): List> { + return zip(other) { c1, c2 -> c1 to c2 } +} + /** * Returns a list of values built from characters of both strings with same indexes using provided [transform]. List has length of shortest string. */ @@ -750,6 +1519,19 @@ public inline fun CharSequence.zip(other: String, transform: (Char, Char) -> return list } +/** + * Returns a list of values built from characters of both strings with same indexes using provided [transform]. List has length of shortest string. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public inline fun String.zip(other: String, transform: (Char, Char) -> V): List { + val length = Math.min(this.length(), other.length()) + val list = ArrayList(length) + for (i in 0..length-1) { + list.add(transform(this[i], other[i])) + } + return list +} + /** * Returns a sequence from the given collection. */ @@ -762,3 +1544,16 @@ public fun CharSequence.asSequence(): Sequence { } } +/** + * Returns a sequence from the given collection. + */ +@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) +public fun String.asSequence(): Sequence { + if (this is String && isEmpty()) return emptySequence() + return object : Sequence { + override fun iterator(): Iterator { + return this@asSequence.iterator() + } + } +} + diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Aggregates.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Aggregates.kt index 4e6f87d5590..39f1cbdf13b 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Aggregates.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Aggregates.kt @@ -15,7 +15,8 @@ fun aggregates(): List { return true """ } - include(Maps, CharSequences) + deprecate(Strings) { forBinaryCompatibility } + include(Maps, CharSequences, Strings) } templates add f("none(predicate: (T) -> Boolean)") { @@ -29,7 +30,8 @@ fun aggregates(): List { return true """ } - include(Maps, CharSequences) + deprecate(Strings) { forBinaryCompatibility } + include(Maps, CharSequences, Strings) } templates add f("none()") { @@ -41,7 +43,8 @@ fun aggregates(): List { return true """ } - include(Maps, CharSequences) + deprecate(Strings) { forBinaryCompatibility } + include(Maps, CharSequences, Strings) } templates add f("any(predicate: (T) -> Boolean)") { @@ -55,7 +58,8 @@ fun aggregates(): List { return false """ } - include(Maps, CharSequences) + deprecate(Strings) { forBinaryCompatibility } + include(Maps, CharSequences, Strings) } templates add f("any()") { @@ -67,7 +71,8 @@ fun aggregates(): List { return false """ } - include(Maps, CharSequences) + deprecate(Strings) { forBinaryCompatibility } + include(Maps, CharSequences, Strings) } templates add f("count(predicate: (T) -> Boolean)") { @@ -82,7 +87,8 @@ fun aggregates(): List { return count """ } - include(Maps, CharSequences) + deprecate(Strings) { forBinaryCompatibility } + include(Maps, CharSequences, Strings) } templates add f("count()") { @@ -95,8 +101,9 @@ fun aggregates(): List { return count """ } + deprecate(Strings) { forBinaryCompatibility } doc(CharSequences) { "Returns the length of this string."} - body(CharSequences) { + body(CharSequences, Strings) { "return length()" } body(Maps, Collections, ArraysOfObjects, ArraysOfPrimitives) { @@ -106,7 +113,8 @@ fun aggregates(): List { templates add f("sumBy(transform: (T) -> Int)") { inline(true) - include(CharSequences) + include(CharSequences, Strings) + deprecate(Strings) { forBinaryCompatibility } doc { "Returns the sum of all values produced by [transform] function from elements in the collection." } doc(CharSequences) { "Returns the sum of all values produced by [transform] function from characters in the string." } returns("Int") @@ -123,7 +131,8 @@ fun aggregates(): List { templates add f("sumByDouble(transform: (T) -> Double)") { inline(true) - include(CharSequences) + include(CharSequences, Strings) + deprecate(Strings) { forBinaryCompatibility } doc { "Returns the sum of all values produced by [transform] function from elements in the collection." } doc(CharSequences) { "Returns the sum of all values produced by [transform] function from characters in the string." } returns("Double") @@ -156,7 +165,8 @@ fun aggregates(): List { return min """ } - body(CharSequences, ArraysOfObjects, ArraysOfPrimitives) { + deprecate(Strings) { forBinaryCompatibility } + body(CharSequences, Strings, ArraysOfObjects, ArraysOfPrimitives) { """ if (isEmpty()) return null var min = this[0] @@ -194,7 +204,8 @@ fun aggregates(): List { return minElem """ } - body(CharSequences, ArraysOfObjects, ArraysOfPrimitives) { + deprecate(Strings) { forBinaryCompatibility } + body(CharSequences, Strings, ArraysOfObjects, ArraysOfPrimitives) { """ if (isEmpty()) return null @@ -259,7 +270,8 @@ fun aggregates(): List { """ } - body(CharSequences, ArraysOfObjects, ArraysOfPrimitives) { + deprecate(Strings) { forBinaryCompatibility } + body(CharSequences, Strings, ArraysOfObjects, ArraysOfPrimitives) { """ if (isEmpty()) return null @@ -298,7 +310,8 @@ fun aggregates(): List { return maxElem """ } - body(CharSequences, ArraysOfObjects, ArraysOfPrimitives) { + deprecate(Strings) { forBinaryCompatibility } + body(CharSequences, Strings, ArraysOfObjects, ArraysOfPrimitives) { """ if (isEmpty()) return null @@ -347,7 +360,8 @@ fun aggregates(): List { templates add f("fold(initial: R, operation: (R, T) -> R)") { inline(true) - include(CharSequences) + deprecate(Strings) { forBinaryCompatibility } + include(CharSequences, Strings) doc { "Accumulates value starting with [initial] value and applying [operation] from left to right to current accumulator value and each element." } typeParam("R") returns("R") @@ -363,7 +377,8 @@ fun aggregates(): List { templates add f("foldRight(initial: R, operation: (T, R) -> R)") { inline(true) - only(CharSequences, Lists, ArraysOfObjects, ArraysOfPrimitives) + deprecate(Strings) { forBinaryCompatibility } + only(CharSequences, Strings, Lists, ArraysOfObjects, ArraysOfPrimitives) doc { "Accumulates value starting with [initial] value and applying [operation] from right to left to each element and current accumulator value." } typeParam("R") returns("R") @@ -382,7 +397,8 @@ fun aggregates(): List { templates add f("reduce(operation: (T, T) -> T)") { inline(true) - include(CharSequences) + deprecate(Strings) { forBinaryCompatibility } + include(CharSequences, Strings) exclude(ArraysOfObjects, Iterables, Sequences) doc { "Accumulates value starting with the first element and applying [operation] from left to right to current accumulator value and each element." } @@ -426,7 +442,8 @@ fun aggregates(): List { templates add f("reduceRight(operation: (T, T) -> T)") { inline(true) - only(CharSequences, ArraysOfPrimitives) + deprecate(Strings) { forBinaryCompatibility } + only(CharSequences, Strings, ArraysOfPrimitives) doc { "Accumulates value starting with last element and applying [operation] from right to left to each element and current accumulator value." } returns("T") body { @@ -477,12 +494,14 @@ fun aggregates(): List { for (element in this) operation(element) """ } - include(Maps, CharSequences) + deprecate(Strings) { forBinaryCompatibility } + include(Maps, CharSequences, Strings) } templates add f("forEachIndexed(operation: (Int, T) -> Unit)") { inline(true) - include(CharSequences) + deprecate(Strings) { forBinaryCompatibility } + include(CharSequences, Strings) doc { "Performs the given [operation] on each element, providing sequential index with the element." } returns("Unit") body { diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Elements.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Elements.kt index 3af3ed6141d..0ea6cdd6882 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Elements.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Elements.kt @@ -224,7 +224,8 @@ fun elements(): List { """ } - body(Lists, CharSequences, ArraysOfPrimitives, ArraysOfObjects) { + deprecate(Strings) { forBinaryCompatibility } + body(Lists, CharSequences, Strings, ArraysOfPrimitives, ArraysOfObjects) { """ for (index in indices) { if (predicate(this[index])) { @@ -254,7 +255,8 @@ fun elements(): List { """ } - body(Lists, CharSequences, ArraysOfPrimitives, ArraysOfObjects) { + deprecate(Strings) { forBinaryCompatibility } + body(Lists, CharSequences, Strings, ArraysOfPrimitives, ArraysOfObjects) { """ for (index in indices.reversed()) { if (predicate(this[index])) { @@ -283,7 +285,8 @@ fun elements(): List { return elementAtOrElse(index) { throw IndexOutOfBoundsException("Sequence doesn't contain element at index $index.") } """ } - body(CharSequences, Lists, ArraysOfObjects, ArraysOfPrimitives) { + deprecate(Strings) { forBinaryCompatibility } + body(CharSequences, Strings, Lists, ArraysOfObjects, ArraysOfPrimitives) { """ return get(index) """ @@ -323,8 +326,9 @@ fun elements(): List { return defaultValue(index) """ } - inline(true, CharSequences, Lists, ArraysOfObjects, ArraysOfPrimitives) - body(CharSequences, Lists, ArraysOfObjects, ArraysOfPrimitives) { + deprecate(Strings) { forBinaryCompatibility } + inline(true, CharSequences, Strings, Lists, ArraysOfObjects, ArraysOfPrimitives) + body(CharSequences, Strings, Lists, ArraysOfObjects, ArraysOfPrimitives) { """ return if (index >= 0 && index <= lastIndex) get(index) else defaultValue(index) """ @@ -335,7 +339,8 @@ fun elements(): List { doc { "Returns an element at the given [index] or the result of calling the [defaultValue] function if the [index] is out of bounds of this collection." } returns("T") inline(true) - only(CharSequences, Lists, ArraysOfObjects, ArraysOfPrimitives) + deprecate(Strings) { forBinaryCompatibility } + only(CharSequences, Strings, Lists, ArraysOfObjects, ArraysOfPrimitives) body { """ return if (index >= 0 && index <= lastIndex) get(index) else defaultValue(index) @@ -377,7 +382,8 @@ fun elements(): List { return null """ } - body(CharSequences, Lists, ArraysOfObjects, ArraysOfPrimitives) { + deprecate(Strings) { forBinaryCompatibility } + body(CharSequences, Strings, Lists, ArraysOfObjects, ArraysOfPrimitives) { """ return if (index >= 0 && index <= lastIndex) get(index) else null """ @@ -387,7 +393,8 @@ fun elements(): List { templates add f("getOrNull(index: Int)") { doc { "Returns an element at the given [index] or `null` if the [index] is out of bounds of this collection." } returns("T?") - only(CharSequences, Lists, ArraysOfObjects, ArraysOfPrimitives) + deprecate(Strings) { forBinaryCompatibility } + only(CharSequences, Strings, Lists, ArraysOfObjects, ArraysOfPrimitives) body { """ return if (index >= 0 && index <= lastIndex) get(index) else null @@ -422,7 +429,8 @@ fun elements(): List { } """ } - body(CharSequences, Lists, ArraysOfObjects, ArraysOfPrimitives) { + deprecate(Strings) { forBinaryCompatibility } + body(CharSequences, Strings, Lists, ArraysOfObjects, ArraysOfPrimitives) { """ if (isEmpty()) throw NoSuchElementException("Collection is empty.") @@ -460,7 +468,8 @@ fun elements(): List { } """ } - body(CharSequences, Lists, ArraysOfObjects, ArraysOfPrimitives) { + deprecate(Strings) { forBinaryCompatibility } + body(CharSequences, Strings, Lists, ArraysOfObjects, ArraysOfPrimitives) { """ return if (isEmpty()) null else this[0] """ @@ -478,7 +487,8 @@ fun elements(): List { templates add f("first(predicate: (T) -> Boolean)") { inline(true) - include(CharSequences) + deprecate(Strings) { forBinaryCompatibility } + include(CharSequences, Strings) doc { """Returns the first element matching the given [predicate]. @throws [NoSuchElementException] if no such element is found.""" } doc(CharSequences) { """Returns the first character matching the given [predicate]. @@ -495,7 +505,8 @@ fun elements(): List { templates add f("firstOrNull(predicate: (T) -> Boolean)") { inline(true) - include(CharSequences) + deprecate(Strings) { forBinaryCompatibility } + include(CharSequences, Strings) doc { "Returns the first element matching the given [predicate], or `null` if element was not found." } doc(CharSequences) { "Returns the first character matching the given [predicate], or `null` if character was not found." } returns("T?") @@ -509,7 +520,8 @@ fun elements(): List { templates add f("find(predicate: (T) -> Boolean)") { inline(true) - include(CharSequences) + deprecate(Strings) { forBinaryCompatibility } + include(CharSequences, Strings) doc { "Returns the first element matching the given [predicate], or `null` if element was not found." } doc(CharSequences) { "Returns the first character matching the given [predicate], or `null` if character was not found." } returns("T?") @@ -554,7 +566,8 @@ fun elements(): List { return last """ } - body(CharSequences, Lists, ArraysOfObjects, ArraysOfPrimitives) { + deprecate(Strings) { forBinaryCompatibility } + body(CharSequences, Strings, Lists, ArraysOfObjects, ArraysOfPrimitives) { """ if (isEmpty()) throw NoSuchElementException("Collection is empty.") @@ -594,7 +607,8 @@ fun elements(): List { return last """ } - body(CharSequences) { + deprecate(Strings) { forBinaryCompatibility } + body(CharSequences, Strings) { """ return if (isEmpty()) null else this[length() - 1] """ @@ -609,7 +623,8 @@ fun elements(): List { templates add f("last(predicate: (T) -> Boolean)") { inline(true) - include(CharSequences) + deprecate(Strings) { forBinaryCompatibility } + include(CharSequences, Strings) doc { """Returns the last element matching the given [predicate]. @throws [NoSuchElementException] if no such element is found.""" } doc(CharSequences) { """"Returns the last character matching the given [predicate]. @@ -649,7 +664,8 @@ fun elements(): List { templates add f("lastOrNull(predicate: (T) -> Boolean)") { inline(true) - include(CharSequences) + deprecate(Strings) { forBinaryCompatibility } + include(CharSequences, Strings) doc { "Returns the last element matching the given [predicate], or `null` if no such element was found." } doc(CharSequences) { "Returns the last character matching the given [predicate], or `null` if no such character was found." } returns("T?") @@ -684,7 +700,8 @@ fun elements(): List { templates add f("findLast(predicate: (T) -> Boolean)") { inline(true) - include(Lists, CharSequences) + deprecate(Strings) { forBinaryCompatibility } + include(Lists, CharSequences, Strings) doc { "Returns the last element matching the given [predicate], or `null` if no such element was found." } doc(CharSequences) { "Returns the last character matching the given [predicate], or `null` if no such character was found." } returns("T?") @@ -726,7 +743,8 @@ fun elements(): List { return single """ } - body(CharSequences) { + deprecate(Strings) { forBinaryCompatibility } + body(CharSequences, Strings) { """ return when (length()) { 0 -> throw NoSuchElementException("Collection is empty.") @@ -777,7 +795,8 @@ fun elements(): List { return single """ } - body(CharSequences) { + deprecate(Strings) { forBinaryCompatibility } + body(CharSequences, Strings) { """ return if (length() == 1) this[0] else null """ @@ -791,7 +810,8 @@ fun elements(): List { templates add f("single(predicate: (T) -> Boolean)") { inline(true) - include(CharSequences) + deprecate(Strings) { forBinaryCompatibility } + include(CharSequences, Strings) doc { "Returns the single element matching the given [predicate], or throws exception if there is no or more than one matching element." } doc(CharSequences) { "Returns the single character matching the given [predicate], or throws exception if there is no or more than one matching character." } returns("T") @@ -814,7 +834,8 @@ fun elements(): List { templates add f("singleOrNull(predicate: (T) -> Boolean)") { inline(true) - include(CharSequences) + deprecate(Strings) { forBinaryCompatibility } + include(CharSequences, Strings) doc { "Returns the single element matching the given [predicate], or `null` if element was not found or more than one element was found." } doc(CharSequences) { "Returns the single character matching the given [predicate], or `null` if character was not found or more than one character was found." } returns("T?") diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Engine.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Engine.kt index 9c3d4b25f65..c3c3ab2f7ed 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Engine.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Engine.kt @@ -58,6 +58,7 @@ fun PrimitiveType.isIntegral(): Boolean = this in PrimitiveType.integralPrimitiv fun PrimitiveType.isNumeric(): Boolean = this in PrimitiveType.numericPrimitives data class Deprecation(val message: String, val replaceWith: String? = null, val level: DeprecationLevel = DeprecationLevel.WARNING) +val forBinaryCompatibility = Deprecation("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) class ConcreteFunction(val textBuilder: (Appendable) -> Unit, val sourceFile: SourceFile) @@ -260,14 +261,14 @@ class GenericFunction(val signature: String, val keyword: String = "fun") { } "TCollection" -> { when (f) { - Strings, CharSequences -> "Appendable" + CharSequences, Strings -> "Appendable" else -> renderType("MutableCollection", receiver) } } "T" -> { when (f) { Generic -> "T" - Strings, CharSequences -> "Char" + CharSequences, Strings -> "Char" Maps -> "Map.Entry" else -> primitive?.name ?: token } diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Filtering.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Filtering.kt index 5f1b19c798e..1f00e67d4cf 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Filtering.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Filtering.kt @@ -47,9 +47,10 @@ fun filtering(): List { """ } + deprecate(Strings) { forBinaryCompatibility } doc(CharSequences) { "Returns a string with the first [n] characters removed."} - body(CharSequences) { "return substring(Math.min(n, length()))" } - returns(CharSequences) { "String" } + body(CharSequences, Strings) { "return substring(Math.min(n, length()))" } + returns(CharSequences, Strings) { "String" } body(ArraysOfObjects, ArraysOfPrimitives) { """ @@ -88,14 +89,15 @@ fun filtering(): List { """ } + deprecate(Strings) { forBinaryCompatibility } doc(CharSequences) { "Returns a string containing the first [n] characters from this string, or the entire string if this string is shorter."} - body(CharSequences) { + body(CharSequences, Strings) { """ require(n >= 0, { "Requested character count $n is less than zero." }) return substring(0, Math.min(n, length())) """ } - returns(CharSequences) { "String" } + returns(CharSequences, Strings) { "String" } doc(Sequences) { "Returns a sequence containing first [n] elements." } returns(Sequences) { "Sequence" } @@ -125,7 +127,8 @@ fun filtering(): List { templates add f("dropLast(n: Int)") { val n = "\$n" - only(Lists, ArraysOfObjects, ArraysOfPrimitives, CharSequences) + deprecate(Strings) { forBinaryCompatibility } + only(Lists, ArraysOfObjects, ArraysOfPrimitives, CharSequences, Strings) doc { "Returns a list containing all elements except last [n] elements." } returns("List") @@ -137,8 +140,8 @@ fun filtering(): List { } doc(CharSequences) { "Returns a string with the last [n] characters removed." } - returns("String", CharSequences) - body(CharSequences) { + returns("String", CharSequences, Strings) + body(CharSequences, Strings) { """ require(n >= 0, { "Requested character count $n is less than zero." }) return take((length() - n).coerceAtLeast(0)) @@ -149,18 +152,19 @@ fun filtering(): List { templates add f("takeLast(n: Int)") { val n = "\$n" doc { "Returns a list containing last [n] elements." } - only(Lists, ArraysOfObjects, ArraysOfPrimitives, CharSequences) + deprecate(Strings) { forBinaryCompatibility } + only(Lists, ArraysOfObjects, ArraysOfPrimitives, CharSequences, Strings) returns("List") doc(CharSequences) { "Returns a string containing the last [n] characters from this string, or the entire string if this string is shorter."} - body(CharSequences) { + body(CharSequences, Strings) { """ require(n >= 0, { "Requested character count $n is less than zero." }) val length = length() return substring(length - Math.min(n, length), length) """ } - returns(CharSequences) { "String" } + returns(CharSequences, Strings) { "String" } body(Lists, ArraysOfObjects, ArraysOfPrimitives) { """ @@ -196,9 +200,10 @@ fun filtering(): List { """ } + deprecate(Strings) { forBinaryCompatibility } doc(CharSequences) { "Returns a string containing all characters except first characters that satisfy the given [predicate]." } - returns(CharSequences) { "String" } - body(CharSequences) { + returns(CharSequences, Strings) { "String" } + body(CharSequences, Strings) { """ return trimStart(predicate) """ @@ -232,9 +237,10 @@ fun filtering(): List { """ } + deprecate(Strings) { forBinaryCompatibility } doc(CharSequences) { "Returns a string containing the first characters that satisfy the given [predicate]."} - returns(CharSequences) { "String" } - body(CharSequences) { + returns(CharSequences, Strings) { "String" } + body(CharSequences, Strings) { """ for (index in 0..length() - 1) if (!predicate(get(index))) { @@ -256,7 +262,8 @@ fun filtering(): List { templates add f("dropLastWhile(predicate: (T) -> Boolean)") { inline(true) - only(Lists, ArraysOfObjects, ArraysOfPrimitives, CharSequences) + deprecate(Strings) { forBinaryCompatibility } + only(Lists, ArraysOfObjects, ArraysOfPrimitives, CharSequences, Strings) doc { "Returns a list containing all elements except last elements that satisfy the given [predicate]." } returns("List") @@ -272,8 +279,8 @@ fun filtering(): List { } doc(CharSequences) { "Returns a string containing all characters except last characters that satisfy the given [predicate]." } - returns("String", CharSequences) - body(CharSequences) { + returns("String", CharSequences, Strings) + body(CharSequences, Strings) { """ return trimEnd(predicate) """ @@ -282,7 +289,8 @@ fun filtering(): List { templates add f("takeLastWhile(predicate: (T) -> Boolean)") { inline(true) - only(Lists, ArraysOfObjects, ArraysOfPrimitives, CharSequences) + deprecate(Strings) { forBinaryCompatibility } + only(Lists, ArraysOfObjects, ArraysOfPrimitives, CharSequences, Strings) doc { "Returns a list containing last elements satisfying the given [predicate]."} returns("List") @@ -298,8 +306,8 @@ fun filtering(): List { } doc(CharSequences) { "Returns a string containing last characters that satisfy the given [predicate]." } - returns("String", CharSequences) - body(CharSequences) { + returns("String", CharSequences, Strings) + body(CharSequences, Strings) { """ for (index in lastIndex downTo 0) { if (!predicate(this[index])) { @@ -322,9 +330,10 @@ fun filtering(): List { """ } + deprecate(Strings) { forBinaryCompatibility } doc(CharSequences) { "Returns a string containing only those characters from the original string that match the given [predicate]." } - returns(CharSequences) { "String" } - body(CharSequences) { + returns(CharSequences, Strings) { "String" } + body(CharSequences, Strings) { """ return filterTo(StringBuilder(), predicate).toString() """ @@ -354,8 +363,9 @@ fun filtering(): List { """ } + deprecate(Strings) { forBinaryCompatibility } doc(CharSequences) { "Appends all characters matching the given [predicate] to the given [destination]." } - body(CharSequences) { + body(CharSequences, Strings) { """ for (index in 0..length() - 1) { val element = get(index) @@ -377,9 +387,10 @@ fun filtering(): List { """ } + deprecate(Strings) { forBinaryCompatibility } doc(CharSequences) { "Returns a string containing only those characters from the original string that do not match the given [predicate]." } - returns(CharSequences) { "String" } - body(CharSequences) { + returns(CharSequences, Strings) { "String" } + body(CharSequences, Strings) { """ return filterNotTo(StringBuilder(), predicate).toString() """ @@ -409,8 +420,9 @@ fun filtering(): List { """ } + deprecate(Strings) { forBinaryCompatibility } doc(CharSequences) { "Appends all characters not matching the given [predicate] to the given [destination]." } - body(CharSequences) { + body(CharSequences, Strings) { """ for (element in this) if (!predicate(element)) destination.append(element) return destination diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Generators.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Generators.kt index 156bf578681..1785925c1de 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Generators.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Generators.kt @@ -419,6 +419,7 @@ fun generators(): List { """ } + deprecate(Strings) { forBinaryCompatibility } doc(CharSequences) { """ Splits the original string into pair of strings, @@ -426,8 +427,8 @@ fun generators(): List { while *second* string contains characters for which [predicate] yielded `false`. """ } - returns(CharSequences) { "Pair" } - body(CharSequences) { + returns(CharSequences, Strings) { "Pair" } + body(CharSequences, Strings) { """ val first = StringBuilder() val second = StringBuilder() @@ -555,7 +556,8 @@ fun generators(): List { } templates add f("zip(other: String, transform: (Char, Char) -> V)") { - only(CharSequences) + deprecate(Strings) { forBinaryCompatibility } + only(CharSequences, Strings) doc { """ Returns a list of values built from characters of both strings with same indexes using provided [transform]. List has length of shortest string. @@ -595,7 +597,8 @@ fun generators(): List { } templates add f("zip(other: String)") { - only(CharSequences) + deprecate(Strings) { forBinaryCompatibility } + only(CharSequences, Strings) doc { """ Returns a list of pairs built from characters of both strings with same indexes. List has length of shortest collection. diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Mapping.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Mapping.kt index 9958ece3357..d48a3f09e5a 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Mapping.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Mapping.kt @@ -6,7 +6,8 @@ fun mapping(): List { val templates = arrayListOf() templates add f("withIndex()") { - include(CharSequences) + deprecate(Strings) { forBinaryCompatibility } + include(CharSequences, Strings) doc { "Returns a lazy [Iterable] of [IndexedValue] for each element of the original collection." } returns("Iterable>") body { @@ -36,7 +37,8 @@ fun mapping(): List { body(ArraysOfObjects, ArraysOfPrimitives) { "return mapIndexedTo(ArrayList(size()), transform)" } - body(CharSequences) { + deprecate(Strings) { forBinaryCompatibility } + body(CharSequences, Strings) { "return mapIndexedTo(ArrayList(length()), transform)" } inline(false, Sequences) @@ -59,7 +61,8 @@ fun mapping(): List { body(ArraysOfObjects, ArraysOfPrimitives, Maps) { "return mapTo(ArrayList(size()), transform)" } - body(CharSequences) { + deprecate(Strings) { forBinaryCompatibility } + body(CharSequences, Strings) { "return mapTo(ArrayList(length()), transform)" } @@ -119,7 +122,8 @@ fun mapping(): List { return destination """ } - include(Maps, CharSequences) + deprecate(Strings) { forBinaryCompatibility } + include(Maps, CharSequences, Strings) } templates add f("mapIndexedTo(destination: C, transform: (Int, T) -> R)") { @@ -143,7 +147,8 @@ fun mapping(): List { return destination """ } - include(Maps, CharSequences) + deprecate(Strings) { forBinaryCompatibility } + include(Maps, CharSequences, Strings) } /* @@ -186,7 +191,8 @@ fun mapping(): List { body { "return flatMapTo(ArrayList(), transform)" } - include(Maps, CharSequences) + deprecate(Strings) { forBinaryCompatibility } + include(Maps, CharSequences, Strings) } templates add f("flatMap(transform: (T) -> Sequence)") { @@ -215,7 +221,8 @@ fun mapping(): List { return destination """ } - include(Maps, CharSequences) + deprecate(Strings) { forBinaryCompatibility } + include(Maps, CharSequences, Strings) } templates add f("flatMapTo(destination: C, transform: (T) -> Sequence)") { @@ -240,7 +247,8 @@ fun mapping(): List { templates add f("groupBy(toKey: (T) -> K)") { inline(true) - include(CharSequences) + deprecate(Strings) { forBinaryCompatibility } + include(CharSequences, Strings) doc { "Returns a map of the elements in original collection grouped by the result of given [toKey] function." } typeParam("K") returns("Map>") @@ -250,7 +258,8 @@ fun mapping(): List { templates add f("groupByTo(map: MutableMap>, toKey: (T) -> K)") { inline(true) - include(CharSequences) + deprecate(Strings) { forBinaryCompatibility } + include(CharSequences, Strings) typeParam("K") doc { "Appends elements from original collection grouped by the result of given [toKey] function to the given [map]." } returns("Map>") diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Ordering.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Ordering.kt index 1b7d492dded..9377ddbce38 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Ordering.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Ordering.kt @@ -39,9 +39,10 @@ fun ordering(): List { """ } + deprecate(Strings) { forBinaryCompatibility } doc(CharSequences) { "Returns a string with characters in reversed order." } - returns(CharSequences) { "String" } - body(CharSequences) { + returns(CharSequences, Strings) { "String" } + body(CharSequences, Strings) { // TODO: Replace with StringBuilder(this) when JS can handle it """ return StringBuilder().append(this).reverse().toString() diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Sequence.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Sequence.kt index ea1cdfec0ba..38f03c0e70e 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Sequence.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Sequence.kt @@ -30,7 +30,8 @@ fun sequences(): List { """ } - body(CharSequences) { + deprecate(Strings) { forBinaryCompatibility } + body(CharSequences, Strings) { """ if (this is String && isEmpty()) return emptySequence() return object : Sequence { diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Snapshots.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Snapshots.kt index a865a06251e..f218dc10aac 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Snapshots.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Snapshots.kt @@ -7,7 +7,8 @@ fun snapshots(): List { val templates = arrayListOf() templates add f("toCollection(collection: C)") { - include(CharSequences) + deprecate(Strings) { forBinaryCompatibility } + include(CharSequences, Strings) doc { "Appends all elements to the given [collection]." } returns("C") typeParam("C : MutableCollection") @@ -26,7 +27,8 @@ fun snapshots(): List { returns("Set") body { "return toCollection(LinkedHashSet(mapCapacity(collectionSizeOrDefault(12))))" } body(Sequences) { "return toCollection(LinkedHashSet())" } - body(CharSequences) { "return toCollection(LinkedHashSet(mapCapacity(length())))" } + deprecate(Strings) { forBinaryCompatibility } + body(CharSequences, Strings) { "return toCollection(LinkedHashSet(mapCapacity(length())))" } body(ArraysOfObjects, ArraysOfPrimitives) { "return toCollection(LinkedHashSet(mapCapacity(size())))" } } @@ -35,12 +37,14 @@ fun snapshots(): List { returns("HashSet") body { "return toCollection(HashSet(mapCapacity(collectionSizeOrDefault(12))))" } body(Sequences) { "return toCollection(HashSet())" } - body(CharSequences) { "return toCollection(HashSet(mapCapacity(length())))" } + deprecate(Strings) { forBinaryCompatibility } + body(CharSequences, Strings) { "return toCollection(HashSet(mapCapacity(length())))" } body(ArraysOfObjects, ArraysOfPrimitives) { "return toCollection(HashSet(mapCapacity(size())))" } } templates add f("toSortedSet()") { - include(CharSequences) + deprecate(Strings) { forBinaryCompatibility } + include(CharSequences, Strings) doc { "Returns a [SortedSet] of all elements." } returns("SortedSet") body { "return toCollection(TreeSet())" } @@ -58,7 +62,8 @@ fun snapshots(): List { """ } body(Collections) { "return ArrayList(this)" } - body(CharSequences) { "return toCollection(ArrayList(length()))" } + deprecate(Strings) { forBinaryCompatibility } + body(CharSequences, Strings) { "return toCollection(ArrayList(length()))" } body(ArraysOfObjects) { "return ArrayList(this.asCollection())" } body(ArraysOfPrimitives) { """ @@ -84,7 +89,8 @@ fun snapshots(): List { } templates add f("toList()") { - include(CharSequences) + deprecate(Strings) { forBinaryCompatibility } + include(CharSequences, Strings) doc { "Returns a [List] containing all elements." } returns("List") body { "return this.toArrayList()" } @@ -99,7 +105,9 @@ fun snapshots(): List { templates add f("toMap(selector: (T) -> K)") { inline(true) - include(CharSequences) + deprecate(Strings) { forBinaryCompatibility } + body(Strings) { "return toMapBy(selector)" } + include(CharSequences, Strings) typeParam("K") returns("Map") deprecate(Deprecation("Use toMapBy instead.", replaceWith = "toMapBy(selector)")) @@ -140,7 +148,8 @@ fun snapshots(): List { return result """ } - body(CharSequences) { + deprecate(Strings) { forBinaryCompatibility } + body(CharSequences, Strings) { """ val capacity = (length()/.75f) + 1 val result = LinkedHashMap(Math.max(capacity.toInt(), 16)) @@ -198,7 +207,8 @@ fun snapshots(): List { return result """ } - body(CharSequences) { + deprecate(Strings) { forBinaryCompatibility } + body(CharSequences, Strings) { """ val capacity = (length()/.75f) + 1 val result = LinkedHashMap(Math.max(capacity.toInt(), 16))