From acbe3126b1ad4fb6ac4a20ebbc65e174a12de476 Mon Sep 17 00:00:00 2001 From: Jinseong Jeon Date: Tue, 24 Mar 2020 22:58:42 -0700 Subject: [PATCH] FIR: consider all functions in scope when computing dispatch receiver parameter. --- .../kotlin/fir/backend/Fir2IrConversionScope.kt | 15 ++++++--------- .../ir/FirBlackBoxCodegenTestGenerated.java | 10 ++++++++++ .../properties/classFieldInsideNestedLambda.kt | 6 ++++++ .../classFieldInsideNestedNestedLambda.kt | 6 ++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 10 ++++++++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 10 ++++++++++ 6 files changed, 48 insertions(+), 9 deletions(-) create mode 100644 compiler/testData/codegen/box/properties/classFieldInsideNestedLambda.kt create mode 100644 compiler/testData/codegen/box/properties/classFieldInsideNestedNestedLambda.kt diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConversionScope.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConversionScope.kt index 9b8db583620..51d69e1c472 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConversionScope.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConversionScope.kt @@ -77,17 +77,14 @@ class Fir2IrConversionScope { fun parent(): IrDeclarationParent? = parentStack.lastOrNull() fun lastDispatchReceiverParameter(): IrValueParameter? { - var dispatchReceiver = functionStack.lastOrNull()?.dispatchReceiverParameter - // Use the dispatch receiver of the containing function - dispatchReceiver?.let { return it } - - // Use the dispatch receiver of the enclosing function if any - dispatchReceiver = functionStack.elementAtOrNull(functionStack.size - 2)?.dispatchReceiverParameter - dispatchReceiver?.let { return it } + // Use the dispatch receiver of the containing/enclosing functions (from the last to the first) + for (function in functionStack.asReversed()) { + function.dispatchReceiverParameter?.let { return it } + } // Use the dispatch receiver of the containing class - val lastClassSymbol = classStack.lastOrNull()?.symbol - return lastClassSymbol?.owner?.thisReceiver + val lastClass = classStack.lastOrNull() + return lastClass?.thisReceiver } fun lastClass(): IrClass? = classStack.lastOrNull() diff --git a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index 8b018dcf8d6..073794d3541 100644 --- a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -18285,6 +18285,16 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/properties/classFieldInsideNested.kt"); } + @TestMetadata("classFieldInsideNestedLambda.kt") + public void testClassFieldInsideNestedLambda() throws Exception { + runTest("compiler/testData/codegen/box/properties/classFieldInsideNestedLambda.kt"); + } + + @TestMetadata("classFieldInsideNestedNestedLambda.kt") + public void testClassFieldInsideNestedNestedLambda() throws Exception { + runTest("compiler/testData/codegen/box/properties/classFieldInsideNestedNestedLambda.kt"); + } + @TestMetadata("classObjectProperties.kt") public void testClassObjectProperties() throws Exception { runTest("compiler/testData/codegen/box/properties/classObjectProperties.kt"); diff --git a/compiler/testData/codegen/box/properties/classFieldInsideNestedLambda.kt b/compiler/testData/codegen/box/properties/classFieldInsideNestedLambda.kt new file mode 100644 index 00000000000..04ae80f0564 --- /dev/null +++ b/compiler/testData/codegen/box/properties/classFieldInsideNestedLambda.kt @@ -0,0 +1,6 @@ +class My { + val my: String = "O" + get() = { { field }() }() + "K" +} + +fun box() = My().my \ No newline at end of file diff --git a/compiler/testData/codegen/box/properties/classFieldInsideNestedNestedLambda.kt b/compiler/testData/codegen/box/properties/classFieldInsideNestedNestedLambda.kt new file mode 100644 index 00000000000..19ed7be9324 --- /dev/null +++ b/compiler/testData/codegen/box/properties/classFieldInsideNestedNestedLambda.kt @@ -0,0 +1,6 @@ +class My { + val my: String = "O" + get() = { { { field }() }() }() + "K" +} + +fun box() = My().my \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index e71dbdafc5f..a6365ea547c 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -19806,6 +19806,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/properties/classFieldInsideNested.kt"); } + @TestMetadata("classFieldInsideNestedLambda.kt") + public void testClassFieldInsideNestedLambda() throws Exception { + runTest("compiler/testData/codegen/box/properties/classFieldInsideNestedLambda.kt"); + } + + @TestMetadata("classFieldInsideNestedNestedLambda.kt") + public void testClassFieldInsideNestedNestedLambda() throws Exception { + runTest("compiler/testData/codegen/box/properties/classFieldInsideNestedNestedLambda.kt"); + } + @TestMetadata("classObjectProperties.kt") public void testClassObjectProperties() throws Exception { runTest("compiler/testData/codegen/box/properties/classObjectProperties.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index a41e355dc45..36bbb98e8e3 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -18285,6 +18285,16 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/properties/classFieldInsideNested.kt"); } + @TestMetadata("classFieldInsideNestedLambda.kt") + public void testClassFieldInsideNestedLambda() throws Exception { + runTest("compiler/testData/codegen/box/properties/classFieldInsideNestedLambda.kt"); + } + + @TestMetadata("classFieldInsideNestedNestedLambda.kt") + public void testClassFieldInsideNestedNestedLambda() throws Exception { + runTest("compiler/testData/codegen/box/properties/classFieldInsideNestedNestedLambda.kt"); + } + @TestMetadata("classObjectProperties.kt") public void testClassObjectProperties() throws Exception { runTest("compiler/testData/codegen/box/properties/classObjectProperties.kt");