IR: move enum value array initialization out of <clinit>
#KT-44192 Fixed
This commit is contained in:
committed by
Alexander Udalov
parent
f8f08e8134
commit
7cc06489dd
+28
-9
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.addField
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildConstructor
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
@@ -46,6 +47,8 @@ internal val enumClassPhase = makeIrFilePhase(
|
||||
description = "Handle enum classes"
|
||||
)
|
||||
|
||||
private const val VALUES_HELPER_FUNCTION_NAME = "\$values"
|
||||
|
||||
private class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||
override fun lower(irClass: IrClass) {
|
||||
if (!irClass.isEnumClass) return
|
||||
@@ -69,13 +72,16 @@ private class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringP
|
||||
irClass.declarations.removeAll { it is IrEnumEntry }
|
||||
irClass.declarations += declarationToEnumEntry.keys
|
||||
|
||||
// Construct the synthetic $VALUES field, which contains an array of all enum entries
|
||||
val valuesField = buildValuesField()
|
||||
// Construct the synthetic $values() function, which creates an array of all enum entries
|
||||
val valuesHelperFunction = buildValuesHelperFunction()
|
||||
|
||||
// Construct the synthetic $VALUES field, which contains an array of all enum entries by calling $values()
|
||||
val valuesField = buildValuesField(valuesHelperFunction)
|
||||
|
||||
// Add synthetic parameters to enum constructors and implement the values and valueOf functions
|
||||
irClass.transformChildrenVoid(EnumClassDeclarationsTransformer(valuesField))
|
||||
|
||||
// Add synthetic arguments to enum constructor calls and remap enum constructor paramters
|
||||
// Add synthetic arguments to enum constructor calls and remap enum constructor parameters
|
||||
irClass.transformChildrenVoid(EnumClassCallTransformer())
|
||||
}
|
||||
|
||||
@@ -85,7 +91,22 @@ private class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringP
|
||||
annotations += enumEntry.annotations
|
||||
}
|
||||
|
||||
private fun buildValuesField(): IrField = irClass.addField {
|
||||
private fun buildValuesHelperFunction(): IrFunction = irClass.addFunction {
|
||||
name = Name.identifier(VALUES_HELPER_FUNCTION_NAME)
|
||||
returnType = context.irBuiltIns.arrayClass.typeWith(irClass.defaultType)
|
||||
visibility = DescriptorVisibilities.PRIVATE
|
||||
origin = IrDeclarationOrigin.SYNTHETIC_HELPER_FOR_ENUM_VALUES
|
||||
}.apply {
|
||||
body = context.createJvmIrBuilder(symbol).run {
|
||||
irExprBody(irArray(returnType) {
|
||||
for (irField in declarationToEnumEntry.keys.filterIsInstance<IrField>()) {
|
||||
+irGetField(null, irField)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildValuesField(valuesHelperFunction: IrFunction): IrField = irClass.addField {
|
||||
name = Name.identifier(ImplementationBodyCodegen.ENUM_VALUES_FIELD_NAME)
|
||||
type = context.irBuiltIns.arrayClass.typeWith(irClass.defaultType)
|
||||
visibility = DescriptorVisibilities.PRIVATE
|
||||
@@ -94,11 +115,9 @@ private class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringP
|
||||
isStatic = true
|
||||
}.apply {
|
||||
initializer = context.createJvmIrBuilder(symbol).run {
|
||||
irExprBody(irArray(type) {
|
||||
for (irField in declarationToEnumEntry.keys.filterIsInstance<IrField>()) {
|
||||
+irGetField(null, irField)
|
||||
}
|
||||
})
|
||||
irExprBody(
|
||||
irCall(valuesHelperFunction.symbol)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ interface IrDeclarationOrigin {
|
||||
object BRIDGE_SPECIAL : IrDeclarationOriginImpl("BRIDGE_SPECIAL")
|
||||
|
||||
object FIELD_FOR_ENUM_ENTRY : IrDeclarationOriginImpl("FIELD_FOR_ENUM_ENTRY")
|
||||
object SYNTHETIC_HELPER_FOR_ENUM_VALUES : IrDeclarationOriginImpl("SYNTHETIC_HELPER_FOR_ENUM_VALUES", isSynthetic = true)
|
||||
object FIELD_FOR_ENUM_VALUES : IrDeclarationOriginImpl("FIELD_FOR_ENUM_VALUES", isSynthetic = true)
|
||||
object FIELD_FOR_OBJECT_INSTANCE : IrDeclarationOriginImpl("FIELD_FOR_OBJECT_INSTANCE")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user