[JS IR BE] Copy type metadata for Boolean, Char and Long varargs
This commit is contained in:
@@ -245,6 +245,7 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
|
|||||||
val arrayConcat = getInternalWithoutPackage("arrayConcat")
|
val arrayConcat = getInternalWithoutPackage("arrayConcat")
|
||||||
|
|
||||||
val primitiveArrayConcat = getInternalWithoutPackage("primitiveArrayConcat")
|
val primitiveArrayConcat = getInternalWithoutPackage("primitiveArrayConcat")
|
||||||
|
val taggedArrayCopy = getInternalWithoutPackage("taggedArrayCopy")
|
||||||
|
|
||||||
val jsArraySlice = defineJsSliceIntrinsic().symbol
|
val jsArraySlice = defineJsSliceIntrinsic().symbol
|
||||||
|
|
||||||
|
|||||||
+9
-3
@@ -15,8 +15,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
|||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.types.classifierOrNull
|
|
||||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
@@ -139,11 +138,18 @@ private class VarargTransformer(
|
|||||||
if (segments.size == 1) {
|
if (segments.size == 1) {
|
||||||
val segment = segments.first()
|
val segment = segments.first()
|
||||||
val argument = if (expression.elements.any { it is IrSpreadElement }) {
|
val argument = if (expression.elements.any { it is IrSpreadElement }) {
|
||||||
|
val elementType = arrayInfo.primitiveElementType
|
||||||
|
val copyFunction =
|
||||||
|
if (elementType.isChar() || elementType.isBoolean() || elementType.isLong())
|
||||||
|
context.intrinsics.taggedArrayCopy
|
||||||
|
else
|
||||||
|
context.intrinsics.jsArraySlice
|
||||||
|
|
||||||
IrCallImpl(
|
IrCallImpl(
|
||||||
expression.startOffset,
|
expression.startOffset,
|
||||||
expression.endOffset,
|
expression.endOffset,
|
||||||
arrayInfo.primitiveArrayType,
|
arrayInfo.primitiveArrayType,
|
||||||
context.intrinsics.jsArraySlice
|
copyFunction
|
||||||
).apply {
|
).apply {
|
||||||
putTypeArgument(0, arrayInfo.primitiveArrayType)
|
putTypeArgument(0, arrayInfo.primitiveArrayType)
|
||||||
putValueArgument(0, segment)
|
putValueArgument(0, segment)
|
||||||
|
|||||||
+5
@@ -6795,6 +6795,11 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
|
|||||||
public void testEmptyVarargInConstructorCall() throws Exception {
|
public void testEmptyVarargInConstructorCall() throws Exception {
|
||||||
runTest("js/js.translator/testData/box/regression/typeChecks/emptyVarargInConstructorCall.kt");
|
runTest("js/js.translator/testData/box/regression/typeChecks/emptyVarargInConstructorCall.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("taggedArrayCopy.kt")
|
||||||
|
public void testTaggedArrayCopy() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/regression/typeChecks/taggedArrayCopy.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
@@ -6830,6 +6830,11 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
|
|||||||
public void testEmptyVarargInConstructorCall() throws Exception {
|
public void testEmptyVarargInConstructorCall() throws Exception {
|
||||||
runTest("js/js.translator/testData/box/regression/typeChecks/emptyVarargInConstructorCall.kt");
|
runTest("js/js.translator/testData/box/regression/typeChecks/emptyVarargInConstructorCall.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("taggedArrayCopy.kt")
|
||||||
|
public void testTaggedArrayCopy() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/regression/typeChecks/taggedArrayCopy.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
// IGNORE_BACKEND: JS
|
||||||
|
// KJS_WITH_FULL_RUNTIME
|
||||||
|
// EXPECTED_REACHABLE_NODES: 1281
|
||||||
|
|
||||||
|
package foo
|
||||||
|
|
||||||
|
fun checkBooleanVararg(vararg xs: Boolean) {
|
||||||
|
assertTrue(xs is BooleanArray)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkLongVararg(vararg xs: Long) {
|
||||||
|
assertTrue(xs is LongArray)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkCharVararg(vararg xs: Char) {
|
||||||
|
assertTrue(xs is CharArray)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
checkBooleanVararg()
|
||||||
|
checkBooleanVararg(true)
|
||||||
|
checkBooleanVararg(true, false)
|
||||||
|
checkBooleanVararg(*booleanArrayOf())
|
||||||
|
checkBooleanVararg(*booleanArrayOf(true, false))
|
||||||
|
checkBooleanVararg(true, *booleanArrayOf(false), false, *booleanArrayOf())
|
||||||
|
|
||||||
|
checkLongVararg()
|
||||||
|
checkLongVararg(1L)
|
||||||
|
checkLongVararg(2L, 3L)
|
||||||
|
checkLongVararg(*longArrayOf())
|
||||||
|
checkLongVararg(*longArrayOf(4L, 5L))
|
||||||
|
checkLongVararg(*longArrayOf(4L, 5L), 10L, 20L, 30L)
|
||||||
|
|
||||||
|
checkCharVararg()
|
||||||
|
checkCharVararg('a')
|
||||||
|
checkCharVararg('b', 'c')
|
||||||
|
checkCharVararg(*charArrayOf())
|
||||||
|
checkCharVararg(*charArrayOf('d', 'e'))
|
||||||
|
checkCharVararg(*charArrayOf(), *charArrayOf(), *charArrayOf())
|
||||||
|
checkCharVararg('e', *charArrayOf(), 'f', *charArrayOf(), 'x', *charArrayOf(), 'd')
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -44,6 +44,12 @@ internal fun <T> primitiveArrayConcat(vararg args: T): T {
|
|||||||
return result.unsafeCast<T>()
|
return result.unsafeCast<T>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun <T> taggedArrayCopy(array: dynamic): T {
|
||||||
|
val res = array.slice()
|
||||||
|
res.`$type$` = array.`$type$`
|
||||||
|
return res.unsafeCast<T>()
|
||||||
|
}
|
||||||
|
|
||||||
@PublishedApi
|
@PublishedApi
|
||||||
internal inline fun withType(type: String, array: dynamic): dynamic {
|
internal inline fun withType(type: String, array: dynamic): dynamic {
|
||||||
array.`$type$` = type
|
array.`$type$` = type
|
||||||
|
|||||||
Reference in New Issue
Block a user