diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 1cd085dd4b9..be7b0a3ceca 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -2534,6 +2534,23 @@ public class ExpressionCodegen extends KtVisitor impleme return generateThisOrOuter(calleeContainingClass, isSuper, false); } + private boolean isInInnerClassConstructorContext(@NotNull ClassDescriptor calleeContainingClass) { + if (!(context instanceof ConstructorContext)) return false; + + CallableMemberDescriptor contextDescriptor = context.getContextDescriptor(); + assert contextDescriptor instanceof ConstructorDescriptor : + "Constructor descriptor expected: " + contextDescriptor; + ConstructorDescriptor constructorDescriptor = (ConstructorDescriptor) contextDescriptor; + + ClassDescriptor classDescriptor = constructorDescriptor.getConstructedClass(); + if (!classDescriptor.isInner()) return false; + + while (classDescriptor != null && classDescriptor.isInner()) { + classDescriptor = DescriptorUtils.getContainingClass(classDescriptor); + } + return classDescriptor == calleeContainingClass; + } + @NotNull public StackValue generateThisOrOuter(@NotNull ClassDescriptor calleeContainingClass, boolean isSuper, boolean forceOuter) { boolean isSingleton = calleeContainingClass.getKind().isSingleton(); @@ -2543,7 +2560,10 @@ public class ExpressionCodegen extends KtVisitor impleme return StackValue.local(0, typeMapper.mapType(calleeContainingClass)); } else if (isEnumEntry(calleeContainingClass)) { - return StackValue.enumEntry(calleeContainingClass, typeMapper); + if (!isInInnerClassConstructorContext(calleeContainingClass)) { + return StackValue.enumEntry(calleeContainingClass, typeMapper); + } + // else fall-through } else { return StackValue.singleton(calleeContainingClass, typeMapper); diff --git a/compiler/testData/codegen/box/enum/innerClassInEnumEntryClass.kt b/compiler/testData/codegen/box/enum/innerClassInEnumEntryClass.kt new file mode 100644 index 00000000000..0dd565a3374 --- /dev/null +++ b/compiler/testData/codegen/box/enum/innerClassInEnumEntryClass.kt @@ -0,0 +1,20 @@ +// LANGUAGE_VERSION: 1.2 + +enum class A { + X { + val x = "OK" + + inner class Inner { + val y = x + } + + val z = Inner() + + override val test: String + get() = z.y + }; + + abstract val test: String +} + +fun box() = A.X.test \ No newline at end of file diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index c9ef831a33f..8f057ad1630 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -7811,6 +7811,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("innerClassInEnumEntryClass.kt") + public void testInnerClassInEnumEntryClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/enum/innerClassInEnumEntryClass.kt"); + doTest(fileName); + } + @TestMetadata("innerWithExistingClassObject.kt") public void testInnerWithExistingClassObject() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/enum/innerWithExistingClassObject.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index c4fc1659f26..d8a5b795d2d 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -7811,6 +7811,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("innerClassInEnumEntryClass.kt") + public void testInnerClassInEnumEntryClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/enum/innerClassInEnumEntryClass.kt"); + doTest(fileName); + } + @TestMetadata("innerWithExistingClassObject.kt") public void testInnerWithExistingClassObject() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/enum/innerWithExistingClassObject.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 44f6d69890c..97112f35bad 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -7811,6 +7811,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes doTest(fileName); } + @TestMetadata("innerClassInEnumEntryClass.kt") + public void testInnerClassInEnumEntryClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/enum/innerClassInEnumEntryClass.kt"); + doTest(fileName); + } + @TestMetadata("innerWithExistingClassObject.kt") public void testInnerWithExistingClassObject() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/enum/innerWithExistingClassObject.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 95f05b64b63..d9d092a50c6 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -8609,6 +8609,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { doTest(fileName); } + @TestMetadata("innerClassInEnumEntryClass.kt") + public void testInnerClassInEnumEntryClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/enum/innerClassInEnumEntryClass.kt"); + doTest(fileName); + } + @TestMetadata("innerWithExistingClassObject.kt") public void testInnerWithExistingClassObject() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/enum/innerWithExistingClassObject.kt");