Add possibility to interpret spread operator on unsigned arrays
This commit is contained in:
committed by
TeamCityServer
parent
ca231ccc53
commit
3c0c8d97cc
+28
-16
@@ -700,32 +700,44 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun interpretVararg(expression: IrVararg): ExecutionResult {
|
private fun interpretVararg(expression: IrVararg): ExecutionResult {
|
||||||
|
fun arrayToList(value: Any?): List<Any?> {
|
||||||
|
return when (value) {
|
||||||
|
is ByteArray -> value.toList()
|
||||||
|
is CharArray -> value.toList()
|
||||||
|
is ShortArray -> value.toList()
|
||||||
|
is IntArray -> value.toList()
|
||||||
|
is LongArray -> value.toList()
|
||||||
|
is FloatArray -> value.toList()
|
||||||
|
is DoubleArray -> value.toList()
|
||||||
|
is BooleanArray -> value.toList()
|
||||||
|
is Array<*> -> value.toList()
|
||||||
|
else -> listOf(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val args = expression.elements.flatMap {
|
val args = expression.elements.flatMap {
|
||||||
it.interpret().check { executionResult -> return executionResult }
|
it.interpret().check { executionResult -> return executionResult }
|
||||||
return@flatMap when (val result = stack.popReturnValue()) {
|
return@flatMap when (val result = stack.popReturnValue()) {
|
||||||
is Wrapper -> listOf(result.value)
|
is Wrapper -> listOf(result.value)
|
||||||
is Primitive<*> ->
|
is Primitive<*> -> arrayToList(result.value)
|
||||||
when (val value = result.value) {
|
is Common -> when {
|
||||||
is ByteArray -> value.toList()
|
result.irClass.defaultType.isUnsignedArray() -> arrayToList((result.fields.single().state as Primitive<*>).value)
|
||||||
is CharArray -> value.toList()
|
else -> listOf(result)
|
||||||
is ShortArray -> value.toList()
|
}
|
||||||
is IntArray -> value.toList()
|
|
||||||
is LongArray -> value.toList()
|
|
||||||
is FloatArray -> value.toList()
|
|
||||||
is DoubleArray -> value.toList()
|
|
||||||
is BooleanArray -> value.toList()
|
|
||||||
is Array<*> -> value.toList()
|
|
||||||
else -> listOf(value)
|
|
||||||
}
|
|
||||||
else -> listOf(result)
|
else -> listOf(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val array = when ((expression.type.classifierOrFail.owner as? IrDeclaration)?.nameForIrSerialization?.asString()) {
|
val array = when {
|
||||||
"UByteArray", "UShortArray", "UIntArray", "ULongArray" -> {
|
expression.type.isUnsignedArray() -> {
|
||||||
val owner = expression.type.classOrNull!!.owner
|
val owner = expression.type.classOrNull!!.owner
|
||||||
val storageProperty = owner.declarations.filterIsInstance<IrProperty>().first { it.name.asString() == "storage" }
|
val storageProperty = owner.declarations.filterIsInstance<IrProperty>().first { it.name.asString() == "storage" }
|
||||||
val primitiveArray = args.map { ((it as Common).fields.single().state as Primitive<*>).value }
|
val primitiveArray = args.map {
|
||||||
|
when (it) {
|
||||||
|
is Common -> (it.fields.single().state as Primitive<*>).value // is unsigned number
|
||||||
|
else -> it // is primitive number
|
||||||
|
}
|
||||||
|
}
|
||||||
val unsignedArray = primitiveArray.toPrimitiveStateArray(storageProperty.backingField!!.type)
|
val unsignedArray = primitiveArray.toPrimitiveStateArray(storageProperty.backingField!!.type)
|
||||||
Common(owner).apply {
|
Common(owner).apply {
|
||||||
setSuperClassRecursive()
|
setSuperClassRecursive()
|
||||||
|
|||||||
@@ -214,6 +214,13 @@ internal fun State?.getCorrectReceiverByFunction(irFunction: IrFunction): State?
|
|||||||
|
|
||||||
internal fun IrFunction.getCapitalizedFileName() = this.file.name.replace(".kt", "Kt").capitalizeAsciiOnly()
|
internal fun IrFunction.getCapitalizedFileName() = this.file.name.replace(".kt", "Kt").capitalizeAsciiOnly()
|
||||||
|
|
||||||
|
internal fun IrType.isUnsigned() = this.isUByte() || this.isUShort() || this.isUInt() || this.isULong()
|
||||||
|
internal fun IrType.isUnsignedArray(): Boolean {
|
||||||
|
if (this !is IrSimpleType || classifier !is IrClassSymbol) return false
|
||||||
|
val fqName = (classifier.owner as IrDeclarationWithName).fqNameWhenAvailable?.asString()
|
||||||
|
return fqName in setOf("kotlin.UByteArray", "kotlin.UShortArray", "kotlin.UIntArray", "kotlin.ULongArray")
|
||||||
|
}
|
||||||
|
|
||||||
internal fun IrType.isPrimitiveArray(): Boolean {
|
internal fun IrType.isPrimitiveArray(): Boolean {
|
||||||
return this.getClass()?.fqNameWhenAvailable?.toUnsafe()?.let { StandardNames.isPrimitiveArray(it) } ?: false
|
return this.getClass()?.fqNameWhenAvailable?.toUnsafe()?.let { StandardNames.isPrimitiveArray(it) } ?: false
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user