JS: fixed <Type>Array.iterator methods; added -Xtypedarray compiler key
The <Type>Array.iterator used to lack next<Type>() method (KT-16626). The -Xtypedarray compiler key enables translation of primitive arrays to TypedArrays, and primitive array`is`-checks (KT-15358, KT-14007, KT-14614, KT-16056).
This commit is contained in:
@@ -19,22 +19,54 @@
|
||||
external private fun <T> Array(size: Int): Array<T>
|
||||
|
||||
@JsName("newArray")
|
||||
fun <T> newArray(size: Int, initValue: T): Array<T> {
|
||||
return fillArray(Array(size), initValue)
|
||||
}
|
||||
|
||||
private fun <T> fillArray(array: Array<T>, value: T): Array<T> {
|
||||
for (i in 0..array.size - 1) {
|
||||
array[i] = value
|
||||
}
|
||||
return array;
|
||||
}
|
||||
fun <T> newArray(size: Int, initValue: T) = fillArrayVal(Array<T>(size), initValue)
|
||||
|
||||
@JsName("newArrayF")
|
||||
fun <T> arrayWithFun(size: Int, init: (Int) -> T): Array<T> {
|
||||
var result = Array<T>(size)
|
||||
for (i in 0..size - 1) {
|
||||
result[i] = init(i)
|
||||
fun <T> arrayWithFun(size: Int, init: (Int) -> T) = fillArrayFun(Array<T>(size), init)
|
||||
|
||||
@JsName("fillArray")
|
||||
fun <T> fillArrayFun(array: Array<T>, init: (Int) -> T): Array<T> {
|
||||
for (i in 0..array.size - 1) {
|
||||
array[i] = init(i)
|
||||
}
|
||||
return result
|
||||
return array
|
||||
}
|
||||
|
||||
@JsName("booleanArray")
|
||||
fun booleanArray(size: Int, init: dynamic): Array<Boolean> {
|
||||
val result: dynamic = Array<Boolean>(size)
|
||||
result.`$type$` = "BooleanArray"
|
||||
return when (init) {
|
||||
null, true -> fillArrayVal(result, false)
|
||||
false -> result
|
||||
else -> fillArrayFun<Boolean>(result, init)
|
||||
}
|
||||
}
|
||||
|
||||
@JsName("charArray")
|
||||
fun charArray(size: Int, init: dynamic): Array<Char> {
|
||||
val result = js("new Uint16Array(size)")
|
||||
result.`$type$` = "CharArray"
|
||||
return when (init) {
|
||||
null, true, false -> result // For consistency
|
||||
else -> fillArrayFun<Char>(result, init)
|
||||
}
|
||||
}
|
||||
|
||||
@JsName("longArray")
|
||||
fun longArray(size: Int, init: dynamic): Array<Long> {
|
||||
val result: dynamic = Array<Long>(size)
|
||||
result.`$type$` = "LongArray"
|
||||
return when (init) {
|
||||
null, true -> fillArrayVal(result, 0L)
|
||||
false -> result
|
||||
else -> fillArrayFun<Long>(result, init)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <T> fillArrayVal(array: Array<T>, initValue: T): Array<T> {
|
||||
for (i in 0..array.size - 1) {
|
||||
array[i] = initValue
|
||||
}
|
||||
return array
|
||||
}
|
||||
@@ -15,21 +15,80 @@
|
||||
*/
|
||||
|
||||
@JsName("arrayIterator")
|
||||
internal fun arrayIterator(array: dynamic): MutableIterator<dynamic> {
|
||||
return object : MutableIterator<dynamic> {
|
||||
var index = 0;
|
||||
|
||||
override fun hasNext(): Boolean {
|
||||
val length: Int = array.length
|
||||
return index < length
|
||||
}
|
||||
|
||||
override fun next() = array[index++]
|
||||
|
||||
override fun remove() {
|
||||
array.splice(--index, 1)
|
||||
internal fun arrayIterator(array: dynamic, type: String?) = when (type) {
|
||||
null -> {
|
||||
val arr: Array<dynamic> = array
|
||||
object : Iterator<dynamic> {
|
||||
var index = 0
|
||||
override fun hasNext() = index < arr.size
|
||||
override fun next() = if (index < arr.size) arr[index++] else throw IndexOutOfBoundsException("$index")
|
||||
}
|
||||
}
|
||||
"BooleanArray" -> booleanArrayIterator(array)
|
||||
"ByteArray" -> byteArrayIterator(array)
|
||||
"ShortArray" -> shortArrayIterator(array)
|
||||
"CharArray" -> charArrayIterator(array)
|
||||
"IntArray" -> intArrayIterator(array)
|
||||
"LongArray" -> longArrayIterator(array)
|
||||
"FloatArray" -> floatArrayIterator(array)
|
||||
"DoubleArray" -> doubleArrayIterator(array)
|
||||
else -> throw IllegalStateException("Unsupported type argument for arrayIterator: $type")
|
||||
}
|
||||
|
||||
@JsName("booleanArrayIterator")
|
||||
internal fun booleanArrayIterator(array: BooleanArray) = object : BooleanIterator() {
|
||||
var index = 0
|
||||
override fun hasNext() = index < array.size
|
||||
override fun nextBoolean() = if (index < array.size) array[index++] else throw IndexOutOfBoundsException("$index")
|
||||
}
|
||||
|
||||
@JsName("byteArrayIterator")
|
||||
internal fun byteArrayIterator(array: ByteArray) = object : ByteIterator() {
|
||||
var index = 0
|
||||
override fun hasNext() = index < array.size
|
||||
override fun nextByte() = if (index < array.size) array[index++] else throw IndexOutOfBoundsException("$index")
|
||||
}
|
||||
|
||||
@JsName("shortArrayIterator")
|
||||
internal fun shortArrayIterator(array: ShortArray) = object : ShortIterator() {
|
||||
var index = 0
|
||||
override fun hasNext() = index < array.size
|
||||
override fun nextShort() = if (index < array.size) array[index++] else throw IndexOutOfBoundsException("$index")
|
||||
}
|
||||
|
||||
@JsName("charArrayIterator")
|
||||
internal fun charArrayIterator(array: CharArray) = object : CharIterator() {
|
||||
var index = 0
|
||||
override fun hasNext() = index < array.size
|
||||
override fun nextChar() = if (index < array.size) array[index++] else throw IndexOutOfBoundsException("$index")
|
||||
}
|
||||
|
||||
@JsName("intArrayIterator")
|
||||
internal fun intArrayIterator(array: IntArray) = object : IntIterator() {
|
||||
var index = 0
|
||||
override fun hasNext() = index < array.size
|
||||
override fun nextInt() = if (index < array.size) array[index++] else throw IndexOutOfBoundsException("$index")
|
||||
}
|
||||
|
||||
@JsName("floatArrayIterator")
|
||||
internal fun floatArrayIterator(array: FloatArray) = object : FloatIterator() {
|
||||
var index = 0
|
||||
override fun hasNext() = index < array.size
|
||||
override fun nextFloat() = if (index < array.size) array[index++] else throw IndexOutOfBoundsException("$index")
|
||||
}
|
||||
|
||||
@JsName("doubleArrayIterator")
|
||||
internal fun doubleArrayIterator(array: DoubleArray) = object : DoubleIterator() {
|
||||
var index = 0
|
||||
override fun hasNext() = index < array.size
|
||||
override fun nextDouble() = if (index < array.size) array[index++] else throw IndexOutOfBoundsException("$index")
|
||||
}
|
||||
|
||||
@JsName("longArrayIterator")
|
||||
internal fun longArrayIterator(array: LongArray) = object : LongIterator() {
|
||||
var index = 0
|
||||
override fun hasNext() = index < array.size
|
||||
override fun nextLong() = if (index < array.size) array[index++] else throw IndexOutOfBoundsException("$index")
|
||||
}
|
||||
|
||||
@JsName("PropertyMetadata")
|
||||
@@ -96,23 +155,71 @@ internal class BoxedChar(val c: Char) : Comparable<Char> {
|
||||
}
|
||||
}
|
||||
|
||||
/* For future binary compatibility with TypedArrays
|
||||
* TODO: concat normal Array's and TypedArrays into an Array
|
||||
internal inline fun <T> concat(args: Array<T>): T {
|
||||
val typed = js("Array")(args.size)
|
||||
for (i in 0..args.size - 1) {
|
||||
val arr = args[i]
|
||||
if (arr !is Array<*>) {
|
||||
typed[i] = js("[]").slice.call(arr)
|
||||
}
|
||||
else {
|
||||
typed[i] = arr
|
||||
}
|
||||
}
|
||||
return js("[]").concat.apply(js("[]"), typed);
|
||||
}
|
||||
|
||||
/** Concat regular Array's and TypedArray's into an Array.
|
||||
*/
|
||||
@PublishedApi
|
||||
@JsName("arrayConcat")
|
||||
internal fun <T> arrayConcat(a: T, b: T): T {
|
||||
return a.asDynamic().concat.apply(js("[]"), js("arguments"));
|
||||
return concat(js("arguments"))
|
||||
}
|
||||
|
||||
/* For future binary compatibility with TypedArrays
|
||||
* TODO: concat primitive arrays.
|
||||
* For Byte-, Short-, Int-, Float-, and DoubleArray concat result into a TypedArray.
|
||||
* For Boolean-, Char-, and LongArray return an Array with corresponding type property.
|
||||
* Default to Array.prototype.concat for compatibility.
|
||||
/** Concat primitive arrays. Main use: prepare vararg arguments.
|
||||
* For compatibility with 1.1.0 the arguments may be a mixture of Array's and TypedArray's.
|
||||
*
|
||||
* If the first argument is TypedArray (Byte-, Short-, Char-, Int-, Float-, and DoubleArray) returns a TypedArray, otherwise an Array.
|
||||
* If the first argument has the $type$ property (Boolean-, Char-, and LongArray) copy its value to result.$type$.
|
||||
* If the first argument is a regular Array without the $type$ property default to arrayConcat.
|
||||
*/
|
||||
@PublishedApi
|
||||
@JsName("primitiveArrayConcat")
|
||||
internal fun <T> primitiveArrayConcat(a: T, b: T): T {
|
||||
return a.asDynamic().concat.apply(js("[]"), js("arguments"));
|
||||
val args: Array<T> = js("arguments")
|
||||
if (a is Array<*> && a.asDynamic().`$type$` === undefined) {
|
||||
return concat(args)
|
||||
}
|
||||
else {
|
||||
var size = 0
|
||||
for (i in 0..args.size - 1) {
|
||||
size += args[i].asDynamic().length as Int
|
||||
}
|
||||
val result = js("new a.constructor(size)")
|
||||
kotlin.copyArrayType(a, result)
|
||||
size = 0
|
||||
for (i in 0..args.size - 1) {
|
||||
val arr = args[i].asDynamic()
|
||||
for (j in 0..arr.length - 1) {
|
||||
result[size++] = arr[j]
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@JsName("booleanArrayOf")
|
||||
internal fun booleanArrayOf() = withType("BooleanArray", js("[].slice.call(arguments)"))
|
||||
|
||||
@JsName("charArrayOf") // The arguments have to be slice'd here because of Rhino (see KT-16974)
|
||||
internal fun charArrayOf() = withType("CharArray", js("new Uint16Array([].slice.call(arguments))"))
|
||||
|
||||
@JsName("longArrayOf")
|
||||
internal fun longArrayOf() = withType("LongArray", js("[].slice.call(arguments)"))
|
||||
|
||||
@JsName("withType")
|
||||
internal inline fun withType(type: String, array: dynamic): dynamic {
|
||||
array.`$type$` = type
|
||||
return array
|
||||
}
|
||||
@@ -49,7 +49,7 @@ public operator fun dynamic.iterator(): Iterator<dynamic> {
|
||||
return when {
|
||||
this["iterator"] != null ->
|
||||
this["iterator"]()
|
||||
js("Array").isArray(r) ->
|
||||
js("Kotlin").isArrayish(r) ->
|
||||
r.unsafeCast<Array<*>>().iterator()
|
||||
|
||||
else ->
|
||||
|
||||
@@ -10,6 +10,7 @@ package kotlin.collections
|
||||
|
||||
import kotlin.js.*
|
||||
import primitiveArrayConcat
|
||||
import withType
|
||||
import kotlin.comparisons.*
|
||||
|
||||
/**
|
||||
@@ -13011,9 +13012,8 @@ public inline fun IntArray.copyOf(): IntArray {
|
||||
/**
|
||||
* Returns new array which is a copy of the original array.
|
||||
*/
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
public inline fun LongArray.copyOf(): LongArray {
|
||||
return this.asDynamic().slice()
|
||||
public fun LongArray.copyOf(): LongArray {
|
||||
return withType("LongArray", this.asDynamic().slice())
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -13035,73 +13035,71 @@ public inline fun DoubleArray.copyOf(): DoubleArray {
|
||||
/**
|
||||
* Returns new array which is a copy of the original array.
|
||||
*/
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
public inline fun BooleanArray.copyOf(): BooleanArray {
|
||||
return this.asDynamic().slice()
|
||||
public fun BooleanArray.copyOf(): BooleanArray {
|
||||
return withType("BooleanArray", this.asDynamic().slice())
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns new array which is a copy of the original array.
|
||||
*/
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
public inline fun CharArray.copyOf(): CharArray {
|
||||
return this.asDynamic().slice()
|
||||
public fun CharArray.copyOf(): CharArray {
|
||||
return withType("CharArray", this.asDynamic().slice())
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns new array which is a copy of the original array, resized to the given [newSize].
|
||||
*/
|
||||
public fun ByteArray.copyOf(newSize: Int): ByteArray {
|
||||
return arrayCopyResize(this, newSize, 0)
|
||||
return fillFrom(this, ByteArray(newSize))
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns new array which is a copy of the original array, resized to the given [newSize].
|
||||
*/
|
||||
public fun ShortArray.copyOf(newSize: Int): ShortArray {
|
||||
return arrayCopyResize(this, newSize, 0)
|
||||
return fillFrom(this, ShortArray(newSize))
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns new array which is a copy of the original array, resized to the given [newSize].
|
||||
*/
|
||||
public fun IntArray.copyOf(newSize: Int): IntArray {
|
||||
return arrayCopyResize(this, newSize, 0)
|
||||
return fillFrom(this, IntArray(newSize))
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns new array which is a copy of the original array, resized to the given [newSize].
|
||||
*/
|
||||
public fun LongArray.copyOf(newSize: Int): LongArray {
|
||||
return arrayCopyResize(this, newSize, 0L)
|
||||
return withType("LongArray", arrayCopyResize(this, newSize, 0L))
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns new array which is a copy of the original array, resized to the given [newSize].
|
||||
*/
|
||||
public fun FloatArray.copyOf(newSize: Int): FloatArray {
|
||||
return arrayCopyResize(this, newSize, 0.0f)
|
||||
return fillFrom(this, FloatArray(newSize))
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns new array which is a copy of the original array, resized to the given [newSize].
|
||||
*/
|
||||
public fun DoubleArray.copyOf(newSize: Int): DoubleArray {
|
||||
return arrayCopyResize(this, newSize, 0.0)
|
||||
return fillFrom(this, DoubleArray(newSize))
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns new array which is a copy of the original array, resized to the given [newSize].
|
||||
*/
|
||||
public fun BooleanArray.copyOf(newSize: Int): BooleanArray {
|
||||
return arrayCopyResize(this, newSize, false)
|
||||
return withType("BooleanArray", arrayCopyResize(this, newSize, false))
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns new array which is a copy of the original array, resized to the given [newSize].
|
||||
*/
|
||||
public fun CharArray.copyOf(newSize: Int): CharArray {
|
||||
return arrayCopyResize(this, newSize, 0)
|
||||
return withType("CharArray", fillFrom(this, CharArray(newSize)))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -13146,9 +13144,8 @@ public inline fun IntArray.copyOfRange(fromIndex: Int, toIndex: Int): IntArray {
|
||||
/**
|
||||
* Returns new array which is a copy of range of original array.
|
||||
*/
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
public inline fun LongArray.copyOfRange(fromIndex: Int, toIndex: Int): LongArray {
|
||||
return this.asDynamic().slice(fromIndex, toIndex)
|
||||
public fun LongArray.copyOfRange(fromIndex: Int, toIndex: Int): LongArray {
|
||||
return withType("LongArray", this.asDynamic().slice(fromIndex, toIndex))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -13170,17 +13167,15 @@ public inline fun DoubleArray.copyOfRange(fromIndex: Int, toIndex: Int): DoubleA
|
||||
/**
|
||||
* Returns new array which is a copy of range of original array.
|
||||
*/
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
public inline fun BooleanArray.copyOfRange(fromIndex: Int, toIndex: Int): BooleanArray {
|
||||
return this.asDynamic().slice(fromIndex, toIndex)
|
||||
public fun BooleanArray.copyOfRange(fromIndex: Int, toIndex: Int): BooleanArray {
|
||||
return withType("BooleanArray", this.asDynamic().slice(fromIndex, toIndex))
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns new array which is a copy of range of original array.
|
||||
*/
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
public inline fun CharArray.copyOfRange(fromIndex: Int, toIndex: Int): CharArray {
|
||||
return this.asDynamic().slice(fromIndex, toIndex)
|
||||
public fun CharArray.copyOfRange(fromIndex: Int, toIndex: Int): CharArray {
|
||||
return withType("CharArray", this.asDynamic().slice(fromIndex, toIndex))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -13266,21 +13261,21 @@ public operator fun <T> Array<out T>.plus(elements: Collection<T>): Array<T> {
|
||||
* Returns an array containing all elements of the original array and then all elements of the given [elements] collection.
|
||||
*/
|
||||
public operator fun ByteArray.plus(elements: Collection<Byte>): ByteArray {
|
||||
return arrayPlusCollection(this, elements)
|
||||
return fillFromCollection(this.copyOf(size + elements.size), this.size, elements)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing all elements of the original array and then all elements of the given [elements] collection.
|
||||
*/
|
||||
public operator fun ShortArray.plus(elements: Collection<Short>): ShortArray {
|
||||
return arrayPlusCollection(this, elements)
|
||||
return fillFromCollection(this.copyOf(size + elements.size), this.size, elements)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing all elements of the original array and then all elements of the given [elements] collection.
|
||||
*/
|
||||
public operator fun IntArray.plus(elements: Collection<Int>): IntArray {
|
||||
return arrayPlusCollection(this, elements)
|
||||
return fillFromCollection(this.copyOf(size + elements.size), this.size, elements)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -13294,14 +13289,14 @@ public operator fun LongArray.plus(elements: Collection<Long>): LongArray {
|
||||
* Returns an array containing all elements of the original array and then all elements of the given [elements] collection.
|
||||
*/
|
||||
public operator fun FloatArray.plus(elements: Collection<Float>): FloatArray {
|
||||
return arrayPlusCollection(this, elements)
|
||||
return fillFromCollection(this.copyOf(size + elements.size), this.size, elements)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing all elements of the original array and then all elements of the given [elements] collection.
|
||||
*/
|
||||
public operator fun DoubleArray.plus(elements: Collection<Double>): DoubleArray {
|
||||
return arrayPlusCollection(this, elements)
|
||||
return fillFromCollection(this.copyOf(size + elements.size), this.size, elements)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -13315,7 +13310,7 @@ public operator fun BooleanArray.plus(elements: Collection<Boolean>): BooleanArr
|
||||
* Returns an array containing all elements of the original array and then all elements of the given [elements] collection.
|
||||
*/
|
||||
public operator fun CharArray.plus(elements: Collection<Char>): CharArray {
|
||||
return arrayPlusCollection(this, elements)
|
||||
return fillFromCollection(this.copyOf(size + elements.size), this.size, elements)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -13474,21 +13469,21 @@ public fun <T> Array<out T>.sortWith(comparator: Comparator<in T>): Unit {
|
||||
* Returns a *typed* object array containing all of the elements of this primitive array.
|
||||
*/
|
||||
public fun ByteArray.toTypedArray(): Array<Byte> {
|
||||
return copyOf().unsafeCast<Array<Byte>>()
|
||||
return js("[]").slice.call(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a *typed* object array containing all of the elements of this primitive array.
|
||||
*/
|
||||
public fun ShortArray.toTypedArray(): Array<Short> {
|
||||
return copyOf().unsafeCast<Array<Short>>()
|
||||
return js("[]").slice.call(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a *typed* object array containing all of the elements of this primitive array.
|
||||
*/
|
||||
public fun IntArray.toTypedArray(): Array<Int> {
|
||||
return copyOf().unsafeCast<Array<Int>>()
|
||||
return js("[]").slice.call(this)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -13502,14 +13497,14 @@ public fun LongArray.toTypedArray(): Array<Long> {
|
||||
* Returns a *typed* object array containing all of the elements of this primitive array.
|
||||
*/
|
||||
public fun FloatArray.toTypedArray(): Array<Float> {
|
||||
return copyOf().unsafeCast<Array<Float>>()
|
||||
return js("[]").slice.call(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a *typed* object array containing all of the elements of this primitive array.
|
||||
*/
|
||||
public fun DoubleArray.toTypedArray(): Array<Double> {
|
||||
return copyOf().unsafeCast<Array<Double>>()
|
||||
return js("[]").slice.call(this)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -71,8 +71,18 @@ internal fun <T> arrayOfNulls(reference: Array<out T>, size: Int): Array<T> {
|
||||
return arrayOfNulls<Any>(size).unsafeCast<Array<T>>()
|
||||
}
|
||||
|
||||
internal fun fillFrom(src: dynamic, dst: dynamic): dynamic {
|
||||
val srcLen: Int = src.length
|
||||
val dstLen: Int = dst.length
|
||||
var index: Int = 0
|
||||
while (index < srcLen && index < dstLen) dst[index] = src[index++]
|
||||
return dst
|
||||
}
|
||||
|
||||
|
||||
internal fun arrayCopyResize(source: dynamic, newSize: Int, defaultValue: Any?): dynamic {
|
||||
val result = source.slice(0, newSize)
|
||||
copyArrayType(source, result)
|
||||
var index: Int = source.length
|
||||
if (newSize > index) {
|
||||
result.length = newSize
|
||||
@@ -84,11 +94,24 @@ internal fun arrayCopyResize(source: dynamic, newSize: Int, defaultValue: Any?):
|
||||
internal fun <T> arrayPlusCollection(array: dynamic, collection: Collection<T>): dynamic {
|
||||
val result = array.slice()
|
||||
result.length += collection.size
|
||||
copyArrayType(array, result)
|
||||
var index: Int = array.length
|
||||
for (element in collection) result[index++] = element
|
||||
return result
|
||||
}
|
||||
|
||||
internal fun <T> fillFromCollection(dst: dynamic, startIndex: Int, collection: Collection<T>): dynamic {
|
||||
var index = startIndex
|
||||
for (element in collection) dst[index++] = element
|
||||
return dst
|
||||
}
|
||||
|
||||
internal inline fun copyArrayType(from: dynamic, to: dynamic) {
|
||||
if (from.`$type$` !== undefined) {
|
||||
to.`$type$` = from.`$type$`
|
||||
}
|
||||
}
|
||||
|
||||
// no singleton map implementation in js, return map as is
|
||||
internal inline fun <K, V> Map<K, V>.toSingletonMapOrSelf(): Map<K, V> = this
|
||||
|
||||
|
||||
@@ -14,21 +14,65 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
Kotlin.isBooleanArray = function (a) {
|
||||
return (Array.isArray(a) || a instanceof Int8Array) && a.$type$ === "BooleanArray"
|
||||
};
|
||||
|
||||
Kotlin.isByteArray = function (a) {
|
||||
return a instanceof Int8Array && a.$type$ !== "BooleanArray"
|
||||
};
|
||||
|
||||
Kotlin.isShortArray = function (a) {
|
||||
return a instanceof Int16Array
|
||||
};
|
||||
|
||||
Kotlin.isCharArray = function (a) {
|
||||
return a instanceof Uint16Array && a.$type$ === "CharArray"
|
||||
};
|
||||
|
||||
Kotlin.isIntArray = function (a) {
|
||||
return a instanceof Int32Array
|
||||
};
|
||||
|
||||
Kotlin.isFloatArray = function (a) {
|
||||
return a instanceof Float32Array
|
||||
};
|
||||
|
||||
Kotlin.isDoubleArray = function (a) {
|
||||
return a instanceof Float64Array
|
||||
};
|
||||
|
||||
Kotlin.isLongArray = function (a) {
|
||||
return Array.isArray(a) && a.$type$ === "LongArray"
|
||||
};
|
||||
|
||||
Kotlin.isArray = function (a) {
|
||||
return Array.isArray(a) && !a.$type$;
|
||||
};
|
||||
|
||||
Kotlin.isArrayish = function (a) {
|
||||
return Array.isArray(a) || ArrayBuffer.isView(a)
|
||||
};
|
||||
|
||||
Kotlin.arrayToString = function (a) {
|
||||
return "[" + a.map(Kotlin.toString).join(", ") + "]";
|
||||
};
|
||||
|
||||
Kotlin.arrayDeepToString = function (a, visited) {
|
||||
visited = visited || [a];
|
||||
return "[" + a.map(function(e) {
|
||||
if (Array.isArray(e) && visited.indexOf(e) < 0) {
|
||||
var toString = Kotlin.toString;
|
||||
if (Kotlin.isCharArray(a)) {
|
||||
toString = String.fromCharCode;
|
||||
}
|
||||
return "[" + a.map(function (e) {
|
||||
if (Kotlin.isArrayish(e) && visited.indexOf(e) < 0) {
|
||||
visited.push(e);
|
||||
var result = Kotlin.arrayDeepToString(e, visited);
|
||||
visited.pop();
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
return Kotlin.toString(e);
|
||||
return toString(e);
|
||||
}
|
||||
}).join(", ") + "]";
|
||||
};
|
||||
@@ -37,7 +81,7 @@ Kotlin.arrayEquals = function (a, b) {
|
||||
if (a === b) {
|
||||
return true;
|
||||
}
|
||||
if (!Array.isArray(b) || a.length !== b.length) {
|
||||
if (!Kotlin.isArrayish(b) || a.length !== b.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -53,16 +97,17 @@ Kotlin.arrayDeepEquals = function (a, b) {
|
||||
if (a === b) {
|
||||
return true;
|
||||
}
|
||||
if (!Array.isArray(b) || a.length !== b.length) {
|
||||
if (!Kotlin.isArrayish(b) || a.length !== b.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0, n = a.length; i < n; i++) {
|
||||
if (Array.isArray(a[i])) {
|
||||
if (Kotlin.isArrayish(a[i])) {
|
||||
if (!Kotlin.arrayDeepEquals(a[i], b[i])) {
|
||||
return false;
|
||||
}
|
||||
} else if (!Kotlin.equals(a[i], b[i])) {
|
||||
}
|
||||
else if (!Kotlin.equals(a[i], b[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -81,11 +126,11 @@ Kotlin.arrayDeepHashCode = function (arr) {
|
||||
var result = 1;
|
||||
for (var i = 0, n = arr.length; i < n; i++) {
|
||||
var e = arr[i];
|
||||
result = ((31 * result | 0) + (Array.isArray(e) ? Kotlin.arrayDeepHashCode(e) : Kotlin.hashCode(e))) | 0;
|
||||
result = ((31 * result | 0) + (Kotlin.isArrayish(e) ? Kotlin.arrayDeepHashCode(e) : Kotlin.hashCode(e))) | 0;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
Kotlin.primitiveArraySort = function(array) {
|
||||
Kotlin.primitiveArraySort = function (array) {
|
||||
array.sort(Kotlin.primitiveCompareTo)
|
||||
};
|
||||
|
||||
@@ -59,7 +59,7 @@ Kotlin.toString = function (o) {
|
||||
if (o == null) {
|
||||
return "null";
|
||||
}
|
||||
else if (Array.isArray(o)) {
|
||||
else if (Kotlin.isArrayish(o)) {
|
||||
return "[...]";
|
||||
}
|
||||
else {
|
||||
|
||||
Reference in New Issue
Block a user