Provide implementation templates for Native platform

This commit is contained in:
Ilya Gorbunov
2018-12-25 06:55:48 +03:00
parent f05efd58de
commit 5584b435dc
2 changed files with 184 additions and 21 deletions
@@ -92,6 +92,24 @@ object ArrayOps : TemplateGroupBase() {
body { "return contentEqualsInternal(other)" }
}
}
on(Platform.Native) {
body {
"""
if (this === other) {
return true
}
if (size != other.size) {
return false
}
for (i in indices) {
if (this[i] != other[i]) {
return false
}
}
return true
"""
}
}
}
val f_contentDeepEquals = fn("contentDeepEquals(other: SELF)") {
@@ -131,6 +149,9 @@ object ArrayOps : TemplateGroupBase() {
body { "return contentDeepEqualsImpl(other)" }
}
}
on(Platform.Native) {
body { "return contentDeepEqualsImpl(other)" }
}
}
val f_contentToString = fn("contentToString()") {
@@ -161,6 +182,9 @@ object ArrayOps : TemplateGroupBase() {
body { "return arrayToString(this as Array<*>)" }
}
}
on(Platform.Native) {
body { """return joinToString(", ", "[", "]")""" }
}
}
val f_contentDeepToString = fn("contentDeepToString()") {
@@ -199,6 +223,9 @@ object ArrayOps : TemplateGroupBase() {
body { "return contentDeepToStringImpl()" }
}
}
on(Platform.Native) {
body { "return contentDeepToStringImpl()" }
}
}
val f_contentHashCode = fn("contentHashCode()") {
@@ -226,6 +253,16 @@ object ArrayOps : TemplateGroupBase() {
body { "return contentHashCodeInternal()" }
}
}
on(Platform.Native) {
body {
"""
var result = 1
for (element in this)
result = 31 * result + element.hashCode()
return result
"""
}
}
}
val f_contentDeepHashCode = fn("contentDeepHashCode()") {
@@ -262,6 +299,9 @@ object ArrayOps : TemplateGroupBase() {
body { "return contentDeepHashCodeInternal()" }
}
}
on(Platform.Native) {
body { "return contentDeepHashCodeImpl()" }
}
}
val f_toPrimitiveArray = fn("toPrimitiveArray()") {
@@ -382,6 +422,10 @@ object ArrayOps : TemplateGroupBase() {
inlineOnly()
body { "return plus(element)" }
}
on(Platform.Native) {
inlineOnly()
body { "return plus(element)" }
}
on(Platform.JS) {
family = ArraysOfObjects
inline(suppressWarning = true)
@@ -433,6 +477,16 @@ object ArrayOps : TemplateGroupBase() {
"return plus(${primitive.name.toLowerCase()}ArrayOf(element))"
}
}
on(Platform.Native) {
body {
"""
val index = size
val result = copyOfUninitializedElements(index + 1)
result[index] = element
return result
"""
}
}
on(Platform.Common) {
specialFor(InvariantArraysOfObjects) {
suppress("NO_ACTUAL_FOR_EXPECT") // TODO: KT-21937
@@ -473,6 +527,16 @@ object ArrayOps : TemplateGroupBase() {
body { "return fillFromCollection(this.copyOf(size + elements.size), this.size, elements)" }
}
}
on(Platform.Native) {
body {
"""
var index = size
val result = copyOfUninitializedElements(index + elements.size)
for (element in elements) result[index++] = element
return result
"""
}
}
on(Platform.Common) {
specialFor(InvariantArraysOfObjects) {
suppress("NO_ACTUAL_FOR_EXPECT") // TODO: KT-21937
@@ -514,6 +578,17 @@ object ArrayOps : TemplateGroupBase() {
body { """return primitiveArrayConcat(this, elements)""" }
}
}
on(Platform.Native) {
body {
"""
val thisSize = size
val arraySize = elements.size
val result = copyOfUninitializedElements(thisSize + arraySize)
elements.copyRangeTo(result, 0, arraySize, thisSize)
return result
"""
}
}
on(Platform.Common) {
specialFor(InvariantArraysOfObjects) {
suppress("NO_ACTUAL_FOR_EXPECT") // TODO: KT-21937
@@ -581,6 +656,15 @@ object ArrayOps : TemplateGroupBase() {
"""
}
}
on(Platform.Native) {
suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
body {
"""
this.copyRangeTo(destination, startIndex, endIndex, destinationOffset)
return destination
"""
}
}
}
}
@@ -654,6 +738,15 @@ object ArrayOps : TemplateGroupBase() {
suppress("NO_ACTUAL_FOR_EXPECT") // TODO: KT-21937
}
}
on(Platform.Native) {
inlineOnly()
body {
"""
checkCopyOfRangeArguments(fromIndex, toIndex, size)
return copyOfUninitializedElements(fromIndex, toIndex)
"""
}
}
}
}
@@ -699,7 +792,10 @@ object ArrayOps : TemplateGroupBase() {
suppress("NO_ACTUAL_FOR_EXPECT") // TODO: KT-21937
}
}
on(Platform.Native) {
inlineOnly()
body { "return this.copyOfUninitializedElements(size)" }
}
}
}
@@ -739,7 +835,10 @@ object ArrayOps : TemplateGroupBase() {
}
body { newSizeCheck + "\n" + body }
}
on(Platform.Native) {
inlineOnly()
body { "return this.copyOfUninitializedElements(newSize)" }
}
}
specialFor(InvariantArraysOfObjects) {
sample("samples.collections.Arrays.CopyOfOperations.resizingCopyOf")
@@ -757,6 +856,10 @@ object ArrayOps : TemplateGroupBase() {
on(Platform.Common) {
suppress("NO_ACTUAL_FOR_EXPECT") // TODO: KT-21937
}
on(Platform.Native) {
inlineOnly()
body { "return this.copyOfNulls(newSize)" }
}
}
specialFor(ArraysOfPrimitives, InvariantArraysOfObjects) {
on(Platform.JVM) {
@@ -814,6 +917,14 @@ object ArrayOps : TemplateGroupBase() {
}
}
}
on(Platform.Native) {
specialFor(ArraysOfObjects) {
body { """if (size > 1) kotlin.util.sortArrayComparable(this)""" }
}
specialFor(ArraysOfPrimitives) {
body { """if (size > 1) kotlin.util.sortArray(this)""" }
}
}
}
val f_sortWith = fn("sortWith(comparator: Comparator<in T>)") {
@@ -834,6 +945,9 @@ object ArrayOps : TemplateGroupBase() {
"""
}
}
on(Platform.Native) {
body { """if (size > 1) kotlin.util.sortArrayWith(this, 0, size, comparator)""" }
}
}
val f_sort_comparison = fn("sort(noinline comparison: (a: T, b: T) -> Int)") {
@@ -902,8 +1016,7 @@ object ArrayOps : TemplateGroupBase() {
body { """return ArrayList<T>(this.unsafeCast<Array<Any?>>())""" }
}
specialFor(ArraysOfPrimitives) {
val objectLiteralImpl = """
val objectLiteralImpl = """
return object : AbstractList<T>(), RandomAccess {
override val size: Int get() = this@asList.size
override fun isEmpty(): Boolean = this@asList.isEmpty()
@@ -913,6 +1026,7 @@ object ArrayOps : TemplateGroupBase() {
override fun lastIndexOf(element: T): Int = this@asList.lastIndexOf(element)
}
"""
specialFor(ArraysOfPrimitives) {
on(Platform.JVM) {
body { objectLiteralImpl }
}
@@ -926,6 +1040,9 @@ object ArrayOps : TemplateGroupBase() {
}
}
}
on(Platform.Native) {
body { objectLiteralImpl }
}
}
val f_toTypedArray = fn("toTypedArray()") {
@@ -145,6 +145,7 @@ object ComparableOps : TemplateGroupBase() {
If values are equal, returns the first one.
"""
}
val defaultImpl = "if (a <= b) a else b"
// TODO: Add a note about NaN propagation for floats.
specialFor(Primitives) {
inlineOnly()
@@ -156,26 +157,45 @@ object ComparableOps : TemplateGroupBase() {
suppress("DEPRECATION_ERROR")
convertBack = "unsafeCast<$primitive>()"
}
body {
"return Math.min(a, b)"
body { "return $defaultImpl" }
on(Platform.JVM) {
body { "return Math.min(a, b)" }
}
on(Platform.JS) {
body { "return Math.min(a, b)" }
if (primitive == PrimitiveType.Long) {
inline(suppressWarning = true)
body { "return $defaultImpl" }
}
}
if (primitive in shortIntPrimitives) {
body { "return Math.min(a.toInt(), b.toInt()).$convertBack" }
on(Platform.Native) {
body { "return minOf(a.toInt(), b.toInt()).$convertBack" }
}
}
on(Platform.JS) {
if (primitive == PrimitiveType.Long) {
inline(suppressWarning = true)
body { "return if (a <= b) a else b" }
if (primitive?.isIntegral() == false) {
on(Platform.Native) {
body {
"""
// TODO: Check +/-0.0
return when {
a.isNaN() -> a
b.isNaN() -> b
else -> $defaultImpl
}
"""
}
}
}
}
on(Platform.JS) { /* just to make expect, KT-22520 */ }
body(Generic) {
"return if (a <= b) a else b"
"return $defaultImpl"
}
}
val f_minOf = fn("minOf(a: T, b: T, c: T)") {
val f_minOf_3 = fn("minOf(a: T, b: T, c: T)") {
include(Generic)
include(Primitives, numericPrimitives)
} builder {
@@ -197,7 +217,10 @@ object ComparableOps : TemplateGroupBase() {
on(Platform.JS) { /* just to make expect, KT-22520 */ }
specialFor(Primitives) {
if (primitive in shortIntPrimitives) {
body { "return Math.min(a.toInt(), Math.min(b.toInt(), c.toInt())).to$primitive()" }
body { "return minOf(a.toInt(), minOf(b.toInt(), c.toInt())).to$primitive()" }
on(Platform.JVM) {
body { "return Math.min(a.toInt(), Math.min(b.toInt(), c.toInt())).to$primitive()" }
}
on(Platform.JS) {
suppress("DEPRECATION_ERROR")
body { "return Math.min(a.toInt(), b.toInt(), c.toInt()).unsafeCast<$primitive>()" }
@@ -262,6 +285,7 @@ object ComparableOps : TemplateGroupBase() {
If values are equal, returns the first one.
"""
}
val defaultImpl = "if (a >= b) a else b"
// TODO: Add a note about NaN propagation for floats.
specialFor(Primitives) {
inlineOnly()
@@ -273,22 +297,41 @@ object ComparableOps : TemplateGroupBase() {
suppress("DEPRECATION_ERROR")
convertBack = "unsafeCast<$primitive>()"
}
body {
"return Math.max(a, b)"
body { "return $defaultImpl" }
on(Platform.JVM) {
body { "return Math.max(a, b)" }
}
on(Platform.JS) {
body { "return Math.max(a, b)" }
if (primitive == PrimitiveType.Long) {
inline(suppressWarning = true)
body { "return $defaultImpl" }
}
}
if (primitive in shortIntPrimitives) {
body { "return Math.max(a.toInt(), b.toInt()).$convertBack" }
on(Platform.Native) {
body { "return maxOf(a.toInt(), b.toInt()).$convertBack" }
}
}
on(Platform.JS) {
if (primitive == PrimitiveType.Long) {
inline(suppressWarning = true)
body { "return if (a >= b) a else b" }
if (primitive?.isIntegral() == false) {
on(Platform.Native) {
body {
"""
// TODO: Check +/-0.0
return when {
a.isNaN() -> a
b.isNaN() -> b
else -> $defaultImpl
}
"""
}
}
}
}
on(Platform.JS) { /* just to make expect, KT-22520 */ }
body(Generic) {
"return if (a >= b) a else b"
"return $defaultImpl"
}
}
@@ -314,7 +357,10 @@ object ComparableOps : TemplateGroupBase() {
on(Platform.JS) { /* just to make expect, KT-22520 */ }
specialFor(Primitives) {
if (primitive in shortIntPrimitives) {
body { "return Math.max(a.toInt(), Math.max(b.toInt(), c.toInt())).to$primitive()" }
body { "return maxOf(a.toInt(), maxOf(b.toInt(), c.toInt())).to$primitive()" }
on(Platform.JVM) {
body { "return Math.max(a.toInt(), Math.max(b.toInt(), c.toInt())).to$primitive()" }
}
on(Platform.JS) {
suppress("DEPRECATION_ERROR")
body { "return Math.max(a.toInt(), b.toInt(), c.toInt()).unsafeCast<$primitive>()" }