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:
+4
@@ -71,6 +71,10 @@ public class K2JSCompilerArguments extends CommonCompilerArguments {
|
||||
@ValueDescription("<path>")
|
||||
public String outputPostfix;
|
||||
|
||||
@GradleOption(DefaultValues.BooleanFalseDefault.class)
|
||||
@Argument(value = "Xtypedarrays", description = "Translate primitive arrays to JS typed arrays")
|
||||
public boolean typedArrays;
|
||||
|
||||
@NotNull
|
||||
public static K2JSCompilerArguments createDefaultInstance() {
|
||||
K2JSCompilerArguments arguments = new K2JSCompilerArguments();
|
||||
|
||||
@@ -286,6 +286,10 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
|
||||
ContainerUtil.addAllNotNull(libraries, arguments.libraries.split(File.pathSeparator));
|
||||
}
|
||||
|
||||
if (arguments.typedArrays) {
|
||||
configuration.put(JSConfigurationKeys.TYPED_ARRAYS_ENABLED, true);
|
||||
}
|
||||
|
||||
configuration.put(JSConfigurationKeys.LIBRARIES, libraries);
|
||||
|
||||
String moduleKindName = arguments.moduleKind;
|
||||
|
||||
+1
@@ -1,5 +1,6 @@
|
||||
Usage: kotlinc-js <options> <source files>
|
||||
where advanced options include:
|
||||
-Xtypedarrays Translate primitive arrays to JS typed arrays
|
||||
-Xno-inline Disable method inlining
|
||||
-Xrepeat <count> Repeat compilation (for performance analysis)
|
||||
-Xskip-metadata-version-check Load classes with bad metadata version anyway (incl. pre-release classes)
|
||||
|
||||
+1
-2
@@ -1,5 +1,4 @@
|
||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||
// IGNORE_BACKEND: JS
|
||||
// IGNORE_BACKEND_WITHOUT_CHECK: JS
|
||||
|
||||
//test [], get and iterator calls
|
||||
fun test(createIntNotLong: Boolean): String {
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
fun box(): String {
|
||||
val a = ByteArray(5)
|
||||
val x = a.iterator()
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
fun box(): String {
|
||||
val a = LongArray(5)
|
||||
val x = a.iterator()
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
//KT-2997 Automatically cast error (Array)
|
||||
// IGNORE_BACKEND: JS
|
||||
// Unmute when JS implements primitive arrays via TypeArray
|
||||
// IGNORE_BACKEND_WITHOUT_CHECK: JS
|
||||
// Unmute when JS implements primitive arrays via TypedArray
|
||||
|
||||
fun foo(a: Any): Int {
|
||||
if (a is IntArray) {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// IGNORE_BACKEND_WITHOUT_CHECK: JS
|
||||
|
||||
fun test(b: Boolean): String {
|
||||
val a = if (b) IntArray(5) else LongArray(5)
|
||||
if (a is IntArray) {
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
import kotlin.test.assertTrue
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFails
|
||||
|
||||
fun box(): String {
|
||||
assertTrue(eqBoolean(booleanArrayOf(false), BooleanArray(1)))
|
||||
assertTrue(eqBoolean(booleanArrayOf(false, true, false), BooleanArray(3) { it % 2 != 0 }))
|
||||
assertTrue(eqBoolean(booleanArrayOf(true), booleanArrayOf(true).copyOf()))
|
||||
assertTrue(eqBoolean(booleanArrayOf(true, false), booleanArrayOf(true).copyOf(2)))
|
||||
assertTrue(eqBoolean(booleanArrayOf(true), booleanArrayOf(true, true).copyOf(1)))
|
||||
assertTrue(eqBoolean(booleanArrayOf(false, true), booleanArrayOf(false) + true))
|
||||
assertTrue(eqBoolean(booleanArrayOf(false, true, false), booleanArrayOf(false) + listOf(true, false)))
|
||||
assertTrue(eqBoolean(booleanArrayOf(true, false), booleanArrayOf(false, true, false, true).copyOfRange(1, 3)))
|
||||
assertTrue(eqBoolean(booleanArrayOf(false, true, false, true), customBooleanArrayOf(false, *booleanArrayOf(true, false), true)))
|
||||
assertTrue(booleanArrayOf(true).iterator() is BooleanIterator)
|
||||
assertEquals(true, booleanArrayOf(true).iterator().nextBoolean())
|
||||
assertEquals(true, booleanArrayOf(true).iterator().next())
|
||||
assertFalse(booleanArrayOf().iterator().hasNext())
|
||||
assertTrue(assertFails { booleanArrayOf().iterator().next() } is IndexOutOfBoundsException)
|
||||
|
||||
assertTrue(eqByte(byteArrayOf(0), ByteArray(1)))
|
||||
assertTrue(eqByte(byteArrayOf(1, 2, 3), ByteArray(3) { (it + 1).toByte() }))
|
||||
assertTrue(eqByte(byteArrayOf(1), byteArrayOf(1).copyOf()))
|
||||
assertTrue(eqByte(byteArrayOf(1, 0), byteArrayOf(1).copyOf(2)))
|
||||
assertTrue(eqByte(byteArrayOf(1), byteArrayOf(1, 2).copyOf(1)))
|
||||
assertTrue(eqByte(byteArrayOf(1, 2), byteArrayOf(1) + 2))
|
||||
assertTrue(eqByte(byteArrayOf(1, 2, 3), byteArrayOf(1) + listOf(2.toByte(), 3.toByte())))
|
||||
assertTrue(eqByte(byteArrayOf(2, 3), byteArrayOf(1, 2, 3, 4).copyOfRange(1, 3)))
|
||||
assertTrue(eqByte(byteArrayOf(1, 2, 3, 4), customByteArrayOf(1.toByte(), *byteArrayOf(2, 3), 4.toByte())))
|
||||
assertTrue(byteArrayOf(1).iterator() is ByteIterator)
|
||||
assertEquals(1, byteArrayOf(1).iterator().nextByte())
|
||||
assertEquals(1, byteArrayOf(1).iterator().next())
|
||||
assertFalse(byteArrayOf().iterator().hasNext())
|
||||
assertTrue(assertFails { byteArrayOf().iterator().next() } is IndexOutOfBoundsException)
|
||||
|
||||
assertTrue(eqShort(shortArrayOf(0), ShortArray(1)))
|
||||
assertTrue(eqShort(shortArrayOf(1, 2, 3), ShortArray(3) { (it + 1).toShort() }))
|
||||
assertTrue(eqShort(shortArrayOf(1), shortArrayOf(1).copyOf()))
|
||||
assertTrue(eqShort(shortArrayOf(1, 0), shortArrayOf(1).copyOf(2)))
|
||||
assertTrue(eqShort(shortArrayOf(1), shortArrayOf(1, 2).copyOf(1)))
|
||||
assertTrue(eqShort(shortArrayOf(1, 2), shortArrayOf(1) + 2))
|
||||
assertTrue(eqShort(shortArrayOf(1, 2, 3), shortArrayOf(1) + listOf(2.toShort(), 3.toShort())))
|
||||
assertTrue(eqShort(shortArrayOf(2, 3), shortArrayOf(1, 2, 3, 4).copyOfRange(1, 3)))
|
||||
assertTrue(eqShort(shortArrayOf(1, 2, 3, 4), customShortArrayOf(1.toShort(), *shortArrayOf(2, 3), 4.toShort())))
|
||||
assertTrue(shortArrayOf(1).iterator() is ShortIterator)
|
||||
assertEquals(1, shortArrayOf(1).iterator().nextShort())
|
||||
assertEquals(1, shortArrayOf(1).iterator().next())
|
||||
assertFalse(shortArrayOf().iterator().hasNext())
|
||||
assertTrue(assertFails { shortArrayOf().iterator().next() } is IndexOutOfBoundsException)
|
||||
|
||||
assertTrue(eqChar(charArrayOf(0.toChar()), CharArray(1)))
|
||||
assertTrue(eqChar(charArrayOf('a', 'b', 'c'), CharArray(3) { 'a' + it }))
|
||||
assertTrue(eqChar(charArrayOf('a'), charArrayOf('a').copyOf()))
|
||||
assertTrue(eqChar(charArrayOf('a', 0.toChar()), charArrayOf('a').copyOf(2)))
|
||||
assertTrue(eqChar(charArrayOf('a'), charArrayOf('a', 'b').copyOf(1)))
|
||||
assertTrue(eqChar(charArrayOf('a', 'b'), charArrayOf('a') + 'b'))
|
||||
assertTrue(eqChar(charArrayOf('a', 'b', 'c'), charArrayOf('a') + listOf('b', 'c')))
|
||||
assertTrue(eqChar(charArrayOf('b', 'c'), charArrayOf('a', 'b', 'c', 'd').copyOfRange(1, 3)))
|
||||
assertTrue(eqChar(charArrayOf('a', 'b', 'c', 'd'), customCharArrayOf('a', *charArrayOf('b', 'c'), 'd')))
|
||||
assertTrue(charArrayOf('a').iterator() is CharIterator)
|
||||
assertEquals('a', charArrayOf('a').iterator().nextChar())
|
||||
assertEquals('a', charArrayOf('a').iterator().next())
|
||||
assertFalse(charArrayOf().iterator().hasNext())
|
||||
assertTrue(assertFails { charArrayOf().iterator().next() } is IndexOutOfBoundsException)
|
||||
|
||||
assertTrue(eqInt(intArrayOf(0), IntArray(1)))
|
||||
assertTrue(eqInt(intArrayOf(1, 2, 3), IntArray(3) { it + 1 }))
|
||||
assertTrue(eqInt(intArrayOf(1), intArrayOf(1).copyOf()))
|
||||
assertTrue(eqInt(intArrayOf(1, 0), intArrayOf(1).copyOf(2)))
|
||||
assertTrue(eqInt(intArrayOf(1), intArrayOf(1, 2).copyOf(1)))
|
||||
assertTrue(eqInt(intArrayOf(1, 2), intArrayOf(1) + 2))
|
||||
assertTrue(eqInt(intArrayOf(1, 2, 3), intArrayOf(1) + listOf(2, 3)))
|
||||
assertTrue(eqInt(intArrayOf(2, 3), intArrayOf(1, 2, 3, 4).copyOfRange(1, 3)))
|
||||
assertTrue(eqInt(intArrayOf(1, 2, 3, 4), customIntArrayOf(1, *intArrayOf(2, 3), 4)))
|
||||
assertTrue(intArrayOf(1).iterator() is IntIterator)
|
||||
assertEquals(1, intArrayOf(1).iterator().nextInt())
|
||||
assertEquals(1, intArrayOf(1).iterator().next())
|
||||
assertFalse(intArrayOf().iterator().hasNext())
|
||||
assertTrue(assertFails { intArrayOf().iterator().next() } is IndexOutOfBoundsException)
|
||||
|
||||
assertTrue(eqFloat(floatArrayOf(0f), FloatArray(1)))
|
||||
assertTrue(eqFloat(floatArrayOf(1f, 2f, 3f), FloatArray(3) { (it + 1).toFloat() }))
|
||||
assertTrue(eqFloat(floatArrayOf(1f), floatArrayOf(1f).copyOf()))
|
||||
assertTrue(eqFloat(floatArrayOf(1f, 0f), floatArrayOf(1f).copyOf(2)))
|
||||
assertTrue(eqFloat(floatArrayOf(1f), floatArrayOf(1f, 2f).copyOf(1)))
|
||||
assertTrue(eqFloat(floatArrayOf(1f, 2f), floatArrayOf(1f) + 2f))
|
||||
assertTrue(eqFloat(floatArrayOf(1f, 2f, 3f), floatArrayOf(1f) + listOf(2f, 3f)))
|
||||
assertTrue(eqFloat(floatArrayOf(2f, 3f), floatArrayOf(1f, 2f, 3f, 4f).copyOfRange(1, 3)))
|
||||
assertTrue(eqFloat(floatArrayOf(1f, 2f, 3f, 4f), customFloatArrayOf(1f, *floatArrayOf(2f, 3f), 4f)))
|
||||
assertTrue(floatArrayOf(1f).iterator() is FloatIterator)
|
||||
assertEquals(1f, floatArrayOf(1f).iterator().nextFloat())
|
||||
assertEquals(1f, floatArrayOf(1f).iterator().next())
|
||||
assertFalse(floatArrayOf().iterator().hasNext())
|
||||
assertTrue(assertFails { floatArrayOf().iterator().next() } is IndexOutOfBoundsException)
|
||||
|
||||
assertTrue(eqDouble(doubleArrayOf(0.0), DoubleArray(1)))
|
||||
assertTrue(eqDouble(doubleArrayOf(1.0, 2.0, 3.0), DoubleArray(3) { (it + 1).toDouble() }))
|
||||
assertTrue(eqDouble(doubleArrayOf(1.0), doubleArrayOf(1.0).copyOf()))
|
||||
assertTrue(eqDouble(doubleArrayOf(1.0, 0.0), doubleArrayOf(1.0).copyOf(2)))
|
||||
assertTrue(eqDouble(doubleArrayOf(1.0), doubleArrayOf(1.0, 2.0).copyOf(1)))
|
||||
assertTrue(eqDouble(doubleArrayOf(1.0, 2.0), doubleArrayOf(1.0) + 2.0))
|
||||
assertTrue(eqDouble(doubleArrayOf(1.0, 2.0, 3.0), doubleArrayOf(1.0) + listOf(2.0, 3.0)))
|
||||
assertTrue(eqDouble(doubleArrayOf(2.0, 3.0), doubleArrayOf(1.0, 2.0, 3.0, 4.0).copyOfRange(1, 3)))
|
||||
assertTrue(eqDouble(doubleArrayOf(1.0, 2.0, 3.0, 4.0), customDoubleArrayOf(1.0, *doubleArrayOf(2.0, 3.0), 4.0)))
|
||||
assertTrue(doubleArrayOf(1.0).iterator() is DoubleIterator)
|
||||
assertEquals(1.0, doubleArrayOf(1.0).iterator().nextDouble())
|
||||
assertEquals(1.0, doubleArrayOf(1.0).iterator().next())
|
||||
assertFalse(doubleArrayOf().iterator().hasNext())
|
||||
assertTrue(assertFails { doubleArrayOf().iterator().next() } is IndexOutOfBoundsException)
|
||||
|
||||
assertTrue(eqLong(longArrayOf(0), LongArray(1)))
|
||||
assertTrue(eqLong(longArrayOf(1, 2, 3), LongArray(3) { it + 1L }))
|
||||
assertTrue(eqLong(longArrayOf(1), longArrayOf(1).copyOf()))
|
||||
assertTrue(eqLong(longArrayOf(1, 0), longArrayOf(1).copyOf(2)))
|
||||
assertTrue(eqLong(longArrayOf(1), longArrayOf(1, 2).copyOf(1)))
|
||||
assertTrue(eqLong(longArrayOf(1, 2), longArrayOf(1) + 2))
|
||||
assertTrue(eqLong(longArrayOf(1, 2, 3), longArrayOf(1) + listOf(2L, 3L)))
|
||||
assertTrue(eqLong(longArrayOf(2, 3), longArrayOf(1, 2, 3, 4).copyOfRange(1, 3)))
|
||||
assertTrue(eqLong(longArrayOf(1, 2, 3, 4), customLongArrayOf(1L, *longArrayOf(2, 3), 4L)))
|
||||
assertTrue(longArrayOf(1).iterator() is LongIterator)
|
||||
assertEquals(1L, longArrayOf(1).iterator().nextLong())
|
||||
assertEquals(1L, longArrayOf(1).iterator().next())
|
||||
assertFalse(longArrayOf().iterator().hasNext())
|
||||
assertTrue(assertFails { longArrayOf().iterator().next() } is IndexOutOfBoundsException)
|
||||
|
||||
// If `is` checks work...
|
||||
if (intArrayOf() is IntArray) {
|
||||
assertTrue(booleanArrayOf(false) is BooleanArray)
|
||||
assertTrue(byteArrayOf(0) is ByteArray)
|
||||
assertTrue(shortArrayOf(0) is ShortArray)
|
||||
assertTrue(charArrayOf('a') is CharArray)
|
||||
assertTrue(intArrayOf(0) is IntArray)
|
||||
assertTrue(floatArrayOf(0f) is FloatArray)
|
||||
assertTrue(doubleArrayOf(0.0) is DoubleArray)
|
||||
assertTrue(longArrayOf(0) is LongArray)
|
||||
}
|
||||
|
||||
// Rhino `instanceof` fails to distinguish TypedArray's
|
||||
if (intArrayOf() is IntArray && (byteArrayOf() as Any) !is IntArray) {
|
||||
assertTrue(checkExactArrayType(booleanArrayOf(false), booleanArray = true))
|
||||
assertTrue(checkExactArrayType(byteArrayOf(0), byteArray = true))
|
||||
assertTrue(checkExactArrayType(shortArrayOf(0), shortArray = true))
|
||||
assertTrue(checkExactArrayType(charArrayOf('a'), charArray = true))
|
||||
assertTrue(checkExactArrayType(intArrayOf(0), intArray = true))
|
||||
assertTrue(checkExactArrayType(floatArrayOf(0f), floatArray = true))
|
||||
assertTrue(checkExactArrayType(doubleArrayOf(0.0), doubleArray = true))
|
||||
assertTrue(checkExactArrayType(longArrayOf(0), longArray = true))
|
||||
assertTrue(checkExactArrayType(arrayOf<Any?>(), array = true))
|
||||
}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
fun eqBoolean(expected: BooleanArray, actual: BooleanArray): Boolean = actual.size == expected.size && actual.foldIndexed(true) { i, r, v -> r && expected[i] == v }
|
||||
fun eqByte(expected: ByteArray, actual: ByteArray): Boolean = actual.size == expected.size && actual.foldIndexed(true) { i, r, v -> r && expected[i] == v }
|
||||
fun eqShort(expected: ShortArray, actual: ShortArray): Boolean = actual.size == expected.size && actual.foldIndexed(true) { i, r, v -> r && expected[i] == v }
|
||||
fun eqChar(expected: CharArray, actual: CharArray): Boolean = actual.size == expected.size && actual.foldIndexed(true) { i, r, v -> r && expected[i] == v }
|
||||
fun eqInt(expected: IntArray, actual: IntArray): Boolean = actual.size == expected.size && actual.foldIndexed(true) { i, r, v -> r && expected[i] == v }
|
||||
fun eqLong(expected: LongArray, actual: LongArray): Boolean = actual.size == expected.size && actual.foldIndexed(true) { i, r, v -> r && expected[i] == v }
|
||||
fun eqFloat(expected: FloatArray, actual: FloatArray): Boolean = actual.size == expected.size && actual.foldIndexed(true) { i, r, v -> r && expected[i] == v }
|
||||
fun eqDouble(expected: DoubleArray, actual: DoubleArray): Boolean = actual.size == expected.size && actual.foldIndexed(true) { i, r, v -> r && expected[i] == v }
|
||||
|
||||
fun customBooleanArrayOf(vararg arr: Boolean): BooleanArray = arr
|
||||
fun customByteArrayOf(vararg arr: Byte): ByteArray = arr
|
||||
fun customShortArrayOf(vararg arr: Short): ShortArray = arr
|
||||
fun customCharArrayOf(vararg arr: Char): CharArray = arr
|
||||
fun customIntArrayOf(vararg arr: Int): IntArray = arr
|
||||
fun customFloatArrayOf(vararg arr: Float): FloatArray = arr
|
||||
fun customDoubleArrayOf(vararg arr: Double): DoubleArray = arr
|
||||
fun customLongArrayOf(vararg arr: Long): LongArray = arr
|
||||
|
||||
fun checkExactArrayType(
|
||||
a: Any?,
|
||||
booleanArray: Boolean = false,
|
||||
byteArray: Boolean = false,
|
||||
shortArray: Boolean = false,
|
||||
charArray: Boolean = false,
|
||||
intArray: Boolean = false,
|
||||
longArray: Boolean = false,
|
||||
floatArray: Boolean = false,
|
||||
doubleArray: Boolean = false,
|
||||
array: Boolean = false
|
||||
): Boolean {
|
||||
return a is BooleanArray == booleanArray &&
|
||||
a is ByteArray == byteArray &&
|
||||
a is ShortArray == shortArray &&
|
||||
a is CharArray == charArray &&
|
||||
a is IntArray == intArray &&
|
||||
a is LongArray == longArray &&
|
||||
a is FloatArray == floatArray &&
|
||||
a is DoubleArray == doubleArray &&
|
||||
a is Array<*> == array
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND_WITHOUT_CHECK: JS
|
||||
// WITH_RUNTIME
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
@kotlin.Metadata
|
||||
public final class PrimitiveArraysKt {
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
public synthetic static method checkExactArrayType$default(p0: java.lang.Object, p1: boolean, p2: boolean, p3: boolean, p4: boolean, p5: boolean, p6: boolean, p7: boolean, p8: boolean, p9: boolean, p10: int, p11: java.lang.Object): boolean
|
||||
public final static method checkExactArrayType(@org.jetbrains.annotations.Nullable p0: java.lang.Object, p1: boolean, p2: boolean, p3: boolean, p4: boolean, p5: boolean, p6: boolean, p7: boolean, p8: boolean, p9: boolean): boolean
|
||||
public final static @org.jetbrains.annotations.NotNull method customBooleanArrayOf(@org.jetbrains.annotations.NotNull p0: boolean[]): boolean[]
|
||||
public final static @org.jetbrains.annotations.NotNull method customByteArrayOf(@org.jetbrains.annotations.NotNull p0: byte[]): byte[]
|
||||
public final static @org.jetbrains.annotations.NotNull method customCharArrayOf(@org.jetbrains.annotations.NotNull p0: char[]): char[]
|
||||
public final static @org.jetbrains.annotations.NotNull method customDoubleArrayOf(@org.jetbrains.annotations.NotNull p0: double[]): double[]
|
||||
public final static @org.jetbrains.annotations.NotNull method customFloatArrayOf(@org.jetbrains.annotations.NotNull p0: float[]): float[]
|
||||
public final static @org.jetbrains.annotations.NotNull method customIntArrayOf(@org.jetbrains.annotations.NotNull p0: int[]): int[]
|
||||
public final static @org.jetbrains.annotations.NotNull method customLongArrayOf(@org.jetbrains.annotations.NotNull p0: long[]): long[]
|
||||
public final static @org.jetbrains.annotations.NotNull method customShortArrayOf(@org.jetbrains.annotations.NotNull p0: short[]): short[]
|
||||
public final static method eqBoolean(@org.jetbrains.annotations.NotNull p0: boolean[], @org.jetbrains.annotations.NotNull p1: boolean[]): boolean
|
||||
public final static method eqByte(@org.jetbrains.annotations.NotNull p0: byte[], @org.jetbrains.annotations.NotNull p1: byte[]): boolean
|
||||
public final static method eqChar(@org.jetbrains.annotations.NotNull p0: char[], @org.jetbrains.annotations.NotNull p1: char[]): boolean
|
||||
public final static method eqDouble(@org.jetbrains.annotations.NotNull p0: double[], @org.jetbrains.annotations.NotNull p1: double[]): boolean
|
||||
public final static method eqFloat(@org.jetbrains.annotations.NotNull p0: float[], @org.jetbrains.annotations.NotNull p1: float[]): boolean
|
||||
public final static method eqInt(@org.jetbrains.annotations.NotNull p0: int[], @org.jetbrains.annotations.NotNull p1: int[]): boolean
|
||||
public final static method eqLong(@org.jetbrains.annotations.NotNull p0: long[], @org.jetbrains.annotations.NotNull p1: long[]): boolean
|
||||
public final static method eqShort(@org.jetbrains.annotations.NotNull p0: short[], @org.jetbrains.annotations.NotNull p1: short[]): boolean
|
||||
}
|
||||
+6
@@ -611,6 +611,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
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");
|
||||
|
||||
@@ -611,6 +611,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
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");
|
||||
|
||||
@@ -611,6 +611,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
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");
|
||||
|
||||
@@ -877,6 +877,20 @@ public abstract class KotlinBuiltIns {
|
||||
return descriptor != null && getPrimitiveTypeByArrayClassFqName(getFqName(descriptor)) != null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PrimitiveType getPrimitiveArrayElementType(@NotNull KotlinType type) {
|
||||
ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
|
||||
if (descriptor == null) return null;
|
||||
return getPrimitiveTypeByArrayClassFqName(getFqName(descriptor));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PrimitiveType getPrimitiveType(@NotNull KotlinType type) {
|
||||
ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
|
||||
if (type.isMarkedNullable() || !(descriptor instanceof ClassDescriptor)) return null;
|
||||
return getPrimitiveTypeByFqName(getFqName(descriptor));
|
||||
}
|
||||
|
||||
public static boolean isPrimitiveType(@NotNull KotlinType type) {
|
||||
return !type.isMarkedNullable() && isPrimitiveTypeOrNullablePrimitiveType(type);
|
||||
}
|
||||
|
||||
@@ -1277,6 +1277,10 @@ fun main(args: Array<String>) {
|
||||
testClass<AbstractEnumValuesInlineTests> {
|
||||
model("codegen/boxInline/enum/", targetBackend = TargetBackend.JS)
|
||||
}
|
||||
|
||||
testClass<AbstractJsTypedArraysBoxTest> {
|
||||
model("codegen/box/arrays", targetBackend = TargetBackend.JS)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -228,11 +228,10 @@ class ArraysTest {
|
||||
assertEquals(arr.asList().toString(), arr.contentToString())
|
||||
}
|
||||
|
||||
// @Ignore("KT-16056")
|
||||
// @Test fun contentDeepToString() {
|
||||
// val arr = arrayOf("aa", 1, null, charArrayOf('d'))
|
||||
// assertEquals("[aa, 1, null, [d]]", arr.contentDeepToString())
|
||||
// }
|
||||
@Test fun contentDeepToString() {
|
||||
val arr = arrayOf("aa", 1, null, charArrayOf('d'))
|
||||
assertEquals("[aa, 1, null, [d]]", arr.contentDeepToString())
|
||||
}
|
||||
|
||||
@Test fun contentDeepToStringNoRecursion() {
|
||||
// a[b[a, b]]
|
||||
|
||||
+7
-1
@@ -48,4 +48,10 @@ interface KotlinJsOptions : org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
|
||||
* Default value: "v5"
|
||||
*/
|
||||
var target: kotlin.String
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate primitive arrays to JS typed arrays
|
||||
* Default value: false
|
||||
*/
|
||||
var typedArrays: kotlin.Boolean
|
||||
}
|
||||
+8
-1
@@ -59,6 +59,11 @@ internal abstract class KotlinJsOptionsBase : org.jetbrains.kotlin.gradle.dsl.Ko
|
||||
get() = targetField ?: "v5"
|
||||
set(value) { targetField = value }
|
||||
|
||||
private var typedArraysField: kotlin.Boolean? = null
|
||||
override var typedArrays: kotlin.Boolean
|
||||
get() = typedArraysField ?: false
|
||||
set(value) { typedArraysField = value }
|
||||
|
||||
internal open fun updateArguments(args: org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments) {
|
||||
apiVersionField?.let { args.apiVersion = it }
|
||||
languageVersionField?.let { args.languageVersion = it }
|
||||
@@ -71,6 +76,7 @@ internal abstract class KotlinJsOptionsBase : org.jetbrains.kotlin.gradle.dsl.Ko
|
||||
outputFileField?.let { args.outputFile = it }
|
||||
sourceMapField?.let { args.sourceMap = it }
|
||||
targetField?.let { args.target = it }
|
||||
typedArraysField?.let { args.typedArrays = it }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,4 +92,5 @@ internal fun org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments.fil
|
||||
outputFile = null
|
||||
sourceMap = false
|
||||
target = "v5"
|
||||
}
|
||||
typedArrays = false
|
||||
}
|
||||
@@ -103,6 +103,7 @@ private fun List<ConcreteFunction>.writeTo(file: File, sourceFile: SourceFile, p
|
||||
writer.appendln("import kotlin.js.*")
|
||||
if (sourceFile == SourceFile.Arrays) {
|
||||
writer.appendln("import primitiveArrayConcat")
|
||||
writer.appendln("import withType")
|
||||
}
|
||||
}
|
||||
writer.append("import kotlin.comparisons.*\n\n")
|
||||
|
||||
@@ -211,33 +211,43 @@ object CommonArrays {
|
||||
}
|
||||
}
|
||||
|
||||
fun f_plusCollection() = f("plus(elements: Collection<T>)") {
|
||||
operator(true)
|
||||
fun f_plusCollection() =
|
||||
(listOf(InvariantArraysOfObjects to null) + PrimitiveType.defaultPrimitives.map { ArraysOfPrimitives to it }).map {
|
||||
val (family, primitive) = it
|
||||
f("plus(elements: Collection<T>)") {
|
||||
operator(true)
|
||||
|
||||
// TODO: inline arrayPlusCollection when @PublishedAPI is available
|
||||
// inline(Platform.JS, Inline.Yes)
|
||||
// annotations(Platform.JS, """@Suppress("NOTHING_TO_INLINE")""")
|
||||
only(family)
|
||||
if (family == InvariantArraysOfObjects) {
|
||||
only(Platform.JS, ArraysOfObjects)
|
||||
}
|
||||
|
||||
only(InvariantArraysOfObjects, ArraysOfPrimitives)
|
||||
only(Platform.JS, ArraysOfObjects, ArraysOfPrimitives)
|
||||
// TODO: inline arrayPlusCollection when @PublishedAPI is available
|
||||
// inline(Platform.JS, Inline.Yes)
|
||||
// annotations(Platform.JS, """@Suppress("NOTHING_TO_INLINE")""")
|
||||
|
||||
returns("SELF")
|
||||
returns(Platform.JS, ArraysOfObjects) { "Array<T>" }
|
||||
doc { "Returns an array containing all elements of the original array and then all elements of the given [elements] collection." }
|
||||
body(Platform.JVM) {
|
||||
"""
|
||||
var index = size
|
||||
val result = java.util.Arrays.copyOf(this, index + elements.size)
|
||||
for (element in elements) result[index++] = element
|
||||
return result
|
||||
"""
|
||||
}
|
||||
body(Platform.JS) {
|
||||
"""
|
||||
return arrayPlusCollection(this, elements)
|
||||
"""
|
||||
}
|
||||
}
|
||||
returns("SELF")
|
||||
returns(Platform.JS, ArraysOfObjects) { "Array<T>" }
|
||||
doc { "Returns an array containing all elements of the original array and then all elements of the given [elements] collection." }
|
||||
body(Platform.JVM) {
|
||||
"""
|
||||
var index = size
|
||||
val result = java.util.Arrays.copyOf(this, index + elements.size)
|
||||
for (element in elements) result[index++] = element
|
||||
return result
|
||||
"""
|
||||
}
|
||||
if (primitive != null) {
|
||||
only(primitive)
|
||||
}
|
||||
when (primitive) {
|
||||
null, PrimitiveType.Boolean, PrimitiveType.Long ->
|
||||
body(Platform.JS) { "return arrayPlusCollection(this, elements)" }
|
||||
else ->
|
||||
body(Platform.JS) { "return fillFromCollection(this.copyOf(size + elements.size), this.size, elements)" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun f_plusArray() = f("plus(elements: SELF)") {
|
||||
operator(true)
|
||||
@@ -275,81 +285,110 @@ object CommonArrays {
|
||||
|
||||
}
|
||||
|
||||
fun f_copyOfRange() = f("copyOfRange(fromIndex: Int, toIndex: Int)") {
|
||||
inline(Platform.JVM, Inline.Only)
|
||||
inline(Platform.JS, Inline.Yes)
|
||||
annotations(Platform.JS, """@Suppress("NOTHING_TO_INLINE")""")
|
||||
fun f_copyOfRange() = (listOf(InvariantArraysOfObjects to null) + PrimitiveType.defaultPrimitives.map { ArraysOfPrimitives to it }).map {
|
||||
val (family, primitive) = it
|
||||
f("copyOfRange(fromIndex: Int, toIndex: Int)") {
|
||||
only(family)
|
||||
if (family == InvariantArraysOfObjects) {
|
||||
only(Platform.JS, ArraysOfObjects)
|
||||
}
|
||||
|
||||
only(InvariantArraysOfObjects, ArraysOfPrimitives)
|
||||
only(Platform.JS, ArraysOfObjects, ArraysOfPrimitives)
|
||||
inline(Platform.JVM, Inline.Only)
|
||||
|
||||
doc { "Returns new array which is a copy of range of original array." }
|
||||
returns("SELF")
|
||||
returns(Platform.JS, ArraysOfObjects) { "Array<T>" }
|
||||
body(Platform.JVM) {
|
||||
"return java.util.Arrays.copyOfRange(this, fromIndex, toIndex)"
|
||||
}
|
||||
body(Platform.JS) {
|
||||
// TODO: Arguments checking as in java?
|
||||
"return this.asDynamic().slice(fromIndex, toIndex)"
|
||||
doc { "Returns new array which is a copy of range of original array." }
|
||||
returns("SELF")
|
||||
returns(Platform.JS, ArraysOfObjects) { "Array<T>" }
|
||||
body(Platform.JVM) {
|
||||
"return java.util.Arrays.copyOfRange(this, fromIndex, toIndex)"
|
||||
}
|
||||
|
||||
if (primitive != null) {
|
||||
only(primitive)
|
||||
}
|
||||
when (primitive) {
|
||||
PrimitiveType.Char, PrimitiveType.Boolean, PrimitiveType.Long ->
|
||||
body(Platform.JS) { "return withType(\"${primitive}Array\", this.asDynamic().slice(fromIndex, toIndex))" }
|
||||
else -> {
|
||||
annotations(Platform.JS, """@Suppress("NOTHING_TO_INLINE")""")
|
||||
inline(Platform.JS, Inline.Yes)
|
||||
body(Platform.JS) { "return this.asDynamic().slice(fromIndex, toIndex)" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun f_copyOf() = f("copyOf()") {
|
||||
inline(Platform.JVM, Inline.Only)
|
||||
inline(Platform.JS, Inline.Yes)
|
||||
annotations(Platform.JS, """@Suppress("NOTHING_TO_INLINE")""")
|
||||
fun f_copyOf() = (listOf(InvariantArraysOfObjects to null) + PrimitiveType.defaultPrimitives.map { ArraysOfPrimitives to it }).map {
|
||||
val (family, primitive) = it
|
||||
f("copyOf()") {
|
||||
only(family)
|
||||
if (family == InvariantArraysOfObjects) {
|
||||
only(Platform.JS, ArraysOfObjects)
|
||||
}
|
||||
|
||||
only(InvariantArraysOfObjects, ArraysOfPrimitives)
|
||||
only(Platform.JS, ArraysOfObjects, ArraysOfPrimitives)
|
||||
inline(Platform.JVM, Inline.Only)
|
||||
|
||||
only(InvariantArraysOfObjects, ArraysOfPrimitives)
|
||||
doc { "Returns new array which is a copy of the original array." }
|
||||
returns("SELF")
|
||||
returns(Platform.JS, ArraysOfObjects) { "Array<T>" }
|
||||
doc { "Returns new array which is a copy of the original array." }
|
||||
returns("SELF")
|
||||
returns(Platform.JS, ArraysOfObjects) { "Array<T>" }
|
||||
|
||||
body(Platform.JVM) {
|
||||
"return java.util.Arrays.copyOf(this, size)"
|
||||
}
|
||||
body(Platform.JS) {
|
||||
"return this.asDynamic().slice()"
|
||||
body(Platform.JVM) {
|
||||
"return java.util.Arrays.copyOf(this, size)"
|
||||
}
|
||||
body(Platform.JS) {
|
||||
"return this.asDynamic().slice()"
|
||||
}
|
||||
|
||||
if (primitive != null) {
|
||||
only(primitive)
|
||||
}
|
||||
when (primitive) {
|
||||
PrimitiveType.Char, PrimitiveType.Boolean, PrimitiveType.Long ->
|
||||
body(Platform.JS) { "return withType(\"${primitive}Array\", this.asDynamic().slice())" }
|
||||
else -> {
|
||||
annotations(Platform.JS, """@Suppress("NOTHING_TO_INLINE")""")
|
||||
inline(Platform.JS, Inline.Yes)
|
||||
body(Platform.JS) { "return this.asDynamic().slice()" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun f_copyOfResized() =
|
||||
(PrimitiveType.defaultPrimitives.map { ArraysOfPrimitives to it } + (InvariantArraysOfObjects to null)).map {
|
||||
val (family, primitive) = it
|
||||
f("copyOf(newSize: Int)") {
|
||||
only(family)
|
||||
if (family == InvariantArraysOfObjects) {
|
||||
only(Platform.JS, ArraysOfObjects)
|
||||
}
|
||||
|
||||
inline(Platform.JVM, Inline.Only)
|
||||
doc { "Returns new array which is a copy of the original array, resized to the given [newSize]." }
|
||||
val defaultValue: String
|
||||
if (primitive != null) {
|
||||
only(primitive)
|
||||
returns("SELF")
|
||||
defaultValue = when (primitive) {
|
||||
PrimitiveType.Boolean -> false.toString()
|
||||
PrimitiveType.Char -> "0"
|
||||
else -> "ZERO"
|
||||
(PrimitiveType.defaultPrimitives.map { ArraysOfPrimitives to it } + (InvariantArraysOfObjects to null)).map {
|
||||
val (family, primitive) = it
|
||||
f("copyOf(newSize: Int)") {
|
||||
only(family)
|
||||
if (family == InvariantArraysOfObjects) {
|
||||
only(Platform.JS, ArraysOfObjects)
|
||||
}
|
||||
|
||||
inline(Platform.JVM, Inline.Only)
|
||||
doc { "Returns new array which is a copy of the original array, resized to the given [newSize]." }
|
||||
|
||||
if (primitive != null) {
|
||||
only(primitive)
|
||||
returns("SELF")
|
||||
when (primitive) {
|
||||
PrimitiveType.Boolean ->
|
||||
body(Platform.JS) { "return withType(\"BooleanArray\", arrayCopyResize(this, newSize, false))" }
|
||||
PrimitiveType.Char ->
|
||||
body(Platform.JS) { "return withType(\"CharArray\", fillFrom(this, ${primitive}Array(newSize)))" }
|
||||
PrimitiveType.Long ->
|
||||
body(Platform.JS) { "return withType(\"LongArray\", arrayCopyResize(this, newSize, ZERO))" }
|
||||
else ->
|
||||
body(Platform.JS) { "return fillFrom(this, ${primitive}Array(newSize))" }
|
||||
}
|
||||
}
|
||||
else {
|
||||
returns { "Array<T?>" }
|
||||
body(Platform.JS) { "return arrayCopyResize(this, newSize, null)" }
|
||||
}
|
||||
|
||||
body(Platform.JVM) {
|
||||
"return java.util.Arrays.copyOf(this, newSize)"
|
||||
}
|
||||
} else {
|
||||
returns { "Array<T?>" }
|
||||
defaultValue = "null"
|
||||
}
|
||||
body(Platform.JVM) {
|
||||
"return java.util.Arrays.copyOf(this, newSize)"
|
||||
}
|
||||
body(Platform.JS) {
|
||||
"""
|
||||
return arrayCopyResize(this, newSize, $defaultValue)
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun f_sortPrimitives() =
|
||||
(PrimitiveType.numericPrimitives + PrimitiveType.Char).map { primitive ->
|
||||
@@ -481,12 +520,13 @@ object CommonArrays {
|
||||
return result as Array<T>
|
||||
"""
|
||||
}
|
||||
|
||||
if (primitive == PrimitiveType.Char) {
|
||||
body(Platform.JS) { "return Array<Char>(size, { i -> this[i] })" }
|
||||
}
|
||||
else {
|
||||
body(Platform.JS) { "return copyOf().unsafeCast<Array<T>>()" }
|
||||
when (primitive) {
|
||||
PrimitiveType.Char ->
|
||||
body(Platform.JS) { "return Array<Char>(size, { i -> this[i] })" }
|
||||
PrimitiveType.Boolean, PrimitiveType.Long ->
|
||||
body(Platform.JS) { "return copyOf().unsafeCast<Array<T>>()" }
|
||||
else ->
|
||||
body(Platform.JS) { "return js(\"[]\").slice.call(this)" }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -496,7 +536,10 @@ object CommonArrays {
|
||||
fun templates() =
|
||||
listOf(f_plusElement()) +
|
||||
f_plusElementOperator() +
|
||||
listOf(f_plusCollection(), f_plusArray(), f_copyOf(), f_copyOfRange()) +
|
||||
f_plusCollection() +
|
||||
listOf(f_plusArray()) +
|
||||
f_copyOf() +
|
||||
f_copyOfRange() +
|
||||
f_copyOfResized() +
|
||||
f_sortPrimitives() +
|
||||
listOf(f_sort(), f_sortWith(), f_asList()) +
|
||||
|
||||
Reference in New Issue
Block a user