From 71d51801ce3ae386a4c1737b68ed86cbf594c991 Mon Sep 17 00:00:00 2001 From: Dmitriy Dolovov Date: Wed, 31 Aug 2022 12:10:00 +0200 Subject: [PATCH] [IR] Partial linkage fix: Implement abstract fake overrides in non-abstract classes so that there are no call sites that still refer to abstract fake overrides ^KT-53663 --- ... CopyIrTreeWithSymbolsForFakeOverrides.kt} | 30 +++++-- .../kotlin/ir/overrides/FakeOverrideCopier.kt | 88 +++++++++--------- .../kotlin/ir/overrides/IrOverridingUtil.kt | 33 +++---- .../IrUnimplementedOverridesStrategy.kt | 25 ++++++ .../org/jetbrains/kotlin/ir/util/IrUtils.kt | 9 +- .../backend/common/overrides/FakeOverrides.kt | 26 +++++- .../unlinked/ImplementedFakeOverrides.kt | 90 ------------------- .../unlinked/UnlinkedDeclarationsProcessor.kt | 43 ++------- .../js/lower/serialization/ir/JsIrLinker.kt | 9 +- .../deserializeLazyDeclarations.kt | 3 +- .../backend/jvm/serialization/JvmIrLinker.kt | 10 ++- .../konan/serialization/KonanIrlinker.kt | 12 ++- 12 files changed, 177 insertions(+), 201 deletions(-) rename compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/{DeepCopyIrTreeWithSymbolsForFakeOverrides.kt => CopyIrTreeWithSymbolsForFakeOverrides.kt} (80%) create mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/IrUnimplementedOverridesStrategy.kt delete mode 100644 compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/unlinked/ImplementedFakeOverrides.kt diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/DeepCopyIrTreeWithSymbolsForFakeOverrides.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/CopyIrTreeWithSymbolsForFakeOverrides.kt similarity index 80% rename from compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/DeepCopyIrTreeWithSymbolsForFakeOverrides.kt rename to compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/CopyIrTreeWithSymbolsForFakeOverrides.kt index 880dce9c969..e8f941483a4 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/DeepCopyIrTreeWithSymbolsForFakeOverrides.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/CopyIrTreeWithSymbolsForFakeOverrides.kt @@ -5,8 +5,8 @@ package org.jetbrains.kotlin.ir.overrides -import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrClass +import org.jetbrains.kotlin.ir.declarations.IrOverridableMember import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer import org.jetbrains.kotlin.ir.expressions.IrConstructorCall import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol @@ -17,18 +17,26 @@ import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.acceptVoid -// This is basicly modelled after the inliner copier. -class DeepCopyIrTreeWithSymbolsForFakeOverrides(typeArguments: Map) { - - fun copy(irElement: IrElement, parent: IrClass): IrElement { +// This is basically modelled after the inliner copier. +class CopyIrTreeWithSymbolsForFakeOverrides( + private val overridableMember: IrOverridableMember, + typeArguments: Map, + private val parent: IrClass, + unimplementedOverridesStrategy: IrUnimplementedOverridesStrategy +) { + fun copy(): IrOverridableMember { // Create new symbols. - irElement.acceptVoid(symbolRemapper) + overridableMember.acceptVoid(symbolRemapper) // Make symbol remapper aware of the callsite's type arguments. // Copy IR. - val result = irElement.transform(if (parent.isEffectivelyExternal()) copierMakingExternal else copier, data = null) + val result = overridableMember.transform( + if (parent.isEffectivelyExternal()) copierMakingExternal else copier, + data = null + ) as IrOverridableMember result.patchDeclarationParents(parent) + return result } @@ -82,10 +90,14 @@ class DeepCopyIrTreeWithSymbolsForFakeOverrides(typeArguments: Map T.transformFunctionChildren(declaration: T): T = - apply { - transformAnnotations(declaration) - copyTypeParametersFrom(declaration) - typeRemapper.withinScope(this) { - // This is the more correct way to produce dispatch receiver for a fake override, - // but some lowerings still expect the below behavior as produced by the current psi2ir. - /* - val superDispatchReceiver = declaration.dispatchReceiverParameter!! - val dispatchReceiverSymbol = IrValueParameterSymbolImpl(WrappedReceiverParameterDescriptor()) - val dispatchReceiverType = destinationClass.defaultType - dispatchReceiverParameter = IrValueParameterImpl( - superDispatchReceiver.startOffset, - superDispatchReceiver.endOffset, - superDispatchReceiver.origin, - dispatchReceiverSymbol, - superDispatchReceiver.name, - superDispatchReceiver.index, - dispatchReceiverType, - null, - superDispatchReceiver.isCrossinline, - superDispatchReceiver.isNoinline - ) - */ - // Should fake override's receiver be the current class is an open question. - dispatchReceiverParameter = declaration.dispatchReceiverParameter?.transform() - extensionReceiverParameter = declaration.extensionReceiverParameter?.transform() - returnType = typeRemapper.remapType(declaration.returnType) - this.valueParameters = declaration.valueParameters.transform() - } - } + override fun visitSimpleFunction(declaration: IrSimpleFunction): IrSimpleFunction { + val customization = unimplementedOverridesStrategy.computeCustomization(declaration, parent) - override fun visitSimpleFunction(declaration: IrSimpleFunction): IrSimpleFunction = - declaration.factory.createFunctionWithLateBinding( + return declaration.factory.createFunctionWithLateBinding( declaration.startOffset, declaration.endOffset, - IrDeclarationOrigin.FAKE_OVERRIDE, + customization.origin ?: IrDeclarationOrigin.FAKE_OVERRIDE, symbolRenamer.getFunctionName(declaration.symbol), declaration.visibility, - declaration.modality, + customization.modality ?: declaration.modality, declaration.returnType, isInline = declaration.isInline, isExternal = makeExternal, @@ -63,17 +35,50 @@ class FakeOverrideCopier( isOperator = declaration.isOperator, isInfix = declaration.isInfix ).apply { - transformFunctionChildren(declaration) + transformAnnotations(declaration) + copyTypeParametersFrom(declaration) + typeRemapper.withinScope(this) { + // This is the more correct way to produce dispatch receiver for a fake override, + // but some lowerings still expect the below behavior as produced by the current psi2ir. + /* + val superDispatchReceiver = declaration.dispatchReceiverParameter!! + val dispatchReceiverSymbol = IrValueParameterSymbolImpl(WrappedReceiverParameterDescriptor()) + val dispatchReceiverType = destinationClass.defaultType + dispatchReceiverParameter = IrValueParameterImpl( + superDispatchReceiver.startOffset, + superDispatchReceiver.endOffset, + superDispatchReceiver.origin, + dispatchReceiverSymbol, + superDispatchReceiver.name, + superDispatchReceiver.index, + dispatchReceiverType, + null, + superDispatchReceiver.isCrossinline, + superDispatchReceiver.isNoinline + ) + */ + // Should fake override's receiver be the current class is an open question. + dispatchReceiverParameter = declaration.dispatchReceiverParameter?.transform() + extensionReceiverParameter = declaration.extensionReceiverParameter?.transform() + returnType = typeRemapper.remapType(declaration.returnType) + valueParameters = declaration.valueParameters.transform() + + if (customization.needToCreateBody && body == null) { + body = factory.createBlockBody(startOffset, endOffset) + } + } } + } + override fun visitProperty(declaration: IrProperty): IrProperty { + val customization = unimplementedOverridesStrategy.computeCustomization(declaration, parent) - override fun visitProperty(declaration: IrProperty): IrProperty = - declaration.factory.createPropertyWithLateBinding( + return declaration.factory.createPropertyWithLateBinding( declaration.startOffset, declaration.endOffset, - IrDeclarationOrigin.FAKE_OVERRIDE, + customization.origin ?: IrDeclarationOrigin.FAKE_OVERRIDE, declaration.name, declaration.visibility, - declaration.modality, + customization.modality ?: declaration.modality, isVar = declaration.isVar, isConst = declaration.isConst, isLateinit = declaration.isLateinit, @@ -85,6 +90,7 @@ class FakeOverrideCopier( this.getter = declaration.getter?.transform() this.setter = declaration.setter?.transform() } + } override fun visitValueParameter(declaration: IrValueParameter): IrValueParameter = declaration.factory.createValueParameter( diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/IrOverridingUtil.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/IrOverridingUtil.kt index 3827d79209d..047dacedde9 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/IrOverridingUtil.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/IrOverridingUtil.kt @@ -17,10 +17,12 @@ import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.TypeCheckerState import org.jetbrains.kotlin.types.Variance -abstract class FakeOverrideBuilderStrategy(private val friendModules: Map>) { - +abstract class FakeOverrideBuilderStrategy( + private val friendModules: Map>, + private val unimplementedOverridesStrategy: IrUnimplementedOverridesStrategy +) { open fun fakeOverrideMember(superType: IrType, member: IrOverridableMember, clazz: IrClass): IrOverridableMember = - buildFakeOverrideMember(superType, member, clazz, friendModules) + buildFakeOverrideMember(superType, member, clazz, friendModules, unimplementedOverridesStrategy) fun linkFakeOverride(fakeOverride: IrOverridableMember, compatibilityMode: Boolean) { when (fakeOverride) { @@ -61,11 +63,13 @@ private fun isInFriendModules( return toModuleName in fromFriends } -fun buildFakeOverrideMember(superType: IrType, member: IrOverridableMember, clazz: IrClass): IrOverridableMember { - return buildFakeOverrideMember(superType, member, clazz, emptyMap()) -} - -fun buildFakeOverrideMember(superType: IrType, member: IrOverridableMember, clazz: IrClass, friendModules: Map>): IrOverridableMember { +fun buildFakeOverrideMember( + superType: IrType, + member: IrOverridableMember, + clazz: IrClass, + friendModules: Map> = emptyMap(), + unimplementedOverridesStrategy: IrUnimplementedOverridesStrategy = IrUnimplementedOverridesStrategy.ProcessAsFakeOverrides +): IrOverridableMember { require(superType is IrSimpleType) { "superType is $superType, expected IrSimpleType" } val classifier = superType.classifier require(classifier is IrClassSymbol) { "superType classifier is not IrClassSymbol: $classifier" } @@ -86,13 +90,12 @@ fun buildFakeOverrideMember(superType: IrType, member: IrOverridableMember, claz substitutionMap[tp.symbol] = ta.type } - val copier = DeepCopyIrTreeWithSymbolsForFakeOverrides(substitutionMap) - val deepCopyFakeOverride = copier.copy(member, clazz) as IrOverridableMember - deepCopyFakeOverride.parent = clazz - if (deepCopyFakeOverride.isPrivateToThisModule(clazz, classifier.owner, friendModules)) - deepCopyFakeOverride.visibility = DescriptorVisibilities.INVISIBLE_FAKE - - return deepCopyFakeOverride + return CopyIrTreeWithSymbolsForFakeOverrides(member, substitutionMap, clazz, unimplementedOverridesStrategy) + .copy() + .apply { + if (isPrivateToThisModule(clazz, classifier.owner, friendModules)) + visibility = DescriptorVisibilities.INVISIBLE_FAKE + } } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/IrUnimplementedOverridesStrategy.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/IrUnimplementedOverridesStrategy.kt new file mode 100644 index 00000000000..8cb29b00c26 --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/IrUnimplementedOverridesStrategy.kt @@ -0,0 +1,25 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.ir.overrides + +import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.ir.declarations.IrClass +import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin +import org.jetbrains.kotlin.ir.declarations.IrOverridableMember + +interface IrUnimplementedOverridesStrategy { + class Customization(val origin: IrDeclarationOrigin?, val modality: Modality?, val needToCreateBody: Boolean) { + companion object { + val NO = Customization(null, null, false) + } + } + + fun computeCustomization(overridableMember: T, parent: IrClass): Customization + + object ProcessAsFakeOverrides : IrUnimplementedOverridesStrategy { + override fun computeCustomization(overridableMember: T, parent: IrClass) = Customization.NO + } +} diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt index 1812596d476..7894a5ef20b 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt @@ -16,6 +16,8 @@ import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.overrides.FakeOverrideBuilderStrategy import org.jetbrains.kotlin.ir.overrides.IrOverridingUtil +import org.jetbrains.kotlin.ir.overrides.IrUnimplementedOverridesStrategy +import org.jetbrains.kotlin.ir.overrides.IrUnimplementedOverridesStrategy.ProcessAsFakeOverrides import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.impl.IrPropertySymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl @@ -24,7 +26,6 @@ import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection import org.jetbrains.kotlin.ir.visitors.IrElementVisitor -import org.jetbrains.kotlin.ir.types.impl.IrErrorClassImpl import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.SpecialNames @@ -1101,8 +1102,10 @@ val IrFunction.allParametersCount: Int // This is essentially the same as FakeOverrideBuilder, // but it bypasses SymbolTable. // TODO: merge it with FakeOverrideBuilder. -private class FakeOverrideBuilderForLowerings : FakeOverrideBuilderStrategy(emptyMap()) { - +private class FakeOverrideBuilderForLowerings : FakeOverrideBuilderStrategy( + friendModules = emptyMap(), + unimplementedOverridesStrategy = ProcessAsFakeOverrides +) { override fun linkFunctionFakeOverride(declaration: IrFunctionWithLateBinding, compatibilityMode: Boolean) { declaration.acquireSymbol(IrSimpleFunctionSymbolImpl()) } diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/overrides/FakeOverrides.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/overrides/FakeOverrides.kt index 7a71b8d5803..298eb4da6bc 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/overrides/FakeOverrides.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/overrides/FakeOverrides.kt @@ -21,9 +21,14 @@ import org.jetbrains.kotlin.backend.common.serialization.DeclarationTable import org.jetbrains.kotlin.backend.common.serialization.GlobalDeclarationTable import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer import org.jetbrains.kotlin.backend.common.serialization.signature.PublicIdSignatureComputer +import org.jetbrains.kotlin.backend.common.serialization.unlinked.UnlinkedDeclarationsProcessor.Companion.MISSING_ABSTRACT_CALLABLE_MEMBER_IMPLEMENTATION +import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.overrides.FakeOverrideBuilderStrategy import org.jetbrains.kotlin.ir.overrides.IrOverridingUtil +import org.jetbrains.kotlin.ir.overrides.IrUnimplementedOverridesStrategy +import org.jetbrains.kotlin.ir.overrides.IrUnimplementedOverridesStrategy.Customization +import org.jetbrains.kotlin.ir.overrides.IrUnimplementedOverridesStrategy.ProcessAsFakeOverrides import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.symbols.impl.IrPropertySymbolImpl @@ -63,17 +68,36 @@ object DefaultFakeOverrideClassFilter : FakeOverrideClassFilter { override fun needToConstructFakeOverrides(clazz: IrClass): Boolean = true } +private object ImplementAsErrorThrowingStubs : IrUnimplementedOverridesStrategy { + override fun computeCustomization(overridableMember: T, parent: IrClass) = + if (overridableMember.modality == Modality.ABSTRACT + && parent.modality != Modality.ABSTRACT + && parent.modality != Modality.SEALED + ) { + Customization( + origin = MISSING_ABSTRACT_CALLABLE_MEMBER_IMPLEMENTATION, + modality = parent.modality, // Use modality of class for implemented callable member. + needToCreateBody = true // At least it should have empty body. Later, the body will be patched in UnlinkedDeclarationsProcessor. + ) + } else + Customization.NO +} + class FakeOverrideBuilder( val linker: FileLocalAwareLinker, val symbolTable: SymbolTable, mangler: KotlinMangler.IrMangler, typeSystem: IrTypeSystemContext, friendModules: Map>, + partialLinkageEnabled: Boolean, val platformSpecificClassFilter: FakeOverrideClassFilter = DefaultFakeOverrideClassFilter, private val fakeOverrideDeclarationTable: DeclarationTable = FakeOverrideDeclarationTable(mangler) { builder, table -> IdSignatureSerializer(builder, table) } -) : FakeOverrideBuilderStrategy(friendModules) { +) : FakeOverrideBuilderStrategy( + friendModules = friendModules, + unimplementedOverridesStrategy = if (partialLinkageEnabled) ImplementAsErrorThrowingStubs else ProcessAsFakeOverrides +) { private val haveFakeOverrides = mutableSetOf() private val irOverridingUtil = IrOverridingUtil(typeSystem, this) diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/unlinked/ImplementedFakeOverrides.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/unlinked/ImplementedFakeOverrides.kt deleted file mode 100644 index 28afde6ecdc..00000000000 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/unlinked/ImplementedFakeOverrides.kt +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.backend.common.serialization.unlinked - -import org.jetbrains.kotlin.ir.declarations.* -import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol -import org.jetbrains.kotlin.ir.util.* - -internal inline fun > T.deepCopyWithImplementedFakeOverrides(): T { - val clazz = parentAsClass - - return deepCopyWithSymbols(clazz, DeepCopySymbolRemapperPreservingSignatures()) { symbolRemapper, typeRemapper -> - ImplementedFakeOverrideCopier(clazz, symbolRemapper, typeRemapper) - } -} - -internal class ImplementedFakeOverrideCopier( - private val clazz: IrClass, - private val symbolRemapper: SymbolRemapper, - private val typeRemapper: TypeRemapper -) : DeepCopyIrTreeWithSymbols(symbolRemapper, typeRemapper) { - override fun visitProperty(declaration: IrProperty): IrProperty = - declaration.factory.createProperty( - startOffset = declaration.startOffset, - endOffset = declaration.endOffset, - origin = MISSING_ABSTRACT_CALLABLE_MEMBER_IMPLEMENTATION, // Customized. - symbol = symbolRemapper.getDeclaredProperty(declaration.symbol), - name = declaration.name, - visibility = declaration.visibility, - modality = clazz.modality, // Customized. - isVar = declaration.isVar, - isConst = declaration.isConst, - isLateinit = declaration.isLateinit, - isDelegated = declaration.isDelegated, - isExternal = declaration.isExternal, - isExpect = declaration.isExpect, - isFakeOverride = false, // Customized. - containerSource = declaration.containerSource, - ).apply { - overriddenSymbols = declaration.overriddenSymbols.map { symbolRemapper.getReferencedProperty(it) } - copyAttributes(declaration) - transformAnnotations(declaration) - backingField = declaration.backingField?.transform()?.also { it.correspondingPropertySymbol = symbol } - getter = declaration.getter?.transform()?.also { it.correspondingPropertySymbol = symbol } - setter = declaration.setter?.transform()?.also { it.correspondingPropertySymbol = symbol } - } - - override fun visitSimpleFunction(declaration: IrSimpleFunction): IrSimpleFunction = - declaration.factory.createFunction( - startOffset = declaration.startOffset, - endOffset = declaration.endOffset, - origin = MISSING_ABSTRACT_CALLABLE_MEMBER_IMPLEMENTATION, // Customized. - symbol = symbolRemapper.getDeclaredFunction(declaration.symbol), - name = declaration.name, - visibility = declaration.visibility, - modality = clazz.modality, // Customized. - returnType = declaration.returnType, - isInline = declaration.isInline, - isExternal = declaration.isExternal, - isTailrec = declaration.isTailrec, - isSuspend = declaration.isSuspend, - isOperator = declaration.isOperator, - isInfix = declaration.isInfix, - isExpect = declaration.isExpect, - isFakeOverride = false, // Customized. - containerSource = declaration.containerSource, - ).apply { - overriddenSymbols = declaration.overriddenSymbols.map { symbolRemapper.getReferencedFunction(it) as IrSimpleFunctionSymbol } - contextReceiverParametersCount = declaration.contextReceiverParametersCount - copyAttributes(declaration) - transformAnnotations(this) - copyTypeParametersFrom(declaration) - typeRemapper.withinScope(this) { - dispatchReceiverParameter = declaration.dispatchReceiverParameter?.transform() - extensionReceiverParameter = declaration.extensionReceiverParameter?.transform() - returnType = typeRemapper.remapType(declaration.returnType) - valueParameters = declaration.valueParameters.transform() - body = factory.createBlockBody( - declaration.body?.startOffset ?: declaration.startOffset, - declaration.body?.endOffset ?: declaration.endOffset - ) // the body should be empty - } - } -} - -private val MISSING_ABSTRACT_CALLABLE_MEMBER_IMPLEMENTATION = - object : IrDeclarationOriginImpl("MISSING_ABSTRACT_CALLABLE_MEMBER_IMPLEMENTATION", isSynthetic = true) {} diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/unlinked/UnlinkedDeclarationsProcessor.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/unlinked/UnlinkedDeclarationsProcessor.kt index faf3a844377..4f10b4bcf79 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/unlinked/UnlinkedDeclarationsProcessor.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/unlinked/UnlinkedDeclarationsProcessor.kt @@ -9,7 +9,6 @@ import org.jetbrains.kotlin.backend.common.serialization.unlinked.PartialLinkage import org.jetbrains.kotlin.backend.common.serialization.unlinked.UnlinkedIrElementRenderer.appendDeclaration import org.jetbrains.kotlin.backend.common.serialization.unlinked.UnlinkedIrElementRenderer.renderError import org.jetbrains.kotlin.backend.common.serialization.unlinked.UsedClassifierSymbolStatus.Companion.isUnlinked -import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.ir.IrBuiltIns import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement @@ -60,31 +59,11 @@ internal class UnlinkedDeclarationsProcessor( fun signatureTransformer(): IrElementTransformerVoid = SignatureTransformer() private inner class SignatureTransformer : IrElementTransformerVoid() { - private val implementedFakeOverrideProperties = hashSetOf() - - private val IrFunction.isAccessorOfImplementedFakeOverrideProperty: Boolean - get() = (this as? IrSimpleFunction)?.correspondingPropertySymbol?.owner in implementedFakeOverrideProperties - - override fun visitProperty(declaration: IrProperty): IrStatement { - val newProperty = declaration.replaceIfUnimplementedFakeOverride() - - val isImplementedFakeOverride = newProperty != declaration - if (isImplementedFakeOverride) implementedFakeOverrideProperties += newProperty - - newProperty.transformChildrenVoid() - - if (isImplementedFakeOverride) implementedFakeOverrideProperties -= newProperty - - return newProperty - } - override fun visitFunction(declaration: IrFunction): IrStatement { - val newFunction = declaration.replaceIfUnimplementedFakeOverride() - val removedUnlinkedTypes = newFunction.fixUnlinkedTypes() + val removedUnlinkedTypes = declaration.fixUnlinkedTypes() + val isImplementedFakeOverride = declaration.origin == MISSING_ABSTRACT_CALLABLE_MEMBER_IMPLEMENTATION - val isImplementedFakeOverride = newFunction != declaration || declaration.isAccessorOfImplementedFakeOverrideProperty - - return newFunction.transformBodyIfNecessary(isImplementedFakeOverride, removedUnlinkedTypes) + return declaration.transformBodyIfNecessary(isImplementedFakeOverride, removedUnlinkedTypes) } override fun visitField(declaration: IrField): IrStatement { @@ -111,19 +90,6 @@ internal class UnlinkedDeclarationsProcessor( return declaration } - /** - * Replaces an [IrProperty] or [IrSimpleFunction] that is abstract fake override in non-abstract class - * by the corresponding non-abstract IR element. - */ - private fun T.replaceIfUnimplementedFakeOverride(): T { - if (this !is IrOverridableDeclaration<*> || !isFakeOverride || modality != Modality.ABSTRACT) return this - - val clazz = parentAsClass - if (clazz.modality == Modality.ABSTRACT || clazz.modality == Modality.SEALED) return this - - return deepCopyWithImplementedFakeOverrides() - } - /** * Returns the set of all unlinked types encountered during transformation of the given [IrFunction]. * Or empty set if there were no unlinked types. @@ -363,6 +329,9 @@ internal class UnlinkedDeclarationsProcessor( companion object { private val ERROR_ORIGIN = object : IrStatementOriginImpl("LINKAGE ERROR") {} + + val MISSING_ABSTRACT_CALLABLE_MEMBER_IMPLEMENTATION = + object : IrDeclarationOriginImpl("MISSING_ABSTRACT_CALLABLE_MEMBER_IMPLEMENTATION", isSynthetic = true) {} } } diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt index b30eddedce0..5089096ba7c 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt @@ -39,7 +39,14 @@ class JsIrLinker( symbol }) { - override val fakeOverrideBuilder = FakeOverrideBuilder(this, symbolTable, JsManglerIr, IrTypeSystemContextImpl(builtIns), friendModules) + override val fakeOverrideBuilder = FakeOverrideBuilder( + linker = this, + symbolTable = symbolTable, + mangler = JsManglerIr, + typeSystem = IrTypeSystemContextImpl(builtIns), + friendModules = friendModules, + partialLinkageEnabled = partialLinkageSupport.partialLinkageEnabled + ) override fun isBuiltInModule(moduleDescriptor: ModuleDescriptor): Boolean = moduleDescriptor === moduleDescriptor.builtIns.builtInsModule diff --git a/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/backend/jvm/serialization/deserializeLazyDeclarations.kt b/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/backend/jvm/serialization/deserializeLazyDeclarations.kt index ce0ec745bc6..6c1865d1fe6 100644 --- a/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/backend/jvm/serialization/deserializeLazyDeclarations.kt +++ b/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/backend/jvm/serialization/deserializeLazyDeclarations.kt @@ -160,7 +160,8 @@ fun makeSimpleFakeOverrideBuilder( JvmIrMangler, typeSystemContext, fakeOverrideDeclarationTable = PrePopulatedDeclarationTable(symbolDeserializer.deserializedSymbols), - friendModules = emptyMap() // TODO: provide friend modules + friendModules = emptyMap(), // TODO: provide friend modules + partialLinkageEnabled = false ) } diff --git a/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmIrLinker.kt b/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmIrLinker.kt index c7c5ccf20cc..2519a36b8c8 100644 --- a/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmIrLinker.kt +++ b/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmIrLinker.kt @@ -43,8 +43,14 @@ class JvmIrLinker( private val enableIdSignatures: Boolean, ) : KotlinIrLinker(currentModule, messageLogger, typeSystem.irBuiltIns, symbolTable, emptyList(), partialLinkageEnabled = false) { - // TODO: provide friend modules - override val fakeOverrideBuilder = FakeOverrideBuilder(this, symbolTable, JvmIrMangler, typeSystem, emptyMap()) + override val fakeOverrideBuilder = FakeOverrideBuilder( + linker = this, + symbolTable = symbolTable, + mangler = JvmIrMangler, + typeSystem = typeSystem, + friendModules = emptyMap(), // TODO: provide friend modules + partialLinkageEnabled = false + ) private val javaName = Name.identifier("java") diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrlinker.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrlinker.kt index f4327797a3b..b3bcfdfd427 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrlinker.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrlinker.kt @@ -336,8 +336,16 @@ internal class KonanIrLinker( override fun isBuiltInModule(moduleDescriptor: ModuleDescriptor): Boolean = moduleDescriptor.isNativeStdlib() private val forwardDeclarationDeserializer = forwardModuleDescriptor?.let { KonanForwardDeclarationModuleDeserializer(it) } - override val fakeOverrideBuilder: FakeOverrideBuilder = - FakeOverrideBuilder(this, symbolTable, KonanManglerIr, IrTypeSystemContextImpl(builtIns), friendModules, KonanFakeOverrideClassFilter) + + override val fakeOverrideBuilder = FakeOverrideBuilder( + linker = this, + symbolTable = symbolTable, + mangler = KonanManglerIr, + typeSystem = IrTypeSystemContextImpl(builtIns), + friendModules = friendModules, + partialLinkageEnabled = partialLinkageSupport.partialLinkageEnabled, + platformSpecificClassFilter = KonanFakeOverrideClassFilter + ) val moduleDeserializers = mutableMapOf() val klibToModuleDeserializerMap = mutableMapOf()