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 7f4fd58a8c2..cdb66771cdd 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 @@ -101,26 +101,16 @@ class IrOverridingUtil( } } - // We need to get Any's members if all the parents are private. - private fun allPublicApiSuperTypesOrAny(clazz: IrClass): List { - val superTypes = clazz.superTypes - val superClasses = superTypes.map { it.getClass() ?: error("Unexpected super type: $it") } - return if (superClasses.isEmpty() || superClasses.any { it.symbol.isPublicApi }) - superTypes - else - listOf(irBuiltIns.anyType) - } - fun buildFakeOverridesForClass(clazz: IrClass) { - val superTypes = allPublicApiSuperTypesOrAny(clazz) + val superTypes = clazz.superTypes @Suppress("UNCHECKED_CAST") - val fromCurrent = clazz.declarations.filter { it is IrOverridableMember && it.symbol.isPublicApi } as List + val fromCurrent = clazz.declarations.filter { it is IrOverridableMember } as List val allFromSuper = superTypes.flatMap { superType -> val superClass = superType.getClass() ?: error("Unexpected super type: $superType") superClass.declarations - .filter { it is IrOverridableMember && it.symbol.isPublicApi } + .filter { it.isOverridableMemberOrAccessor() } .map { val overridenMember = it as IrOverridableMember val fakeOverride = fakeOverrideBuilder.fakeOverrideMember(superType, overridenMember, clazz) diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/overrides/FakeOverrideChecker.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/overrides/FakeOverrideChecker.kt index 3cca086b0ea..a96546e90bc 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/overrides/FakeOverrideChecker.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/overrides/FakeOverrideChecker.kt @@ -76,9 +76,6 @@ class FakeOverrideChecker( validateFakeOverrides(declaration) super.visitClass(declaration) } - override fun visitFunction(declaration: IrFunction) { - // Don't go for function local classes - } }) } } 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 1cdfa73af65..8f73089cc22 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 @@ -23,20 +23,13 @@ import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.descriptors.WrappedPropertyDescriptor import org.jetbrains.kotlin.ir.descriptors.WrappedSimpleFunctionDescriptor -import org.jetbrains.kotlin.ir.overrides.DeepCopyIrTreeWithSymbolsForFakeOverrides import org.jetbrains.kotlin.ir.overrides.FakeOverrideBuilderStrategy import org.jetbrains.kotlin.ir.overrides.IrOverridingUtil -import org.jetbrains.kotlin.ir.symbols.IrClassSymbol -import org.jetbrains.kotlin.ir.symbols.IrSymbol -import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol +import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol +import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.symbols.impl.IrPropertySymbolImpl -import org.jetbrains.kotlin.ir.types.IrSimpleType -import org.jetbrains.kotlin.ir.types.IrType -import org.jetbrains.kotlin.ir.types.IrTypeProjection -import org.jetbrains.kotlin.ir.types.extractTypeParameters import org.jetbrains.kotlin.ir.types.getClass -import org.jetbrains.kotlin.ir.util.SymbolTable -import org.jetbrains.kotlin.types.Variance +import org.jetbrains.kotlin.ir.util.* class FakeOverrideGlobalDeclarationTable(signatureSerializer: IdSignatureSerializer) : GlobalDeclarationTable(signatureSerializer, signatureSerializer.mangler) { @@ -54,7 +47,18 @@ class FakeOverrideDeclarationTable( } } -object DefaultFakeOverrideClassFilter : PlatformFakeOverrideClassFilter +interface FakeOverrideClassFilter { + fun needToConstructFakeOverrides(clazz: IrClass): Boolean +} + +interface FileLocalAwareLinker { + fun tryReferencingSimpleFunctionByLocalSignature(parent: IrDeclaration, idSignature: IdSignature): IrSimpleFunctionSymbol? + fun tryReferencingPropertyByLocalSignature(parent: IrDeclaration, idSignature: IdSignature): IrPropertySymbol? +} + +object DefaultFakeOverrideClassFilter : FakeOverrideClassFilter { + override fun needToConstructFakeOverrides(clazz: IrClass): Boolean = true +} object FakeOverrideControl { // If set to true: all fake overrides go to klib serialized IR. @@ -70,15 +74,25 @@ object FakeOverrideControl { class FakeOverrideBuilder( val symbolTable: SymbolTable, val signaturer: IdSignatureSerializer, - val irBuiltIns: IrBuiltIns, - val platformSpecificClassFilter: PlatformFakeOverrideClassFilter = DefaultFakeOverrideClassFilter + irBuiltIns: IrBuiltIns, + val platformSpecificClassFilter: FakeOverrideClassFilter = DefaultFakeOverrideClassFilter ) : FakeOverrideBuilderStrategy() { private val haveFakeOverrides = mutableSetOf() + private val irOverridingUtil = IrOverridingUtil(irBuiltIns, this) - fun buildFakeOverrideChainsForClass(clazz: IrClass) { + // TODO: The declaration table is needed for the signaturer. + private val fakeOverrideDeclarationTable = FakeOverrideDeclarationTable(signaturer) + + private val fakeOverrideClassQueue = mutableListOf() + fun enqueueClass(clazz: IrClass, signature: IdSignature) { + fakeOverrideDeclarationTable.assumeDeclarationSignature(clazz, signature) + fakeOverrideClassQueue.add(clazz) + } + + private fun buildFakeOverrideChainsForClass(clazz: IrClass) { if (haveFakeOverrides.contains(clazz)) return - if (!platformSpecificClassFilter.constructFakeOverrides(clazz) || !clazz.symbol.isPublicApi) return + if (!platformSpecificClassFilter.needToConstructFakeOverrides(clazz)) return val superTypes = clazz.superTypes @@ -127,11 +141,8 @@ class FakeOverrideBuilder( it.correspondingPropertySymbol = tempSymbol } - val signature = signaturer.composePublicIdSignature(declaration) - - symbolTable.declarePropertyFromLinker(WrappedPropertyDescriptor(), signature) { - declaration.acquireSymbol(it) - } + val signature = composeSignature(declaration) + declarePropertyFakeOverride(declaration, signature) declaration.getter?.let { it.correspondingPropertySymbol = declaration.symbol @@ -149,4 +160,11 @@ class FakeOverrideBuilder( irOverridingUtil.clear() haveFakeOverrides.add(klass) } + + fun provideFakeOverrides() { + while (fakeOverrideClassQueue.isNotEmpty()) { + val klass = fakeOverrideClassQueue.removeLast() + provideFakeOverrides(klass) + } + } } diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt index 68a4787b9bd..522956c5f07 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt @@ -8,7 +8,8 @@ package org.jetbrains.kotlin.backend.common.serialization import org.jetbrains.kotlin.backend.common.LoggingContext import org.jetbrains.kotlin.backend.common.ir.ir2string import org.jetbrains.kotlin.backend.common.lower.InnerClassesSupport -import org.jetbrains.kotlin.backend.common.overrides.PlatformFakeOverrideClassFilter +import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideBuilder +import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideClassFilter import org.jetbrains.kotlin.backend.common.peek import org.jetbrains.kotlin.backend.common.pop import org.jetbrains.kotlin.backend.common.push @@ -114,7 +115,7 @@ abstract class IrFileDeserializer( val symbolTable: SymbolTable, protected var deserializeBodies: Boolean, private val deserializeFakeOverrides: Boolean, - private val fakeOverrideQueue: MutableList, + private val fakeOverrideBuilder: FakeOverrideBuilder, private val allowErrorNodes: Boolean ) { protected val irFactory: IrFactory get() = symbolTable.irFactory @@ -134,7 +135,7 @@ abstract class IrFileDeserializer( private val delegatedSymbolMap = mutableMapOf() abstract val deserializeInlineFunctions: Boolean - abstract val platformFakeOverrideClassFilter: PlatformFakeOverrideClassFilter + abstract val platformFakeOverrideClassFilter: FakeOverrideClassFilter fun deserializeFqName(fqn: List): String = fqn.joinToString(".", transform = ::deserializeString) @@ -1088,11 +1089,7 @@ abstract class IrFileDeserializer( (descriptor as? WrappedClassDescriptor)?.bind(this) - if (!deserializeFakeOverrides) { - if (symbol.isPublicApi) { - fakeOverrideQueue.add(this) - } - } + fakeOverrideBuilder.enqueueClass(this, signature) } } @@ -1470,7 +1467,7 @@ abstract class IrFileDeserializer( // or reconstruct them after IR linker completes. private fun isSkippableFakeOverride(proto: ProtoDeclaration, parent: IrClass): Boolean { if (deserializeFakeOverrides) return false - if (!platformFakeOverrideClassFilter.constructFakeOverrides(parent)) return false + if (!platformFakeOverrideClassFilter.needToConstructFakeOverrides(parent)) return false val symbol = when (proto.declaratorCase!!) { IR_FUNCTION -> deserializeIrSymbol(proto.irFunction.base.base.symbol) diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt index 6eee813b7eb..9d43c48d29f 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt @@ -1245,9 +1245,8 @@ open class IrFileSerializer( assert(member.parent is IrClass) if (FakeOverrideControl.serializeFakeOverrides) return true if (backendSpecificSerializeAllMembers(member.parent as IrClass)) return true - // TODO: we can, probably, maintain a privacy bit while traversing the tree - // instead of running the parent hierarchy for isExported every time. - return !(member.isFakeOverride && declarationTable.isExportedDeclaration(member)) + + return (!member.isFakeOverride) } private fun fillPlatformExplicitlyExported(file: IrFile, proto: ProtoFile.Builder) { diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt index 5e7f339740a..ebe20b7627c 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt @@ -73,7 +73,6 @@ abstract class KotlinIrLinker( abstract val translationPluginContext: TranslationPluginContext? private val haveSeen = mutableSetOf() - private val fakeOverrideClassQueue = mutableListOf() private lateinit var linkerExtensions: Collection @@ -234,7 +233,17 @@ abstract class KotlinIrLinker( deserializeFakeOverrides: Boolean, private val moduleDeserializer: IrModuleDeserializer, allowErrorNodes: Boolean - ) : IrFileDeserializer(logger, builtIns, symbolTable, !onlyHeaders, deserializeFakeOverrides, fakeOverrideClassQueue, allowErrorNodes) { + ) : + IrFileDeserializer( + logger, + builtIns, + symbolTable, + !onlyHeaders, + deserializeFakeOverrides, + fakeOverrideBuilder, + allowErrorNodes + ) + { private var fileLoops = mutableMapOf() @@ -600,12 +609,7 @@ abstract class KotlinIrLinker( override fun postProcess() { finalizeExpectActualLinker() - - while (fakeOverrideClassQueue.isNotEmpty()) { - val klass = fakeOverrideClassQueue.removeLast() - fakeOverrideBuilder.provideFakeOverrides(klass) - } - + fakeOverrideBuilder.provideFakeOverrides() haveSeen.clear() // TODO: fix IrPluginContext to make it not produce additional external reference 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 b939637c93b..916668a80c4 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 @@ -31,7 +31,7 @@ class JsIrLinker( deserializeFakeOverrides: Boolean = FakeOverrideControl.deserializeFakeOverrides ) : KotlinIrLinker(currentModule, logger, builtIns, symbolTable, emptyList(), deserializeFakeOverrides) { - override val fakeOverrideBuilder = FakeOverrideBuilder(symbolTable, IdSignatureSerializer(JsManglerIr), builtIns) + override val fakeOverrideBuilder = FakeOverrideBuilder(this, symbolTable, IdSignatureSerializer(JsManglerIr), builtIns) override fun isBuiltInModule(moduleDescriptor: ModuleDescriptor): Boolean = moduleDescriptor === moduleDescriptor.builtIns.builtInsModule 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 8a7de99cea7..57d823faefd 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 @@ -44,7 +44,7 @@ class JvmIrLinker( deserializeFakeOverrides: Boolean = FakeOverrideControl.deserializeFakeOverrides ) : KotlinIrLinker(currentModule, logger, builtIns, symbolTable, emptyList(), deserializeFakeOverrides) { - override val fakeOverrideBuilder = FakeOverrideBuilder(symbolTable, IdSignatureSerializer(JvmManglerIr), builtIns) + override val fakeOverrideBuilder = FakeOverrideBuilder(this, symbolTable, IdSignatureSerializer(JvmManglerIr), builtIns) private val javaName = Name.identifier("java")