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:
@@ -228,11 +228,10 @@ class ArraysTest {
|
||||
assertEquals(arr.asList().toString(), arr.contentToString())
|
||||
}
|
||||
|
||||
// @Ignore("KT-16056")
|
||||
// @Test fun contentDeepToString() {
|
||||
// val arr = arrayOf("aa", 1, null, charArrayOf('d'))
|
||||
// assertEquals("[aa, 1, null, [d]]", arr.contentDeepToString())
|
||||
// }
|
||||
@Test fun contentDeepToString() {
|
||||
val arr = arrayOf("aa", 1, null, charArrayOf('d'))
|
||||
assertEquals("[aa, 1, null, [d]]", arr.contentDeepToString())
|
||||
}
|
||||
|
||||
@Test fun contentDeepToStringNoRecursion() {
|
||||
// a[b[a, b]]
|
||||
|
||||
+7
-1
@@ -48,4 +48,10 @@ interface KotlinJsOptions : org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
|
||||
* Default value: "v5"
|
||||
*/
|
||||
var target: kotlin.String
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate primitive arrays to JS typed arrays
|
||||
* Default value: false
|
||||
*/
|
||||
var typedArrays: kotlin.Boolean
|
||||
}
|
||||
+8
-1
@@ -59,6 +59,11 @@ internal abstract class KotlinJsOptionsBase : org.jetbrains.kotlin.gradle.dsl.Ko
|
||||
get() = targetField ?: "v5"
|
||||
set(value) { targetField = value }
|
||||
|
||||
private var typedArraysField: kotlin.Boolean? = null
|
||||
override var typedArrays: kotlin.Boolean
|
||||
get() = typedArraysField ?: false
|
||||
set(value) { typedArraysField = value }
|
||||
|
||||
internal open fun updateArguments(args: org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments) {
|
||||
apiVersionField?.let { args.apiVersion = it }
|
||||
languageVersionField?.let { args.languageVersion = it }
|
||||
@@ -71,6 +76,7 @@ internal abstract class KotlinJsOptionsBase : org.jetbrains.kotlin.gradle.dsl.Ko
|
||||
outputFileField?.let { args.outputFile = it }
|
||||
sourceMapField?.let { args.sourceMap = it }
|
||||
targetField?.let { args.target = it }
|
||||
typedArraysField?.let { args.typedArrays = it }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,4 +92,5 @@ internal fun org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments.fil
|
||||
outputFile = null
|
||||
sourceMap = false
|
||||
target = "v5"
|
||||
}
|
||||
typedArrays = false
|
||||
}
|
||||
@@ -103,6 +103,7 @@ private fun List<ConcreteFunction>.writeTo(file: File, sourceFile: SourceFile, p
|
||||
writer.appendln("import kotlin.js.*")
|
||||
if (sourceFile == SourceFile.Arrays) {
|
||||
writer.appendln("import primitiveArrayConcat")
|
||||
writer.appendln("import withType")
|
||||
}
|
||||
}
|
||||
writer.append("import kotlin.comparisons.*\n\n")
|
||||
|
||||
@@ -211,33 +211,43 @@ object CommonArrays {
|
||||
}
|
||||
}
|
||||
|
||||
fun f_plusCollection() = f("plus(elements: Collection<T>)") {
|
||||
operator(true)
|
||||
fun f_plusCollection() =
|
||||
(listOf(InvariantArraysOfObjects to null) + PrimitiveType.defaultPrimitives.map { ArraysOfPrimitives to it }).map {
|
||||
val (family, primitive) = it
|
||||
f("plus(elements: Collection<T>)") {
|
||||
operator(true)
|
||||
|
||||
// TODO: inline arrayPlusCollection when @PublishedAPI is available
|
||||
// inline(Platform.JS, Inline.Yes)
|
||||
// annotations(Platform.JS, """@Suppress("NOTHING_TO_INLINE")""")
|
||||
only(family)
|
||||
if (family == InvariantArraysOfObjects) {
|
||||
only(Platform.JS, ArraysOfObjects)
|
||||
}
|
||||
|
||||
only(InvariantArraysOfObjects, ArraysOfPrimitives)
|
||||
only(Platform.JS, ArraysOfObjects, ArraysOfPrimitives)
|
||||
// TODO: inline arrayPlusCollection when @PublishedAPI is available
|
||||
// inline(Platform.JS, Inline.Yes)
|
||||
// annotations(Platform.JS, """@Suppress("NOTHING_TO_INLINE")""")
|
||||
|
||||
returns("SELF")
|
||||
returns(Platform.JS, ArraysOfObjects) { "Array<T>" }
|
||||
doc { "Returns an array containing all elements of the original array and then all elements of the given [elements] collection." }
|
||||
body(Platform.JVM) {
|
||||
"""
|
||||
var index = size
|
||||
val result = java.util.Arrays.copyOf(this, index + elements.size)
|
||||
for (element in elements) result[index++] = element
|
||||
return result
|
||||
"""
|
||||
}
|
||||
body(Platform.JS) {
|
||||
"""
|
||||
return arrayPlusCollection(this, elements)
|
||||
"""
|
||||
}
|
||||
}
|
||||
returns("SELF")
|
||||
returns(Platform.JS, ArraysOfObjects) { "Array<T>" }
|
||||
doc { "Returns an array containing all elements of the original array and then all elements of the given [elements] collection." }
|
||||
body(Platform.JVM) {
|
||||
"""
|
||||
var index = size
|
||||
val result = java.util.Arrays.copyOf(this, index + elements.size)
|
||||
for (element in elements) result[index++] = element
|
||||
return result
|
||||
"""
|
||||
}
|
||||
if (primitive != null) {
|
||||
only(primitive)
|
||||
}
|
||||
when (primitive) {
|
||||
null, PrimitiveType.Boolean, PrimitiveType.Long ->
|
||||
body(Platform.JS) { "return arrayPlusCollection(this, elements)" }
|
||||
else ->
|
||||
body(Platform.JS) { "return fillFromCollection(this.copyOf(size + elements.size), this.size, elements)" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun f_plusArray() = f("plus(elements: SELF)") {
|
||||
operator(true)
|
||||
@@ -275,81 +285,110 @@ object CommonArrays {
|
||||
|
||||
}
|
||||
|
||||
fun f_copyOfRange() = f("copyOfRange(fromIndex: Int, toIndex: Int)") {
|
||||
inline(Platform.JVM, Inline.Only)
|
||||
inline(Platform.JS, Inline.Yes)
|
||||
annotations(Platform.JS, """@Suppress("NOTHING_TO_INLINE")""")
|
||||
fun f_copyOfRange() = (listOf(InvariantArraysOfObjects to null) + PrimitiveType.defaultPrimitives.map { ArraysOfPrimitives to it }).map {
|
||||
val (family, primitive) = it
|
||||
f("copyOfRange(fromIndex: Int, toIndex: Int)") {
|
||||
only(family)
|
||||
if (family == InvariantArraysOfObjects) {
|
||||
only(Platform.JS, ArraysOfObjects)
|
||||
}
|
||||
|
||||
only(InvariantArraysOfObjects, ArraysOfPrimitives)
|
||||
only(Platform.JS, ArraysOfObjects, ArraysOfPrimitives)
|
||||
inline(Platform.JVM, Inline.Only)
|
||||
|
||||
doc { "Returns new array which is a copy of range of original array." }
|
||||
returns("SELF")
|
||||
returns(Platform.JS, ArraysOfObjects) { "Array<T>" }
|
||||
body(Platform.JVM) {
|
||||
"return java.util.Arrays.copyOfRange(this, fromIndex, toIndex)"
|
||||
}
|
||||
body(Platform.JS) {
|
||||
// TODO: Arguments checking as in java?
|
||||
"return this.asDynamic().slice(fromIndex, toIndex)"
|
||||
doc { "Returns new array which is a copy of range of original array." }
|
||||
returns("SELF")
|
||||
returns(Platform.JS, ArraysOfObjects) { "Array<T>" }
|
||||
body(Platform.JVM) {
|
||||
"return java.util.Arrays.copyOfRange(this, fromIndex, toIndex)"
|
||||
}
|
||||
|
||||
if (primitive != null) {
|
||||
only(primitive)
|
||||
}
|
||||
when (primitive) {
|
||||
PrimitiveType.Char, PrimitiveType.Boolean, PrimitiveType.Long ->
|
||||
body(Platform.JS) { "return withType(\"${primitive}Array\", this.asDynamic().slice(fromIndex, toIndex))" }
|
||||
else -> {
|
||||
annotations(Platform.JS, """@Suppress("NOTHING_TO_INLINE")""")
|
||||
inline(Platform.JS, Inline.Yes)
|
||||
body(Platform.JS) { "return this.asDynamic().slice(fromIndex, toIndex)" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun f_copyOf() = f("copyOf()") {
|
||||
inline(Platform.JVM, Inline.Only)
|
||||
inline(Platform.JS, Inline.Yes)
|
||||
annotations(Platform.JS, """@Suppress("NOTHING_TO_INLINE")""")
|
||||
fun f_copyOf() = (listOf(InvariantArraysOfObjects to null) + PrimitiveType.defaultPrimitives.map { ArraysOfPrimitives to it }).map {
|
||||
val (family, primitive) = it
|
||||
f("copyOf()") {
|
||||
only(family)
|
||||
if (family == InvariantArraysOfObjects) {
|
||||
only(Platform.JS, ArraysOfObjects)
|
||||
}
|
||||
|
||||
only(InvariantArraysOfObjects, ArraysOfPrimitives)
|
||||
only(Platform.JS, ArraysOfObjects, ArraysOfPrimitives)
|
||||
inline(Platform.JVM, Inline.Only)
|
||||
|
||||
only(InvariantArraysOfObjects, ArraysOfPrimitives)
|
||||
doc { "Returns new array which is a copy of the original array." }
|
||||
returns("SELF")
|
||||
returns(Platform.JS, ArraysOfObjects) { "Array<T>" }
|
||||
doc { "Returns new array which is a copy of the original array." }
|
||||
returns("SELF")
|
||||
returns(Platform.JS, ArraysOfObjects) { "Array<T>" }
|
||||
|
||||
body(Platform.JVM) {
|
||||
"return java.util.Arrays.copyOf(this, size)"
|
||||
}
|
||||
body(Platform.JS) {
|
||||
"return this.asDynamic().slice()"
|
||||
body(Platform.JVM) {
|
||||
"return java.util.Arrays.copyOf(this, size)"
|
||||
}
|
||||
body(Platform.JS) {
|
||||
"return this.asDynamic().slice()"
|
||||
}
|
||||
|
||||
if (primitive != null) {
|
||||
only(primitive)
|
||||
}
|
||||
when (primitive) {
|
||||
PrimitiveType.Char, PrimitiveType.Boolean, PrimitiveType.Long ->
|
||||
body(Platform.JS) { "return withType(\"${primitive}Array\", this.asDynamic().slice())" }
|
||||
else -> {
|
||||
annotations(Platform.JS, """@Suppress("NOTHING_TO_INLINE")""")
|
||||
inline(Platform.JS, Inline.Yes)
|
||||
body(Platform.JS) { "return this.asDynamic().slice()" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun f_copyOfResized() =
|
||||
(PrimitiveType.defaultPrimitives.map { ArraysOfPrimitives to it } + (InvariantArraysOfObjects to null)).map {
|
||||
val (family, primitive) = it
|
||||
f("copyOf(newSize: Int)") {
|
||||
only(family)
|
||||
if (family == InvariantArraysOfObjects) {
|
||||
only(Platform.JS, ArraysOfObjects)
|
||||
}
|
||||
|
||||
inline(Platform.JVM, Inline.Only)
|
||||
doc { "Returns new array which is a copy of the original array, resized to the given [newSize]." }
|
||||
val defaultValue: String
|
||||
if (primitive != null) {
|
||||
only(primitive)
|
||||
returns("SELF")
|
||||
defaultValue = when (primitive) {
|
||||
PrimitiveType.Boolean -> false.toString()
|
||||
PrimitiveType.Char -> "0"
|
||||
else -> "ZERO"
|
||||
(PrimitiveType.defaultPrimitives.map { ArraysOfPrimitives to it } + (InvariantArraysOfObjects to null)).map {
|
||||
val (family, primitive) = it
|
||||
f("copyOf(newSize: Int)") {
|
||||
only(family)
|
||||
if (family == InvariantArraysOfObjects) {
|
||||
only(Platform.JS, ArraysOfObjects)
|
||||
}
|
||||
|
||||
inline(Platform.JVM, Inline.Only)
|
||||
doc { "Returns new array which is a copy of the original array, resized to the given [newSize]." }
|
||||
|
||||
if (primitive != null) {
|
||||
only(primitive)
|
||||
returns("SELF")
|
||||
when (primitive) {
|
||||
PrimitiveType.Boolean ->
|
||||
body(Platform.JS) { "return withType(\"BooleanArray\", arrayCopyResize(this, newSize, false))" }
|
||||
PrimitiveType.Char ->
|
||||
body(Platform.JS) { "return withType(\"CharArray\", fillFrom(this, ${primitive}Array(newSize)))" }
|
||||
PrimitiveType.Long ->
|
||||
body(Platform.JS) { "return withType(\"LongArray\", arrayCopyResize(this, newSize, ZERO))" }
|
||||
else ->
|
||||
body(Platform.JS) { "return fillFrom(this, ${primitive}Array(newSize))" }
|
||||
}
|
||||
}
|
||||
else {
|
||||
returns { "Array<T?>" }
|
||||
body(Platform.JS) { "return arrayCopyResize(this, newSize, null)" }
|
||||
}
|
||||
|
||||
body(Platform.JVM) {
|
||||
"return java.util.Arrays.copyOf(this, newSize)"
|
||||
}
|
||||
} else {
|
||||
returns { "Array<T?>" }
|
||||
defaultValue = "null"
|
||||
}
|
||||
body(Platform.JVM) {
|
||||
"return java.util.Arrays.copyOf(this, newSize)"
|
||||
}
|
||||
body(Platform.JS) {
|
||||
"""
|
||||
return arrayCopyResize(this, newSize, $defaultValue)
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun f_sortPrimitives() =
|
||||
(PrimitiveType.numericPrimitives + PrimitiveType.Char).map { primitive ->
|
||||
@@ -481,12 +520,13 @@ object CommonArrays {
|
||||
return result as Array<T>
|
||||
"""
|
||||
}
|
||||
|
||||
if (primitive == PrimitiveType.Char) {
|
||||
body(Platform.JS) { "return Array<Char>(size, { i -> this[i] })" }
|
||||
}
|
||||
else {
|
||||
body(Platform.JS) { "return copyOf().unsafeCast<Array<T>>()" }
|
||||
when (primitive) {
|
||||
PrimitiveType.Char ->
|
||||
body(Platform.JS) { "return Array<Char>(size, { i -> this[i] })" }
|
||||
PrimitiveType.Boolean, PrimitiveType.Long ->
|
||||
body(Platform.JS) { "return copyOf().unsafeCast<Array<T>>()" }
|
||||
else ->
|
||||
body(Platform.JS) { "return js(\"[]\").slice.call(this)" }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -496,7 +536,10 @@ object CommonArrays {
|
||||
fun templates() =
|
||||
listOf(f_plusElement()) +
|
||||
f_plusElementOperator() +
|
||||
listOf(f_plusCollection(), f_plusArray(), f_copyOf(), f_copyOfRange()) +
|
||||
f_plusCollection() +
|
||||
listOf(f_plusArray()) +
|
||||
f_copyOf() +
|
||||
f_copyOfRange() +
|
||||
f_copyOfResized() +
|
||||
f_sortPrimitives() +
|
||||
listOf(f_sort(), f_sortWith(), f_asList()) +
|
||||
|
||||
Reference in New Issue
Block a user