From df9d59851d84beb9667a57f6cae6cb9cf6b6a277 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 5 Mar 2024 17:28:30 +0100 Subject: [PATCH] IR: do not use SymbolRemapper in FakeOverrideCopier It was only used to keep track of mappings from old type/value parameters to new. We can do it manually instead of inheriting from DeepCopySymbolRemapper, because the latter does more work than needed, namely it creates 16 hash maps, and traverses the IR tree looking for any other declarations. #KT-66281 --- .../CopyIrTreeWithSymbolsForFakeOverrides.kt | 84 +++++++------------ .../kotlin/ir/overrides/FakeOverrideCopier.kt | 14 +++- 2 files changed, 38 insertions(+), 60 deletions(-) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/CopyIrTreeWithSymbolsForFakeOverrides.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/CopyIrTreeWithSymbolsForFakeOverrides.kt index fe0dcee0d3e..6b0f2c3db1b 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/CopyIrTreeWithSymbolsForFakeOverrides.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/CopyIrTreeWithSymbolsForFakeOverrides.kt @@ -6,38 +6,38 @@ package org.jetbrains.kotlin.ir.overrides import org.jetbrains.kotlin.ir.declarations.* -import org.jetbrains.kotlin.ir.expressions.IrBlockBody -import org.jetbrains.kotlin.ir.expressions.IrExpressionBody import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol +import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.impl.buildSimpleType import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection -import org.jetbrains.kotlin.ir.util.* -import org.jetbrains.kotlin.ir.visitors.acceptVoid +import org.jetbrains.kotlin.ir.util.TypeRemapper +import org.jetbrains.kotlin.ir.util.copyAnnotations +import org.jetbrains.kotlin.ir.util.findAnnotation +import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.name.StandardClassIds.Annotations.EnhancedNullability import org.jetbrains.kotlin.name.StandardClassIds.Annotations.FlexibleNullability import org.jetbrains.kotlin.utils.addIfNotNull import org.jetbrains.kotlin.utils.memoryOptimizedMap -// This is basically modelled after the inliner copier. class CopyIrTreeWithSymbolsForFakeOverrides( private val overridableMember: IrOverridableMember, - typeArguments: Map, - parentClass: IrClass, - unimplementedOverridesStrategy: IrUnimplementedOverridesStrategy + private val substitution: Map, + private val parentClass: IrClass, + private val unimplementedOverridesStrategy: IrUnimplementedOverridesStrategy ) { - private val symbolRemapper = FakeOverrideSymbolRemapperImpl(typeArguments, NullDescriptorsRemapper) - - private val copier = FakeOverrideCopier( - symbolRemapper, - FakeOverrideTypeRemapper(symbolRemapper, typeArguments), - parentClass, - unimplementedOverridesStrategy - ) - fun copy(): IrOverridableMember { - overridableMember.acceptVoid(symbolRemapper) + val typeParameters = HashMap() + val valueParameters = HashMap() + + val copier = FakeOverrideCopier( + valueParameters, + typeParameters, + FakeOverrideTypeRemapper(typeParameters, substitution), + parentClass, + unimplementedOverridesStrategy + ) return when (overridableMember) { is IrSimpleFunction -> copier.copySimpleFunction(overridableMember) @@ -46,11 +46,10 @@ class CopyIrTreeWithSymbolsForFakeOverrides( } } - private inner class FakeOverrideTypeRemapper( - val symbolRemapper: SymbolRemapper, - val typeArguments: Map + private class FakeOverrideTypeRemapper( + val typeParameters: Map, + val substitution: Map ) : TypeRemapper { - override fun enterScope(irTypeParametersContainer: IrTypeParametersContainer) {} override fun leaveScope() {} @@ -79,50 +78,23 @@ class CopyIrTreeWithSymbolsForFakeOverrides( override fun remapType(type: IrType): IrType { if (type !is IrSimpleType) return type - return when (val substitutedType = typeArguments[type.classifier]) { + return when (val substitutedType = substitution[type.classifier]) { is IrDynamicType -> substitutedType is IrSimpleType -> substitutedType.mergeNullability(type).mergeTypeAnnotations(type) else -> type.buildSimpleType { kotlinType = null - classifier = symbolRemapper.getReferencedClassifier(type.classifier) + classifier = remapClassifier(type.classifier) arguments = remapTypeArguments(type.arguments) annotations = type.copyAnnotations() } } } - } - private class FakeOverrideSymbolRemapperImpl( - private val typeArguments: Map, - descriptorsRemapper: DescriptorsRemapper - ) : DeepCopySymbolRemapper(descriptorsRemapper) { - - // We need to avoid visiting parts of the tree that would not be visited by [FakeOverrideCopier] - // Otherwise, we can record symbols inside them for rebinding, but would not actually copy them. - // Normally, this is not important, as these local symbols would not be used anyway - // But they can be used in return values of functions/accessors if it is effectively a private declaration, - // e.g. public declaration inside a private class. - - override fun visitField(declaration: IrField) {} // don't visit property backing field - override fun visitBlockBody(body: IrBlockBody) {} // don't visit function body and parameter default values - override fun visitExpressionBody(body: IrExpressionBody) {} // don't visit function body and parameter default values - - override fun visitSimpleFunction(declaration: IrSimpleFunction, data: Nothing?) { - // In case of FIR tests with JVM IR serialization enabled, even accessing the function body with `IrFunction.body` does not work - // in some cases because it tries to load IR and ends up with unbound symbols for some reason (most likely related to KT-63509). - // So we avoid accessing the body by copying the `IrFunction.acceptChildren` implementation and removing the `body.accept` call. - declaration.typeParameters.forEach { it.accept(this, data) } - declaration.dispatchReceiverParameter?.accept(this, data) - declaration.extensionReceiverParameter?.accept(this, data) - declaration.valueParameters.forEach { it.accept(this, data) } - } - - override fun getReferencedClassifier(symbol: IrClassifierSymbol): IrClassifierSymbol { - val result = super.getReferencedClassifier(symbol) - if (result !is IrTypeParameterSymbol) - return result - return typeArguments[result]?.classifierOrNull ?: result - } + private fun remapClassifier(classifier: IrClassifierSymbol): IrClassifierSymbol = + if (classifier is IrTypeParameterSymbol) + typeParameters.getOrElse(classifier) { classifier } + else + classifier } private companion object { diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/FakeOverrideCopier.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/FakeOverrideCopier.kt index a6d49b98717..cc77fb5c882 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/FakeOverrideCopier.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/FakeOverrideCopier.kt @@ -6,12 +6,16 @@ package org.jetbrains.kotlin.ir.overrides import org.jetbrains.kotlin.ir.declarations.* -import org.jetbrains.kotlin.ir.util.SymbolRemapper +import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol +import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol +import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl +import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl import org.jetbrains.kotlin.ir.util.TypeRemapper import org.jetbrains.kotlin.ir.util.copyAnnotations internal class FakeOverrideCopier( - private val symbolRemapper: SymbolRemapper, + private val valueParameters: MutableMap, + private val typeParameters: MutableMap, private val typeRemapper: TypeRemapper, private val parentClass: IrClass, private val unimplementedOverridesStrategy: IrUnimplementedOverridesStrategy @@ -81,13 +85,14 @@ internal class FakeOverrideCopier( name = declaration.name, type = typeRemapper.remapType(declaration.type), isAssignable = declaration.isAssignable, - symbol = symbolRemapper.getDeclaredValueParameter(declaration.symbol), + symbol = IrValueParameterSymbolImpl(null), index = declaration.index, varargElementType = declaration.varargElementType?.let(typeRemapper::remapType), isCrossinline = declaration.isCrossinline, isNoinline = declaration.isNoinline, isHidden = declaration.isHidden, ).apply { + valueParameters[declaration.symbol] = symbol parent = newParent annotations = declaration.copyAnnotations() // Don't set the default value for fake overrides. @@ -99,11 +104,12 @@ internal class FakeOverrideCopier( endOffset = declaration.endOffset, origin = declaration.origin, name = declaration.name, - symbol = symbolRemapper.getDeclaredTypeParameter(declaration.symbol), + symbol = IrTypeParameterSymbolImpl(null), variance = declaration.variance, index = declaration.index, isReified = declaration.isReified, ).apply { + typeParameters[declaration.symbol] = symbol parent = newParent annotations = declaration.copyAnnotations() }