diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/SharedVariablesLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/SharedVariablesLowering.kt index 30cffec939d..1f5d54c6496 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/SharedVariablesLowering.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/SharedVariablesLowering.kt @@ -17,14 +17,11 @@ package org.jetbrains.kotlin.backend.common.lower import org.jetbrains.kotlin.backend.common.BackendContext -import org.jetbrains.kotlin.backend.common.FunctionLoweringPass +import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement -import org.jetbrains.kotlin.ir.declarations.IrDeclaration -import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent -import org.jetbrains.kotlin.ir.declarations.IrFunction -import org.jetbrains.kotlin.ir.declarations.IrVariable +import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.symbols.IrValueSymbol import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol @@ -40,12 +37,35 @@ val sharedVariablesPhase = makeIrFilePhase( object CoroutineIntrinsicLambdaOrigin : IrStatementOriginImpl("Coroutine intrinsic lambda") -class SharedVariablesLowering(val context: BackendContext) : FunctionLoweringPass { - override fun lower(irFunction: IrFunction) { - SharedVariablesTransformer(irFunction).lowerSharedVariables() +class SharedVariablesLowering(val context: BackendContext) : FileLoweringPass { + override fun lower(irFile: IrFile) { + irFile.acceptChildrenVoid(object : IrElementVisitorVoid { + override fun visitElement(element: IrElement) { + element.acceptChildrenVoid(this) + } + + override fun visitFunction(declaration: IrFunction) { + declaration.acceptChildrenVoid(this) + + SharedVariablesTransformer(declaration).lowerSharedVariables() + } + + override fun visitField(declaration: IrField) { + declaration.acceptChildrenVoid(this) + + SharedVariablesTransformer(declaration).lowerSharedVariables() + } + + override fun visitAnonymousInitializer(declaration: IrAnonymousInitializer) { + declaration.acceptChildrenVoid(this) + + SharedVariablesTransformer(declaration).lowerSharedVariables() + } + }) } - private inner class SharedVariablesTransformer(val irFunction: IrFunction) { + + private inner class SharedVariablesTransformer(val irDeclaration: IrDeclaration) { private val sharedVariables = HashSet() fun lowerSharedVariables() { @@ -56,7 +76,7 @@ class SharedVariablesLowering(val context: BackendContext) : FunctionLoweringPas } private fun collectSharedVariables() { - irFunction.accept(object : IrElementVisitor { + irDeclaration.accept(object : IrElementVisitor { val relevantVars = mutableSetOf() override fun visitElement(element: IrElement, data: IrDeclarationParent?) { @@ -93,13 +113,13 @@ class SharedVariablesLowering(val context: BackendContext) : FunctionLoweringPas sharedVariables.add(value) } } - }, irFunction) + }, irDeclaration as? IrDeclarationParent ?: irDeclaration.parent) } private fun rewriteSharedVariables() { val transformedSymbols = HashMap() - irFunction.transformChildrenVoid(object : IrElementTransformerVoid() { + irDeclaration.transformChildrenVoid(object : IrElementTransformerVoid() { override fun visitVariable(declaration: IrVariable): IrStatement { declaration.transformChildrenVoid(this) @@ -113,7 +133,7 @@ class SharedVariablesLowering(val context: BackendContext) : FunctionLoweringPas } }) - irFunction.transformChildrenVoid(object : IrElementTransformerVoid() { + irDeclaration.transformChildrenVoid(object : IrElementTransformerVoid() { override fun visitGetValue(expression: IrGetValue): IrExpression { expression.transformChildrenVoid(this) diff --git a/compiler/testData/codegen/box/callableReference/bound/captureVarInInitBlock.kt b/compiler/testData/codegen/box/callableReference/bound/captureVarInInitBlock.kt new file mode 100644 index 00000000000..2f443a31dca --- /dev/null +++ b/compiler/testData/codegen/box/callableReference/bound/captureVarInInitBlock.kt @@ -0,0 +1,20 @@ + +fun bar(b: ()-> Unit) { b() } + +class C() { + var f: Int + + init { + var i = 10 + bar { + i = 20 + } + f = i + 1 + } +} + +fun box(): String { + val c = C() + if (c.f != 21) return "fail" + return "OK" +} diff --git a/compiler/testData/codegen/box/callableReference/bound/captureVarInPropertyInit.kt b/compiler/testData/codegen/box/callableReference/bound/captureVarInPropertyInit.kt new file mode 100644 index 00000000000..7a29b25c7e3 --- /dev/null +++ b/compiler/testData/codegen/box/callableReference/bound/captureVarInPropertyInit.kt @@ -0,0 +1,18 @@ + +fun bar(b: ()-> Unit) { b() } + +class C() { + val p: Int = run { + var v = 10 + bar() { + v = 20 + } + v + 1 + } +} + +fun box(): String { + val c = C() + if (c.p != 21) return "fail ${c.p}" + return "OK" +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index c45e66fe0c0..c1f8417b024 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -1834,6 +1834,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/callableReference/bound/boundJvmFieldInInterfaceCompanion.kt"); } + @TestMetadata("captureVarInInitBlock.kt") + public void testCaptureVarInInitBlock() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/bound/captureVarInInitBlock.kt"); + } + + @TestMetadata("captureVarInPropertyInit.kt") + public void testCaptureVarInPropertyInit() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/bound/captureVarInPropertyInit.kt"); + } + @TestMetadata("coercionToUnit.kt") public void testCoercionToUnit() throws Exception { runTest("compiler/testData/codegen/box/callableReference/bound/coercionToUnit.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 932c6d93c34..ad79dffa334 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -1834,6 +1834,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/callableReference/bound/boundJvmFieldInInterfaceCompanion.kt"); } + @TestMetadata("captureVarInInitBlock.kt") + public void testCaptureVarInInitBlock() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/bound/captureVarInInitBlock.kt"); + } + + @TestMetadata("captureVarInPropertyInit.kt") + public void testCaptureVarInPropertyInit() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/bound/captureVarInPropertyInit.kt"); + } + @TestMetadata("coercionToUnit.kt") public void testCoercionToUnit() throws Exception { runTest("compiler/testData/codegen/box/callableReference/bound/coercionToUnit.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index e45fa004454..1a8d49ec9e5 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -1834,6 +1834,16 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/callableReference/bound/boundJvmFieldInInterfaceCompanion.kt"); } + @TestMetadata("captureVarInInitBlock.kt") + public void testCaptureVarInInitBlock() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/bound/captureVarInInitBlock.kt"); + } + + @TestMetadata("captureVarInPropertyInit.kt") + public void testCaptureVarInPropertyInit() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/bound/captureVarInPropertyInit.kt"); + } + @TestMetadata("coercionToUnit.kt") public void testCoercionToUnit() throws Exception { runTest("compiler/testData/codegen/box/callableReference/bound/coercionToUnit.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index bee60886e29..9cb8d0897a9 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -1369,6 +1369,16 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/callableReference/bound/arrayGetIntrinsic.kt"); } + @TestMetadata("captureVarInInitBlock.kt") + public void testCaptureVarInInitBlock() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/bound/captureVarInInitBlock.kt"); + } + + @TestMetadata("captureVarInPropertyInit.kt") + public void testCaptureVarInPropertyInit() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/bound/captureVarInPropertyInit.kt"); + } + @TestMetadata("coercionToUnit.kt") public void testCoercionToUnit() throws Exception { runTest("compiler/testData/codegen/box/callableReference/bound/coercionToUnit.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 0354b391b11..8e69968eac9 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 @@ -1369,6 +1369,16 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/callableReference/bound/arrayGetIntrinsic.kt"); } + @TestMetadata("captureVarInInitBlock.kt") + public void testCaptureVarInInitBlock() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/bound/captureVarInInitBlock.kt"); + } + + @TestMetadata("captureVarInPropertyInit.kt") + public void testCaptureVarInPropertyInit() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/bound/captureVarInPropertyInit.kt"); + } + @TestMetadata("coercionToUnit.kt") public void testCoercionToUnit() throws Exception { runTest("compiler/testData/codegen/box/callableReference/bound/coercionToUnit.kt");