diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index 623d2da523c..ea15af2113a 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -11090,6 +11090,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/enum/classForEnumEntry.kt"); } + @TestMetadata("companionAccessingEnumValue.kt") + public void testCompanionAccessingEnumValue() throws Exception { + runTest("compiler/testData/codegen/box/enum/companionAccessingEnumValue.kt"); + } + @TestMetadata("companionObjectInEnum.kt") public void testCompanionObjectInEnum() throws Exception { runTest("compiler/testData/codegen/box/enum/companionObjectInEnum.kt"); diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/EnumClassLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/EnumClassLowering.kt index ba5e2abb355..014d66d10c8 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/EnumClassLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/EnumClassLowering.kt @@ -47,7 +47,7 @@ class EnumUsageLowering(val context: JsCommonBackendContext) : BodyLoweringPass } private fun lowerEnumEntry(enumEntry: IrEnumEntry) = - enumEntry.getInstanceFun!!.run { JsIrBuilder.buildCall(symbol) } + JsIrBuilder.buildCall(enumEntry.getInstanceFun!!.symbol) } @@ -168,7 +168,7 @@ class EnumClassConstructorBodyTransformer(val context: JsCommonBackendContext) : if (container is IrConstructor) { - if (irClass.goodEnum) { + if (irClass.isInstantiableEnum) { // Pass new parameters to delegating constructor calls lowerEnumConstructorsBody(container) } @@ -278,9 +278,6 @@ class EnumClassConstructorBodyTransformer(val context: JsCommonBackendContext) : //------------------------------------------------------- -private val IrClass.goodEnum: Boolean - get() = isEnumClass && !isExpect && !isEffectivelyExternal() - class EnumEntryInstancesLowering(val context: JsCommonBackendContext) : DeclarationTransformer { private var IrEnumEntry.correspondingField by context.mapping.enumEntryToCorrespondingField @@ -288,7 +285,7 @@ class EnumEntryInstancesLowering(val context: JsCommonBackendContext) : Declarat override fun transformFlat(declaration: IrDeclaration): List? { if (declaration is IrEnumEntry) { val irClass = declaration.parentAsClass - if (irClass.goodEnum) { + if (irClass.isInstantiableEnum) { // Create instance variable for each enum entry initialized with `null` return listOf(declaration, createEnumEntryInstanceVariable(irClass, declaration)) } @@ -322,7 +319,7 @@ class EnumEntryInstancesBodyLowering(val context: JsCommonBackendContext) : Body if (container is IrConstructor && container.constructedClass.kind == ClassKind.ENUM_ENTRY) { val entryClass = container.constructedClass val enum = entryClass.parentAsClass - if (enum.goodEnum) { + if (enum.isInstantiableEnum) { val entry = enum.declarations.filterIsInstance().find { it.correspondingClass === entryClass }!! //In ES6 using `this` before superCall is unavailable, so @@ -344,7 +341,7 @@ class EnumClassCreateInitializerLowering(val context: JsCommonBackendContext) : private var IrClass.initEntryInstancesFun: IrSimpleFunction? by context.mapping.enumClassToInitEntryInstancesFun override fun transformFlat(declaration: IrDeclaration): List? { - if (declaration is IrClass && declaration.goodEnum) { + if (declaration is IrClass && declaration.isInstantiableEnum) { // Create boolean flag that indicates if entry instances were initialized. val entryInstancesInitializedVar = createEntryInstancesInitializedVar(declaration) @@ -394,6 +391,10 @@ class EnumClassCreateInitializerLowering(val context: JsCommonBackendContext) : +irSetField(null, instanceField, entry.initializerExpression!!.expression.deepCopyWithSymbols(it)) } } + + irClass.companionObject()?.let { companionObject -> + +irGetObjectValue(companionObject.defaultType, companionObject.symbol) + } }.statements } } @@ -402,12 +403,12 @@ class EnumClassCreateInitializerLowering(val context: JsCommonBackendContext) : class EnumEntryCreateGetInstancesFunsLowering(val context: JsCommonBackendContext) : DeclarationTransformer { private var IrEnumEntry.correspondingField by context.mapping.enumEntryToCorrespondingField - private var IrClass.initEntryInstancesFun: IrSimpleFunction? by context.mapping.enumClassToInitEntryInstancesFun + private val IrClass.initEntryInstancesFun: IrSimpleFunction? by context.mapping.enumClassToInitEntryInstancesFun override fun transformFlat(declaration: IrDeclaration): List? { if (declaration is IrEnumEntry) { val irClass = declaration.parentAsClass - if (irClass.goodEnum) { + if (irClass.isInstantiableEnum) { // Create entry instance getters. These are used to lower `IrGetEnumValue`. val entryGetInstanceFun = createGetEntryInstanceFun(irClass, declaration, irClass.initEntryInstancesFun!!) @@ -445,6 +446,9 @@ class EnumEntryCreateGetInstancesFunsLowering(val context: JsCommonBackendContex } } +private val IrClass.isInstantiableEnum: Boolean + get() = isEnumClass && !isExpect && !isEffectivelyExternal() + class EnumSyntheticFunctionsLowering(val context: JsCommonBackendContext) : DeclarationTransformer { private var IrEnumEntry.getInstanceFun by context.mapping.enumEntryToGetInstanceFun @@ -454,7 +458,7 @@ class EnumSyntheticFunctionsLowering(val context: JsCommonBackendContext) : Decl (declaration.body as? IrSyntheticBody)?.let { body -> val kind = body.kind - declaration.parents.filterIsInstance().firstOrNull { it.goodEnum }?.let { irClass -> + declaration.parents.filterIsInstance().firstOrNull { it.isInstantiableEnum }?.let { irClass -> declaration.body = context.irFactory.createBlockBody(UNDEFINED_OFFSET, UNDEFINED_OFFSET) { statements += when (kind) { IrSyntheticBodyKind.ENUM_VALUES -> createEnumValuesBody(declaration, irClass) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/InvokeStaticInitializersLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/InvokeStaticInitializersLowering.kt index 688a5965729..298305656a7 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/InvokeStaticInitializersLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/InvokeStaticInitializersLowering.kt @@ -12,13 +12,12 @@ import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.expressions.IrBody import org.jetbrains.kotlin.ir.expressions.IrStatementContainer import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl -import org.jetbrains.kotlin.ir.util.companionObject -import org.jetbrains.kotlin.ir.util.constructedClass -import org.jetbrains.kotlin.ir.util.isEffectivelyExternal +import org.jetbrains.kotlin.ir.util.* class InvokeStaticInitializersLowering(val context: JsIrBackendContext) : BodyLoweringPass { override fun lower(irBody: IrBody, container: IrDeclaration) { if (container !is IrConstructor) return + if (container?.parentClassOrNull?.isEnumClass == true) return val irClass = container.constructedClass if (irClass.isEffectivelyExternal()) { diff --git a/compiler/testData/codegen/box/enum/companionAccessingEnumValue.kt b/compiler/testData/codegen/box/enum/companionAccessingEnumValue.kt new file mode 100644 index 00000000000..ea358a6d4da --- /dev/null +++ b/compiler/testData/codegen/box/enum/companionAccessingEnumValue.kt @@ -0,0 +1,35 @@ +private var logs = "" + +enum class Foo(val text: String) { + FOO("foo"), + BAR("bar"), + PING("foo"); + + init { + logs += "${text}A;" + } + + companion object { + init { + logs += "StatA;" + } + val first = values()[0] + init { + logs += "Stat${first.text};" + } + } + + init { + logs += "${text}B;" + } +} + +fun box(): String { + Foo.FOO + + if (Foo.first !== Foo.FOO) return "FAIL 0: ${Foo.first}" + + if (logs != "fooA;fooB;barA;barB;fooA;fooB;StatA;Statfoo;") return "FAIL 1: ${logs}" + + return "OK" +} \ No newline at end of file diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index a06f0587e26..86566d0a845 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -11090,6 +11090,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/enum/classForEnumEntry.kt"); } + @TestMetadata("companionAccessingEnumValue.kt") + public void testCompanionAccessingEnumValue() throws Exception { + runTest("compiler/testData/codegen/box/enum/companionAccessingEnumValue.kt"); + } + @TestMetadata("companionObjectInEnum.kt") public void testCompanionObjectInEnum() throws Exception { runTest("compiler/testData/codegen/box/enum/companionObjectInEnum.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index d99b2c153c9..d68bdc6c5c5 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -11090,6 +11090,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/enum/classForEnumEntry.kt"); } + @TestMetadata("companionAccessingEnumValue.kt") + public void testCompanionAccessingEnumValue() throws Exception { + runTest("compiler/testData/codegen/box/enum/companionAccessingEnumValue.kt"); + } + @TestMetadata("companionObjectInEnum.kt") public void testCompanionObjectInEnum() throws Exception { runTest("compiler/testData/codegen/box/enum/companionObjectInEnum.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index bf252f8b44a..749b7f10298 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -11090,6 +11090,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/enum/classForEnumEntry.kt"); } + @TestMetadata("companionAccessingEnumValue.kt") + public void testCompanionAccessingEnumValue() throws Exception { + runTest("compiler/testData/codegen/box/enum/companionAccessingEnumValue.kt"); + } + @TestMetadata("companionObjectInEnum.kt") public void testCompanionObjectInEnum() throws Exception { runTest("compiler/testData/codegen/box/enum/companionObjectInEnum.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index b8a38136f6b..250ada97c5f 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -9495,6 +9495,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes runTest("compiler/testData/codegen/box/enum/asReturnExpression.kt"); } + @TestMetadata("companionAccessingEnumValue.kt") + public void testCompanionAccessingEnumValue() throws Exception { + runTest("compiler/testData/codegen/box/enum/companionAccessingEnumValue.kt"); + } + @TestMetadata("companionObjectInEnum.kt") public void testCompanionObjectInEnum() throws Exception { runTest("compiler/testData/codegen/box/enum/companionObjectInEnum.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index ca1f06642fd..1afba166ad5 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -9495,6 +9495,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/enum/asReturnExpression.kt"); } + @TestMetadata("companionAccessingEnumValue.kt") + public void testCompanionAccessingEnumValue() throws Exception { + runTest("compiler/testData/codegen/box/enum/companionAccessingEnumValue.kt"); + } + @TestMetadata("companionObjectInEnum.kt") public void testCompanionObjectInEnum() throws Exception { runTest("compiler/testData/codegen/box/enum/companionObjectInEnum.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index ddc4f01c978..4fe28af80a4 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -9495,6 +9495,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/enum/asReturnExpression.kt"); } + @TestMetadata("companionAccessingEnumValue.kt") + public void testCompanionAccessingEnumValue() throws Exception { + runTest("compiler/testData/codegen/box/enum/companionAccessingEnumValue.kt"); + } + @TestMetadata("companionObjectInEnum.kt") public void testCompanionObjectInEnum() throws Exception { runTest("compiler/testData/codegen/box/enum/companionObjectInEnum.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java index 4461339f686..217848da792 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java @@ -4594,6 +4594,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest runTest("compiler/testData/codegen/box/enum/asReturnExpression.kt"); } + @TestMetadata("companionAccessingEnumValue.kt") + public void testCompanionAccessingEnumValue() throws Exception { + runTest("compiler/testData/codegen/box/enum/companionAccessingEnumValue.kt"); + } + @TestMetadata("companionObjectInEnum.kt") public void testCompanionObjectInEnum() throws Exception { runTest("compiler/testData/codegen/box/enum/companionObjectInEnum.kt");