[IR BE] Fix capturing of var-locals inside class/field initializers
This commit is contained in:
+33
-13
@@ -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<IrVariable>()
|
||||
|
||||
fun lowerSharedVariables() {
|
||||
@@ -56,7 +76,7 @@ class SharedVariablesLowering(val context: BackendContext) : FunctionLoweringPas
|
||||
}
|
||||
|
||||
private fun collectSharedVariables() {
|
||||
irFunction.accept(object : IrElementVisitor<Unit, IrDeclarationParent?> {
|
||||
irDeclaration.accept(object : IrElementVisitor<Unit, IrDeclarationParent?> {
|
||||
val relevantVars = mutableSetOf<IrVariable>()
|
||||
|
||||
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<IrValueSymbol, IrVariableSymbol>()
|
||||
|
||||
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)
|
||||
|
||||
|
||||
+20
@@ -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"
|
||||
}
|
||||
+18
@@ -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"
|
||||
}
|
||||
+10
@@ -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");
|
||||
|
||||
+10
@@ -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");
|
||||
|
||||
+10
@@ -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");
|
||||
|
||||
Generated
+10
@@ -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");
|
||||
|
||||
+10
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user