From 81c06b24f7541c4fac506122db6af2f9ffb3a834 Mon Sep 17 00:00:00 2001 From: Alexander Gorshenev Date: Wed, 21 Oct 2020 22:40:52 +0300 Subject: [PATCH] [Private fake overrides] Private fake overrides linkage --- .../kotlin/psi2ir/Psi2IrTranslator.kt | 3 +- .../kotlin/ir/overrides/IrOverridingUtil.kt | 14 ++++-- .../backend/common/overrides/FakeOverrides.kt | 45 ++++++++++++------- .../serialization/IrModuleDeserializer.kt | 19 ++++++-- .../common/serialization/KotlinIrLinker.kt | 34 +++++++++++--- 5 files changed, 85 insertions(+), 30 deletions(-) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt index 37ad971ff13..db664015249 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt @@ -89,8 +89,7 @@ class Psi2IrTranslator( moduleGenerator.generateUnboundSymbolsAsDependencies(irProviders) deserializers.forEach { it.postProcess() } - val allUnbound = context.symbolTable.allUnbound - assert(allUnbound.isEmpty()) { "Unbound symbols not allowed\n${allUnbound.joinToString("\n\t", "\t")}" } + context.symbolTable.noUnboundLeft("Unbound symbols not allowed\n") postprocessingSteps.forEach { it.invoke(irModule) } // assert(context.symbolTable.allUnbound.isEmpty()) // TODO: fix IrPluginContext to make it not produce additional external reference 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 cdb66771cdd..410bc0479c5 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 @@ -51,8 +51,16 @@ abstract class FakeOverrideBuilderStrategy { return deepCopyFakeOverride } - // TODO: this one doesn't belong here. IrOverridingUtil shouldn't know about symbol table. - abstract fun linkFakeOverride(fakeOverride: IrOverridableMember) + fun linkFakeOverride(fakeOverride: IrOverridableMember) { + when (fakeOverride) { + is IrFakeOverrideFunction -> linkFunctionFakeOverride(fakeOverride) + is IrFakeOverrideProperty -> linkPropertyFakeOverride(fakeOverride) + else -> error("Unexpected fake override: $fakeOverride") + } + } + + protected abstract fun linkFunctionFakeOverride(declaration: IrFakeOverrideFunction) + protected abstract fun linkPropertyFakeOverride(declaration: IrFakeOverrideProperty) // TODO: need to make IrProperty carry overriddenSymbols. val propertyOverriddenSymbols: MutableMap> = mutableMapOf() @@ -390,8 +398,8 @@ class IrOverridingUtil( fakeOverride.overriddenSymbols.isNotEmpty() ) { "Overridden symbols should be set for " + CallableMemberDescriptor.Kind.FAKE_OVERRIDE } - fakeOverrideBuilder.linkFakeOverride(fakeOverride) addedFakeOverrides.add(fakeOverride) + fakeOverrideBuilder.linkFakeOverride(fakeOverride) } private fun isVisibilityMoreSpecific( 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 8f73089cc22..f957b3d44ea 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 @@ -72,6 +72,7 @@ object FakeOverrideControl { } class FakeOverrideBuilder( + val linker: FileLocalAwareLinker, val symbolTable: SymbolTable, val signaturer: IdSignatureSerializer, irBuiltIns: IrBuiltIns, @@ -108,23 +109,12 @@ class FakeOverrideBuilder( irOverridingUtil.buildFakeOverridesForClass(clazz) } - override fun linkFakeOverride(fakeOverride: IrOverridableMember) { - when (fakeOverride) { - is IrFakeOverrideFunction -> linkFunctionFakeOverride(fakeOverride) - is IrFakeOverrideProperty -> linkPropertyFakeOverride(fakeOverride) - else -> error("Unexpected fake override: $fakeOverride") - } + override fun linkFunctionFakeOverride(declaration: IrFakeOverrideFunction) { + val signature = composeSignature(declaration) + declareFunctionFakeOverride(declaration, signature) } - private fun linkFunctionFakeOverride(declaration: IrFakeOverrideFunction) { - val signature = signaturer.composePublicIdSignature(declaration) - - symbolTable.declareSimpleFunctionFromLinker(WrappedSimpleFunctionDescriptor(), signature) { - declaration.acquireSymbol(it) - } - } - - private fun linkPropertyFakeOverride(declaration: IrFakeOverrideProperty) { + override fun linkPropertyFakeOverride(declaration: IrFakeOverrideProperty) { // To compute a signature for a property with type parameters, // we must have its accessor's correspondingProperty pointing to the property's symbol. // See IrMangleComputer.mangleTypeParameterReference() for details. @@ -154,7 +144,30 @@ class FakeOverrideBuilder( } } - fun provideFakeOverrides(klass: IrClass) { + private fun composeSignature(declaration: IrDeclaration) = + signaturer.composeSignatureForDeclaration(declaration) + + private fun declareFunctionFakeOverride(declaration: IrFakeOverrideFunction, signature: IdSignature) { + val parent = declaration.parentAsClass + val symbol = linker.tryReferencingSimpleFunctionByLocalSignature(parent, signature) + val descriptor = symbol?.descriptor ?: WrappedSimpleFunctionDescriptor() + symbolTable.declareSimpleFunctionFromLinker(descriptor, signature) { + assert(it === symbol || symbol == null) + declaration.acquireSymbol(it) + } + } + + private fun declarePropertyFakeOverride(declaration: IrFakeOverrideProperty, signature: IdSignature) { + val parent = declaration.parentAsClass + val symbol = linker.tryReferencingPropertyByLocalSignature(parent, signature) + val descriptor = symbol?.descriptor ?: WrappedPropertyDescriptor() + symbolTable.declarePropertyFromLinker(descriptor, signature) { + assert(it === symbol || symbol == null) + declaration.acquireSymbol(it) + } + } + + private fun provideFakeOverrides(klass: IrClass) { buildFakeOverrideChainsForClass(klass) propertyOverriddenSymbols.clear() irOverridingUtil.clear() diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrModuleDeserializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrModuleDeserializer.kt index 5a562f3a091..44d3fe1f054 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrModuleDeserializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrModuleDeserializer.kt @@ -9,10 +9,7 @@ import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolD import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor import org.jetbrains.kotlin.builtins.functions.FunctionClassKind import org.jetbrains.kotlin.descriptors.ModuleDescriptor -import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithName -import org.jetbrains.kotlin.ir.declarations.IrModuleFragment -import org.jetbrains.kotlin.ir.declarations.IrProperty -import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner +import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.descriptors.IrAbstractFunctionFactory import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.descriptors.WrappedDeclarationDescriptor @@ -36,6 +33,12 @@ abstract class IrModuleDeserializer(val moduleDescriptor: ModuleDescriptor) { abstract operator fun contains(idSig: IdSignature): Boolean abstract fun deserializeIrSymbol(idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol + open fun referenceSimpleFunctionByLocalSignature(file: IrFile, idSignature: IdSignature) : IrSimpleFunctionSymbol = + error("Unsupported operation") + + open fun referencePropertyByLocalSignature(file: IrFile, idSignature: IdSignature): IrPropertySymbol = + error("Unsupported operation") + open fun declareIrSymbol(symbol: IrSymbol) { val signature = symbol.signature require(signature != null) { "Symbol is not public API: ${symbol.descriptor}" } @@ -47,6 +50,8 @@ abstract class IrModuleDeserializer(val moduleDescriptor: ModuleDescriptor) { open fun init() = init(this) + open fun postProcess() {} + open fun init(delegate: IrModuleDeserializer) {} open fun addModuleReachableTopLevel(idSig: IdSignature) { error("Unsupported Operation (sig: $idSig") } @@ -93,6 +98,12 @@ class IrModuleDeserializerWithBuiltIns( return checkIsFunctionInterface(idSig) || idSig in delegate } + override fun referenceSimpleFunctionByLocalSignature(file: IrFile, idSignature: IdSignature) : IrSimpleFunctionSymbol = + delegate.referenceSimpleFunctionByLocalSignature(file, idSignature) + + override fun referencePropertyByLocalSignature(file: IrFile, idSignature: IdSignature): IrPropertySymbol = + delegate.referencePropertyByLocalSignature(file, idSignature) + override fun deserializeReachableDeclarations() { delegate.deserializeReachableDeclarations() } 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 ebe20b7627c..69e2ee3ce8e 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 @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.backend.common.serialization import org.jetbrains.kotlin.backend.common.LoggingContext import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideBuilder +import org.jetbrains.kotlin.backend.common.overrides.FileLocalAwareLinker import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolData import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor @@ -14,7 +15,6 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.builders.TranslationPluginContext -import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrModuleFragment @@ -29,9 +29,7 @@ import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.impl.* import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.impl.IrErrorTypeImpl -import org.jetbrains.kotlin.ir.util.IdSignature -import org.jetbrains.kotlin.ir.util.NaiveSourceBasedFileEntryImpl -import org.jetbrains.kotlin.ir.util.SymbolTable +import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.library.IrLibrary import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.name.FqName @@ -56,7 +54,7 @@ abstract class KotlinIrLinker( val symbolTable: SymbolTable, private val exportedDependencies: List, private val deserializeFakeOverrides: Boolean -) : IrDeserializer { +) : IrDeserializer, FileLocalAwareLinker { // Kotlin-MPP related data. Consider some refactoring private val expectUniqIdToActualUniqId = mutableMapOf() @@ -129,6 +127,14 @@ abstract class KotlinIrLinker( fileToDeserializerMap.values.forEach { it.deserializeExpectActualMapping() } } + override fun referenceSimpleFunctionByLocalSignature(file: IrFile, idSignature: IdSignature) : IrSimpleFunctionSymbol = + fileToDeserializerMap[file]?.referenceSimpleFunctionByLocalSignature(idSignature) + ?: error("No deserializer for file $file in module ${moduleDescriptor.name}") + + override fun referencePropertyByLocalSignature(file: IrFile, idSignature: IdSignature): IrPropertySymbol = + fileToDeserializerMap[file]?.referencePropertyByLocalSignature(idSignature) + ?: error("No deserializer for file $file in module ${moduleDescriptor.name}") + // TODO: fix to topLevel checker override fun contains(idSig: IdSignature): Boolean = idSig in moduleReversedFileIndex @@ -374,6 +380,12 @@ abstract class KotlinIrLinker( } } + fun referenceSimpleFunctionByLocalSignature(idSignature: IdSignature) : IrSimpleFunctionSymbol = + deserializeIrSymbolData(idSignature, BinarySymbolData.SymbolKind.FUNCTION_SYMBOL) as IrSimpleFunctionSymbol + + fun referencePropertyByLocalSignature(idSignature: IdSignature): IrPropertySymbol = + deserializeIrSymbolData(idSignature, BinarySymbolData.SymbolKind.PROPERTY_SYMBOL) as IrPropertySymbol + private fun deserializeIrSymbolData(idSignature: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol { if (idSignature.isLocal) return deserializeIrLocalSymbolData(idSignature, symbolKind) @@ -591,6 +603,18 @@ abstract class KotlinIrLinker( return symbol.owner as IrDeclaration } + override fun tryReferencingSimpleFunctionByLocalSignature(parent: IrDeclaration, idSignature: IdSignature): IrSimpleFunctionSymbol? { + if (idSignature.isPublic) return null + return deserializersForModules[parent.file.packageFragmentDescriptor.containingDeclaration]?.referenceSimpleFunctionByLocalSignature(parent.file, idSignature) + ?: error("No module deserializer for ${parent.render()}") + } + + override fun tryReferencingPropertyByLocalSignature(parent: IrDeclaration, idSignature: IdSignature): IrPropertySymbol? { + if (idSignature.isPublic) return null + return deserializersForModules[parent.file.packageFragmentDescriptor.containingDeclaration]?.referencePropertyByLocalSignature(parent.file, idSignature) + ?: error("No module deserializer for ${parent.render()}") + } + protected open fun createCurrentModuleDeserializer(moduleFragment: IrModuleFragment, dependencies: Collection): IrModuleDeserializer = CurrentModuleDeserializer(moduleFragment, dependencies)