From c5613888eb45a44512127930839e7bfabd456804 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Tue, 1 Aug 2017 10:35:57 +0300 Subject: [PATCH] Look into proper context when generating backing field access Problem manifests when a class property name matches a companion object property name, and class property is referenced in closure context. #KT-19367 Fixed Target versions 1.1.5 --- .../kotlin/codegen/ExpressionCodegen.java | 9 ++++++++- .../classes/comanionObjectFieldVsClassField.kt | 15 +++++++++++++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 6 ++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 ++++++ .../codegen/LightAnalysisModeTestGenerated.java | 6 ++++++ .../test/semantics/JsCodegenBoxTestGenerated.java | 6 ++++++ 6 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/codegen/box/classes/comanionObjectFieldVsClassField.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index e1d2d33b8cb..1356bb0c6c5 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -1868,7 +1868,14 @@ public class ExpressionCodegen extends KtVisitor impleme @NotNull DeclarationDescriptor containingDeclaration ) { switch (accessorKind) { - case NORMAL: return context.getParentContext(); + case NORMAL: + if (containingDeclaration instanceof ClassDescriptor) { + CodegenContext parentWithDescriptor = context.findParentContextWithDescriptor(containingDeclaration); + if (parentWithDescriptor != null) { + return parentWithDescriptor; + } + } + return context.getParentContext(); // For companion object property, backing field lives in object containing class // Otherwise, it lives in its containing declaration case IN_CLASS_COMPANION: return context.findParentContextWithDescriptor(containingDeclaration.getContainingDeclaration()); diff --git a/compiler/testData/codegen/box/classes/comanionObjectFieldVsClassField.kt b/compiler/testData/codegen/box/classes/comanionObjectFieldVsClassField.kt new file mode 100644 index 00000000000..12667820fd5 --- /dev/null +++ b/compiler/testData/codegen/box/classes/comanionObjectFieldVsClassField.kt @@ -0,0 +1,15 @@ +// WITH_RUNTIME + +class Host { + val ok = "OK" + + fun foo() = run { bar(ok) } + + companion object { + val ok = 0 + + fun bar(s: String) = s.substring(ok) + } +} + +fun box() = Host().foo() \ 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 2679eb94d01..26c1bb556ab 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 @@ -2921,6 +2921,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("comanionObjectFieldVsClassField.kt") + public void testComanionObjectFieldVsClassField() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/classes/comanionObjectFieldVsClassField.kt"); + doTest(fileName); + } + @TestMetadata("defaultObjectSameNamesAsInOuter.kt") public void testDefaultObjectSameNamesAsInOuter() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/classes/defaultObjectSameNamesAsInOuter.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index bde04226f1e..9f8d1bc41d8 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -2921,6 +2921,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("comanionObjectFieldVsClassField.kt") + public void testComanionObjectFieldVsClassField() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/classes/comanionObjectFieldVsClassField.kt"); + doTest(fileName); + } + @TestMetadata("defaultObjectSameNamesAsInOuter.kt") public void testDefaultObjectSameNamesAsInOuter() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/classes/defaultObjectSameNamesAsInOuter.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index d6045a3b904..b1ea8ebe078 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -2921,6 +2921,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes doTest(fileName); } + @TestMetadata("comanionObjectFieldVsClassField.kt") + public void testComanionObjectFieldVsClassField() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/classes/comanionObjectFieldVsClassField.kt"); + doTest(fileName); + } + @TestMetadata("defaultObjectSameNamesAsInOuter.kt") public void testDefaultObjectSameNamesAsInOuter() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/classes/defaultObjectSameNamesAsInOuter.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 be90bb4de8b..596bbe15c83 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 @@ -3539,6 +3539,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { doTest(fileName); } + @TestMetadata("comanionObjectFieldVsClassField.kt") + public void testComanionObjectFieldVsClassField() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/classes/comanionObjectFieldVsClassField.kt"); + doTest(fileName); + } + @TestMetadata("defaultObjectSameNamesAsInOuter.kt") public void testDefaultObjectSameNamesAsInOuter() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/classes/defaultObjectSameNamesAsInOuter.kt");