IR: slightly simplify deep copy interface

Do not pass TypeRemapper explicitly unless an instance of something
other than DeepCopyTypeRemapper is required.
This commit is contained in:
Alexander Udalov
2024-03-07 12:47:46 +01:00
committed by Space Team
parent d659b76de5
commit e7e8cba1b4
9 changed files with 32 additions and 49 deletions
@@ -166,9 +166,7 @@ open class ExpectDeclarationRemover(val symbolTable: ReferenceSymbolTable, priva
expectActualTypeParametersMap: Map<IrTypeParameter, IrTypeParameter> expectActualTypeParametersMap: Map<IrTypeParameter, IrTypeParameter>
): IrExpressionBody { ): IrExpressionBody {
return this return this
.deepCopyWithSymbols(actualFunction) { symbolRemapper, _ -> .deepCopyWithSymbols(actualFunction) { IrTypeParameterRemapper(expectActualTypeParametersMap) }
DeepCopyIrTreeWithSymbols(symbolRemapper, IrTypeParameterRemapper(expectActualTypeParametersMap))
}
.transform(object : IrElementTransformerVoid() { .transform(object : IrElementTransformerVoid() {
override fun visitGetValue(expression: IrGetValue): IrExpression { override fun visitGetValue(expression: IrGetValue): IrExpression {
expression.transformChildrenVoid() expression.transformChildrenVoid()
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.types.IrSimpleType import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.util.DeepCopyIrTreeWithSymbols import org.jetbrains.kotlin.ir.util.DeepCopyIrTreeWithSymbols
import org.jetbrains.kotlin.ir.util.SymbolRemapper import org.jetbrains.kotlin.ir.util.SymbolRemapper
import org.jetbrains.kotlin.ir.util.TypeRemapper
import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.utils.memoryOptimizedMap import org.jetbrains.kotlin.utils.memoryOptimizedMap
@@ -76,9 +75,7 @@ internal class ActualizerSymbolRemapper(private val expectActualMap: Map<IrSymbo
private inline fun <reified S : IrSymbol> S.actualizeSymbol(): S = (expectActualMap[this] as? S) ?: this private inline fun <reified S : IrSymbol> S.actualizeSymbol(): S = (expectActualMap[this] as? S) ?: this
} }
internal open class ActualizerVisitor(private val symbolRemapper: SymbolRemapper, typeRemapper: TypeRemapper) : internal open class ActualizerVisitor(private val symbolRemapper: SymbolRemapper) : DeepCopyIrTreeWithSymbols(symbolRemapper) {
DeepCopyIrTreeWithSymbols(symbolRemapper, typeRemapper) {
// We shouldn't touch attributes, because Fir2Ir wouldn't set them to anything meaningful anyway. // We shouldn't touch attributes, because Fir2Ir wouldn't set them to anything meaningful anyway.
// So it would be better to have them as is, i.e. referring to `this`, not some random node removed from the tree // So it would be better to have them as is, i.e. referring to `this`, not some random node removed from the tree
override fun <D : IrAttributeContainer> D.processAttributes(other: IrAttributeContainer?): D = this override fun <D : IrAttributeContainer> D.processAttributes(other: IrAttributeContainer?): D = this
@@ -10,14 +10,15 @@ import org.jetbrains.kotlin.ir.declarations.copyAttributes
import org.jetbrains.kotlin.ir.expressions.IrGetValue import org.jetbrains.kotlin.ir.expressions.IrGetValue
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.SymbolRemapper
import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
import org.jetbrains.kotlin.ir.util.remapSymbolParent
internal class FunctionDefaultParametersActualizer( internal class FunctionDefaultParametersActualizer(
symbolRemapper: ActualizerSymbolRemapper, symbolRemapper: ActualizerSymbolRemapper,
typeRemapper: DeepCopyTypeRemapper,
private val expectActualMap: Map<IrSymbol, IrSymbol> private val expectActualMap: Map<IrSymbol, IrSymbol>
) { ) {
private val visitor = FunctionDefaultParametersActualizerVisitor(symbolRemapper, typeRemapper) private val visitor = FunctionDefaultParametersActualizerVisitor(symbolRemapper)
fun actualize() { fun actualize() {
for ((expect, actual) in expectActualMap) { for ((expect, actual) in expectActualMap) {
@@ -37,8 +38,7 @@ internal class FunctionDefaultParametersActualizer(
} }
} }
private class FunctionDefaultParametersActualizerVisitor(private val symbolRemapper: SymbolRemapper, typeRemapper: TypeRemapper) : private class FunctionDefaultParametersActualizerVisitor(private val symbolRemapper: SymbolRemapper) : ActualizerVisitor(symbolRemapper) {
ActualizerVisitor(symbolRemapper, typeRemapper) {
override fun visitGetValue(expression: IrGetValue): IrGetValue { override fun visitGetValue(expression: IrGetValue): IrGetValue {
// It performs actualization of dispatch/extension receivers // It performs actualization of dispatch/extension receivers
// It's actual only for default parameter values of expect functions because expect functions don't have bodies // It's actual only for default parameter values of expect functions because expect functions don't have bodies
@@ -5,16 +5,17 @@
package org.jetbrains.kotlin.backend.common.actualizer package org.jetbrains.kotlin.backend.common.actualizer
import org.jetbrains.kotlin.ir.IrDiagnosticReporter
import org.jetbrains.kotlin.backend.common.actualizer.checker.IrExpectActualCheckers import org.jetbrains.kotlin.backend.common.actualizer.checker.IrExpectActualCheckers
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.ir.IrDiagnosticReporter
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.types.IrTypeSystemContext import org.jetbrains.kotlin.ir.types.IrTypeSystemContext
import org.jetbrains.kotlin.ir.types.classOrFail import org.jetbrains.kotlin.ir.types.classOrFail
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.SymbolRemapper
import org.jetbrains.kotlin.ir.util.classIdOrFail
data class IrActualizedResult( data class IrActualizedResult(
val actualizedExpectDeclarations: List<IrDeclaration>, val actualizedExpectDeclarations: List<IrDeclaration>,
@@ -70,9 +71,7 @@ class IrActualizer(
return getReferencedClass(symbol) return getReferencedClass(symbol)
} }
} }
val classTypeRemapper = DeepCopyTypeRemapper(classSymbolRemapper) dependentFragments.forEach { it.transform(ActualizerVisitor(classSymbolRemapper), null) }
val classActualizerVisitor = ActualizerVisitor(classSymbolRemapper, classTypeRemapper)
dependentFragments.forEach { it.transform(classActualizerVisitor, null) }
} }
fun actualizeCallablesAndMergeModules(): Map<IrSymbol, IrSymbol> { fun actualizeCallablesAndMergeModules(): Map<IrSymbol, IrSymbol> {
@@ -95,11 +94,10 @@ class IrActualizer(
// 4. Copy and actualize function parameter default values from expect functions // 4. Copy and actualize function parameter default values from expect functions
val symbolRemapper = ActualizerSymbolRemapper(expectActualMap) val symbolRemapper = ActualizerSymbolRemapper(expectActualMap)
val typeRemapper = DeepCopyTypeRemapper(symbolRemapper) FunctionDefaultParametersActualizer(symbolRemapper, expectActualMap).actualize()
FunctionDefaultParametersActualizer(symbolRemapper, typeRemapper, expectActualMap).actualize()
// 5. Actualize expect calls in dependent fragments using info obtained in the previous steps // 5. Actualize expect calls in dependent fragments using info obtained in the previous steps
val actualizerVisitor = ActualizerVisitor(symbolRemapper, typeRemapper) val actualizerVisitor = ActualizerVisitor(symbolRemapper)
dependentFragments.forEach { it.transform(actualizerVisitor, null) } dependentFragments.forEach { it.transform(actualizerVisitor, null) }
// 6. Move all declarations to mainFragment // 6. Move all declarations to mainFragment
@@ -5,8 +5,8 @@
package org.jetbrains.kotlin.backend.common.actualizer package org.jetbrains.kotlin.backend.common.actualizer
import org.jetbrains.kotlin.ir.IrDiagnosticReporter
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.ir.IrDiagnosticReporter
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.builders.declarations.buildFun import org.jetbrains.kotlin.ir.builders.declarations.buildFun
@@ -21,7 +21,9 @@ import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.resolve.calls.mpp.AbstractExpectActualMatcher import org.jetbrains.kotlin.resolve.calls.mpp.AbstractExpectActualMatcher
import org.jetbrains.kotlin.resolve.multiplatform.* import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualAnnotationsIncompatibilityType
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCheckingCompatibility
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualMatchingCompatibility
import org.jetbrains.kotlin.utils.addToStdlib.runIf import org.jetbrains.kotlin.utils.addToStdlib.runIf
import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled
@@ -220,9 +222,8 @@ private fun createFakeOverrideFunction(
it.annotations = actualFunction.annotations.map { p -> p.deepCopyWithSymbols(it) } it.annotations = actualFunction.annotations.map { p -> p.deepCopyWithSymbols(it) }
it.typeParameters = actualFunction.typeParameters.map { p -> p.deepCopyWithSymbols(it) } it.typeParameters = actualFunction.typeParameters.map { p -> p.deepCopyWithSymbols(it) }
val typeRemapper = IrTypeParameterRemapper(actualFunction.typeParameters.zip(it.typeParameters).toMap()) fun IrValueParameter.deepCopyWithTypeParameters(): IrValueParameter = deepCopyWithSymbols(it) { _ ->
fun IrValueParameter.deepCopyWithTypeParameters(): IrValueParameter = deepCopyWithSymbols(it) { symbolRemapper, _ -> IrTypeParameterRemapper(actualFunction.typeParameters.zip(it.typeParameters).toMap())
DeepCopyIrTreeWithSymbols(symbolRemapper, typeRemapper)
} }
it.dispatchReceiverParameter = actualFunction.dispatchReceiverParameter?.deepCopyWithTypeParameters() it.dispatchReceiverParameter = actualFunction.dispatchReceiverParameter?.deepCopyWithTypeParameters()
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.ir
import org.jetbrains.kotlin.ir.util.DeepCopyIrTreeWithSymbols import org.jetbrains.kotlin.ir.util.DeepCopyIrTreeWithSymbols
import org.jetbrains.kotlin.ir.util.DeepCopySymbolRemapper import org.jetbrains.kotlin.ir.util.DeepCopySymbolRemapper
import org.jetbrains.kotlin.ir.util.DeepCopyTypeRemapper
import org.jetbrains.kotlin.ir.util.NullDescriptorsRemapper import org.jetbrains.kotlin.ir.util.NullDescriptorsRemapper
import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid
@@ -16,7 +15,5 @@ fun <T : IrElement> T.deepCopyWithVariables(): T {
val symbolsRemapper = DeepCopySymbolRemapper(NullDescriptorsRemapper) val symbolsRemapper = DeepCopySymbolRemapper(NullDescriptorsRemapper)
acceptVoid(symbolsRemapper) acceptVoid(symbolsRemapper)
val typesRemapper = DeepCopyTypeRemapper(symbolsRemapper) return this.transform(DeepCopyIrTreeWithSymbols(symbolsRemapper), null) as T
return this.transform(DeepCopyIrTreeWithSymbols(symbolsRemapper, typesRemapper), null) as T
} }
@@ -25,33 +25,29 @@ import org.jetbrains.kotlin.utils.memoryOptimizedMap
inline fun <reified T : IrElement> T.deepCopyWithSymbols( inline fun <reified T : IrElement> T.deepCopyWithSymbols(
initialParent: IrDeclarationParent? = null, initialParent: IrDeclarationParent? = null,
createCopier: (SymbolRemapper, TypeRemapper) -> DeepCopyIrTreeWithSymbols = createTypeRemapper: (SymbolRemapper) -> TypeRemapper = ::DeepCopyTypeRemapper
{ symbolRemapper, typeRemapper -> DeepCopyIrTreeWithSymbols(symbolRemapper, typeRemapper) },
): T = deepCopyWithSymbols(initialParent, DeepCopySymbolRemapper(), createCopier)
inline fun <reified T : IrElement> T.deepCopyWithSymbols(
initialParent: IrDeclarationParent?,
symbolRemapper: DeepCopySymbolRemapper,
createCopier: (SymbolRemapper, TypeRemapper) -> DeepCopyIrTreeWithSymbols =
{ symbolRemapper, typeRemapper -> DeepCopyIrTreeWithSymbols(symbolRemapper, typeRemapper) },
): T { ): T {
val symbolRemapper = DeepCopySymbolRemapper()
acceptVoid(symbolRemapper) acceptVoid(symbolRemapper)
val typeRemapper = DeepCopyTypeRemapper(symbolRemapper) val typeRemapper = createTypeRemapper(symbolRemapper)
return transform(createCopier(symbolRemapper, typeRemapper), null).patchDeclarationParents(initialParent) as T return transform(DeepCopyIrTreeWithSymbols(symbolRemapper, typeRemapper), null).patchDeclarationParents(initialParent) as T
} }
@OptIn(ObsoleteDescriptorBasedAPI::class) @OptIn(ObsoleteDescriptorBasedAPI::class)
open class DeepCopyIrTreeWithSymbols( open class DeepCopyIrTreeWithSymbols(
private val symbolRemapper: SymbolRemapper, private val symbolRemapper: SymbolRemapper,
private val typeRemapper: TypeRemapper, typeRemapper: TypeRemapper? = null,
// This parameter is not used meaningfully, but is left for compatibility with compose. // This parameter is not used meaningfully, but is left for compatibility with compose.
@Suppress("UNUSED_PARAMETER") symbolRenamer: SymbolRenamer? = null, @Suppress("UNUSED_PARAMETER") symbolRenamer: SymbolRenamer? = null,
) : IrElementTransformerVoid() { ) : IrElementTransformerVoid() {
private var transformedModule: IrModuleFragment? = null private var transformedModule: IrModuleFragment? = null
private val typeRemapper: TypeRemapper = typeRemapper ?: DeepCopyTypeRemapper(symbolRemapper)
init { init {
// TODO refactor // TODO refactor
(typeRemapper as? DeepCopyTypeRemapper)?.let { // After removing usages of DeepCopyTypeRemapper constructor from compose, the lateinit property `DeepCopyTypeRemapper.deepCopy`
// can be refactored to a constructor parameter.
(this.typeRemapper as? DeepCopyTypeRemapper)?.let {
it.deepCopy = this it.deepCopy = this
} }
} }
@@ -14,14 +14,11 @@ fun <T : IrElement> T.deepCopySavingMetadata(
symbolRemapper: DeepCopySymbolRemapper = DeepCopySymbolRemapper() symbolRemapper: DeepCopySymbolRemapper = DeepCopySymbolRemapper()
): T { ): T {
acceptVoid(symbolRemapper) acceptVoid(symbolRemapper)
val typeRemapper = DeepCopyTypeRemapper(symbolRemapper)
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
return transform(DeepCopySavingMetadata(symbolRemapper, typeRemapper), null) return transform(DeepCopySavingMetadata(symbolRemapper), null).patchDeclarationParents(initialParent) as T
.patchDeclarationParents(initialParent) as T
} }
private class DeepCopySavingMetadata(symbolRemapper: SymbolRemapper, typeRemapper: TypeRemapper) : private class DeepCopySavingMetadata(symbolRemapper: SymbolRemapper) : DeepCopyIrTreeWithSymbols(symbolRemapper) {
DeepCopyIrTreeWithSymbols(symbolRemapper, typeRemapper) {
override fun visitFile(declaration: IrFile): IrFile = override fun visitFile(declaration: IrFile): IrFile =
super.visitFile(declaration).apply { super.visitFile(declaration).apply {
metadata = declaration.metadata metadata = declaration.metadata
@@ -30,7 +27,6 @@ private class DeepCopySavingMetadata(symbolRemapper: SymbolRemapper, typeRemappe
override fun visitClass(declaration: IrClass): IrClass = override fun visitClass(declaration: IrClass): IrClass =
super.visitClass(declaration).apply { super.visitClass(declaration).apply {
metadata = declaration.metadata metadata = declaration.metadata
} }
override fun visitConstructor(declaration: IrConstructor): IrConstructor = override fun visitConstructor(declaration: IrConstructor): IrConstructor =
@@ -169,7 +169,7 @@ internal class ExpectToActualDefaultValueCopier(private val irModule: IrModuleFr
val symbolRemapper = SymbolRemapper() val symbolRemapper = SymbolRemapper()
acceptVoid(symbolRemapper) acceptVoid(symbolRemapper)
return transform(DeepCopyIrTreeWithSymbols(symbolRemapper, DeepCopyTypeRemapper(symbolRemapper)), data = null) return transform(DeepCopyIrTreeWithSymbols(symbolRemapper), data = null)
} }
private fun remapExpectTypeParameter(symbol: IrTypeParameterSymbol): IrTypeParameter { private fun remapExpectTypeParameter(symbol: IrTypeParameterSymbol): IrTypeParameter {