diff --git a/libraries/stdlib/src/generated/_SpecialJVM.kt b/libraries/stdlib/src/generated/_SpecialJVM.kt index a48abe04611..21b31cbba84 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 Array.copyOf(): Array { - return Arrays.copyOf(this, size()) +public fun > A.copyOf(): A { + return Arrays.copyOf(this, size()) as A } /** @@ -263,14 +263,6 @@ 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. */ @@ -345,8 +337,8 @@ public fun Array.copyOf(newSize: Int): Array { /** * Returns new array which is a copy of range of original array. */ -public fun Array.copyOfRange(fromIndex: Int, toIndex: Int): Array { - return Arrays.copyOfRange(this, fromIndex, toIndex) +public fun > A.copyOfRange(fromIndex: Int, toIndex: Int): A { + return Arrays.copyOfRange(this, fromIndex, toIndex) as A } /** @@ -405,14 +397,6 @@ 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/tools/kotlin-stdlib-gen/src/templates/Engine.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Engine.kt index 6607f773a8a..a1a0135ac5b 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Engine.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Engine.kt @@ -16,6 +16,7 @@ enum class Family { ArraysOfObjects, ArraysOfPrimitives, InvariantArraysOfObjects, + ArraysOfObjectsSubtype, Strings, Ranges, RangesOfPrimitives, @@ -167,7 +168,7 @@ class GenericFunction(val signature: String, val keyword: String = "fun") : Comp fun build(vararg families: Family = Family.values()): String { val builder = StringBuilder() - for (family in families.sortBy { it.name() }) { + for (family in families.sortedBy { it.name() }) { if (buildFamilies.contains(family)) build(builder, family) } @@ -177,7 +178,7 @@ class GenericFunction(val signature: String, val keyword: String = "fun") : Comp fun build(builder: StringBuilder, f: Family) { val onlyPrimitives = buildFamilyPrimitives[f] if (f.isPrimitiveSpecialization || onlyPrimitives != null) { - for (primitive in (onlyPrimitives ?: buildPrimitives).sortBy { it.name() }) + for (primitive in (onlyPrimitives ?: buildPrimitives).sortedBy { it.name() }) build(builder, f, primitive) } else { build(builder, f, null) @@ -262,6 +263,7 @@ 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>" @@ -275,8 +277,19 @@ class GenericFunction(val signature: String, val keyword: String = "fun") : Comp fun String.renderType(): String = renderType(this, receiver) fun effectiveTypeParams(): List { + fun getGenericTypeParameters(genericType: String) = + genericType + .dropWhile { it != '<' } + .drop(1) + .takeWhile { it != '>' } + .split(",") + .map { it.removePrefix("out").removePrefix("in").trim() } + // 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:")}) { @@ -285,9 +298,8 @@ class GenericFunction(val signature: String, val keyword: String = "fun") : Comp return types } else if (primitive == null && f != Strings) { - val implicitTypeParameters = receiver.dropWhile { it != '<' }.drop(1).takeWhile { it != '>' }.split(",") - .map { it.removePrefix("out").removePrefix("in").trim() } - for (implicit in implicitTypeParameters.reverse()) { + val implicitTypeParameters = getGenericTypeParameters(receiver) + types.flatMap { getGenericTypeParameters(it) } + for (implicit in implicitTypeParameters.reversed()) { if (implicit != "*" && !types.any { it.startsWith(implicit) || it.startsWith("reified " + implicit) }) { types.add(0, implicit) } @@ -295,7 +307,8 @@ class GenericFunction(val signature: String, val keyword: String = "fun") : Comp return types } else { - // primitive type arrays should drop constraints + // remove T as parameter + // TODO: Substitute primitive or String instead of T in other parameters from effective types not from original typeParams return typeParams.filter { !it.startsWith("T") } } } diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/SpecialJVM.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/SpecialJVM.kt index ceec51f09a2..826ba0af2b4 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/SpecialJVM.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/SpecialJVM.kt @@ -51,23 +51,27 @@ fun specialJVM(): List { templates add f("copyOfRange(fromIndex: Int, toIndex: Int)") { - only(ArraysOfObjects, InvariantArraysOfObjects, ArraysOfPrimitives) + only(ArraysOfObjectsSubtype, 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(ArraysOfObjects, InvariantArraysOfObjects, ArraysOfPrimitives) + only(ArraysOfObjectsSubtype, 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