From 6f71e54268c8145b34cfe5854b9fa691af267552 Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Sat, 25 Jul 2015 01:31:52 +0300 Subject: [PATCH] In-place array sorting in JS. --- js/js.libraries/src/core/kotlin_special.kt | 126 ++++++++++++++++++ js/js.translator/testData/kotlin_lib.js | 4 + .../stdlib/test/collections/ArraysJVMTest.kt | 9 -- .../stdlib/test/collections/ArraysTest.kt | 19 +++ .../kotlin-stdlib-gen/src/templates/Arrays.kt | 1 + .../src/templates/SpecialJS.kt | 31 +++++ 6 files changed, 181 insertions(+), 9 deletions(-) diff --git a/js/js.libraries/src/core/kotlin_special.kt b/js/js.libraries/src/core/kotlin_special.kt index 4e0757ee5a9..10d290347dd 100644 --- a/js/js.libraries/src/core/kotlin_special.kt +++ b/js/js.libraries/src/core/kotlin_special.kt @@ -489,6 +489,132 @@ public inline fun ShortArray.plus(element: Short): ShortArray { return (this: dynamic).concat(arrayOf(element)) } +/** + * Sorts the array inplace. + */ +library("primitiveArraySort") +public fun ByteArray.sort(): Unit { + return noImpl +} + +/** + * Sorts the array inplace. + */ +library("primitiveArraySort") +public fun CharArray.sort(): Unit { + return noImpl +} + +/** + * Sorts the array inplace. + */ +library("primitiveArraySort") +public fun DoubleArray.sort(): Unit { + return noImpl +} + +/** + * Sorts the array inplace. + */ +library("primitiveArraySort") +public fun FloatArray.sort(): Unit { + return noImpl +} + +/** + * Sorts the array inplace. + */ +library("primitiveArraySort") +public fun IntArray.sort(): Unit { + return noImpl +} + +/** + * Sorts the array inplace. + */ +library("primitiveArraySort") +public fun ShortArray.sort(): Unit { + return noImpl +} + +/** + * Sorts the array inplace. + */ +public fun > Array.sort(): Unit { + sort { a: T, b: T -> a.compareTo(b) } +} + +/** + * Sorts the array inplace. + */ +public fun LongArray.sort(): Unit { + sort { a: Long, b: Long -> a.compareTo(b) } +} + +/** + * Sorts the array inplace according to the order specified by the given [comparison] function. + */ +native +public fun Array.sort(comparison: (T, T) -> Int): Unit { + return noImpl +} + +/** + * Sorts the array inplace according to the order specified by the given [comparison] function. + */ +native +public fun ByteArray.sort(comparison: (Byte, Byte) -> Int): Unit { + return noImpl +} + +/** + * Sorts the array inplace according to the order specified by the given [comparison] function. + */ +native +public fun CharArray.sort(comparison: (Char, Char) -> Int): Unit { + return noImpl +} + +/** + * Sorts the array inplace according to the order specified by the given [comparison] function. + */ +native +public fun DoubleArray.sort(comparison: (Double, Double) -> Int): Unit { + return noImpl +} + +/** + * Sorts the array inplace according to the order specified by the given [comparison] function. + */ +native +public fun FloatArray.sort(comparison: (Float, Float) -> Int): Unit { + return noImpl +} + +/** + * Sorts the array inplace according to the order specified by the given [comparison] function. + */ +native +public fun IntArray.sort(comparison: (Int, Int) -> Int): Unit { + return noImpl +} + +/** + * Sorts the array inplace according to the order specified by the given [comparison] function. + */ +native +public fun LongArray.sort(comparison: (Long, Long) -> Int): Unit { + return noImpl +} + +/** + * Sorts the array inplace according to the order specified by the given [comparison] function. + */ +native +public fun ShortArray.sort(comparison: (Short, Short) -> Int): Unit { + return noImpl +} + /** * Returns a *typed* object array containing all of the elements of this primitive array. */ diff --git a/js/js.translator/testData/kotlin_lib.js b/js/js.translator/testData/kotlin_lib.js index 166ee2e1449..0fd49fc4918 100644 --- a/js/js.translator/testData/kotlin_lib.js +++ b/js/js.translator/testData/kotlin_lib.js @@ -1005,6 +1005,10 @@ } }; + Kotlin.primitiveArraySort = function(array) { + array.sort(Kotlin.primitiveCompareTo) + }; + Kotlin.copyToArray = function (collection) { var array = []; var it = collection.iterator(); diff --git a/libraries/stdlib/test/collections/ArraysJVMTest.kt b/libraries/stdlib/test/collections/ArraysJVMTest.kt index b4892a7457f..17f9ac09581 100644 --- a/libraries/stdlib/test/collections/ArraysJVMTest.kt +++ b/libraries/stdlib/test/collections/ArraysJVMTest.kt @@ -5,15 +5,6 @@ import org.junit.Test as test class ArraysJVMTest { - test fun sort() { - var a = intArrayOf(5, 2, 1, 4, 3) - var b = intArrayOf(1, 2, 3, 4, 5) - a.sort() - for (i in a.indices) - expect(b[i]) { a[i] } - } - - test fun orEmptyNull() { val x: Array? = null val y: Array? = null diff --git a/libraries/stdlib/test/collections/ArraysTest.kt b/libraries/stdlib/test/collections/ArraysTest.kt index 4b1647b741d..4601f1ff42b 100644 --- a/libraries/stdlib/test/collections/ArraysTest.kt +++ b/libraries/stdlib/test/collections/ArraysTest.kt @@ -769,4 +769,23 @@ class ArraysTest { assertEquals(Array(0, { "" }).asList(), emptyList()) } + + test fun sort() { + val intArr = intArrayOf(5, 2, 1, 9, 80, Int.MIN_VALUE, Int.MAX_VALUE) + intArr.sort() + assertArrayNotSameButEquals(intArrayOf(Int.MIN_VALUE, 1, 2, 5, 9, 80, Int.MAX_VALUE), intArr) + + val longArr = longArrayOf(200, 2, 1, 4, 3, Long.MIN_VALUE, Long.MAX_VALUE) + longArr.sort() + assertArrayNotSameButEquals(longArrayOf(Long.MIN_VALUE, 1, 2, 3, 4, 200, Long.MAX_VALUE), longArr) + + val charArr = charArrayOf('d', 'c', 'E', 'a', '\u0000', '\uFFFF') + charArr.sort() + assertArrayNotSameButEquals(charArrayOf('\u0000', 'E', 'a', 'c', 'd', '\uFFFF'), charArr) + + val strArr = arrayOf("9", "80", "all", "Foo") + strArr.sort() + assertArrayNotSameButEquals(arrayOf("80", "9", "Foo", "all"), strArr) + } + } diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Arrays.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Arrays.kt index 6c159b4173a..6381fc746f5 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Arrays.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Arrays.kt @@ -68,6 +68,7 @@ fun toPrimitiveArrays(): List = doc(ArraysOfObjects) { "Returns an array of ${primitive.name} containing all of the elements of this generic array." } doc(Collections) { "Returns an array of ${primitive.name} containing all of the elements of this collection." } returns(arrayType) + // TODO: Use different implementations for JS body { """ val result = $arrayType(size()) diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/SpecialJS.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/SpecialJS.kt index 82abed760c3..8f412e7f8cf 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/SpecialJS.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/SpecialJS.kt @@ -131,6 +131,37 @@ fun specialJS(): List { } } + templates add f("sort(comparison: (T, T) -> Int)") { + only(ArraysOfObjects, ArraysOfPrimitives) + exclude(PrimitiveType.Boolean) + annotations("native") + returns("Unit") + doc { "Sorts the array inplace according to the order specified by the given [comparison] function." } + body { "return noImpl" } + } + + templates add f("sort()") { + only(ArraysOfPrimitives) + only(numericPrimitives + PrimitiveType.Char) + exclude(PrimitiveType.Long) + returns("Unit") + doc { "Sorts the array inplace." } + annotations("""library("primitiveArraySort")""") + body { "return noImpl" } + } + + templates add f("sort()") { + only(ArraysOfObjects, ArraysOfPrimitives) + only(PrimitiveType.Long) + typeParam("T: Comparable") + returns("Unit") + doc { "Sorts the array inplace." } + body { + """ + sort { a: T, b: T -> a.compareTo(b) } + """ + } + } return templates