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() }