[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
@@ -16705,6 +16705,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
runTest("compiler/testData/codegen/box/enum/enumEntriesIntrinsicMultipleEnums.kt");
}
@Test
@TestMetadata("enumEntriesIntrinsicWithoutFeature.kt")
public void testEnumEntriesIntrinsicWithoutFeature() throws Exception {
runTest("compiler/testData/codegen/box/enum/enumEntriesIntrinsicWithoutFeature.kt");
}
@Test
@TestMetadata("enumEntriesMultimodule.kt")
public void testEnumEntriesMultimodule() throws Exception {
@@ -16705,6 +16705,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
runTest("compiler/testData/codegen/box/enum/enumEntriesIntrinsicMultipleEnums.kt");
}
@Test
@TestMetadata("enumEntriesIntrinsicWithoutFeature.kt")
public void testEnumEntriesIntrinsicWithoutFeature() throws Exception {
runTest("compiler/testData/codegen/box/enum/enumEntriesIntrinsicWithoutFeature.kt");
}
@Test
@TestMetadata("enumEntriesMultimodule.kt")
public void testEnumEntriesMultimodule() throws Exception {
@@ -0,0 +1,15 @@
// !LANGUAGE: -EnumEntries
// IGNORE_BACKEND: JS
// WITH_STDLIB
@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
import kotlin.enums.*
enum class E { A, B, C };
@OptIn(kotlin.ExperimentalStdlibApi::class)
fun box() : String {
if (enumEntries<E>() != listOf(E.A, E.B, E.C)) return "FAIL"
return "OK"
}
@@ -3,6 +3,11 @@
// IGNORE_BACKEND: JS, JVM
// WITH_STDLIB
@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
import kotlin.enums.*
enum class EnumWithClash {
values,
entries,
@@ -14,5 +19,6 @@ fun box(): String {
val ref = EnumWithClash::entries
if (ref().toString() != "[values, entries, valueOf]") return "FAIL 1"
if (EnumWithClash.entries.toString() != "entries") return "FAIL 2"
if (enumEntries<EnumWithClash>().toString() != "[values, entries, valueOf]") return "FAIL 3"
return "OK"
}
@@ -16339,6 +16339,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/enum/enumEntriesInCompanion.kt");
}
@Test
@TestMetadata("enumEntriesIntrinsicWithoutFeature.kt")
public void testEnumEntriesIntrinsicWithoutFeature() throws Exception {
runTest("compiler/testData/codegen/box/enum/enumEntriesIntrinsicWithoutFeature.kt");
}
@Test
@TestMetadata("enumEntriesMultimoduleNoMappings.kt")
public void testEnumEntriesMultimoduleNoMappings() throws Exception {
@@ -16705,6 +16705,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/enum/enumEntriesIntrinsicMultipleEnums.kt");
}
@Test
@TestMetadata("enumEntriesIntrinsicWithoutFeature.kt")
public void testEnumEntriesIntrinsicWithoutFeature() throws Exception {
runTest("compiler/testData/codegen/box/enum/enumEntriesIntrinsicWithoutFeature.kt");
}
@Test
@TestMetadata("enumEntriesMultimodule.kt")
public void testEnumEntriesMultimodule() throws Exception {
@@ -16705,6 +16705,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
runTest("compiler/testData/codegen/box/enum/enumEntriesIntrinsicMultipleEnums.kt");
}
@Test
@TestMetadata("enumEntriesIntrinsicWithoutFeature.kt")
public void testEnumEntriesIntrinsicWithoutFeature() throws Exception {
runTest("compiler/testData/codegen/box/enum/enumEntriesIntrinsicWithoutFeature.kt");
}
@Test
@TestMetadata("enumEntriesMultimodule.kt")
public void testEnumEntriesMultimodule() throws Exception {
@@ -13796,6 +13796,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/enum/enumEntriesIntrinsicMultipleEnums.kt");
}
@TestMetadata("enumEntriesIntrinsicWithoutFeature.kt")
public void testEnumEntriesIntrinsicWithoutFeature() throws Exception {
runTest("compiler/testData/codegen/box/enum/enumEntriesIntrinsicWithoutFeature.kt");
}
@TestMetadata("enumEntriesMultimodule.kt")
public void testEnumEntriesMultimodule() throws Exception {
runTest("compiler/testData/codegen/box/enum/enumEntriesMultimodule.kt");
@@ -12619,6 +12619,12 @@ public class FirJsCodegenBoxTestGenerated extends AbstractFirJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/enum/enumEntriesInCompanion.kt");
}
@Test
@TestMetadata("enumEntriesIntrinsicWithoutFeature.kt")
public void testEnumEntriesIntrinsicWithoutFeature() throws Exception {
runTest("compiler/testData/codegen/box/enum/enumEntriesIntrinsicWithoutFeature.kt");
}
@Test
@TestMetadata("enumEntriesMultimoduleNoMappings.kt")
public void testEnumEntriesMultimoduleNoMappings() throws Exception {
@@ -12619,6 +12619,12 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/enum/enumEntriesInCompanion.kt");
}
@Test
@TestMetadata("enumEntriesIntrinsicWithoutFeature.kt")
public void testEnumEntriesIntrinsicWithoutFeature() throws Exception {
runTest("compiler/testData/codegen/box/enum/enumEntriesIntrinsicWithoutFeature.kt");
}
@Test
@TestMetadata("enumEntriesMultimoduleNoMappings.kt")
public void testEnumEntriesMultimoduleNoMappings() throws Exception {
@@ -12619,6 +12619,12 @@ public class IrJsES6CodegenBoxTestGenerated extends AbstractIrJsES6CodegenBoxTes
runTest("compiler/testData/codegen/box/enum/enumEntriesInCompanion.kt");
}
@Test
@TestMetadata("enumEntriesIntrinsicWithoutFeature.kt")
public void testEnumEntriesIntrinsicWithoutFeature() throws Exception {
runTest("compiler/testData/codegen/box/enum/enumEntriesIntrinsicWithoutFeature.kt");
}
@Test
@TestMetadata("enumEntriesMultimoduleNoMappings.kt")
public void testEnumEntriesMultimoduleNoMappings() throws Exception {
@@ -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"
@@ -13686,6 +13686,12 @@ public class FirNativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTe
runTest("compiler/testData/codegen/box/enum/enumEntriesInCompanion.kt");
}
@Test
@TestMetadata("enumEntriesIntrinsicWithoutFeature.kt")
public void testEnumEntriesIntrinsicWithoutFeature() throws Exception {
runTest("compiler/testData/codegen/box/enum/enumEntriesIntrinsicWithoutFeature.kt");
}
@Test
@TestMetadata("enumEntriesMultimoduleNoMappings.kt")
public void testEnumEntriesMultimoduleNoMappings() throws Exception {
@@ -14008,6 +14008,12 @@ public class FirNativeCodegenBoxTestNoPLGenerated extends AbstractNativeCodegenB
runTest("compiler/testData/codegen/box/enum/enumEntriesInCompanion.kt");
}
@Test
@TestMetadata("enumEntriesIntrinsicWithoutFeature.kt")
public void testEnumEntriesIntrinsicWithoutFeature() throws Exception {
runTest("compiler/testData/codegen/box/enum/enumEntriesIntrinsicWithoutFeature.kt");
}
@Test
@TestMetadata("enumEntriesMultimoduleNoMappings.kt")
public void testEnumEntriesMultimoduleNoMappings() throws Exception {
@@ -13526,6 +13526,12 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest
runTest("compiler/testData/codegen/box/enum/enumEntriesInCompanion.kt");
}
@Test
@TestMetadata("enumEntriesIntrinsicWithoutFeature.kt")
public void testEnumEntriesIntrinsicWithoutFeature() throws Exception {
runTest("compiler/testData/codegen/box/enum/enumEntriesIntrinsicWithoutFeature.kt");
}
@Test
@TestMetadata("enumEntriesMultimoduleNoMappings.kt")
public void testEnumEntriesMultimoduleNoMappings() throws Exception {
@@ -13687,6 +13687,12 @@ public class NativeCodegenBoxTestNoPLGenerated extends AbstractNativeCodegenBoxT
runTest("compiler/testData/codegen/box/enum/enumEntriesInCompanion.kt");
}
@Test
@TestMetadata("enumEntriesIntrinsicWithoutFeature.kt")
public void testEnumEntriesIntrinsicWithoutFeature() throws Exception {
runTest("compiler/testData/codegen/box/enum/enumEntriesIntrinsicWithoutFeature.kt");
}
@Test
@TestMetadata("enumEntriesMultimoduleNoMappings.kt")
public void testEnumEntriesMultimoduleNoMappings() throws Exception {
@@ -12595,6 +12595,12 @@ public class FirWasmCodegenBoxTestGenerated extends AbstractFirWasmCodegenBoxTes
runTest("compiler/testData/codegen/box/enum/enumEntriesInCompanion.kt");
}
@Test
@TestMetadata("enumEntriesIntrinsicWithoutFeature.kt")
public void testEnumEntriesIntrinsicWithoutFeature() throws Exception {
runTest("compiler/testData/codegen/box/enum/enumEntriesIntrinsicWithoutFeature.kt");
}
@Test
@TestMetadata("enumEntriesMultimoduleNoMappings.kt")
public void testEnumEntriesMultimoduleNoMappings() throws Exception {
@@ -12595,6 +12595,12 @@ public class K1WasmCodegenBoxTestGenerated extends AbstractK1WasmCodegenBoxTest
runTest("compiler/testData/codegen/box/enum/enumEntriesInCompanion.kt");
}
@Test
@TestMetadata("enumEntriesIntrinsicWithoutFeature.kt")
public void testEnumEntriesIntrinsicWithoutFeature() throws Exception {
runTest("compiler/testData/codegen/box/enum/enumEntriesIntrinsicWithoutFeature.kt");
}
@Test
@TestMetadata("enumEntriesMultimoduleNoMappings.kt")
public void testEnumEntriesMultimoduleNoMappings() throws Exception {