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:
@@ -27,6 +27,7 @@ public class JSConfigurationKeys {
|
||||
|
||||
public static final CompilerConfigurationKey<Boolean> SOURCE_MAP =
|
||||
CompilerConfigurationKey.create("generate source map");
|
||||
|
||||
public static final CompilerConfigurationKey<Boolean> META_INFO =
|
||||
CompilerConfigurationKey.create("generate .meta.js and .kjsm files");
|
||||
|
||||
@@ -38,4 +39,7 @@ public class JSConfigurationKeys {
|
||||
|
||||
public static final CompilerConfigurationKey<ModuleKind> MODULE_KIND =
|
||||
CompilerConfigurationKey.create("module kind");
|
||||
|
||||
public static final CompilerConfigurationKey<Boolean> TYPED_ARRAYS_ENABLED =
|
||||
CompilerConfigurationKey.create("TypedArrays enabled");
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -60,7 +60,8 @@ import java.util.regex.Pattern
|
||||
|
||||
abstract class BasicBoxTest(
|
||||
private val pathToTestDir: String,
|
||||
private val pathToOutputDir: String
|
||||
private val pathToOutputDir: String,
|
||||
private val typedArraysEnabled: Boolean = false
|
||||
) : KotlinTestWithEnvironment() {
|
||||
private val COMMON_FILES_NAME = "_common"
|
||||
private val COMMON_FILES_DIR = "_commonFiles/"
|
||||
@@ -268,6 +269,10 @@ abstract class BasicBoxTest(
|
||||
//configuration.put(JSConfigurationKeys.SOURCE_MAP, shouldGenerateSourceMap())
|
||||
configuration.put(JSConfigurationKeys.META_INFO, multiModule)
|
||||
|
||||
if (typedArraysEnabled) {
|
||||
configuration.put(JSConfigurationKeys.TYPED_ARRAYS_ENABLED, true)
|
||||
}
|
||||
|
||||
return JsConfig(project, configuration)
|
||||
}
|
||||
|
||||
|
||||
@@ -191,6 +191,7 @@ public final class RhinoUtils {
|
||||
private static ScriptableObject initScope(@NotNull EcmaVersion version, @NotNull Context context, @NotNull List<String> jsLibraries) {
|
||||
ScriptableObject scope = context.initStandardObjects();
|
||||
try {
|
||||
runFileWithRhino(DIST_DIR_JS_PATH + "../../js/js.translator/testData/rhino-polyfills.js", context, scope);
|
||||
runFileWithRhino(DIST_DIR_JS_PATH + "kotlin.js", context, scope);
|
||||
runFileWithRhino(DIST_DIR_JS_PATH + "../classes/kotlin-test-js/kotlin-test.js", context, scope);
|
||||
|
||||
|
||||
+32
-50
@@ -391,6 +391,24 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Arrays extends AbstractJsCodegenBoxTest {
|
||||
@TestMetadata("arrayInstanceOf.kt")
|
||||
public void ignoreArrayInstanceOf() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/arrayInstanceOf.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt2997.kt")
|
||||
public void ignoreKt2997() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/kt2997.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt7288.kt")
|
||||
public void ignoreKt7288() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/kt7288.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInArrays() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/arrays"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true);
|
||||
}
|
||||
@@ -413,18 +431,6 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("arrayInstanceOf.kt")
|
||||
public void testArrayInstanceOf() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/arrayInstanceOf.kt");
|
||||
try {
|
||||
doTest(fileName);
|
||||
}
|
||||
catch (Throwable ignore) {
|
||||
return;
|
||||
}
|
||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
||||
}
|
||||
|
||||
@TestMetadata("arrayPlusAssign.kt")
|
||||
public void testArrayPlusAssign() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/arrayPlusAssign.kt");
|
||||
@@ -590,13 +596,7 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
@TestMetadata("iteratorByteArrayNextByte.kt")
|
||||
public void testIteratorByteArrayNextByte() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/iteratorByteArrayNextByte.kt");
|
||||
try {
|
||||
doTest(fileName);
|
||||
}
|
||||
catch (Throwable ignore) {
|
||||
return;
|
||||
}
|
||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("iteratorCharArray.kt")
|
||||
@@ -632,13 +632,7 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
@TestMetadata("iteratorLongArrayNextLong.kt")
|
||||
public void testIteratorLongArrayNextLong() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/iteratorLongArrayNextLong.kt");
|
||||
try {
|
||||
doTest(fileName);
|
||||
}
|
||||
catch (Throwable ignore) {
|
||||
return;
|
||||
}
|
||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("iteratorShortArray.kt")
|
||||
@@ -659,18 +653,6 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt2997.kt")
|
||||
public void testKt2997() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/kt2997.kt");
|
||||
try {
|
||||
doTest(fileName);
|
||||
}
|
||||
catch (Throwable ignore) {
|
||||
return;
|
||||
}
|
||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
||||
}
|
||||
|
||||
@TestMetadata("kt33.kt")
|
||||
public void testKt33() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/kt33.kt");
|
||||
@@ -737,12 +719,6 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt7288.kt")
|
||||
public void testKt7288() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/kt7288.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt7338.kt")
|
||||
public void testKt7338() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/kt7338.kt");
|
||||
@@ -803,6 +779,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("primitiveArrays.kt")
|
||||
public void testPrimitiveArrays() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/primitiveArrays.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("stdlib.kt")
|
||||
public void testStdlib() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/stdlib.kt");
|
||||
@@ -14894,6 +14876,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ForInIndices extends AbstractJsCodegenBoxTest {
|
||||
@TestMetadata("kt13241_Array.kt")
|
||||
public void ignoreKt13241_Array() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/forInIndices/kt13241_Array.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInForInIndices() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/ranges/forInIndices"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true);
|
||||
}
|
||||
@@ -14970,12 +14958,6 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt13241_Array.kt")
|
||||
public void testKt13241_Array() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/forInIndices/kt13241_Array.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt13241_CharSequence.kt")
|
||||
public void testKt13241_CharSequence() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/forInIndices/kt13241_CharSequence.kt");
|
||||
|
||||
+557
@@ -0,0 +1,557 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.js.test.semantics;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.TargetBackend;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("compiler/testData/codegen/box/arrays")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class JsTypedArraysBoxTestGenerated extends AbstractJsTypedArraysBoxTest {
|
||||
@TestMetadata("arrayInstanceOf.kt")
|
||||
public void ignoreArrayInstanceOf() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/arrayInstanceOf.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt2997.kt")
|
||||
public void ignoreKt2997() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/kt2997.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt7288.kt")
|
||||
public void ignoreKt7288() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/kt7288.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInArrays() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/arrays"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true);
|
||||
}
|
||||
|
||||
@TestMetadata("arrayConstructorsSimple.kt")
|
||||
public void testArrayConstructorsSimple() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/arrayConstructorsSimple.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("arrayGetAssignMultiIndex.kt")
|
||||
public void testArrayGetAssignMultiIndex() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/arrayGetAssignMultiIndex.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("arrayGetMultiIndex.kt")
|
||||
public void testArrayGetMultiIndex() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/arrayGetMultiIndex.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("arrayPlusAssign.kt")
|
||||
public void testArrayPlusAssign() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/arrayPlusAssign.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("arraysAreCloneable.kt")
|
||||
public void testArraysAreCloneable() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/arraysAreCloneable.kt");
|
||||
try {
|
||||
doTest(fileName);
|
||||
}
|
||||
catch (Throwable ignore) {
|
||||
return;
|
||||
}
|
||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
||||
}
|
||||
|
||||
@TestMetadata("cloneArray.kt")
|
||||
public void testCloneArray() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/cloneArray.kt");
|
||||
try {
|
||||
doTest(fileName);
|
||||
}
|
||||
catch (Throwable ignore) {
|
||||
return;
|
||||
}
|
||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
||||
}
|
||||
|
||||
@TestMetadata("clonePrimitiveArrays.kt")
|
||||
public void testClonePrimitiveArrays() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/clonePrimitiveArrays.kt");
|
||||
try {
|
||||
doTest(fileName);
|
||||
}
|
||||
catch (Throwable ignore) {
|
||||
return;
|
||||
}
|
||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
||||
}
|
||||
|
||||
@TestMetadata("collectionAssignGetMultiIndex.kt")
|
||||
public void testCollectionAssignGetMultiIndex() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/collectionAssignGetMultiIndex.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("collectionGetMultiIndex.kt")
|
||||
public void testCollectionGetMultiIndex() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/collectionGetMultiIndex.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("forEachBooleanArray.kt")
|
||||
public void testForEachBooleanArray() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/forEachBooleanArray.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("forEachByteArray.kt")
|
||||
public void testForEachByteArray() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/forEachByteArray.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("forEachCharArray.kt")
|
||||
public void testForEachCharArray() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/forEachCharArray.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("forEachDoubleArray.kt")
|
||||
public void testForEachDoubleArray() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/forEachDoubleArray.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("forEachFloatArray.kt")
|
||||
public void testForEachFloatArray() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/forEachFloatArray.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("forEachIntArray.kt")
|
||||
public void testForEachIntArray() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/forEachIntArray.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("forEachLongArray.kt")
|
||||
public void testForEachLongArray() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/forEachLongArray.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("forEachShortArray.kt")
|
||||
public void testForEachShortArray() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/forEachShortArray.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("genericArrayInObjectLiteralConstructor.kt")
|
||||
public void testGenericArrayInObjectLiteralConstructor() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/genericArrayInObjectLiteralConstructor.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("hashMap.kt")
|
||||
public void testHashMap() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/hashMap.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inProjectionAsParameter.kt")
|
||||
public void testInProjectionAsParameter() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/inProjectionAsParameter.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inProjectionOfArray.kt")
|
||||
public void testInProjectionOfArray() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/inProjectionOfArray.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inProjectionOfList.kt")
|
||||
public void testInProjectionOfList() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/inProjectionOfList.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("indices.kt")
|
||||
public void testIndices() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/indices.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("indicesChar.kt")
|
||||
public void testIndicesChar() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/indicesChar.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("iterator.kt")
|
||||
public void testIterator() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/iterator.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("iteratorBooleanArray.kt")
|
||||
public void testIteratorBooleanArray() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/iteratorBooleanArray.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("iteratorByteArray.kt")
|
||||
public void testIteratorByteArray() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/iteratorByteArray.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("iteratorByteArrayNextByte.kt")
|
||||
public void testIteratorByteArrayNextByte() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/iteratorByteArrayNextByte.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("iteratorCharArray.kt")
|
||||
public void testIteratorCharArray() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/iteratorCharArray.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("iteratorDoubleArray.kt")
|
||||
public void testIteratorDoubleArray() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/iteratorDoubleArray.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("iteratorFloatArray.kt")
|
||||
public void testIteratorFloatArray() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/iteratorFloatArray.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("iteratorIntArray.kt")
|
||||
public void testIteratorIntArray() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/iteratorIntArray.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("iteratorLongArray.kt")
|
||||
public void testIteratorLongArray() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/iteratorLongArray.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("iteratorLongArrayNextLong.kt")
|
||||
public void testIteratorLongArrayNextLong() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/iteratorLongArrayNextLong.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("iteratorShortArray.kt")
|
||||
public void testIteratorShortArray() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/iteratorShortArray.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt1291.kt")
|
||||
public void testKt1291() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/kt1291.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt238.kt")
|
||||
public void testKt238() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/kt238.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt33.kt")
|
||||
public void testKt33() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/kt33.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt3771.kt")
|
||||
public void testKt3771() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/kt3771.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt4118.kt")
|
||||
public void testKt4118() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/kt4118.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt4348.kt")
|
||||
public void testKt4348() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/kt4348.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt4357.kt")
|
||||
public void testKt4357() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/kt4357.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt503.kt")
|
||||
public void testKt503() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/kt503.kt");
|
||||
try {
|
||||
doTest(fileName);
|
||||
}
|
||||
catch (Throwable ignore) {
|
||||
return;
|
||||
}
|
||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
||||
}
|
||||
|
||||
@TestMetadata("kt594.kt")
|
||||
public void testKt594() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/kt594.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt602.kt")
|
||||
public void testKt602() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/kt602.kt");
|
||||
try {
|
||||
doTest(fileName);
|
||||
}
|
||||
catch (Throwable ignore) {
|
||||
return;
|
||||
}
|
||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
||||
}
|
||||
|
||||
@TestMetadata("kt7009.kt")
|
||||
public void testKt7009() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/kt7009.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt7338.kt")
|
||||
public void testKt7338() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/kt7338.kt");
|
||||
try {
|
||||
doTest(fileName);
|
||||
}
|
||||
catch (Throwable ignore) {
|
||||
return;
|
||||
}
|
||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
||||
}
|
||||
|
||||
@TestMetadata("kt779.kt")
|
||||
public void testKt779() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/kt779.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt945.kt")
|
||||
public void testKt945() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/kt945.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt950.kt")
|
||||
public void testKt950() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/kt950.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("longAsIndex.kt")
|
||||
public void testLongAsIndex() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/longAsIndex.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("multiArrayConstructors.kt")
|
||||
public void testMultiArrayConstructors() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/multiArrayConstructors.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("nonLocalReturnArrayConstructor.kt")
|
||||
public void testNonLocalReturnArrayConstructor() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/nonLocalReturnArrayConstructor.kt");
|
||||
try {
|
||||
doTest(fileName);
|
||||
}
|
||||
catch (Throwable ignore) {
|
||||
return;
|
||||
}
|
||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
||||
}
|
||||
|
||||
@TestMetadata("nonNullArray.kt")
|
||||
public void testNonNullArray() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/nonNullArray.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("primitiveArrays.kt")
|
||||
public void testPrimitiveArrays() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/primitiveArrays.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("stdlib.kt")
|
||||
public void testStdlib() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/stdlib.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/arrays/multiDecl")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class MultiDecl extends AbstractJsTypedArraysBoxTest {
|
||||
public void testAllFilesPresentInMultiDecl() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/arrays/multiDecl"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true);
|
||||
}
|
||||
|
||||
@TestMetadata("kt15560.kt")
|
||||
public void testKt15560() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/multiDecl/kt15560.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt15568.kt")
|
||||
public void testKt15568() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/multiDecl/kt15568.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt15575.kt")
|
||||
public void testKt15575() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/multiDecl/kt15575.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("MultiDeclFor.kt")
|
||||
public void testMultiDeclFor() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/multiDecl/MultiDeclFor.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("MultiDeclForComponentExtensions.kt")
|
||||
public void testMultiDeclForComponentExtensions() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/multiDecl/MultiDeclForComponentExtensions.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("MultiDeclForComponentMemberExtensions.kt")
|
||||
public void testMultiDeclForComponentMemberExtensions() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/multiDecl/MultiDeclForComponentMemberExtensions.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("MultiDeclForComponentMemberExtensionsInExtensionFunction.kt")
|
||||
public void testMultiDeclForComponentMemberExtensionsInExtensionFunction() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/multiDecl/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("MultiDeclForValCaptured.kt")
|
||||
public void testMultiDeclForValCaptured() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/multiDecl/MultiDeclForValCaptured.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/arrays/multiDecl/int")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Int extends AbstractJsTypedArraysBoxTest {
|
||||
public void testAllFilesPresentInInt() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/arrays/multiDecl/int"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true);
|
||||
}
|
||||
|
||||
@TestMetadata("MultiDeclForComponentExtensions.kt")
|
||||
public void testMultiDeclForComponentExtensions() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/multiDecl/int/MultiDeclForComponentExtensions.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("MultiDeclForComponentExtensionsValCaptured.kt")
|
||||
public void testMultiDeclForComponentExtensionsValCaptured() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/multiDecl/int/MultiDeclForComponentExtensionsValCaptured.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("MultiDeclForComponentMemberExtensions.kt")
|
||||
public void testMultiDeclForComponentMemberExtensions() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/multiDecl/int/MultiDeclForComponentMemberExtensions.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("MultiDeclForComponentMemberExtensionsInExtensionFunction.kt")
|
||||
public void testMultiDeclForComponentMemberExtensionsInExtensionFunction() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/multiDecl/int/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/arrays/multiDecl/long")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Long extends AbstractJsTypedArraysBoxTest {
|
||||
public void testAllFilesPresentInLong() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/arrays/multiDecl/long"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true);
|
||||
}
|
||||
|
||||
@TestMetadata("MultiDeclForComponentExtensions.kt")
|
||||
public void testMultiDeclForComponentExtensions() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/multiDecl/long/MultiDeclForComponentExtensions.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("MultiDeclForComponentExtensionsValCaptured.kt")
|
||||
public void testMultiDeclForComponentExtensionsValCaptured() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/multiDecl/long/MultiDeclForComponentExtensionsValCaptured.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("MultiDeclForComponentMemberExtensions.kt")
|
||||
public void testMultiDeclForComponentMemberExtensions() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/multiDecl/long/MultiDeclForComponentMemberExtensions.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("MultiDeclForComponentMemberExtensionsInExtensionFunction.kt")
|
||||
public void testMultiDeclForComponentMemberExtensionsInExtensionFunction() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/multiDecl/long/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
@@ -46,3 +46,9 @@ abstract class AbstractJsCodegenBoxTest : BasicBoxTest(
|
||||
"compiler/testData/codegen/box/",
|
||||
BasicBoxTest.TEST_DATA_DIR_PATH + "out/codegen/box/"
|
||||
)
|
||||
|
||||
abstract class AbstractJsTypedArraysBoxTest : BasicBoxTest(
|
||||
"compiler/testData/codegen/box/arrays/",
|
||||
BasicBoxTest.TEST_DATA_DIR_PATH + "out/codegen/box/arrays-typedarrays/",
|
||||
typedArraysEnabled = true
|
||||
)
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.js.translate.context;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType;
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor;
|
||||
@@ -283,6 +284,16 @@ public final class Namer {
|
||||
return kotlin(IS_CHAR_SEQUENCE);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JsExpression isArray() {
|
||||
return kotlin("isArray");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JsExpression isPrimitiveArray(@NotNull PrimitiveType type) {
|
||||
return kotlin("is" + type.getArrayTypeName().asString());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression invokeFunctionAndSetTypeCheckMetadata(
|
||||
@NotNull String functionName,
|
||||
|
||||
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.js.backend.ast.*
|
||||
import org.jetbrains.kotlin.js.translate.callTranslator.CallTranslator
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
||||
import org.jetbrains.kotlin.js.translate.general.Translation
|
||||
import org.jetbrains.kotlin.js.translate.intrinsic.functions.factories.CompositeFIF
|
||||
import org.jetbrains.kotlin.js.translate.intrinsic.functions.factories.ArrayFIF
|
||||
import org.jetbrains.kotlin.js.translate.utils.BindingUtils.*
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.*
|
||||
import org.jetbrains.kotlin.js.translate.utils.PsiUtils.getLoopRange
|
||||
@@ -165,7 +165,7 @@ fun translateForExpression(expression: KtForExpression, context: TranslationCont
|
||||
|
||||
fun translateForOverArray(): JsStatement {
|
||||
val rangeExpression = context.defineTemporary(Translation.translateAsExpression(loopRange, context))
|
||||
val length = CompositeFIF.LENGTH_PROPERTY_INTRINSIC.apply(rangeExpression, listOf<JsExpression>(), context)
|
||||
val length = ArrayFIF.LENGTH_PROPERTY_INTRINSIC.apply(rangeExpression, listOf<JsExpression>(), context)
|
||||
val end = context.defineTemporary(length)
|
||||
val index = context.declareTemporary(context.program().getNumberLiteral(0))
|
||||
|
||||
|
||||
+20
-2
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.js.backend.ast.JsConditional;
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsExpression;
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsInvocation;
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsLiteral;
|
||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys;
|
||||
import org.jetbrains.kotlin.js.patterns.NamePredicate;
|
||||
import org.jetbrains.kotlin.js.patterns.typePredicates.TypePredicatesKt;
|
||||
import org.jetbrains.kotlin.js.translate.context.Namer;
|
||||
@@ -34,9 +35,10 @@ import org.jetbrains.kotlin.js.translate.context.TemporaryVariable;
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
|
||||
import org.jetbrains.kotlin.js.translate.general.AbstractTranslator;
|
||||
import org.jetbrains.kotlin.js.translate.general.Translation;
|
||||
import org.jetbrains.kotlin.js.translate.intrinsic.functions.factories.ArrayFIF;
|
||||
import org.jetbrains.kotlin.js.translate.intrinsic.functions.factories.TopLevelFIF;
|
||||
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils;
|
||||
import org.jetbrains.kotlin.js.translate.reference.ReferenceTranslator;
|
||||
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils;
|
||||
import org.jetbrains.kotlin.js.translate.utils.BindingUtils;
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils;
|
||||
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils;
|
||||
@@ -210,7 +212,15 @@ public final class PatternTranslator extends AbstractTranslator {
|
||||
return namer().isTypeOf(program().getStringLiteral("function"));
|
||||
}
|
||||
|
||||
if (isArray(type)) return Namer.IS_ARRAY_FUN_REF;
|
||||
if (isArray(type)) {
|
||||
if (ArrayFIF.typedArraysEnabled(context())) {
|
||||
return namer().isArray();
|
||||
}
|
||||
else {
|
||||
return Namer.IS_ARRAY_FUN_REF;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (TypePredicatesKt.getCHAR_SEQUENCE().apply(type)) return namer().isCharSequence();
|
||||
|
||||
@@ -247,6 +257,14 @@ public final class PatternTranslator extends AbstractTranslator {
|
||||
return namer().isTypeOf(program().getStringLiteral("number"));
|
||||
}
|
||||
|
||||
if (ArrayFIF.typedArraysEnabled(context())) {
|
||||
if (KotlinBuiltIns.isPrimitiveArray(type)) {
|
||||
PrimitiveType arrayType = KotlinBuiltIns.getPrimitiveArrayElementType(type);
|
||||
assert arrayType != null;
|
||||
return namer().isPrimitiveArray(arrayType);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
-139
@@ -1,139 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.js.translate.intrinsic.functions.factories;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType;
|
||||
import org.jetbrains.kotlin.js.backend.ast.*;
|
||||
import org.jetbrains.kotlin.js.patterns.DescriptorPredicate;
|
||||
import org.jetbrains.kotlin.js.patterns.NamePredicate;
|
||||
import org.jetbrains.kotlin.js.translate.context.Namer;
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
|
||||
import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsic;
|
||||
import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsicWithReceiverComputed;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.intellij.openapi.util.text.StringUtil.decapitalize;
|
||||
import static org.jetbrains.kotlin.js.patterns.PatternBuilder.pattern;
|
||||
import static org.jetbrains.kotlin.js.translate.utils.JsAstUtils.assignment;
|
||||
|
||||
public final class ArrayFIF extends CompositeFIF {
|
||||
private static final NamePredicate NUMBER_ARRAY;
|
||||
private static final NamePredicate CHAR_ARRAY;
|
||||
private static final NamePredicate BOOLEAN_ARRAY;
|
||||
private static final NamePredicate LONG_ARRAY;
|
||||
private static final NamePredicate ARRAYS;
|
||||
private static final DescriptorPredicate ARRAY_FACTORY_METHODS;
|
||||
|
||||
static {
|
||||
List<Name> arrayTypeNames = Lists.newArrayList();
|
||||
List<Name> arrayFactoryMethodNames = Lists.newArrayList(Name.identifier("arrayOf"));
|
||||
for (PrimitiveType type : PrimitiveType.values()) {
|
||||
Name arrayTypeName = type.getArrayTypeName();
|
||||
if (type != PrimitiveType.CHAR && type != PrimitiveType.BOOLEAN && type != PrimitiveType.LONG) {
|
||||
arrayTypeNames.add(arrayTypeName);
|
||||
}
|
||||
arrayFactoryMethodNames.add(Name.identifier(decapitalize(arrayTypeName.asString() + "Of")));
|
||||
}
|
||||
|
||||
Name arrayName = KotlinBuiltIns.FQ_NAMES.array.shortName();
|
||||
Name booleanArrayName = PrimitiveType.BOOLEAN.getArrayTypeName();
|
||||
Name charArrayName = PrimitiveType.CHAR.getArrayTypeName();
|
||||
Name longArrayName = PrimitiveType.LONG.getArrayTypeName();
|
||||
|
||||
NUMBER_ARRAY = new NamePredicate(arrayTypeNames);
|
||||
CHAR_ARRAY = new NamePredicate(charArrayName);
|
||||
BOOLEAN_ARRAY = new NamePredicate(booleanArrayName);
|
||||
LONG_ARRAY = new NamePredicate(longArrayName);
|
||||
|
||||
arrayTypeNames.add(charArrayName);
|
||||
arrayTypeNames.add(booleanArrayName);
|
||||
arrayTypeNames.add(longArrayName);
|
||||
arrayTypeNames.add(arrayName);
|
||||
ARRAYS = new NamePredicate(arrayTypeNames);
|
||||
ARRAY_FACTORY_METHODS = pattern(Namer.KOTLIN_LOWER_NAME, new NamePredicate(arrayFactoryMethodNames));
|
||||
}
|
||||
|
||||
private static final FunctionIntrinsic ARRAY_INTRINSIC = new FunctionIntrinsicWithReceiverComputed() {
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression apply(
|
||||
@Nullable JsExpression receiver,
|
||||
@NotNull List<? extends JsExpression> arguments,
|
||||
@NotNull TranslationContext context
|
||||
) {
|
||||
assert arguments.size() == 1;
|
||||
return arguments.get(0);
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
public static final FunctionIntrinsic GET_INTRINSIC = new FunctionIntrinsicWithReceiverComputed() {
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression apply(@Nullable JsExpression receiver,
|
||||
@NotNull List<? extends JsExpression> arguments,
|
||||
@NotNull TranslationContext context) {
|
||||
assert receiver != null;
|
||||
assert arguments.size() == 1 : "Array get expression must have one argument.";
|
||||
JsExpression indexExpression = arguments.get(0);
|
||||
return new JsArrayAccess(receiver, indexExpression);
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
public static final FunctionIntrinsic SET_INTRINSIC = new FunctionIntrinsicWithReceiverComputed() {
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression apply(@Nullable JsExpression receiver,
|
||||
@NotNull List<? extends JsExpression> arguments,
|
||||
@NotNull TranslationContext context) {
|
||||
assert receiver != null;
|
||||
assert arguments.size() == 2 : "Array set expression must have two arguments.";
|
||||
JsExpression indexExpression = arguments.get(0);
|
||||
JsExpression value = arguments.get(1);
|
||||
JsArrayAccess arrayAccess = new JsArrayAccess(receiver, indexExpression);
|
||||
return assignment(arrayAccess, value);
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
public static final FunctionIntrinsicFactory INSTANCE = new ArrayFIF();
|
||||
|
||||
private ArrayFIF() {
|
||||
add(pattern(ARRAYS, "get"), GET_INTRINSIC);
|
||||
add(pattern(ARRAYS, "set"), SET_INTRINSIC);
|
||||
add(pattern(ARRAYS, "<get-size>"), LENGTH_PROPERTY_INTRINSIC);
|
||||
add(pattern(ARRAYS, "iterator"), new KotlinFunctionIntrinsic("arrayIterator"));
|
||||
|
||||
add(pattern(NUMBER_ARRAY, "<init>(Int)"), new KotlinFunctionIntrinsic("newArray", JsNumberLiteral.ZERO));
|
||||
add(pattern(CHAR_ARRAY, "<init>(Int)"), new KotlinFunctionIntrinsic("newArray", JsNumberLiteral.ZERO));
|
||||
add(pattern(BOOLEAN_ARRAY, "<init>(Int)"), new KotlinFunctionIntrinsic("newArray", JsLiteral.FALSE));
|
||||
add(pattern(LONG_ARRAY, "<init>(Int)"), new KotlinFunctionIntrinsic("newArray", new JsNameRef(Namer.LONG_ZERO, Namer.kotlinLong())));
|
||||
|
||||
add(pattern(ARRAYS, "<init>(Int,Function1)"), new KotlinFunctionIntrinsic("newArrayF"));
|
||||
|
||||
add(pattern("kotlin", "arrayOfNulls"), new KotlinFunctionIntrinsic("newArray", JsLiteral.NULL));
|
||||
|
||||
add(ARRAY_FACTORY_METHODS, ARRAY_INTRINSIC);
|
||||
}
|
||||
}
|
||||
+162
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.js.translate.intrinsic.functions.factories
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil.decapitalize
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType.*
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.SideEffectKind
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.sideEffects
|
||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||
import org.jetbrains.kotlin.js.patterns.NamePredicate
|
||||
import org.jetbrains.kotlin.js.patterns.PatternBuilder.pattern
|
||||
import org.jetbrains.kotlin.js.translate.context.Namer
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
||||
import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.BuiltInPropertyIntrinsic
|
||||
import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsicWithReceiverComputed
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import java.util.*
|
||||
|
||||
object ArrayFIF : CompositeFIF() {
|
||||
@JvmField
|
||||
val GET_INTRINSIC = intrinsify { receiver, arguments, _ ->
|
||||
assert(arguments.size == 1) { "Array get expression must have one argument." }
|
||||
val (indexExpression) = arguments
|
||||
JsArrayAccess(receiver!!, indexExpression)
|
||||
}
|
||||
|
||||
@JvmField
|
||||
val SET_INTRINSIC = intrinsify { receiver, arguments, _ ->
|
||||
assert(arguments.size == 2) { "Array set expression must have two arguments." }
|
||||
val (indexExpression, value) = arguments
|
||||
val arrayAccess = JsArrayAccess(receiver!!, indexExpression)
|
||||
JsAstUtils.assignment(arrayAccess, value)
|
||||
}
|
||||
|
||||
@JvmField
|
||||
val LENGTH_PROPERTY_INTRINSIC = BuiltInPropertyIntrinsic("length")
|
||||
|
||||
@JvmStatic
|
||||
fun typedArraysEnabled(ctx: TranslationContext) = ctx.config.configuration.getBoolean(JSConfigurationKeys.TYPED_ARRAYS_ENABLED)
|
||||
|
||||
fun castOrCreatePrimitiveArray(ctx: TranslationContext, type: PrimitiveType?, arg: JsArrayLiteral): JsExpression {
|
||||
if (type == null || !typedArraysEnabled(ctx)) return arg
|
||||
|
||||
if (type in TYPED_ARRAY_MAP) {
|
||||
return createTypedArray(type, arg)
|
||||
}
|
||||
else {
|
||||
return JsAstUtils.invokeKotlinFunction(type.lowerCaseName + "ArrayOf", *arg.expressions.toTypedArray())
|
||||
}
|
||||
}
|
||||
|
||||
private val TYPED_ARRAY_MAP = EnumMap(mapOf(BYTE to "Int8",
|
||||
SHORT to "Int16",
|
||||
INT to "Int32",
|
||||
FLOAT to "Float32",
|
||||
DOUBLE to "Float64"))
|
||||
|
||||
private fun createTypedArray(type: PrimitiveType, arg: JsExpression): JsExpression {
|
||||
assert(type in TYPED_ARRAY_MAP)
|
||||
return JsNew(JsNameRef(TYPED_ARRAY_MAP[type] + "Array"), listOf(arg))
|
||||
}
|
||||
|
||||
private val PrimitiveType.lowerCaseName
|
||||
get() = typeName.asString().toLowerCase()
|
||||
|
||||
init {
|
||||
val arrayName = KotlinBuiltIns.FQ_NAMES.array.shortName()
|
||||
|
||||
val arrayTypeNames = mutableListOf(arrayName)
|
||||
PrimitiveType.values().mapTo(arrayTypeNames) { it.arrayTypeName }
|
||||
|
||||
val arrays = NamePredicate(arrayTypeNames)
|
||||
add(pattern(arrays, "get"), GET_INTRINSIC)
|
||||
add(pattern(arrays, "set"), SET_INTRINSIC)
|
||||
add(pattern(arrays, "<get-size>"), LENGTH_PROPERTY_INTRINSIC)
|
||||
|
||||
for (type in PrimitiveType.values()) {
|
||||
add(pattern(NamePredicate(type.arrayTypeName), "<init>(Int)"), intrinsify { _, arguments, context ->
|
||||
assert(arguments.size == 1) { "Array <init>(Int) expression must have one argument." }
|
||||
val (size) = arguments
|
||||
|
||||
if (typedArraysEnabled(context)) {
|
||||
if (type in TYPED_ARRAY_MAP) {
|
||||
createTypedArray(type, size)
|
||||
}
|
||||
else {
|
||||
JsAstUtils.invokeKotlinFunction("${type.lowerCaseName}Array", size)
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
val initValue = when (type) {
|
||||
BOOLEAN -> JsLiteral.FALSE
|
||||
LONG -> JsNameRef(Namer.LONG_ZERO, Namer.kotlinLong())
|
||||
else -> JsNumberLiteral.ZERO
|
||||
}
|
||||
JsAstUtils.invokeKotlinFunction("newArray", size, initValue)
|
||||
}
|
||||
})
|
||||
|
||||
add(pattern(NamePredicate(type.arrayTypeName), "<init>(Int,Function1)"), intrinsify { _, arguments, context ->
|
||||
assert(arguments.size == 2) { "Array <init>(Int,Function1) expression must have two arguments." }
|
||||
val (size, fn) = arguments
|
||||
if (typedArraysEnabled(context)) {
|
||||
if (type in TYPED_ARRAY_MAP) {
|
||||
JsAstUtils.invokeKotlinFunction("fillArray", createTypedArray(type, size), fn)
|
||||
}
|
||||
else {
|
||||
JsAstUtils.invokeKotlinFunction("${type.lowerCaseName}Array", size, fn)
|
||||
}
|
||||
}
|
||||
else {
|
||||
JsAstUtils.invokeKotlinFunction("newArrayF", size, fn)
|
||||
}
|
||||
})
|
||||
|
||||
add(pattern(NamePredicate(type.arrayTypeName), "iterator"), intrinsify { receiver, _, context ->
|
||||
if (typedArraysEnabled(context)) {
|
||||
JsAstUtils.invokeKotlinFunction("${type.lowerCaseName}ArrayIterator", receiver!!)
|
||||
}
|
||||
else {
|
||||
JsAstUtils.invokeKotlinFunction("arrayIterator", receiver!!,
|
||||
context.program().getStringLiteral(type.arrayTypeName.asString()))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
add(pattern(NamePredicate(arrayName), "<init>(Int,Function1)"), KotlinFunctionIntrinsic("newArrayF"))
|
||||
add(pattern(NamePredicate(arrayName), "iterator"), KotlinFunctionIntrinsic("arrayIterator"))
|
||||
|
||||
add(pattern(Namer.KOTLIN_LOWER_NAME, "arrayOfNulls"), KotlinFunctionIntrinsic("newArray", JsLiteral.NULL))
|
||||
|
||||
val arrayFactoryMethodNames = arrayTypeNames.map { Name.identifier(decapitalize(it.asString() + "Of")) }
|
||||
val arrayFactoryMethods = pattern(Namer.KOTLIN_LOWER_NAME, NamePredicate(arrayFactoryMethodNames))
|
||||
add(arrayFactoryMethods, intrinsify { _, arguments, _ -> arguments[0] })
|
||||
}
|
||||
|
||||
private fun intrinsify(f: (receiver: JsExpression?, arguments: List<JsExpression>, context: TranslationContext) -> JsExpression)
|
||||
= object : FunctionIntrinsicWithReceiverComputed() {
|
||||
override fun apply(receiver: JsExpression?, arguments: List<JsExpression>, context: TranslationContext): JsExpression {
|
||||
return f(receiver, arguments, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
-4
@@ -22,15 +22,11 @@ import com.intellij.openapi.util.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.BuiltInPropertyIntrinsic;
|
||||
import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsic;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class CompositeFIF implements FunctionIntrinsicFactory {
|
||||
@NotNull
|
||||
public static final BuiltInPropertyIntrinsic LENGTH_PROPERTY_INTRINSIC = new BuiltInPropertyIntrinsic("length");
|
||||
|
||||
@NotNull
|
||||
private final List<Pair<Predicate<FunctionDescriptor>, FunctionIntrinsic>> patternsAndIntrinsics = Lists.newArrayList();
|
||||
|
||||
|
||||
+9
-6
@@ -16,12 +16,14 @@
|
||||
|
||||
package org.jetbrains.kotlin.js.translate.intrinsic.functions.factories;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsExpression;
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsInvocation;
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsNameRef;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.js.patterns.DescriptorPredicate;
|
||||
import org.jetbrains.kotlin.js.patterns.NamePredicate;
|
||||
import org.jetbrains.kotlin.js.translate.callTranslator.CallInfo;
|
||||
@@ -164,13 +166,14 @@ public final class TopLevelFIF extends CompositeFIF {
|
||||
public static final KotlinFunctionIntrinsic TO_STRING = new KotlinFunctionIntrinsic("toString");
|
||||
|
||||
@NotNull
|
||||
public static final FunctionIntrinsic CHAR_TO_STRING = new FunctionIntrinsic() {
|
||||
public static final FunctionIntrinsic CHAR_TO_STRING = new FunctionIntrinsicWithReceiverComputed() {
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression apply(
|
||||
@NotNull CallInfo callInfo, @NotNull List<? extends JsExpression> arguments, @NotNull TranslationContext context
|
||||
@Nullable JsExpression receiver, @NotNull List<? extends JsExpression> arguments, @NotNull TranslationContext context
|
||||
) {
|
||||
return JsAstUtils.charToString(callInfo.getDispatchReceiver());
|
||||
assert receiver != null;
|
||||
return JsAstUtils.charToString(receiver);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+82
-71
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.js.translate.reference
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
@@ -28,6 +29,7 @@ import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
||||
import org.jetbrains.kotlin.js.translate.expression.PatternTranslator
|
||||
import org.jetbrains.kotlin.js.translate.general.AbstractTranslator
|
||||
import org.jetbrains.kotlin.js.translate.general.Translation
|
||||
import org.jetbrains.kotlin.js.translate.intrinsic.functions.factories.ArrayFIF
|
||||
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
|
||||
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils
|
||||
@@ -83,7 +85,7 @@ class CallArgumentTranslator private constructor(
|
||||
var argsBeforeVararg: List<JsExpression>? = null
|
||||
var concatArguments: MutableList<JsExpression>? = null
|
||||
val argsToJsExpr = translateUnresolvedArguments(context(), resolvedCall)
|
||||
var isVarargTypePrimitive: Boolean? = null
|
||||
var varargPrimitiveType: PrimitiveType? = null
|
||||
|
||||
for (parameterDescriptor in valueParameters) {
|
||||
val actualArgument = valueArgumentsByIndex[parameterDescriptor.index]
|
||||
@@ -96,19 +98,21 @@ class CallArgumentTranslator private constructor(
|
||||
hasSpreadOperator = arguments.any { it.getSpreadElement() != null }
|
||||
}
|
||||
|
||||
isVarargTypePrimitive = KotlinBuiltIns.isPrimitiveType(parameterDescriptor.original.varargElementType!!)
|
||||
varargPrimitiveType = KotlinBuiltIns.getPrimitiveType(parameterDescriptor.original.varargElementType!!)
|
||||
|
||||
if (hasSpreadOperator) {
|
||||
if (isNativeFunctionCall) {
|
||||
argsBeforeVararg = result
|
||||
result = mutableListOf<JsExpression>()
|
||||
concatArguments = prepareConcatArguments(arguments, translateResolvedArgument(actualArgument, argsToJsExpr))
|
||||
concatArguments = prepareConcatArguments(arguments,
|
||||
translateResolvedArgument(actualArgument, argsToJsExpr),
|
||||
null)
|
||||
}
|
||||
else {
|
||||
result.addAll(translateVarargArgument(actualArgument,
|
||||
argsToJsExpr,
|
||||
actualArgument.arguments.size > 1,
|
||||
isVarargTypePrimitive))
|
||||
varargPrimitiveType))
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -116,7 +120,7 @@ class CallArgumentTranslator private constructor(
|
||||
result.addAll(translateResolvedArgument(actualArgument, argsToJsExpr))
|
||||
}
|
||||
else {
|
||||
result.addAll(translateVarargArgument(actualArgument, argsToJsExpr, true, isVarargTypePrimitive))
|
||||
result.addAll(translateVarargArgument(actualArgument, argsToJsExpr, true, varargPrimitiveType))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -130,14 +134,14 @@ class CallArgumentTranslator private constructor(
|
||||
assert(concatArguments != null) { "concatArguments should not be null" }
|
||||
|
||||
if (!result.isEmpty()) {
|
||||
concatArguments!!.add(JsArrayLiteral(result).apply { sideEffects = SideEffectKind.DEPENDS_ON_STATE })
|
||||
concatArguments!!.add(toArray(null, result))
|
||||
}
|
||||
|
||||
if (!argsBeforeVararg!!.isEmpty()) {
|
||||
concatArguments!!.add(0, JsArrayLiteral(argsBeforeVararg).apply { sideEffects = SideEffectKind.DEPENDS_ON_STATE })
|
||||
concatArguments!!.add(0, toArray(null, argsBeforeVararg))
|
||||
}
|
||||
|
||||
result = mutableListOf(concatArgumentsIfNeeded(concatArguments!!, isVarargTypePrimitive!!, true))
|
||||
result = mutableListOf(concatArgumentsIfNeeded(concatArguments!!, varargPrimitiveType, true))
|
||||
|
||||
if (receiver != null) {
|
||||
cachedReceiver = context().getOrDeclareTemporaryConstVariable(receiver)
|
||||
@@ -210,6 +214,74 @@ class CallArgumentTranslator private constructor(
|
||||
return result
|
||||
}
|
||||
|
||||
private fun translateVarargArgument(
|
||||
resolvedArgument: ResolvedValueArgument,
|
||||
translatedArgs: Map<ValueArgument, JsExpression>,
|
||||
shouldWrapVarargInArray: Boolean,
|
||||
varargPrimitiveType: PrimitiveType?
|
||||
): List<JsExpression> {
|
||||
val arguments = resolvedArgument.arguments
|
||||
if (arguments.isEmpty()) {
|
||||
return if (shouldWrapVarargInArray) {
|
||||
return listOf(toArray(varargPrimitiveType, listOf<JsExpression>()))
|
||||
}
|
||||
else {
|
||||
listOf()
|
||||
}
|
||||
}
|
||||
|
||||
val list = translateResolvedArgument(resolvedArgument, translatedArgs)
|
||||
|
||||
return if (shouldWrapVarargInArray) {
|
||||
val concatArguments = prepareConcatArguments(arguments, list, varargPrimitiveType)
|
||||
val concatExpression = concatArgumentsIfNeeded(concatArguments, varargPrimitiveType, false)
|
||||
listOf(concatExpression)
|
||||
}
|
||||
else {
|
||||
listOf(JsAstUtils.invokeMethod(list[0], "slice"))
|
||||
}
|
||||
}
|
||||
|
||||
private fun toArray(varargPrimitiveType: PrimitiveType?, elements: List<JsExpression>): JsExpression {
|
||||
return ArrayFIF.castOrCreatePrimitiveArray(context(),
|
||||
varargPrimitiveType,
|
||||
JsArrayLiteral(elements).apply { sideEffects = SideEffectKind.PURE })
|
||||
}
|
||||
|
||||
private fun prepareConcatArguments(
|
||||
arguments: List<ValueArgument>,
|
||||
list: List<JsExpression>,
|
||||
varargPrimitiveType: PrimitiveType?
|
||||
): MutableList<JsExpression> {
|
||||
assert(arguments.isNotEmpty()) { "arguments.size should not be 0" }
|
||||
assert(arguments.size == list.size) { "arguments.size: " + arguments.size + " != list.size: " + list.size }
|
||||
|
||||
val concatArguments = mutableListOf<JsExpression>()
|
||||
var lastArrayContent = mutableListOf<JsExpression>()
|
||||
|
||||
val size = arguments.size
|
||||
for (index in 0..size - 1) {
|
||||
val valueArgument = arguments[index]
|
||||
val expressionArgument = list[index]
|
||||
|
||||
if (valueArgument.getSpreadElement() != null) {
|
||||
if (lastArrayContent.size > 0) {
|
||||
concatArguments.add(toArray(varargPrimitiveType, lastArrayContent))
|
||||
lastArrayContent = mutableListOf<JsExpression>()
|
||||
}
|
||||
concatArguments.add(expressionArgument)
|
||||
}
|
||||
else {
|
||||
lastArrayContent.add(expressionArgument)
|
||||
}
|
||||
}
|
||||
if (lastArrayContent.size > 0) {
|
||||
concatArguments.add(toArray(varargPrimitiveType, lastArrayContent))
|
||||
}
|
||||
|
||||
return concatArguments
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@JvmStatic fun translate(resolvedCall: ResolvedCall<*>, receiver: JsExpression?, context: TranslationContext): ArgumentsInfo {
|
||||
@@ -240,43 +312,15 @@ class CallArgumentTranslator private constructor(
|
||||
return resolvedArgument.arguments.map { translatedArgs[it]!! }
|
||||
}
|
||||
|
||||
private fun translateVarargArgument(
|
||||
resolvedArgument: ResolvedValueArgument,
|
||||
translatedArgs: Map<ValueArgument, JsExpression>,
|
||||
shouldWrapVarargInArray: Boolean,
|
||||
isVarargTypePrimitive: Boolean
|
||||
): List<JsExpression> {
|
||||
val arguments = resolvedArgument.arguments
|
||||
if (arguments.isEmpty()) {
|
||||
return if (shouldWrapVarargInArray) {
|
||||
return listOf(JsArrayLiteral(listOf<JsExpression>()).apply { sideEffects = SideEffectKind.DEPENDS_ON_STATE })
|
||||
}
|
||||
else {
|
||||
listOf()
|
||||
}
|
||||
}
|
||||
|
||||
val list = translateResolvedArgument(resolvedArgument, translatedArgs)
|
||||
|
||||
return if (shouldWrapVarargInArray) {
|
||||
val concatArguments = prepareConcatArguments(arguments, list)
|
||||
val concatExpression = concatArgumentsIfNeeded(concatArguments, isVarargTypePrimitive, false)
|
||||
listOf(concatExpression)
|
||||
}
|
||||
else {
|
||||
listOf(JsAstUtils.invokeMethod(list[0], "slice"))
|
||||
}
|
||||
}
|
||||
|
||||
private fun concatArgumentsIfNeeded(
|
||||
concatArguments: List<JsExpression>,
|
||||
isVarargTypePrimitive: Boolean,
|
||||
varargPrimitiveType: PrimitiveType?,
|
||||
isMixed: Boolean
|
||||
): JsExpression {
|
||||
assert(concatArguments.isNotEmpty()) { "concatArguments.size should not be 0" }
|
||||
|
||||
if (concatArguments.size > 1) {
|
||||
if (isVarargTypePrimitive) {
|
||||
if (varargPrimitiveType != null) {
|
||||
val method = if (isMixed) "arrayConcat" else "primitiveArrayConcat"
|
||||
return JsAstUtils.invokeKotlinFunction(method, concatArguments[0],
|
||||
*concatArguments.subList(1, concatArguments.size).toTypedArray())
|
||||
@@ -289,39 +333,6 @@ class CallArgumentTranslator private constructor(
|
||||
return concatArguments[0]
|
||||
}
|
||||
}
|
||||
|
||||
private fun prepareConcatArguments(arguments: List<ValueArgument>, list: List<JsExpression>): MutableList<JsExpression> {
|
||||
assert(arguments.isNotEmpty()) { "arguments.size should not be 0" }
|
||||
assert(arguments.size == list.size) { "arguments.size: " + arguments.size + " != list.size: " + list.size }
|
||||
|
||||
val concatArguments = mutableListOf<JsExpression>()
|
||||
var lastArrayContent = mutableListOf<JsExpression>()
|
||||
|
||||
val size = arguments.size
|
||||
for (index in 0..size - 1) {
|
||||
val valueArgument = arguments[index]
|
||||
val expressionArgument = list[index]
|
||||
|
||||
if (valueArgument.getSpreadElement() != null) {
|
||||
if (lastArrayContent.size > 0) {
|
||||
concatArguments.add(JsArrayLiteral(lastArrayContent).apply { sideEffects = SideEffectKind.DEPENDS_ON_STATE })
|
||||
concatArguments.add(expressionArgument)
|
||||
lastArrayContent = mutableListOf<JsExpression>()
|
||||
}
|
||||
else {
|
||||
concatArguments.add(expressionArgument)
|
||||
}
|
||||
}
|
||||
else {
|
||||
lastArrayContent.add(expressionArgument)
|
||||
}
|
||||
}
|
||||
if (lastArrayContent.size > 0) {
|
||||
concatArguments.add(JsArrayLiteral(lastArrayContent).apply { sideEffects = SideEffectKind.DEPENDS_ON_STATE })
|
||||
}
|
||||
|
||||
return concatArguments
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.js.translate.utils;
|
||||
|
||||
import org.jetbrains.kotlin.js.backend.ast.*;
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.MetadataProperties;
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.SideEffectKind;
|
||||
import com.intellij.util.SmartList;
|
||||
import kotlin.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.js.backend.ast.*;
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.MetadataProperties;
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.SideEffectKind;
|
||||
import org.jetbrains.kotlin.js.translate.context.Namer;
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions;
|
||||
@@ -575,4 +575,13 @@ public final class JsAstUtils {
|
||||
MetadataProperties.setCoroutineReceiver(result, true);
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression comma(JsExpression first, JsExpression... tail) {
|
||||
JsExpression result = first;
|
||||
for (JsExpression e : tail) {
|
||||
result = new JsBinaryOperation(JsBinaryOperator.COMMA, result, e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
function normalizeOffset(offset, length) {
|
||||
if (offset < 0) return Math.max(0, offset + length);
|
||||
return Math.min(offset, length);
|
||||
}
|
||||
function typedArraySlice(begin, end) {
|
||||
if (typeof end === "undefined") {
|
||||
end = this.length;
|
||||
}
|
||||
begin = normalizeOffset(begin || 0, this.length);
|
||||
end = Math.max(begin, normalizeOffset(end, this.length));
|
||||
return new this.constructor(this.subarray(begin, end));
|
||||
}
|
||||
|
||||
var arrays = [Int8Array, Int16Array, Uint16Array, Int32Array, Float32Array, Float64Array];
|
||||
for (var i = 0; i < arrays.length; ++i) {
|
||||
var TypedArray = arrays[i];
|
||||
if (typeof TypedArray.prototype.slice === "undefined") {
|
||||
Object.defineProperty(TypedArray.prototype, 'slice', {
|
||||
value: typedArraySlice
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Patch apply to work with TypedArrays if needed.
|
||||
try {
|
||||
(function() {}).apply(null, new Int32Array(0))
|
||||
} catch (e) {
|
||||
var apply = Function.prototype.apply;
|
||||
Object.defineProperty(Function.prototype, 'apply', {
|
||||
value: function(self, array) {
|
||||
return apply.call(this, self, [].slice.call(array));
|
||||
}
|
||||
});
|
||||
}
|
||||
})();
|
||||
Vendored
+2
-2
@@ -3,10 +3,10 @@
|
||||
<head>
|
||||
<script type="application/javascript" src="../../../dist/js/kotlin.js"></script>
|
||||
<script type="application/javascript" src="../../../dist/classes/kotlin-test-js/kotlin-test.js"></script>
|
||||
<script type="application/javascript" src="../../../js/js.translator/testData/out/box/standardClasses/stringBuilder_v5.js"></script>
|
||||
<script type="application/javascript" src="../../../js/js.translator/testData/out/codegen/box/arrays/primitiveArrays_v5.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
console.log(JS_TESTS.foo.box());
|
||||
console.log(JS_TESTS.box());
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
Reference in New Issue
Block a user