JS IR: hide runtime helpers from users
This commit is contained in:
@@ -7,7 +7,8 @@ package kotlin.js
|
|||||||
|
|
||||||
import withType
|
import withType
|
||||||
|
|
||||||
external fun <T> Array(size: Int): Array<T>
|
@PublishedApi
|
||||||
|
internal external fun <T> Array(size: Int): Array<T>
|
||||||
|
|
||||||
@PublishedApi
|
@PublishedApi
|
||||||
internal fun <T> fillArrayVal(array: Array<T>, initValue: T): Array<T> {
|
internal fun <T> fillArrayVal(array: Array<T>, initValue: T): Array<T> {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ package kotlin.js
|
|||||||
|
|
||||||
// Adopted from misc.js
|
// Adopted from misc.js
|
||||||
|
|
||||||
fun compareTo(a: dynamic, b: dynamic): Int = when (jsTypeOf(a)) {
|
internal fun compareTo(a: dynamic, b: dynamic): Int = when (jsTypeOf(a)) {
|
||||||
"number" -> when {
|
"number" -> when {
|
||||||
jsTypeOf(b) == "number" ->
|
jsTypeOf(b) == "number" ->
|
||||||
doubleCompareTo(a, b)
|
doubleCompareTo(a, b)
|
||||||
@@ -27,14 +27,14 @@ fun compareTo(a: dynamic, b: dynamic): Int = when (jsTypeOf(a)) {
|
|||||||
private fun <T : Comparable<T>> compareToDoNotIntrinsicify(a: Comparable<T>, b: T) =
|
private fun <T : Comparable<T>> compareToDoNotIntrinsicify(a: Comparable<T>, b: T) =
|
||||||
a.compareTo(b)
|
a.compareTo(b)
|
||||||
|
|
||||||
fun primitiveCompareTo(a: dynamic, b: dynamic): Int =
|
internal fun primitiveCompareTo(a: dynamic, b: dynamic): Int =
|
||||||
when {
|
when {
|
||||||
a < b -> -1
|
a < b -> -1
|
||||||
a > b -> 1
|
a > b -> 1
|
||||||
else -> 0
|
else -> 0
|
||||||
}
|
}
|
||||||
|
|
||||||
fun doubleCompareTo(a: dynamic, b: dynamic): Int =
|
internal fun doubleCompareTo(a: dynamic, b: dynamic): Int =
|
||||||
when {
|
when {
|
||||||
a < b -> -1
|
a < b -> -1
|
||||||
a > b -> 1
|
a > b -> 1
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
package kotlin.js
|
package kotlin.js
|
||||||
|
|
||||||
fun equals(obj1: dynamic, obj2: dynamic): Boolean {
|
internal fun equals(obj1: dynamic, obj2: dynamic): Boolean {
|
||||||
if (obj1 == null) {
|
if (obj1 == null) {
|
||||||
return obj2 == null
|
return obj2 == null
|
||||||
}
|
}
|
||||||
@@ -27,20 +27,20 @@ fun equals(obj1: dynamic, obj2: dynamic): Boolean {
|
|||||||
return obj1 === obj2
|
return obj1 === obj2
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toString(o: dynamic): String = when {
|
internal fun toString(o: dynamic): String = when {
|
||||||
o == null -> "null"
|
o == null -> "null"
|
||||||
isArrayish(o) -> "[...]"
|
isArrayish(o) -> "[...]"
|
||||||
|
|
||||||
else -> (o.toString)().unsafeCast<String>()
|
else -> (o.toString)().unsafeCast<String>()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun anyToString(o: dynamic): String = js("Object").prototype.toString.call(o)
|
internal fun anyToString(o: dynamic): String = js("Object").prototype.toString.call(o)
|
||||||
|
|
||||||
private fun hasOwnPrototypeProperty(o: Any, name: String): Boolean {
|
private fun hasOwnPrototypeProperty(o: Any, name: String): Boolean {
|
||||||
return JsObject.getPrototypeOf(o).hasOwnProperty(name).unsafeCast<Boolean>()
|
return JsObject.getPrototypeOf(o).hasOwnProperty(name).unsafeCast<Boolean>()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hashCode(obj: dynamic): Int {
|
internal fun hashCode(obj: dynamic): Int {
|
||||||
if (obj == null)
|
if (obj == null)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ fun hashCode(obj: dynamic): Int {
|
|||||||
private const val POW_2_32 = 4294967296.0
|
private const val POW_2_32 = 4294967296.0
|
||||||
private const val OBJECT_HASH_CODE_PROPERTY_NAME = "kotlinHashCodeValue$"
|
private const val OBJECT_HASH_CODE_PROPERTY_NAME = "kotlinHashCodeValue$"
|
||||||
|
|
||||||
fun getObjectHashCode(obj: dynamic): Int {
|
internal fun getObjectHashCode(obj: dynamic): Int {
|
||||||
if (!jsIn(OBJECT_HASH_CODE_PROPERTY_NAME, obj)) {
|
if (!jsIn(OBJECT_HASH_CODE_PROPERTY_NAME, obj)) {
|
||||||
var hash = jsBitwiseOr(js("Math").random() * POW_2_32, 0) // Make 32-bit singed integer.
|
var hash = jsBitwiseOr(js("Math").random() * POW_2_32, 0) // Make 32-bit singed integer.
|
||||||
var descriptor = js("new Object()")
|
var descriptor = js("new Object()")
|
||||||
@@ -67,7 +67,7 @@ fun getObjectHashCode(obj: dynamic): Int {
|
|||||||
return obj[OBJECT_HASH_CODE_PROPERTY_NAME].unsafeCast<Int>();
|
return obj[OBJECT_HASH_CODE_PROPERTY_NAME].unsafeCast<Int>();
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getStringHashCode(str: String): Int {
|
internal fun getStringHashCode(str: String): Int {
|
||||||
var hash = 0
|
var hash = 0
|
||||||
val length: Int = str.length // TODO: Implement WString.length
|
val length: Int = str.length // TODO: Implement WString.length
|
||||||
for (i in 0..length-1) {
|
for (i in 0..length-1) {
|
||||||
@@ -77,7 +77,7 @@ fun getStringHashCode(str: String): Int {
|
|||||||
return hash
|
return hash
|
||||||
}
|
}
|
||||||
|
|
||||||
fun identityHashCode(obj: Any?): Int = getObjectHashCode(obj)
|
internal fun identityHashCode(obj: Any?): Int = getObjectHashCode(obj)
|
||||||
|
|
||||||
internal fun captureStack(instance: Throwable) {
|
internal fun captureStack(instance: Throwable) {
|
||||||
if (js("Error").captureStackTrace != null) {
|
if (js("Error").captureStackTrace != null) {
|
||||||
|
|||||||
@@ -15,18 +15,20 @@ internal fun throwKotlinNothingValueException(): Nothing =
|
|||||||
|
|
||||||
internal fun noWhenBranchMatchedException(): Nothing = throw NoWhenBranchMatchedException()
|
internal fun noWhenBranchMatchedException(): Nothing = throw NoWhenBranchMatchedException()
|
||||||
|
|
||||||
|
internal fun THROW_ISE(): Nothing {
|
||||||
fun THROW_ISE(): Nothing {
|
|
||||||
throw IllegalStateException()
|
throw IllegalStateException()
|
||||||
}
|
}
|
||||||
fun THROW_CCE(): Nothing {
|
|
||||||
|
internal fun THROW_CCE(): Nothing {
|
||||||
throw ClassCastException()
|
throw ClassCastException()
|
||||||
}
|
}
|
||||||
fun THROW_NPE(): Nothing {
|
|
||||||
|
internal fun THROW_NPE(): Nothing {
|
||||||
throw NullPointerException()
|
throw NullPointerException()
|
||||||
}
|
}
|
||||||
fun THROW_IAE(msg: String): Nothing {
|
|
||||||
|
internal fun THROW_IAE(msg: String): Nothing {
|
||||||
throw IllegalArgumentException(msg)
|
throw IllegalArgumentException(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T:Any> ensureNotNull(v: T?): T = if (v == null) THROW_NPE() else v
|
internal fun <T:Any> ensureNotNull(v: T?): T = if (v == null) THROW_NPE() else v
|
||||||
@@ -384,7 +384,7 @@ private val MIN_VALUE = Long(0, 1 shl 31)
|
|||||||
private val TWO_PWR_24_ = fromInt(1 shl 24)
|
private val TWO_PWR_24_ = fromInt(1 shl 24)
|
||||||
|
|
||||||
@JsName("Math")
|
@JsName("Math")
|
||||||
external object JsMath {
|
internal external object JsMath {
|
||||||
fun max(lhs: Number, rhs: Number): Double
|
fun max(lhs: Number, rhs: Number): Double
|
||||||
fun floor(x: Number): Double
|
fun floor(x: Number): Double
|
||||||
fun ceil(x: Number): Double
|
fun ceil(x: Number): Double
|
||||||
|
|||||||
@@ -5,26 +5,26 @@
|
|||||||
|
|
||||||
package kotlin.js
|
package kotlin.js
|
||||||
|
|
||||||
fun numberToByte(a: dynamic): Byte = toByte(numberToInt(a))
|
internal fun numberToByte(a: dynamic): Byte = toByte(numberToInt(a))
|
||||||
|
|
||||||
fun numberToDouble(a: dynamic): Double = js("+a").unsafeCast<Double>()
|
internal fun numberToDouble(a: dynamic): Double = js("+a").unsafeCast<Double>()
|
||||||
|
|
||||||
fun numberToInt(a: dynamic): Int = if (a is Long) a.toInt() else doubleToInt(a)
|
internal fun numberToInt(a: dynamic): Int = if (a is Long) a.toInt() else doubleToInt(a)
|
||||||
|
|
||||||
fun numberToShort(a: dynamic): Short = toShort(numberToInt(a))
|
internal fun numberToShort(a: dynamic): Short = toShort(numberToInt(a))
|
||||||
|
|
||||||
// << and >> shifts are used to preserve sign of the number
|
// << and >> shifts are used to preserve sign of the number
|
||||||
fun toByte(a: dynamic): Byte = js("a << 24 >> 24").unsafeCast<Byte>()
|
internal fun toByte(a: dynamic): Byte = js("a << 24 >> 24").unsafeCast<Byte>()
|
||||||
fun toShort(a: dynamic): Short = js("a << 16 >> 16").unsafeCast<Short>()
|
internal fun toShort(a: dynamic): Short = js("a << 16 >> 16").unsafeCast<Short>()
|
||||||
|
|
||||||
fun numberToLong(a: dynamic): Long = if (a is Long) a else fromNumber(a)
|
internal fun numberToLong(a: dynamic): Long = if (a is Long) a else fromNumber(a)
|
||||||
|
|
||||||
fun toLong(a: dynamic): Long = fromInt(a)
|
internal fun toLong(a: dynamic): Long = fromInt(a)
|
||||||
|
|
||||||
fun doubleToInt(a: Double): Int = when {
|
internal fun doubleToInt(a: Double): Int = when {
|
||||||
a > 2147483647 -> 2147483647
|
a > 2147483647 -> 2147483647
|
||||||
a < -2147483648 -> -2147483648
|
a < -2147483648 -> -2147483648
|
||||||
else -> jsBitwiseOr(a, 0)
|
else -> jsBitwiseOr(a, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun numberToChar(a: dynamic) = Char(numberToInt(a) and 0xFFFF)
|
internal fun numberToChar(a: dynamic) = Char(numberToInt(a) and 0xFFFF)
|
||||||
@@ -6,10 +6,10 @@
|
|||||||
package kotlin.js
|
package kotlin.js
|
||||||
|
|
||||||
// Creates IntRange for {Byte, Short, Int}.rangeTo(x: {Byte, Short, Int})
|
// Creates IntRange for {Byte, Short, Int}.rangeTo(x: {Byte, Short, Int})
|
||||||
fun numberRangeToNumber(start: dynamic, endInclusive: dynamic) =
|
internal fun numberRangeToNumber(start: dynamic, endInclusive: dynamic) =
|
||||||
IntRange(start, endInclusive)
|
IntRange(start, endInclusive)
|
||||||
|
|
||||||
// Create LongRange for {Byte, Short, Int}.rangeTo(x: Long)
|
// Create LongRange for {Byte, Short, Int}.rangeTo(x: Long)
|
||||||
// Long.rangeTo(x: *) should be implemented in Long class
|
// Long.rangeTo(x: *) should be implemented in Long class
|
||||||
fun numberRangeToLong(start: dynamic, endInclusive: dynamic) =
|
internal fun numberRangeToLong(start: dynamic, endInclusive: dynamic) =
|
||||||
LongRange(numberToLong(start), endInclusive)
|
LongRange(numberToLong(start), endInclusive)
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ private fun isInterfaceImpl(ctor: Ctor, iface: dynamic): Boolean {
|
|||||||
return superConstructor != null && isInterfaceImpl(superConstructor, iface)
|
return superConstructor != null && isInterfaceImpl(superConstructor, iface)
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun isInterface(obj: dynamic, iface: dynamic): Boolean {
|
internal fun isInterface(obj: dynamic, iface: dynamic): Boolean {
|
||||||
val ctor = obj.constructor ?: return false
|
val ctor = obj.constructor ?: return false
|
||||||
|
|
||||||
return isInterfaceImpl(ctor, iface)
|
return isInterfaceImpl(ctor, iface)
|
||||||
@@ -82,7 +82,7 @@ internal fun isSuspendFunction(obj: dynamic, arity: Int): Boolean {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isObject(obj: dynamic): Boolean {
|
internal fun isObject(obj: dynamic): Boolean {
|
||||||
val objTypeOf = jsTypeOf(obj)
|
val objTypeOf = jsTypeOf(obj)
|
||||||
|
|
||||||
return when (objTypeOf) {
|
return when (objTypeOf) {
|
||||||
@@ -98,32 +98,32 @@ private fun isJsArray(obj: Any): Boolean {
|
|||||||
return js("Array").isArray(obj).unsafeCast<Boolean>()
|
return js("Array").isArray(obj).unsafeCast<Boolean>()
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun isArray(obj: Any): Boolean {
|
internal fun isArray(obj: Any): Boolean {
|
||||||
return isJsArray(obj) && !(obj.asDynamic().`$type$`)
|
return isJsArray(obj) && !(obj.asDynamic().`$type$`)
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun isArrayish(o: dynamic) =
|
internal fun isArrayish(o: dynamic) =
|
||||||
isJsArray(o) || js("ArrayBuffer").isView(o).unsafeCast<Boolean>()
|
isJsArray(o) || js("ArrayBuffer").isView(o).unsafeCast<Boolean>()
|
||||||
|
|
||||||
|
|
||||||
public fun isChar(c: Any): Boolean {
|
internal fun isChar(c: Any): Boolean {
|
||||||
error("isChar is not implemented")
|
error("isChar is not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Distinguish Boolean/Byte and Short/Char
|
// TODO: Distinguish Boolean/Byte and Short/Char
|
||||||
public fun isBooleanArray(a: dynamic): Boolean = isJsArray(a) && a.`$type$` === "BooleanArray"
|
internal fun isBooleanArray(a: dynamic): Boolean = isJsArray(a) && a.`$type$` === "BooleanArray"
|
||||||
public fun isByteArray(a: dynamic): Boolean = jsInstanceOf(a, js("Int8Array"))
|
internal fun isByteArray(a: dynamic): Boolean = jsInstanceOf(a, js("Int8Array"))
|
||||||
public fun isShortArray(a: dynamic): Boolean = jsInstanceOf(a, js("Int16Array"))
|
internal fun isShortArray(a: dynamic): Boolean = jsInstanceOf(a, js("Int16Array"))
|
||||||
public fun isCharArray(a: dynamic): Boolean = isJsArray(a) && a.`$type$` === "CharArray"
|
internal fun isCharArray(a: dynamic): Boolean = isJsArray(a) && a.`$type$` === "CharArray"
|
||||||
public fun isIntArray(a: dynamic): Boolean = jsInstanceOf(a, js("Int32Array"))
|
internal fun isIntArray(a: dynamic): Boolean = jsInstanceOf(a, js("Int32Array"))
|
||||||
public fun isFloatArray(a: dynamic): Boolean = jsInstanceOf(a, js("Float32Array"))
|
internal fun isFloatArray(a: dynamic): Boolean = jsInstanceOf(a, js("Float32Array"))
|
||||||
public fun isDoubleArray(a: dynamic): Boolean = jsInstanceOf(a, js("Float64Array"))
|
internal fun isDoubleArray(a: dynamic): Boolean = jsInstanceOf(a, js("Float64Array"))
|
||||||
public fun isLongArray(a: dynamic): Boolean = isJsArray(a) && a.`$type$` === "LongArray"
|
internal fun isLongArray(a: dynamic): Boolean = isJsArray(a) && a.`$type$` === "LongArray"
|
||||||
|
|
||||||
|
|
||||||
internal fun jsGetPrototypeOf(jsClass: dynamic) = js("Object").getPrototypeOf(jsClass)
|
internal fun jsGetPrototypeOf(jsClass: dynamic) = js("Object").getPrototypeOf(jsClass)
|
||||||
|
|
||||||
public fun jsIsType(obj: dynamic, jsClass: dynamic): Boolean {
|
internal fun jsIsType(obj: dynamic, jsClass: dynamic): Boolean {
|
||||||
if (jsClass === js("Object")) {
|
if (jsClass === js("Object")) {
|
||||||
return isObject(obj)
|
return isObject(obj)
|
||||||
}
|
}
|
||||||
@@ -159,9 +159,9 @@ public fun jsIsType(obj: dynamic, jsClass: dynamic): Boolean {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isNumber(a: dynamic) = jsTypeOf(a) == "number" || a is Long
|
internal fun isNumber(a: dynamic) = jsTypeOf(a) == "number" || a is Long
|
||||||
|
|
||||||
fun isComparable(value: dynamic): Boolean {
|
internal fun isComparable(value: dynamic): Boolean {
|
||||||
var type = jsTypeOf(value)
|
var type = jsTypeOf(value)
|
||||||
|
|
||||||
return type == "string" ||
|
return type == "string" ||
|
||||||
@@ -170,5 +170,5 @@ fun isComparable(value: dynamic): Boolean {
|
|||||||
isInterface(value, Comparable::class.js)
|
isInterface(value, Comparable::class.js)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isCharSequence(value: dynamic): Boolean =
|
internal fun isCharSequence(value: dynamic): Boolean =
|
||||||
jsTypeOf(value) == "string" || isInterface(value, CharSequence::class.js)
|
jsTypeOf(value) == "string" || isInterface(value, CharSequence::class.js)
|
||||||
|
|||||||
Reference in New Issue
Block a user