Make EnumEntries implementation eager

* Addresses the recent design changes of the corresponding language feature
* Also rework JS/Wasm enumEntries implementation with the function that accepts array instead of fabric function


^KT-57318


Co-authored-by: Artem Kobzar <Artem.Kobzar@jetbrains.com>

Merge-request: KT-MR-9204
Merged-by: Vsevolod Tolstopyatov <qwwdfsad@gmail.com>
This commit is contained in:
Vsevolod Tolstopyatov
2023-03-20 10:18:28 +00:00
committed by Space Team
parent 7a79de6d16
commit 33d13474c5
7 changed files with 25 additions and 96 deletions
@@ -189,7 +189,7 @@ class JsIrBackendContext(
override val enumEntries = getIrClass(ENUMS_PACKAGE_FQNAME.child(Name.identifier("EnumEntries")))
override val createEnumEntries = getFunctions(ENUMS_PACKAGE_FQNAME.child(Name.identifier("enumEntries")))
.find { it.valueParameters.firstOrNull()?.type?.isFunctionType == true }
.find { it.valueParameters.firstOrNull()?.type?.isFunctionType == false }
.let { symbolTable.referenceSimpleFunction(it!!) }
override val ir = object : Ir<JsIrBackendContext>(this) {
@@ -365,7 +365,7 @@ private val enumEntryCreateGetInstancesFunsLoweringPhase = makeDeclarationTransf
)
private val enumSyntheticFunsLoweringPhase = makeDeclarationTransformerPhase(
{ EnumSyntheticFunctionsAndPropertiesLowering(it, supportRawFunctionReference = true) },
::EnumSyntheticFunctionsAndPropertiesLowering,
name = "EnumSyntheticFunctionsAndPropertiesLowering",
description = "Implement `valueOf, `values` and `entries`",
prerequisite = setOf(
@@ -462,9 +462,7 @@ class EnumEntryCreateGetInstancesFunsLowering(val context: JsCommonBackendContex
private const val ENTRIES_FIELD_NAME = "\$ENTRIES"
class EnumSyntheticFunctionsAndPropertiesLowering(
val context: JsCommonBackendContext,
private val supportRawFunctionReference: Boolean = false,
private val syntheticFieldsShouldBeReinitialized: Boolean = false,
val context: JsCommonBackendContext
) : DeclarationTransformer {
private val IrEnumEntry.getInstanceFun by context.mapping.enumEntryToGetInstanceFun
private val IrClass.initEntryInstancesFun: IrSimpleFunction? by context.mapping.enumClassToInitEntryInstancesFun
@@ -506,29 +504,27 @@ class EnumSyntheticFunctionsAndPropertiesLowering(
private val throwISESymbol = context.ir.symbols.throwISE
private fun createEnumEntriesBody(entriesGetter: IrFunction, enumClass: IrClass): IrBlockBody {
val entriesField = enumClass.addEnumEntriesField()
val entriesField = enumClass.buildEntriesField()
val valuesFunction = enumClass.searchForValuesFunction()
val createEnumEntriesFunction = context.createEnumEntries
return context.createIrBuilder(entriesGetter.symbol).run {
irBlockBody {
if (syntheticFieldsShouldBeReinitialized) {
+irIfThen(
irEqualsNull(irGetField(null, entriesField)),
irSetField(null, entriesField, entriesField.initializer!!.expression)
)
}
+irIfThen(
irEqualsNull(irGetField(null, entriesField)),
irSetField(null, entriesField, irCall(createEnumEntriesFunction).apply {
putValueArgument(0, irCall(valuesFunction))
})
)
+irReturn(irGetField(null, entriesField))
}
}
}
private fun IrClass.addEnumEntriesField(): IrField {
return buildEntriesField(searchForValuesFunction())
}
private fun IrClass.searchForValuesFunction(): IrFunction {
return declarations.find { it is IrFunction && it.isStatic && it.returnType.isArray() } as IrFunction
}
private fun IrClass.buildEntriesField(entriesHelper: IrFunction): IrField = with(context) {
private fun IrClass.buildEntriesField(): IrField = with(context) {
addField {
name = Name.identifier(ENTRIES_FIELD_NAME)
type = enumEntries.defaultType
@@ -536,25 +532,9 @@ class EnumSyntheticFunctionsAndPropertiesLowering(
origin = IrDeclarationOrigin.FIELD_FOR_ENUM_ENTRIES
isFinal = true
isStatic = true
}.apply {
initializer = context.createIrBuilder(symbol).run {
irExprBody(irCall(createEnumEntries).apply {
val referenceType = context.irBuiltIns.functionN(0).typeWith(enumEntries.defaultType)
putValueArgument(0, referenceFor(entriesHelper, referenceType))
})
}
}
}
private fun IrBuilderWithScope.referenceFor(function: IrFunction, type: IrType): IrDeclarationReference {
return if (supportRawFunctionReference) {
irRawFunctionReference(type, function.symbol)
} else {
irFunctionReference(type, function.symbol)
}
}
private fun createEnumValueOfBody(valueOfFun: IrFunction, irClass: IrClass): IrBlockBody {
val nameParameter = valueOfFun.valueParameters[0]
@@ -258,7 +258,7 @@ private val enumEntryCreateGetInstancesFunsLoweringPhase = makeWasmModulePhase(
)
private val enumSyntheticFunsLoweringPhase = makeWasmModulePhase(
{ EnumSyntheticFunctionsAndPropertiesLowering(it, syntheticFieldsShouldBeReinitialized = true) },
::EnumSyntheticFunctionsAndPropertiesLowering,
name = "EnumSyntheticFunctionsAndPropertiesLowering",
description = "Implement `valueOf`, `values` and `entries`",
prerequisite = setOf(
@@ -108,7 +108,7 @@ class WasmSymbols(
val enumEntries = getIrClass(FqName.fromSegments(listOf("kotlin", "enums", "EnumEntries")))
val createEnumEntries = findFunctions(enumsInternalPackage.memberScope, Name.identifier("enumEntries"))
.find { it.valueParameters.firstOrNull()?.type?.isFunctionType == true }
.find { it.valueParameters.firstOrNull()?.type?.isFunctionType == false }
.let { symbolTable.referenceSimpleFunction(it!!) }
val enumValueOfIntrinsic = getInternalFunction("enumValueOfIntrinsic")