[K/N] Intrinsify enumEntries<T>

^KT-59711
This commit is contained in:
Pavel Kunyavskiy
2023-07-06 17:16:06 +02:00
committed by Space Team
parent 26b0b02553
commit 9cbd55aa72
21 changed files with 138 additions and 14 deletions
@@ -71,6 +71,7 @@ internal enum class IntrinsicType {
// Enums
ENUM_VALUES,
ENUM_VALUE_OF,
ENUM_ENTRIES,
// Coroutines
GET_CONTINUATION,
RETURN_IF_SUSPENDED,
@@ -288,6 +289,7 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv
IntrinsicType.INTEROP_CONVERT,
IntrinsicType.ENUM_VALUES,
IntrinsicType.ENUM_VALUE_OF,
IntrinsicType.ENUM_ENTRIES,
IntrinsicType.WORKER_EXECUTE,
IntrinsicType.COMPARE_AND_SET_FIELD,
IntrinsicType.COMPARE_AND_EXCHANGE_FIELD,
@@ -113,7 +113,7 @@ internal class EnumUsageLowering(val context: Context) : IrElementTransformer<Ir
expression.transformChildren(this, data)
val intrinsicType = tryGetIntrinsicType(expression)
if (intrinsicType != IntrinsicType.ENUM_VALUES && intrinsicType != IntrinsicType.ENUM_VALUE_OF)
if (intrinsicType != IntrinsicType.ENUM_VALUES && intrinsicType != IntrinsicType.ENUM_VALUE_OF && intrinsicType != IntrinsicType.ENUM_ENTRIES)
return expression
data!!.at(expression)
@@ -129,21 +129,35 @@ internal class EnumUsageLowering(val context: Context) : IrElementTransformer<Ir
require(irClass.kind == ClassKind.ENUM_CLASS)
fun IrClass.findStaticMethod(name: Name) = simpleFunctions().single {
it.name == name && it.dispatchReceiverParameter == null
}
return when (intrinsicType) {
IntrinsicType.ENUM_VALUES -> {
val function = irClass.simpleFunctions().single {
it.name == Name.identifier("values") && it.dispatchReceiverParameter == null
}
val function = irClass.findStaticMethod(Name.identifier("values"))
data.irCall(function)
}
IntrinsicType.ENUM_VALUE_OF -> {
val function = irClass.simpleFunctions().single {
it.name == Name.identifier("valueOf") && it.dispatchReceiverParameter == null
}
val function = irClass.findStaticMethod(Name.identifier("valueOf"))
data.irCall(function).apply {
putValueArgument(0, expression.getValueArgument(0)!!)
}
}
IntrinsicType.ENUM_ENTRIES -> {
val entriesProperty = irClass.properties.singleOrNull {
it.name == Name.identifier("entries") && it.getter != null && it.getter!!.dispatchReceiverParameter == null
}
if (entriesProperty != null) {
data.irCall(entriesProperty.getter!!)
} else {
// fallback for enums from old klibs
val valuesFunction = irClass.findStaticMethod(Name.identifier("values"))
data.irCall(context.ir.symbols.createEnumEntries, listOf(irClass.defaultType)).apply {
putValueArgument(0, data.irCall(valuesFunction))
}
}
}
else -> TODO("Unsupported intrinsic type ${intrinsicType}")
}
}
@@ -5,13 +5,10 @@
package kotlin.enums
import kotlin.native.internal.*
@SinceKotlin("1.9")
@ExperimentalStdlibApi
@PublishedApi
internal actual inline fun <reified T : Enum<T>> enumEntriesIntrinsic(): EnumEntries<T> {
/*
* Implementation note: this body will be replaced with `throw NotImplementedException()` the moment
* all backends starts intrinsifying this call.
*/
return enumEntries(enumValues<T>())
}
@TypedIntrinsic(IntrinsicType.ENUM_ENTRIES)
internal actual external inline fun <reified T : Enum<T>> enumEntriesIntrinsic(): EnumEntries<T>
@@ -59,6 +59,7 @@ internal class IntrinsicType {
// Enums
const val ENUM_VALUES = "ENUM_VALUES"
const val ENUM_VALUE_OF = "ENUM_VALUE_OF"
const val ENUM_ENTRIES = "ENUM_ENTRIES"
// Coroutines
const val GET_CONTINUATION = "GET_CONTINUATION"