Fix initializer lowering crash during deep copy

This commit is contained in:
Roman Artemev
2018-04-29 03:58:42 +03:00
parent 449943da01
commit 131fb642aa
3 changed files with 14 additions and 10 deletions
@@ -93,7 +93,7 @@ class InitializersLowering(
irClass.transformChildrenVoid(object : IrElementTransformerVoid() {
override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall): IrExpression {
return IrBlockImpl(irClass.startOffset, irClass.endOffset, context.builtIns.unitType, null,
instanceInitializerStatements.map { it.copy() })
instanceInitializerStatements.map { it.copy(irClass) })
}
})
}
@@ -114,7 +114,7 @@ class InitializersLowering(
irClass.startOffset, irClass.endOffset, declarationOrigin,
staticInitializerDescriptor,
IrBlockBodyImpl(irClass.startOffset, irClass.endOffset,
staticInitializerStatements.map { it.copy() })
staticInitializerStatements.map { it.copy(irClass) })
)
)
}
@@ -123,7 +123,7 @@ class InitializersLowering(
companion object {
val clinitName = Name.special("<clinit>")
fun IrStatement.copy() = deepCopyWithSymbols()
fun IrExpression.copy() = deepCopyWithSymbols()
fun IrStatement.copy(containingDeclaration: IrClass) = deepCopyWithSymbols(containingDeclaration)
fun IrExpression.copy(containingDeclaration: IrClass) = deepCopyWithSymbols(containingDeclaration)
}
}
@@ -31,10 +31,10 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
import java.util.*
inline fun <reified T : IrElement> T.deepCopyWithSymbols(): T {
inline fun <reified T : IrElement> T.deepCopyWithSymbols(initialParent: IrDeclarationParent? = null): T {
val remapper = DeepCopySymbolsRemapper()
acceptVoid(remapper)
return transform(DeepCopyIrTreeWithSymbols(remapper), null).patchDeclarationParents() as T
return transform(DeepCopyIrTreeWithSymbols(remapper), null).patchDeclarationParents(initialParent) as T
}
@@ -9,18 +9,22 @@ import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
import org.jetbrains.kotlin.ir.declarations.IrPackageFragment
import org.jetbrains.kotlin.ir.declarations.impl.IrDeclarationBase
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
import java.util.*
fun <T : IrElement> T.patchDeclarationParents() =
fun <T : IrElement> T.patchDeclarationParents(initialParent: IrDeclarationParent? = null) =
apply {
acceptVoid(PatchDeclarationParentsVisitor())
val visitor = initialParent?.let { PatchDeclarationParentsVisitor(it) } ?: PatchDeclarationParentsVisitor()
acceptVoid(visitor)
}
class PatchDeclarationParentsVisitor : IrElementVisitorVoid {
class PatchDeclarationParentsVisitor() : IrElementVisitorVoid {
constructor(containingDeclaration: IrDeclarationParent) : this() {
declarationParentsStack.push(containingDeclaration)
}
private val declarationParentsStack = ArrayDeque<IrDeclarationParent>()