diff --git a/js/js.libraries/src/core/kotlin.kt b/js/js.libraries/src/core/kotlin.kt index 219612926b3..a7d14df3900 100644 --- a/js/js.libraries/src/core/kotlin.kt +++ b/js/js.libraries/src/core/kotlin.kt @@ -61,3 +61,22 @@ public fun lazy(initializer: () -> T): Lazy = UnsafeLazyImpl(initializer) * * The [mode] parameter is ignored. */ public fun lazy(mode: LazyThreadSafetyMode, initializer: () -> T): Lazy = UnsafeLazyImpl(initializer) + + +private fun arrayCopyResize(source: dynamic, newSize: Int, defaultValue: Any?): dynamic { + val result = source.slice(0, newSize) + var index: Int = source.length + if (newSize > index) { + result.length = newSize + while (index < newSize) result[index++] = defaultValue + } + return result +} + +private fun arrayPlusCollection(array: dynamic, collection: Collection): dynamic { + val result = array.slice(0) + result.length += collection.size() + var index: Int = array.length + for (element in collection) result[index++] = element + return result +} \ No newline at end of file diff --git a/js/js.libraries/src/core/kotlin_special.kt b/js/js.libraries/src/core/kotlin_special.kt index a04427d27d2..897655626a6 100644 --- a/js/js.libraries/src/core/kotlin_special.kt +++ b/js/js.libraries/src/core/kotlin_special.kt @@ -75,3 +75,426 @@ public inline fun ShortArray.asList(): List { return (this as Array).asList() } +/** + * Returns new array which is a copy of the original array. + */ +suppress("NOTHING_TO_INLINE") +public inline fun Array.copyOf(): Array { + return (this: dynamic).slice(0) +} + +/** + * Returns new array which is a copy of the original array. + */ +suppress("NOTHING_TO_INLINE") +public inline fun BooleanArray.copyOf(): BooleanArray { + return (this: dynamic).slice(0) +} + +/** + * Returns new array which is a copy of the original array. + */ +suppress("NOTHING_TO_INLINE") +public inline fun ByteArray.copyOf(): ByteArray { + return (this: dynamic).slice(0) +} + +/** + * Returns new array which is a copy of the original array. + */ +suppress("NOTHING_TO_INLINE") +public inline fun CharArray.copyOf(): CharArray { + return (this: dynamic).slice(0) +} + +/** + * Returns new array which is a copy of the original array. + */ +suppress("NOTHING_TO_INLINE") +public inline fun DoubleArray.copyOf(): DoubleArray { + return (this: dynamic).slice(0) +} + +/** + * Returns new array which is a copy of the original array. + */ +suppress("NOTHING_TO_INLINE") +public inline fun FloatArray.copyOf(): FloatArray { + return (this: dynamic).slice(0) +} + +/** + * Returns new array which is a copy of the original array. + */ +suppress("NOTHING_TO_INLINE") +public inline fun IntArray.copyOf(): IntArray { + return (this: dynamic).slice(0) +} + +/** + * Returns new array which is a copy of the original array. + */ +suppress("NOTHING_TO_INLINE") +public inline fun LongArray.copyOf(): LongArray { + return (this: dynamic).slice(0) +} + +/** + * Returns new array which is a copy of the original array. + */ +suppress("NOTHING_TO_INLINE") +public inline fun ShortArray.copyOf(): ShortArray { + return (this: dynamic).slice(0) +} + +/** + * Returns new array which is a copy of the original array. + */ +public fun BooleanArray.copyOf(newSize: Int): BooleanArray { + return arrayCopyResize(this, newSize, false) +} + +/** + * Returns new array which is a copy of the original array. + */ +public fun ByteArray.copyOf(newSize: Int): ByteArray { + return arrayCopyResize(this, newSize, 0) +} + +/** + * Returns new array which is a copy of the original array. + */ +public fun CharArray.copyOf(newSize: Int): CharArray { + return arrayCopyResize(this, newSize, '\u0000') +} + +/** + * Returns new array which is a copy of the original array. + */ +public fun ShortArray.copyOf(newSize: Int): ShortArray { + return arrayCopyResize(this, newSize, 0) +} + +/** + * Returns new array which is a copy of the original array. + */ +public fun IntArray.copyOf(newSize: Int): IntArray { + return arrayCopyResize(this, newSize, 0) +} + +/** + * Returns new array which is a copy of the original array. + */ +public fun LongArray.copyOf(newSize: Int): LongArray { + return arrayCopyResize(this, newSize, 0L) +} + +/** + * Returns new array which is a copy of the original array. + */ +public fun FloatArray.copyOf(newSize: Int): FloatArray { + return arrayCopyResize(this, newSize, 0.0f) +} + +/** + * Returns new array which is a copy of the original array. + */ +public fun DoubleArray.copyOf(newSize: Int): DoubleArray { + return arrayCopyResize(this, newSize, 0.0) +} + +/** + * Returns new array which is a copy of the original array. + */ +public fun Array.copyOf(newSize: Int): Array { + return arrayCopyResize(this, newSize, null) +} + +/** + * Returns new array which is a copy of range of original array. + */ +suppress("NOTHING_TO_INLINE") +public inline fun Array.copyOfRange(from: Int, to: Int): Array { + return (this: dynamic).slice(from, to) +} + +/** + * Returns new array which is a copy of range of original array. + */ +suppress("NOTHING_TO_INLINE") +public inline fun BooleanArray.copyOfRange(from: Int, to: Int): BooleanArray { + return (this: dynamic).slice(from, to) +} + +/** + * Returns new array which is a copy of range of original array. + */ +suppress("NOTHING_TO_INLINE") +public inline fun ByteArray.copyOfRange(from: Int, to: Int): ByteArray { + return (this: dynamic).slice(from, to) +} + +/** + * Returns new array which is a copy of range of original array. + */ +suppress("NOTHING_TO_INLINE") +public inline fun CharArray.copyOfRange(from: Int, to: Int): CharArray { + return (this: dynamic).slice(from, to) +} + +/** + * Returns new array which is a copy of range of original array. + */ +suppress("NOTHING_TO_INLINE") +public inline fun DoubleArray.copyOfRange(from: Int, to: Int): DoubleArray { + return (this: dynamic).slice(from, to) +} + +/** + * Returns new array which is a copy of range of original array. + */ +suppress("NOTHING_TO_INLINE") +public inline fun FloatArray.copyOfRange(from: Int, to: Int): FloatArray { + return (this: dynamic).slice(from, to) +} + +/** + * Returns new array which is a copy of range of original array. + */ +suppress("NOTHING_TO_INLINE") +public inline fun IntArray.copyOfRange(from: Int, to: Int): IntArray { + return (this: dynamic).slice(from, to) +} + +/** + * Returns new array which is a copy of range of original array. + */ +suppress("NOTHING_TO_INLINE") +public inline fun LongArray.copyOfRange(from: Int, to: Int): LongArray { + return (this: dynamic).slice(from, to) +} + +/** + * Returns new array which is a copy of range of original array. + */ +suppress("NOTHING_TO_INLINE") +public inline fun ShortArray.copyOfRange(from: Int, to: Int): ShortArray { + return (this: dynamic).slice(from, to) +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [array]. + */ +suppress("NOTHING_TO_INLINE") +public inline fun Array.plus(array: Array): Array { + return (this: dynamic).concat(array) +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [array]. + */ +suppress("NOTHING_TO_INLINE") +public inline fun BooleanArray.plus(array: BooleanArray): BooleanArray { + return (this: dynamic).concat(array) +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [array]. + */ +suppress("NOTHING_TO_INLINE") +public inline fun ByteArray.plus(array: ByteArray): ByteArray { + return (this: dynamic).concat(array) +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [array]. + */ +suppress("NOTHING_TO_INLINE") +public inline fun CharArray.plus(array: CharArray): CharArray { + return (this: dynamic).concat(array) +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [array]. + */ +suppress("NOTHING_TO_INLINE") +public inline fun DoubleArray.plus(array: DoubleArray): DoubleArray { + return (this: dynamic).concat(array) +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [array]. + */ +suppress("NOTHING_TO_INLINE") +public inline fun FloatArray.plus(array: FloatArray): FloatArray { + return (this: dynamic).concat(array) +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [array]. + */ +suppress("NOTHING_TO_INLINE") +public inline fun IntArray.plus(array: IntArray): IntArray { + return (this: dynamic).concat(array) +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [array]. + */ +suppress("NOTHING_TO_INLINE") +public inline fun LongArray.plus(array: LongArray): LongArray { + return (this: dynamic).concat(array) +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [array]. + */ +suppress("NOTHING_TO_INLINE") +public inline fun ShortArray.plus(array: ShortArray): ShortArray { + return (this: dynamic).concat(array) +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [collection]. + */ +public fun Array.plus(collection: Collection): Array { + return arrayPlusCollection(this, collection) +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [collection]. + */ +public fun BooleanArray.plus(collection: Collection): BooleanArray { + return arrayPlusCollection(this, collection) +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [collection]. + */ +public fun ByteArray.plus(collection: Collection): ByteArray { + return arrayPlusCollection(this, collection) +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [collection]. + */ +public fun CharArray.plus(collection: Collection): CharArray { + return arrayPlusCollection(this, collection) +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [collection]. + */ +public fun DoubleArray.plus(collection: Collection): DoubleArray { + return arrayPlusCollection(this, collection) +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [collection]. + */ +public fun FloatArray.plus(collection: Collection): FloatArray { + return arrayPlusCollection(this, collection) +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [collection]. + */ +public fun IntArray.plus(collection: Collection): IntArray { + return arrayPlusCollection(this, collection) +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [collection]. + */ +public fun LongArray.plus(collection: Collection): LongArray { + return arrayPlusCollection(this, collection) +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [collection]. + */ +public fun ShortArray.plus(collection: Collection): ShortArray { + return arrayPlusCollection(this, collection) +} + +/** + * Returns an array containing all elements of the original array and then the given [element]. + */ +public fun Array.plus(element: T): Array { + val result = this.copyOf() + (result: dynamic).push(element) + return result as Array +} + +/** + * Returns an array containing all elements of the original array and then the given [element]. + */ +public fun BooleanArray.plus(element: Boolean): BooleanArray { + val result = this.copyOf() + (result: dynamic).push(element) + return result as BooleanArray +} + +/** + * Returns an array containing all elements of the original array and then the given [element]. + */ +public fun ByteArray.plus(element: Byte): ByteArray { + val result = this.copyOf() + (result: dynamic).push(element) + return result as ByteArray +} + +/** + * Returns an array containing all elements of the original array and then the given [element]. + */ +public fun CharArray.plus(element: Char): CharArray { + val result = this.copyOf() + (result: dynamic).push(element) + return result as CharArray +} + +/** + * Returns an array containing all elements of the original array and then the given [element]. + */ +public fun DoubleArray.plus(element: Double): DoubleArray { + val result = this.copyOf() + (result: dynamic).push(element) + return result as DoubleArray +} + +/** + * Returns an array containing all elements of the original array and then the given [element]. + */ +public fun FloatArray.plus(element: Float): FloatArray { + val result = this.copyOf() + (result: dynamic).push(element) + return result as FloatArray +} + +/** + * Returns an array containing all elements of the original array and then the given [element]. + */ +public fun IntArray.plus(element: Int): IntArray { + val result = this.copyOf() + (result: dynamic).push(element) + return result as IntArray +} + +/** + * Returns an array containing all elements of the original array and then the given [element]. + */ +public fun LongArray.plus(element: Long): LongArray { + val result = this.copyOf() + (result: dynamic).push(element) + return result as LongArray +} + +/** + * Returns an array containing all elements of the original array and then the given [element]. + */ +public fun ShortArray.plus(element: Short): ShortArray { + val result = this.copyOf() + (result: dynamic).push(element) + return result as ShortArray +} + diff --git a/libraries/stdlib/src/generated/_Generators.kt b/libraries/stdlib/src/generated/_Generators.kt index f458dd2d021..5fc48ae7361 100644 --- a/libraries/stdlib/src/generated/_Generators.kt +++ b/libraries/stdlib/src/generated/_Generators.kt @@ -598,35 +598,35 @@ public inline fun String.partition(predicate: (Char) -> Boolean): Pair Collection.plus(array: Array): List { - val answer = ArrayList(this.size() + array.size()) - answer.addAll(this) - answer.addAll(array) - return answer + val result = ArrayList(this.size() + array.size()) + result.addAll(this) + result.addAll(array) + return result } /** - * Returns a list containing all elements of original collection and then all elements of the given [array]. + * Returns a list containing all elements of the original collection and then all elements of the given [array]. */ public fun Iterable.plus(array: Array): List { if (this is Collection) return this.plus(array) - val answer = ArrayList() - answer.addAll(this) - answer.addAll(array) - return answer + val result = ArrayList() + result.addAll(this) + result.addAll(array) + return result } /** - * Returns a list containing all elements of original collection and then all elements of the given [array]. + * Returns a sequence containing all elements of original sequence and then all elements of the given [array]. */ public fun Sequence.plus(array: Array): Sequence { return this.plus(array.asList()) } /** - * Returns a list containing all elements of original collection and then all elements of the given [array]. + * Returns a set containing all elements both of the original set and the given [array]. */ public fun Set.plus(array: Array): Set { val result = LinkedHashSet(mapCapacity(this.size() + array.size())) @@ -635,92 +635,14 @@ public fun Set.plus(array: Array): Set { return result } -public fun Array.plus(collection: Collection): Array { - val thisSize = size() - val answer = this.copyOf(thisSize + collection.size()) - collection.forEachIndexed { i, element -> - answer[thisSize + i] = element - } - return answer as Array -} - -public fun BooleanArray.plus(collection: Collection): BooleanArray { - val thisSize = size() - val answer = this.copyOf(thisSize + collection.size()) - collection.forEachIndexed { i, element -> - answer[thisSize + i] = element - } - return answer as BooleanArray -} - -public fun ByteArray.plus(collection: Collection): ByteArray { - val thisSize = size() - val answer = this.copyOf(thisSize + collection.size()) - collection.forEachIndexed { i, element -> - answer[thisSize + i] = element - } - return answer as ByteArray -} - -public fun CharArray.plus(collection: Collection): CharArray { - val thisSize = size() - val answer = this.copyOf(thisSize + collection.size()) - collection.forEachIndexed { i, element -> - answer[thisSize + i] = element - } - return answer as CharArray -} - -public fun DoubleArray.plus(collection: Collection): DoubleArray { - val thisSize = size() - val answer = this.copyOf(thisSize + collection.size()) - collection.forEachIndexed { i, element -> - answer[thisSize + i] = element - } - return answer as DoubleArray -} - -public fun FloatArray.plus(collection: Collection): FloatArray { - val thisSize = size() - val answer = this.copyOf(thisSize + collection.size()) - collection.forEachIndexed { i, element -> - answer[thisSize + i] = element - } - return answer as FloatArray -} - -public fun IntArray.plus(collection: Collection): IntArray { - val thisSize = size() - val answer = this.copyOf(thisSize + collection.size()) - collection.forEachIndexed { i, element -> - answer[thisSize + i] = element - } - return answer as IntArray -} - -public fun LongArray.plus(collection: Collection): LongArray { - val thisSize = size() - val answer = this.copyOf(thisSize + collection.size()) - collection.forEachIndexed { i, element -> - answer[thisSize + i] = element - } - return answer as LongArray -} - -public fun ShortArray.plus(collection: Collection): ShortArray { - val thisSize = size() - val answer = this.copyOf(thisSize + collection.size()) - collection.forEachIndexed { i, element -> - answer[thisSize + i] = element - } - return answer as ShortArray -} - +/** + * Returns a list containing all elements of the original collection and then all elements of the given [collection]. + */ public fun Collection.plus(collection: Collection): List { - val answer = ArrayList(this.size() + collection.size()) - answer.addAll(this) - answer.addAll(collection) - return answer + val result = ArrayList(this.size() + collection.size()) + result.addAll(this) + result.addAll(collection) + return result } /** @@ -728,9 +650,9 @@ public fun Collection.plus(collection: Collection): List { */ public fun Collection.plus(collection: Iterable): List { if (collection is Collection) return this.plus(collection) - val answer = ArrayList(this) - answer.addAll(collection) - return answer + val result = ArrayList(this) + result.addAll(collection) + return result } /** @@ -738,21 +660,21 @@ public fun Collection.plus(collection: Iterable): List { */ public fun Iterable.plus(collection: Iterable): List { if (this is Collection) return this.plus(collection) - val answer = ArrayList(0) - answer.addAll(this) - answer.addAll(collection) - return answer + val result = ArrayList() + result.addAll(this) + result.addAll(collection) + return result } /** - * Returns a sequence containing all elements of original sequence and then all elements of the given [collection] + * Returns a sequence containing all elements of original sequence and then all elements of the given [collection]. */ public fun Sequence.plus(collection: Iterable): Sequence { return sequenceOf(this, collection.asSequence()).flatten() } /** - * Returns a list containing all elements of the original collection and then all elements of the given [collection]. + * Returns a set containing all elements both of the original set and the given [collection]. */ public fun Set.plus(collection: Iterable): Set { val result = LinkedHashSet(mapCapacity(collection.collectionSizeOrNull()?.let { this.size() + it } ?: this.size() * 2)) @@ -761,176 +683,14 @@ public fun Set.plus(collection: Iterable): Set { return result } -public fun Array.plus(collection: Array): Array { - val thisSize = size() - val answer = this.copyOf(thisSize + collection.size()) - collection.forEachIndexed { i, element -> - answer[thisSize + i] = element - } - return answer as Array -} - -public fun BooleanArray.plus(collection: BooleanArray): BooleanArray { - val thisSize = size() - val answer = this.copyOf(thisSize + collection.size()) - collection.forEachIndexed { i, element -> - answer[thisSize + i] = element - } - return answer as BooleanArray -} - -public fun ByteArray.plus(collection: ByteArray): ByteArray { - val thisSize = size() - val answer = this.copyOf(thisSize + collection.size()) - collection.forEachIndexed { i, element -> - answer[thisSize + i] = element - } - return answer as ByteArray -} - -public fun CharArray.plus(collection: CharArray): CharArray { - val thisSize = size() - val answer = this.copyOf(thisSize + collection.size()) - collection.forEachIndexed { i, element -> - answer[thisSize + i] = element - } - return answer as CharArray -} - -public fun DoubleArray.plus(collection: DoubleArray): DoubleArray { - val thisSize = size() - val answer = this.copyOf(thisSize + collection.size()) - collection.forEachIndexed { i, element -> - answer[thisSize + i] = element - } - return answer as DoubleArray -} - -public fun FloatArray.plus(collection: FloatArray): FloatArray { - val thisSize = size() - val answer = this.copyOf(thisSize + collection.size()) - collection.forEachIndexed { i, element -> - answer[thisSize + i] = element - } - return answer as FloatArray -} - -public fun IntArray.plus(collection: IntArray): IntArray { - val thisSize = size() - val answer = this.copyOf(thisSize + collection.size()) - collection.forEachIndexed { i, element -> - answer[thisSize + i] = element - } - return answer as IntArray -} - -public fun LongArray.plus(collection: LongArray): LongArray { - val thisSize = size() - val answer = this.copyOf(thisSize + collection.size()) - collection.forEachIndexed { i, element -> - answer[thisSize + i] = element - } - return answer as LongArray -} - -public fun ShortArray.plus(collection: ShortArray): ShortArray { - val thisSize = size() - val answer = this.copyOf(thisSize + collection.size()) - collection.forEachIndexed { i, element -> - answer[thisSize + i] = element - } - return answer as ShortArray -} - -/** - * Returns an array containing all elements of the original array and then the given [element]. - */ -public fun Array.plus(element: T): Array { - val answer = this.copyOf(size() + 1) - answer[size()] = element - return answer as Array -} - -/** - * Returns an array containing all elements of the original array and then the given [element]. - */ -public fun BooleanArray.plus(element: Boolean): BooleanArray { - val answer = this.copyOf(size() + 1) - answer[size()] = element - return answer as BooleanArray -} - -/** - * Returns an array containing all elements of the original array and then the given [element]. - */ -public fun ByteArray.plus(element: Byte): ByteArray { - val answer = this.copyOf(size() + 1) - answer[size()] = element - return answer as ByteArray -} - -/** - * Returns an array containing all elements of the original array and then the given [element]. - */ -public fun CharArray.plus(element: Char): CharArray { - val answer = this.copyOf(size() + 1) - answer[size()] = element - return answer as CharArray -} - -/** - * Returns an array containing all elements of the original array and then the given [element]. - */ -public fun DoubleArray.plus(element: Double): DoubleArray { - val answer = this.copyOf(size() + 1) - answer[size()] = element - return answer as DoubleArray -} - -/** - * Returns an array containing all elements of the original array and then the given [element]. - */ -public fun FloatArray.plus(element: Float): FloatArray { - val answer = this.copyOf(size() + 1) - answer[size()] = element - return answer as FloatArray -} - -/** - * Returns an array containing all elements of the original array and then the given [element]. - */ -public fun IntArray.plus(element: Int): IntArray { - val answer = this.copyOf(size() + 1) - answer[size()] = element - return answer as IntArray -} - -/** - * Returns an array containing all elements of the original array and then the given [element]. - */ -public fun LongArray.plus(element: Long): LongArray { - val answer = this.copyOf(size() + 1) - answer[size()] = element - return answer as LongArray -} - -/** - * Returns an array containing all elements of the original array and then the given [element]. - */ -public fun ShortArray.plus(element: Short): ShortArray { - val answer = this.copyOf(size() + 1) - answer[size()] = element - return answer as ShortArray -} - /** * Returns a list containing all elements of the original collection and then the given [element]. */ public fun Collection.plus(element: T): List { - val answer = ArrayList(size() + 1) - answer.addAll(this) - answer.add(element) - return answer + val result = ArrayList(size() + 1) + result.addAll(this) + result.add(element) + return result } /** @@ -938,10 +698,10 @@ public fun Collection.plus(element: T): List { */ public fun Iterable.plus(element: T): List { if (this is Collection) return this.plus(element) - val answer = ArrayList() - answer.addAll(this) - answer.add(element) - return answer + val result = ArrayList() + result.addAll(this) + result.add(element) + return result } /** @@ -955,10 +715,10 @@ public fun Sequence.plus(element: T): Sequence { * Returns a set containing all elements of the original set and then the given [element]. */ public fun Set.plus(element: T): Set { - val copyOfSet = LinkedHashSet(mapCapacity(size() + 1)) - copyOfSet.addAll(this) - copyOfSet.add(element) - return copyOfSet + val result = LinkedHashSet(mapCapacity(size() + 1)) + result.addAll(this) + result.add(element) + return result } /** diff --git a/libraries/stdlib/src/generated/_SpecialJVM.kt b/libraries/stdlib/src/generated/_SpecialJVM.kt index 79880f368fe..9aa542ba942 100644 --- a/libraries/stdlib/src/generated/_SpecialJVM.kt +++ b/libraries/stdlib/src/generated/_SpecialJVM.kt @@ -544,6 +544,294 @@ public fun , R> Sequence<*>.filterIsInstanceTo(desti return destination } +/** + * Returns an array containing all elements of the original array and then all elements of the given [array]. + */ +public fun Array.plus(array: Array): Array { + val thisSize = size() + val arraySize = array.size() + val result = this.copyOf(thisSize + arraySize) + System.arraycopy(array, 0, result, thisSize, arraySize) + return result as Array +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [array]. + */ +public fun BooleanArray.plus(array: BooleanArray): BooleanArray { + val thisSize = size() + val arraySize = array.size() + val result = this.copyOf(thisSize + arraySize) + System.arraycopy(array, 0, result, thisSize, arraySize) + return result as BooleanArray +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [array]. + */ +public fun ByteArray.plus(array: ByteArray): ByteArray { + val thisSize = size() + val arraySize = array.size() + val result = this.copyOf(thisSize + arraySize) + System.arraycopy(array, 0, result, thisSize, arraySize) + return result as ByteArray +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [array]. + */ +public fun CharArray.plus(array: CharArray): CharArray { + val thisSize = size() + val arraySize = array.size() + val result = this.copyOf(thisSize + arraySize) + System.arraycopy(array, 0, result, thisSize, arraySize) + return result as CharArray +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [array]. + */ +public fun DoubleArray.plus(array: DoubleArray): DoubleArray { + val thisSize = size() + val arraySize = array.size() + val result = this.copyOf(thisSize + arraySize) + System.arraycopy(array, 0, result, thisSize, arraySize) + return result as DoubleArray +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [array]. + */ +public fun FloatArray.plus(array: FloatArray): FloatArray { + val thisSize = size() + val arraySize = array.size() + val result = this.copyOf(thisSize + arraySize) + System.arraycopy(array, 0, result, thisSize, arraySize) + return result as FloatArray +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [array]. + */ +public fun IntArray.plus(array: IntArray): IntArray { + val thisSize = size() + val arraySize = array.size() + val result = this.copyOf(thisSize + arraySize) + System.arraycopy(array, 0, result, thisSize, arraySize) + return result as IntArray +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [array]. + */ +public fun LongArray.plus(array: LongArray): LongArray { + val thisSize = size() + val arraySize = array.size() + val result = this.copyOf(thisSize + arraySize) + System.arraycopy(array, 0, result, thisSize, arraySize) + return result as LongArray +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [array]. + */ +public fun ShortArray.plus(array: ShortArray): ShortArray { + val thisSize = size() + val arraySize = array.size() + val result = this.copyOf(thisSize + arraySize) + System.arraycopy(array, 0, result, thisSize, arraySize) + return result as ShortArray +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [collection]. + */ +public fun Array.plus(collection: Collection): Array { + val thisSize = size() + val result = this.copyOf(thisSize + collection.size()) + collection.forEachIndexed { i, element -> + result[thisSize + i] = element + } + return result as Array +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [collection]. + */ +public fun BooleanArray.plus(collection: Collection): BooleanArray { + val thisSize = size() + val result = this.copyOf(thisSize + collection.size()) + collection.forEachIndexed { i, element -> + result[thisSize + i] = element + } + return result as BooleanArray +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [collection]. + */ +public fun ByteArray.plus(collection: Collection): ByteArray { + val thisSize = size() + val result = this.copyOf(thisSize + collection.size()) + collection.forEachIndexed { i, element -> + result[thisSize + i] = element + } + return result as ByteArray +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [collection]. + */ +public fun CharArray.plus(collection: Collection): CharArray { + val thisSize = size() + val result = this.copyOf(thisSize + collection.size()) + collection.forEachIndexed { i, element -> + result[thisSize + i] = element + } + return result as CharArray +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [collection]. + */ +public fun DoubleArray.plus(collection: Collection): DoubleArray { + val thisSize = size() + val result = this.copyOf(thisSize + collection.size()) + collection.forEachIndexed { i, element -> + result[thisSize + i] = element + } + return result as DoubleArray +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [collection]. + */ +public fun FloatArray.plus(collection: Collection): FloatArray { + val thisSize = size() + val result = this.copyOf(thisSize + collection.size()) + collection.forEachIndexed { i, element -> + result[thisSize + i] = element + } + return result as FloatArray +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [collection]. + */ +public fun IntArray.plus(collection: Collection): IntArray { + val thisSize = size() + val result = this.copyOf(thisSize + collection.size()) + collection.forEachIndexed { i, element -> + result[thisSize + i] = element + } + return result as IntArray +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [collection]. + */ +public fun LongArray.plus(collection: Collection): LongArray { + val thisSize = size() + val result = this.copyOf(thisSize + collection.size()) + collection.forEachIndexed { i, element -> + result[thisSize + i] = element + } + return result as LongArray +} + +/** + * Returns an array containing all elements of the original array and then all elements of the given [collection]. + */ +public fun ShortArray.plus(collection: Collection): ShortArray { + val thisSize = size() + val result = this.copyOf(thisSize + collection.size()) + collection.forEachIndexed { i, element -> + result[thisSize + i] = element + } + return result as ShortArray +} + +/** + * Returns an array containing all elements of the original array and then the given [element]. + */ +public fun Array.plus(element: T): Array { + val result = this.copyOf(size() + 1) + result[size()] = element + return result as Array +} + +/** + * Returns an array containing all elements of the original array and then the given [element]. + */ +public fun BooleanArray.plus(element: Boolean): BooleanArray { + val result = this.copyOf(size() + 1) + result[size()] = element + return result as BooleanArray +} + +/** + * Returns an array containing all elements of the original array and then the given [element]. + */ +public fun ByteArray.plus(element: Byte): ByteArray { + val result = this.copyOf(size() + 1) + result[size()] = element + return result as ByteArray +} + +/** + * Returns an array containing all elements of the original array and then the given [element]. + */ +public fun CharArray.plus(element: Char): CharArray { + val result = this.copyOf(size() + 1) + result[size()] = element + return result as CharArray +} + +/** + * Returns an array containing all elements of the original array and then the given [element]. + */ +public fun DoubleArray.plus(element: Double): DoubleArray { + val result = this.copyOf(size() + 1) + result[size()] = element + return result as DoubleArray +} + +/** + * Returns an array containing all elements of the original array and then the given [element]. + */ +public fun FloatArray.plus(element: Float): FloatArray { + val result = this.copyOf(size() + 1) + result[size()] = element + return result as FloatArray +} + +/** + * Returns an array containing all elements of the original array and then the given [element]. + */ +public fun IntArray.plus(element: Int): IntArray { + val result = this.copyOf(size() + 1) + result[size()] = element + return result as IntArray +} + +/** + * Returns an array containing all elements of the original array and then the given [element]. + */ +public fun LongArray.plus(element: Long): LongArray { + val result = this.copyOf(size() + 1) + result[size()] = element + return result as LongArray +} + +/** + * Returns an array containing all elements of the original array and then the given [element]. + */ +public fun ShortArray.plus(element: Short): ShortArray { + val result = this.copyOf(size() + 1) + result[size()] = element + return result as ShortArray +} + /** * Sorts array or range in array inplace. */ diff --git a/libraries/stdlib/test/collections/ArraysTest.kt b/libraries/stdlib/test/collections/ArraysTest.kt index ff1dbf37519..7752eee1c2b 100644 --- a/libraries/stdlib/test/collections/ArraysTest.kt +++ b/libraries/stdlib/test/collections/ArraysTest.kt @@ -210,13 +210,21 @@ class ArraysTest { } test fun plus() { - assertEquals(listOf("1", "2", "3", "4"), arrayOf("1", "2") + arrayOf("3", "4")) assertEquals(listOf("1", "2", "3", "4"), listOf("1", "2") + arrayOf("3", "4")) + val arr = arrayOf("1", "2") + arrayOf("3", "4") + assertEquals(4, arr.size()) + checkContent(arr.iterator(), 4) { (it + 1).toString() } } test fun plusVararg() { - fun onePlus(vararg a: String) = arrayOf("1") + a - assertEquals(listOf("1", "2"), onePlus("2")) + fun stringOnePlus(vararg a: String) = arrayOf("1") + a + fun numberOnePlus(vararg a: Int) = intArrayOf(1) + a + + val arrS = stringOnePlus("2") + checkContent(arrS.iterator(), 2) { (it + 1).toString() } + + val arrN = numberOnePlus(2) + checkContent(arrN.iterator(), 2) { it + 1 } } test fun first() { diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Generators.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Generators.kt index 84db08671e1..a2606c501c3 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Generators.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Generators.kt @@ -6,48 +6,37 @@ fun generators(): List { val templates = arrayListOf() templates add f("plus(element: T)") { - exclude(Strings) + only(Iterables, Collections, Sets, Sequences) doc { "Returns a list containing all elements of the original collection and then the given [element]." } returns("List") - returns("SELF", ArraysOfObjects, ArraysOfPrimitives, Sets, Sequences) body { """ if (this is Collection) return this.plus(element) - val answer = ArrayList() - answer.addAll(this) - answer.add(element) - return answer + val result = ArrayList() + result.addAll(this) + result.add(element) + return result """ } body(Collections) { """ - val answer = ArrayList(size() + 1) - answer.addAll(this) - answer.add(element) - return answer - """ - } - - - doc(ArraysOfObjects, ArraysOfPrimitives) { "Returns an array containing all elements of the original array and then the given [element]." } - body(ArraysOfObjects, ArraysOfPrimitives) { - """ - val answer = this.copyOf(size() + 1) - answer[size()] = element - return answer as SELF + val result = ArrayList(size() + 1) + result.addAll(this) + result.add(element) + return result """ } // TODO: use build scope function when available // TODO: use immutable sets when available - // TODO: precalculate size + returns("SELF", Sets, Sequences) doc(Sets) { "Returns a set containing all elements of the original set and then the given [element]." } body(Sets) { """ - val copyOfSet = LinkedHashSet(mapCapacity(size() + 1)) - copyOfSet.addAll(this) - copyOfSet.add(element) - return copyOfSet + val result = LinkedHashSet(mapCapacity(size() + 1)) + result.addAll(this) + result.add(element) + return result """ } @@ -67,23 +56,24 @@ fun generators(): List { body { """ if (this is Collection) return this.plus(collection) - val answer = ArrayList(0) - answer.addAll(this) - answer.addAll(collection) - return answer + val result = ArrayList() + result.addAll(this) + result.addAll(collection) + return result """ } body(Collections) { """ if (collection is Collection) return this.plus(collection) - val answer = ArrayList(this) - answer.addAll(collection) - return answer + val result = ArrayList(this) + result.addAll(collection) + return result """ } // TODO: try to precalculate size // TODO: use immutable set builder when available + doc(Sets) { "Returns a set containing all elements both of the original set and the given [collection]." } body(Sets) { """ val result = LinkedHashSet(mapCapacity(collection.collectionSizeOrNull()?.let { this.size() + it } ?: this.size() * 2)) @@ -93,7 +83,7 @@ fun generators(): List { """ } - doc(Sequences) { "Returns a sequence containing all elements of original sequence and then all elements of the given [collection]" } + doc(Sequences) { "Returns a sequence containing all elements of original sequence and then all elements of the given [collection]." } body(Sequences) { """ return sequenceOf(this, collection.asSequence()).flatten() @@ -102,52 +92,42 @@ fun generators(): List { } templates add f("plus(collection: Collection)") { - only(Collections, ArraysOfPrimitives, ArraysOfObjects) + only(Collections) + doc { "Returns a list containing all elements of the original collection and then all elements of the given [collection]." } returns("List") - returns("SELF", ArraysOfObjects, ArraysOfPrimitives) - body(Collections) { + body { """ - val answer = ArrayList(this.size() + collection.size()) - answer.addAll(this) - answer.addAll(collection) - return answer - """ - } - // ? - body(ArraysOfObjects, ArraysOfPrimitives) { - """ - val thisSize = size() - val answer = this.copyOf(thisSize + collection.size()) - collection.forEachIndexed { i, element -> - answer[thisSize + i] = element - } - return answer as SELF + val result = ArrayList(this.size() + collection.size()) + result.addAll(this) + result.addAll(collection) + return result """ } } templates add f("plus(array: Array)") { only(Iterables, Collections, Sets, Sequences) - doc { "Returns a list containing all elements of original collection and then all elements of the given [array]." } + doc { "Returns a list containing all elements of the original collection and then all elements of the given [array]." } returns("List") returns("SELF", Sets, Sequences) body { """ if (this is Collection) return this.plus(array) - val answer = ArrayList() - answer.addAll(this) - answer.addAll(array) - return answer + val result = ArrayList() + result.addAll(this) + result.addAll(array) + return result """ } body(Collections) { """ - val answer = ArrayList(this.size() + array.size()) - answer.addAll(this) - answer.addAll(array) - return answer + val result = ArrayList(this.size() + array.size()) + result.addAll(this) + result.addAll(array) + return result """ } + doc(Sets) { "Returns a set containing all elements both of the original set and the given [array]." } body(Sets) { """ val result = LinkedHashSet(mapCapacity(this.size() + array.size())) @@ -156,6 +136,7 @@ fun generators(): List { return result """ } + doc(Sequences) { "Returns a sequence containing all elements of original sequence and then all elements of the given [array]." } body(Sequences) { """ return this.plus(array.asList()) @@ -163,20 +144,6 @@ fun generators(): List { } } - templates add f("plus(collection: SELF)") { - only(ArraysOfObjects, ArraysOfPrimitives) - returns("SELF") - body { - """ - val thisSize = size() - val answer = this.copyOf(thisSize + collection.size()) - collection.forEachIndexed { i, element -> - answer[thisSize + i] = element - } - return answer as SELF - """ - } - } templates add f("plus(sequence: Sequence)") { only(Sequences) diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/SpecialJS.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/SpecialJS.kt index 7caf0eae313..18bd82d9717 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/SpecialJS.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/SpecialJS.kt @@ -21,5 +21,98 @@ fun specialJS(): List { body(ArraysOfPrimitives) {"""return (this as Array).asList()"""} } + templates add f("copyOfRange(from: Int, to: Int)") { + // TODO: Arguments checking as in java? + only(ArraysOfObjects, ArraysOfPrimitives) + doc { "Returns new array which is a copy of range of original array." } + inline(true) + annotations("""suppress("NOTHING_TO_INLINE")""") + returns("SELF") + returns(ArraysOfObjects) { "Array" } + body { + "return (this: dynamic).slice(from, to)" + } + } + + templates add f("copyOf()") { + only(ArraysOfObjects, ArraysOfPrimitives) + doc { "Returns new array which is a copy of the original array." } + inline(true) + annotations("""suppress("NOTHING_TO_INLINE")""") + returns("SELF") + returns(ArraysOfObjects) { "Array" } + body { + "return (this: dynamic).slice(0)" + } + } + + val allArrays = PrimitiveType.defaultPrimitives.map { ArraysOfPrimitives to it } + (ArraysOfObjects to null) + templates addAll allArrays.map { + val (family, primitive) = it + f("copyOf(newSize: Int)") { + only(family) + val defaultValue: String + if (primitive != null) { + returns("SELF") + only(primitive) + defaultValue = when (primitive) { + PrimitiveType.Boolean -> false.toString() + PrimitiveType.Char -> "'\\u0000'" + else -> "ZERO" + } + } else { + returns(ArraysOfObjects) { "Array" } + defaultValue = "null" + } + doc { "Returns new array which is a copy of the original array." } + body { + """ + return arrayCopyResize(this, newSize, $defaultValue) + """ + } + } + } + + + templates add f("plus(element: T)") { + only(ArraysOfObjects, ArraysOfPrimitives) + returns("SELF") + doc { "Returns an array containing all elements of the original array and then the given [element]." } + body(ArraysOfObjects, ArraysOfPrimitives) { + """ + val result = this.copyOf() + (result: dynamic).push(element) + return result as SELF + """ + } + } + + templates add f("plus(collection: Collection)") { + only(ArraysOfObjects, ArraysOfPrimitives) + returns("SELF") + doc { "Returns an array containing all elements of the original array and then all elements of the given [collection]." } + body { + """ + return arrayPlusCollection(this, collection) + """ + } + } + + // This overload can cause nulls if array size is expanding, hence different return overload + templates add f("plus(array: SELF)") { + only(ArraysOfObjects, ArraysOfPrimitives) + doc { "Returns an array containing all elements of the original array and then all elements of the given [array]." } + inline(true) + annotations("""suppress("NOTHING_TO_INLINE")""") + returns("SELF") + body { + """ + return (this: dynamic).concat(array) + """ + } + } + + + return templates } \ No newline at end of file diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/SpecialJVM.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/SpecialJVM.kt index 3cd1e713263..7a17e3a7bcd 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/SpecialJVM.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/SpecialJVM.kt @@ -5,6 +5,51 @@ import templates.Family.* fun specialJVM(): List { val templates = arrayListOf() + templates add f("plus(element: T)") { + only(ArraysOfObjects, ArraysOfPrimitives) + returns("SELF") + doc { "Returns an array containing all elements of the original array and then the given [element]." } + body(ArraysOfObjects, ArraysOfPrimitives) { + """ + val result = this.copyOf(size() + 1) + result[size()] = element + return result as SELF + """ + } + } + + templates add f("plus(collection: Collection)") { + only(ArraysOfObjects, ArraysOfPrimitives) + returns("SELF") + doc { "Returns an array containing all elements of the original array and then all elements of the given [collection]." } + body { + """ + val thisSize = size() + val result = this.copyOf(thisSize + collection.size()) + collection.forEachIndexed { i, element -> + result[thisSize + i] = element + } + return result as SELF + """ + } + } + + templates add f("plus(array: SELF)") { + only(ArraysOfObjects, ArraysOfPrimitives) + doc { "Returns an array containing all elements of the original array and then all elements of the given [array]." } + returns("SELF") + body { + """ + val thisSize = size() + val arraySize = array.size() + val result = this.copyOf(thisSize + arraySize) + System.arraycopy(array, 0, result, thisSize, arraySize) + return result as SELF + """ + } + } + + templates add f("copyOfRange(from: Int, to: Int)") { only(ArraysOfObjects, ArraysOfPrimitives) doc { "Returns new array which is a copy of range of original array." }