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 {
|
||||
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 {
|
||||
it.interpret().check { executionResult -> return executionResult }
|
||||
return@flatMap when (val result = stack.popReturnValue()) {
|
||||
is Wrapper -> listOf(result.value)
|
||||
is Primitive<*> ->
|
||||
when (val value = result.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)
|
||||
}
|
||||
is Primitive<*> -> arrayToList(result.value)
|
||||
is Common -> when {
|
||||
result.irClass.defaultType.isUnsignedArray() -> arrayToList((result.fields.single().state as Primitive<*>).value)
|
||||
else -> listOf(result)
|
||||
}
|
||||
else -> listOf(result)
|
||||
}
|
||||
}
|
||||
|
||||
val array = when ((expression.type.classifierOrFail.owner as? IrDeclaration)?.nameForIrSerialization?.asString()) {
|
||||
"UByteArray", "UShortArray", "UIntArray", "ULongArray" -> {
|
||||
val array = when {
|
||||
expression.type.isUnsignedArray() -> {
|
||||
val owner = expression.type.classOrNull!!.owner
|
||||
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)
|
||||
Common(owner).apply {
|
||||
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 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 {
|
||||
return this.getClass()?.fqNameWhenAvailable?.toUnsafe()?.let { StandardNames.isPrimitiveArray(it) } ?: false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user