From e95be9096ef677283101bffac0ae0b4e7f7d7ecc Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Thu, 17 Sep 2015 18:12:21 +0300 Subject: [PATCH] Revert unification of operations on Array and Array (copyOf, copyOfRange) which return the same type as the receiver. Leave sortedArray, reversedArray and sliceArray only for covariant projection of array as the receiver. --- libraries/stdlib/src/generated/_Filtering.kt | 11 +++-- libraries/stdlib/src/generated/_Ordering.kt | 44 +++++++++---------- libraries/stdlib/src/generated/_SpecialJVM.kt | 24 ++++++++-- .../src/kotlin/collections/ArraysJVM.kt | 4 +- .../stdlib/test/collections/ArraysTest.kt | 4 +- .../kotlin-stdlib-gen/src/templates/Engine.kt | 5 --- .../src/templates/Filtering.kt | 15 +++---- .../src/templates/Ordering.kt | 22 +++++----- .../src/templates/SpecialJVM.kt | 12 ++--- 9 files changed, 73 insertions(+), 68 deletions(-) diff --git a/libraries/stdlib/src/generated/_Filtering.kt b/libraries/stdlib/src/generated/_Filtering.kt index 63657a02a1c..8dca320bcfe 100644 --- a/libraries/stdlib/src/generated/_Filtering.kt +++ b/libraries/stdlib/src/generated/_Filtering.kt @@ -1229,14 +1229,13 @@ public fun String.slice(indices: Iterable): String { /** * Returns an array containing elements of this array at specified [indices]. */ -public fun > A.sliceArray(indices: Collection): A { - if (indices.isEmpty()) return arrayOfNulls(this, 0) as A +public fun Array.sliceArray(indices: Collection): Array { val result = arrayOfNulls(this, indices.size()) as Array var targetIndex = 0 for (sourceIndex in indices) { result[targetIndex++] = this[sourceIndex] } - return result as A + return result } /** @@ -1338,9 +1337,9 @@ public fun ShortArray.sliceArray(indices: Collection): ShortArray { /** * Returns a list containing elements at indices in the specified [indices] range. */ -public fun > A.sliceArray(indices: IntRange): A { - if (indices.isEmpty()) return copyOf(0) as A - return copyOfRange(indices.start, indices.end + 1) as A +public fun Array.sliceArray(indices: IntRange): Array { + if (indices.isEmpty()) return copyOfRange(0, 0) + return copyOfRange(indices.start, indices.end + 1) } /** diff --git a/libraries/stdlib/src/generated/_Ordering.kt b/libraries/stdlib/src/generated/_Ordering.kt index 88ffdb4555c..230df18d9f0 100644 --- a/libraries/stdlib/src/generated/_Ordering.kt +++ b/libraries/stdlib/src/generated/_Ordering.kt @@ -208,13 +208,13 @@ public fun String.reversed(): String { /** * Returns an array with elements of this array in reversed order. */ -public fun > A.reversedArray(): A { +public fun Array.reversedArray(): Array { if (isEmpty()) return this val result = arrayOfNulls(this, size()) as Array val lastIndex = lastIndex for (i in 0..lastIndex) result[lastIndex - i] = this[i] - return result as A + return result } /** @@ -494,9 +494,9 @@ public fun > Sequence.sorted(): Sequence { /** * Returns an array with all elements of this array sorted according to their natural sort order. */ -public fun , A: Array> A.sortedArray(): A { +public fun > Array.sortedArray(): Array { if (isEmpty()) return this - return this.copyOf().apply { sort() } as A + return this.copyOf().apply { sort() } } /** @@ -504,7 +504,7 @@ public fun , A: Array> A.sortedArray(): A { */ public fun ByteArray.sortedArray(): ByteArray { if (isEmpty()) return this - return this.copyOf().apply { sort() } as ByteArray + return this.copyOf().apply { sort() } } /** @@ -512,7 +512,7 @@ public fun ByteArray.sortedArray(): ByteArray { */ public fun CharArray.sortedArray(): CharArray { if (isEmpty()) return this - return this.copyOf().apply { sort() } as CharArray + return this.copyOf().apply { sort() } } /** @@ -520,7 +520,7 @@ public fun CharArray.sortedArray(): CharArray { */ public fun DoubleArray.sortedArray(): DoubleArray { if (isEmpty()) return this - return this.copyOf().apply { sort() } as DoubleArray + return this.copyOf().apply { sort() } } /** @@ -528,7 +528,7 @@ public fun DoubleArray.sortedArray(): DoubleArray { */ public fun FloatArray.sortedArray(): FloatArray { if (isEmpty()) return this - return this.copyOf().apply { sort() } as FloatArray + return this.copyOf().apply { sort() } } /** @@ -536,7 +536,7 @@ public fun FloatArray.sortedArray(): FloatArray { */ public fun IntArray.sortedArray(): IntArray { if (isEmpty()) return this - return this.copyOf().apply { sort() } as IntArray + return this.copyOf().apply { sort() } } /** @@ -544,7 +544,7 @@ public fun IntArray.sortedArray(): IntArray { */ public fun LongArray.sortedArray(): LongArray { if (isEmpty()) return this - return this.copyOf().apply { sort() } as LongArray + return this.copyOf().apply { sort() } } /** @@ -552,16 +552,16 @@ public fun LongArray.sortedArray(): LongArray { */ public fun ShortArray.sortedArray(): ShortArray { if (isEmpty()) return this - return this.copyOf().apply { sort() } as ShortArray + return this.copyOf().apply { sort() } } /** * Returns an array with all elements of this array sorted descending according to their natural sort order. */ -public fun , A: Array> A.sortedArrayDescending(): A { +public fun > Array.sortedArrayDescending(): Array { if (isEmpty()) return this // TODO: Use reverseOrder() - return this.copyOf().apply { sortWith(comparator { a, b -> b.compareTo(a) }) } as A + return this.copyOf().apply { sortWith(comparator { a, b -> b.compareTo(a) }) } } /** @@ -570,7 +570,7 @@ public fun , A: Array> A.sortedArrayDescending(): A { public fun ByteArray.sortedArrayDescending(): ByteArray { if (isEmpty()) return this // TODO: Use in-place reverse - return this.copyOf().apply { sort() }.reversedArray() as ByteArray + return this.copyOf().apply { sort() }.reversedArray() } /** @@ -579,7 +579,7 @@ public fun ByteArray.sortedArrayDescending(): ByteArray { public fun CharArray.sortedArrayDescending(): CharArray { if (isEmpty()) return this // TODO: Use in-place reverse - return this.copyOf().apply { sort() }.reversedArray() as CharArray + return this.copyOf().apply { sort() }.reversedArray() } /** @@ -588,7 +588,7 @@ public fun CharArray.sortedArrayDescending(): CharArray { public fun DoubleArray.sortedArrayDescending(): DoubleArray { if (isEmpty()) return this // TODO: Use in-place reverse - return this.copyOf().apply { sort() }.reversedArray() as DoubleArray + return this.copyOf().apply { sort() }.reversedArray() } /** @@ -597,7 +597,7 @@ public fun DoubleArray.sortedArrayDescending(): DoubleArray { public fun FloatArray.sortedArrayDescending(): FloatArray { if (isEmpty()) return this // TODO: Use in-place reverse - return this.copyOf().apply { sort() }.reversedArray() as FloatArray + return this.copyOf().apply { sort() }.reversedArray() } /** @@ -606,7 +606,7 @@ public fun FloatArray.sortedArrayDescending(): FloatArray { public fun IntArray.sortedArrayDescending(): IntArray { if (isEmpty()) return this // TODO: Use in-place reverse - return this.copyOf().apply { sort() }.reversedArray() as IntArray + return this.copyOf().apply { sort() }.reversedArray() } /** @@ -615,7 +615,7 @@ public fun IntArray.sortedArrayDescending(): IntArray { public fun LongArray.sortedArrayDescending(): LongArray { if (isEmpty()) return this // TODO: Use in-place reverse - return this.copyOf().apply { sort() }.reversedArray() as LongArray + return this.copyOf().apply { sort() }.reversedArray() } /** @@ -624,15 +624,15 @@ public fun LongArray.sortedArrayDescending(): LongArray { public fun ShortArray.sortedArrayDescending(): ShortArray { if (isEmpty()) return this // TODO: Use in-place reverse - return this.copyOf().apply { sort() }.reversedArray() as ShortArray + return this.copyOf().apply { sort() }.reversedArray() } /** * Returns an array with all elements of this array sorted according the specified [comparator]. */ -public fun > A.sortedArrayWith(comparator: Comparator): A { +public fun Array.sortedArrayWith(comparator: Comparator): Array { if (isEmpty()) return this - return this.copyOf().apply { sortWith(comparator) } as A + return this.copyOf().apply { sortWith(comparator) } } /** diff --git a/libraries/stdlib/src/generated/_SpecialJVM.kt b/libraries/stdlib/src/generated/_SpecialJVM.kt index 24e38bfb233..abff977be2b 100644 --- a/libraries/stdlib/src/generated/_SpecialJVM.kt +++ b/libraries/stdlib/src/generated/_SpecialJVM.kt @@ -203,8 +203,8 @@ public fun ShortArray.binarySearch(element: Short, fromIndex: Int = 0, toIndex: /** * Returns new array which is a copy of the original array. */ -public fun > A.copyOf(): A { - return Arrays.copyOf(this, size()) as A +public fun Array.copyOf(): Array { + return Arrays.copyOf(this, size()) } /** @@ -263,6 +263,14 @@ public fun ShortArray.copyOf(): ShortArray { return Arrays.copyOf(this, size()) } +/** + * Returns new array which is a copy of the original array. + */ +platformName("mutableCopyOf") +public fun Array.copyOf(): Array { + return Arrays.copyOf(this, size()) +} + /** * Returns new array which is a copy of the original array. */ @@ -337,8 +345,8 @@ public fun Array.copyOf(newSize: Int): Array { /** * Returns new array which is a copy of range of original array. */ -public fun > A.copyOfRange(fromIndex: Int, toIndex: Int): A { - return Arrays.copyOfRange(this, fromIndex, toIndex) as A +public fun Array.copyOfRange(fromIndex: Int, toIndex: Int): Array { + return Arrays.copyOfRange(this, fromIndex, toIndex) } /** @@ -397,6 +405,14 @@ public fun ShortArray.copyOfRange(fromIndex: Int, toIndex: Int): ShortArray { return Arrays.copyOfRange(this, fromIndex, toIndex) } +/** + * Returns new array which is a copy of range of original array. + */ +platformName("mutableCopyOfRange") +public fun Array.copyOfRange(fromIndex: Int, toIndex: Int): Array { + return Arrays.copyOfRange(this, fromIndex, toIndex) +} + /** * Fills original array with the provided value. */ diff --git a/libraries/stdlib/src/kotlin/collections/ArraysJVM.kt b/libraries/stdlib/src/kotlin/collections/ArraysJVM.kt index 595b21fcd34..28cca186d3c 100644 --- a/libraries/stdlib/src/kotlin/collections/ArraysJVM.kt +++ b/libraries/stdlib/src/kotlin/collections/ArraysJVM.kt @@ -97,6 +97,6 @@ public inline fun Collection.toTypedArray(): Array { public inline fun Array?.orEmpty(): Array = this ?: arrayOf() /** Internal unsafe construction of array based on reference array type */ -private fun > arrayOfNulls(reference: A, size: Int): A { - return java.lang.reflect.Array.newInstance(reference.javaClass.componentType, size) as A +private fun arrayOfNulls(reference: Array, size: Int): Array { + return java.lang.reflect.Array.newInstance(reference.javaClass.componentType, size) as Array } \ No newline at end of file diff --git a/libraries/stdlib/test/collections/ArraysTest.kt b/libraries/stdlib/test/collections/ArraysTest.kt index 991029cecb8..40ad2fed1c6 100644 --- a/libraries/stdlib/test/collections/ArraysTest.kt +++ b/libraries/stdlib/test/collections/ArraysTest.kt @@ -819,7 +819,7 @@ class ArraysTest { with (arrayData("ac", "aD", "aba") { toList().toTypedArray() }) { checkSorted>({ sorted() }, { sortedDescending() }, { iterator() }) - checkSorted>({ sortedArray() }, { sortedArrayDescending()}, { iterator() } ) + checkSorted>({ sortedArray() }, { sortedArrayDescending()}, { iterator() } ) } with (arrayData(3, 7, 1) { toIntArray() }) { @@ -873,7 +873,7 @@ class ArraysTest { .checkSorted>( { sortedWith(comparator) }, { sortedWith(comparator.reversed()) }, { iterator() }) arrayData(arrayOf(0, 1, 2, 3, 4, 5), comparator) - .checkSorted>( { sortedArrayWith(comparator) }, { sortedArrayWith(comparator.reversed()) }, { iterator() }) + .checkSorted>( { sortedArrayWith(comparator) }, { sortedArrayWith(comparator.reversed()) }, { iterator() }) } } diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Engine.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Engine.kt index f671239f9b3..e06a1579cfd 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Engine.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Engine.kt @@ -16,7 +16,6 @@ enum class Family { ArraysOfObjects, ArraysOfPrimitives, InvariantArraysOfObjects, - ArraysOfObjectsSubtype, Strings, Ranges, RangesOfPrimitives, @@ -263,7 +262,6 @@ class GenericFunction(val signature: String, val keyword: String = "fun") : Comp Sets -> "Set<$isAsteriskOrT>" Sequences -> "Sequence<$isAsteriskOrT>" InvariantArraysOfObjects -> "Array" - ArraysOfObjectsSubtype -> "A" ArraysOfObjects -> "Array<${isAsteriskOrT.replace("T", "out T")}>" Strings -> "String" Ranges -> "Range<$isAsteriskOrT>" @@ -287,9 +285,6 @@ class GenericFunction(val signature: String, val keyword: String = "fun") : Comp // TODO: Model for type parameter val types = ArrayList(typeParams) - if (f == ArraysOfObjectsSubtype) { - types.add("A: Array") - } if (f == Generic) { // ensure type parameter T, if it's not added to typeParams before if (!types.any { it == "T" || it.startsWith("T:")}) { diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Filtering.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Filtering.kt index 9e8684266f6..dce6a858e5f 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Filtering.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Filtering.kt @@ -513,18 +513,17 @@ fun filtering(): List { } templates add f("sliceArray(indices: Collection)") { - only(ArraysOfObjectsSubtype, ArraysOfPrimitives) + only(ArraysOfObjects, ArraysOfPrimitives) doc { "Returns an array containing elements of this array at specified [indices]." } returns("SELF") - body(ArraysOfObjectsSubtype) { + body(ArraysOfObjects) { """ - if (indices.isEmpty()) return arrayOfNulls(this, 0) as SELF val result = arrayOfNulls(this, indices.size()) as Array var targetIndex = 0 for (sourceIndex in indices) { result[targetIndex++] = this[sourceIndex] } - return result as SELF + return result """ } body(ArraysOfPrimitives) { @@ -540,13 +539,13 @@ fun filtering(): List { } templates add f("sliceArray(indices: IntRange)") { - only(ArraysOfObjectsSubtype, ArraysOfPrimitives) + only(ArraysOfObjects, ArraysOfPrimitives) doc { "Returns a list containing elements at indices in the specified [indices] range." } returns("SELF") - body(ArraysOfObjectsSubtype) { + body(ArraysOfObjects) { """ - if (indices.isEmpty()) return copyOf(0) as SELF - return copyOfRange(indices.start, indices.end + 1) as SELF + if (indices.isEmpty()) return copyOfRange(0, 0) + return copyOfRange(indices.start, indices.end + 1) """ } body(ArraysOfPrimitives) { diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Ordering.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Ordering.kt index 3a2586dcdd2..3042f4db207 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Ordering.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Ordering.kt @@ -53,16 +53,16 @@ fun ordering(): List { templates add f("reversedArray()") { doc { "Returns an array with elements of this array in reversed order." } - only(ArraysOfObjectsSubtype, ArraysOfPrimitives) + only(ArraysOfObjects, ArraysOfPrimitives) returns("SELF") - body(ArraysOfObjectsSubtype) { + body(ArraysOfObjects) { """ if (isEmpty()) return this val result = arrayOfNulls(this, size()) as Array val lastIndex = lastIndex for (i in 0..lastIndex) result[lastIndex - i] = this[i] - return result as A + return result """ } body(ArraysOfPrimitives) { @@ -114,7 +114,7 @@ fun ordering(): List { } templates add f("sortedArray()") { - only(ArraysOfObjectsSubtype, ArraysOfPrimitives) + only(ArraysOfObjects, ArraysOfPrimitives) exclude(PrimitiveType.Boolean) doc { "Returns an array with all elements of this array sorted according to their natural sort order." @@ -124,7 +124,7 @@ fun ordering(): List { body() { """ if (isEmpty()) return this - return this.copyOf().apply { sort() } as SELF + return this.copyOf().apply { sort() } """ } } @@ -163,18 +163,18 @@ fun ordering(): List { } templates add f("sortedArrayDescending()") { - only(ArraysOfObjectsSubtype, ArraysOfPrimitives) + only(ArraysOfObjects, ArraysOfPrimitives) exclude(PrimitiveType.Boolean) doc { "Returns an array with all elements of this array sorted descending according to their natural sort order." } typeParam("T : Comparable") returns("SELF") - body(ArraysOfObjectsSubtype) { + body(ArraysOfObjects) { """ if (isEmpty()) return this // TODO: Use reverseOrder() - return this.copyOf().apply { sortWith(comparator { a, b -> b.compareTo(a) }) } as SELF + return this.copyOf().apply { sortWith(comparator { a, b -> b.compareTo(a) }) } """ } @@ -182,7 +182,7 @@ fun ordering(): List { """ if (isEmpty()) return this // TODO: Use in-place reverse - return this.copyOf().apply { sort() }.reversedArray() as SELF + return this.copyOf().apply { sort() }.reversedArray() """ } } @@ -221,7 +221,7 @@ fun ordering(): List { } templates add f("sortedArrayWith(comparator: Comparator)") { - only(ArraysOfObjectsSubtype) + only(ArraysOfObjects) doc { "Returns an array with all elements of this array sorted according the specified [comparator]." } @@ -229,7 +229,7 @@ fun ordering(): List { body() { """ if (isEmpty()) return this - return this.copyOf().apply { sortWith(comparator) } as SELF + return this.copyOf().apply { sortWith(comparator) } """ } } diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/SpecialJVM.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/SpecialJVM.kt index 8143d9e6d88..02ed05aa445 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/SpecialJVM.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/SpecialJVM.kt @@ -51,27 +51,23 @@ fun specialJVM(): List { templates add f("copyOfRange(fromIndex: Int, toIndex: Int)") { - only(ArraysOfObjectsSubtype, ArraysOfPrimitives) + only(ArraysOfObjects, InvariantArraysOfObjects, ArraysOfPrimitives) doc { "Returns new array which is a copy of range of original array." } returns("SELF") + annotations(InvariantArraysOfObjects) { """platformName("mutableCopyOfRange")"""} body { "return Arrays.copyOfRange(this, fromIndex, toIndex)" } - body(ArraysOfObjectsSubtype) { - "return Arrays.copyOfRange(this, fromIndex, toIndex) as A" - } } templates add f("copyOf()") { - only(ArraysOfObjectsSubtype, ArraysOfPrimitives) + only(ArraysOfObjects, InvariantArraysOfObjects, ArraysOfPrimitives) doc { "Returns new array which is a copy of the original array." } returns("SELF") + annotations(InvariantArraysOfObjects) { """platformName("mutableCopyOf")"""} body { "return Arrays.copyOf(this, size())" } - body(ArraysOfObjectsSubtype) { - "return Arrays.copyOf(this, size()) as A" - } } // This overload can cause nulls if array size is expanding, hence different return overload