[JS IR BE] Implement *Array.plus(Collection<>) in typed Kotlin without dynamic helper

This commit is contained in:
Svyatoslav Kuzmich
2019-01-24 18:33:42 +03:00
parent 8c89ffbe2d
commit a5f537adc5
3 changed files with 44 additions and 15 deletions
@@ -1015,21 +1015,30 @@ public actual operator fun <T> Array<out T>.plus(elements: Collection<T>): Array
* Returns an array containing all elements of the original array and then all elements of the given [elements] collection.
*/
public actual operator fun ByteArray.plus(elements: Collection<Byte>): ByteArray {
return fillFromCollection(this.copyOf(size + elements.size), this.size, elements)
var index = size
val result = this.copyOf(size + elements.size)
for (element in elements) result[index++] = element
return result
}
/**
* Returns an array containing all elements of the original array and then all elements of the given [elements] collection.
*/
public actual operator fun ShortArray.plus(elements: Collection<Short>): ShortArray {
return fillFromCollection(this.copyOf(size + elements.size), this.size, elements)
var index = size
val result = this.copyOf(size + elements.size)
for (element in elements) result[index++] = element
return result
}
/**
* Returns an array containing all elements of the original array and then all elements of the given [elements] collection.
*/
public actual operator fun IntArray.plus(elements: Collection<Int>): IntArray {
return fillFromCollection(this.copyOf(size + elements.size), this.size, elements)
var index = size
val result = this.copyOf(size + elements.size)
for (element in elements) result[index++] = element
return result
}
/**
@@ -1043,14 +1052,20 @@ public actual 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 actual operator fun FloatArray.plus(elements: Collection<Float>): FloatArray {
return fillFromCollection(this.copyOf(size + elements.size), this.size, elements)
var index = size
val result = this.copyOf(size + elements.size)
for (element in elements) result[index++] = element
return result
}
/**
* Returns an array containing all elements of the original array and then all elements of the given [elements] collection.
*/
public actual operator fun DoubleArray.plus(elements: Collection<Double>): DoubleArray {
return fillFromCollection(this.copyOf(size + elements.size), this.size, elements)
var index = size
val result = this.copyOf(size + elements.size)
for (element in elements) result[index++] = element
return result
}
/**
@@ -1064,7 +1079,10 @@ public actual operator fun BooleanArray.plus(elements: Collection<Boolean>): Boo
* Returns an array containing all elements of the original array and then all elements of the given [elements] collection.
*/
public actual operator fun CharArray.plus(elements: Collection<Char>): CharArray {
return fillFromCollection(this.copyOf(size + elements.size), this.size, elements)
var index = size
val result = this.copyOf(size + elements.size)
for (element in elements) result[index++] = element
return result
}
/**
@@ -66,13 +66,6 @@ internal fun <T> arrayPlusCollection(array: dynamic, collection: Collection<T>):
return result
}
internal fun <T> fillFromCollection(dst: dynamic, startIndex: Int, collection: Collection<T>): dynamic {
var index = startIndex
val arr = dst.unsafeCast<Array<T>>()
for (element in collection) arr[index++] = element
return dst
}
internal inline fun copyArrayType(from: dynamic, to: dynamic) {
if (from.`$type$` !== undefined) {
to.`$type$` = from.`$type$`
@@ -532,8 +532,26 @@ object ArrayOps : TemplateGroupBase() {
when (primitive) {
null, PrimitiveType.Boolean, PrimitiveType.Long ->
body { "return arrayPlusCollection(this, elements)" }
else ->
body { "return fillFromCollection(this.copyOf(size + elements.size), this.size, elements)" }
else -> {
on(Backend.Legacy) {
body {
"return fillFromCollection(this.copyOf(size + elements.size), this.size, elements)"
}
}
on(Backend.IR) {
// Don't use fillFromCollection because it treats arrays
// as `dynamic` but we need to concrete types to perform
// unboxing of collections elements
body {
"""
var index = size
val result = this.copyOf(size + elements.size)
for (element in elements) result[index++] = element
return result
"""
}
}
}
}
}
on(Platform.Native) {