diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/extensions/IrPluginContext.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/extensions/IrPluginContext.kt index 858c8b57d38..633580fe3f6 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/extensions/IrPluginContext.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/extensions/IrPluginContext.kt @@ -10,7 +10,9 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.builders.IrGeneratorContext +import org.jetbrains.kotlin.ir.linkage.IrDeserializer import org.jetbrains.kotlin.ir.symbols.* +import org.jetbrains.kotlin.ir.util.IdSignature import org.jetbrains.kotlin.ir.util.IrMessageLogger import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable import org.jetbrains.kotlin.ir.util.TypeTranslator @@ -51,4 +53,7 @@ interface IrPluginContext : IrGeneratorContext { fun referenceConstructors(classFqn: FqName): Collection fun referenceFunctions(fqName: FqName): Collection fun referenceProperties(fqName: FqName): Collection + + // temporary solution to load synthetic top-level declaration + fun referenceTopLevel(signature: IdSignature, kind: IrDeserializer.TopLevelSymbolKind, moduleDescriptor: ModuleDescriptor): IrSymbol? } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/extensions/IrPluginContextImpl.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/extensions/IrPluginContextImpl.kt index bf8da2ef0ba..7de0210fbff 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/extensions/IrPluginContextImpl.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/extensions/IrPluginContextImpl.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.ir.declarations.IrConstructor import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.linkage.IrDeserializer import org.jetbrains.kotlin.ir.symbols.* +import org.jetbrains.kotlin.ir.util.IdSignature import org.jetbrains.kotlin.ir.util.IrMessageLogger import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable import org.jetbrains.kotlin.ir.util.TypeTranslator @@ -134,4 +135,14 @@ open class IrPluginContextImpl constructor( descriptors.map { st.referenceProperty(it) } } } + + override fun referenceTopLevel( + signature: IdSignature, + kind: IrDeserializer.TopLevelSymbolKind, + moduleDescriptor: ModuleDescriptor + ): IrSymbol? { + val symbol = linker.resolveBySignatureInModule(signature, kind, moduleDescriptor.name) + linker.postProcess() + return symbol + } } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/linkage/IrDeserializer.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/linkage/IrDeserializer.kt index c6a4407ef6b..015911d9dc8 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/linkage/IrDeserializer.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/linkage/IrDeserializer.kt @@ -9,6 +9,8 @@ import org.jetbrains.kotlin.ir.builders.TranslationPluginContext import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.symbols.IrSymbol +import org.jetbrains.kotlin.ir.util.IdSignature +import org.jetbrains.kotlin.name.Name interface IrDeserializer : IrProvider { @@ -16,6 +18,14 @@ interface IrDeserializer : IrProvider { fun resolveSymbol(symbol: IrSymbol, context: TranslationPluginContext): IrDeclaration? = null } + enum class TopLevelSymbolKind { + FUNCTION_SYMBOL, + CLASS_SYMBOL, + PROPERTY_SYMBOL, + TYPEALIAS_SYMBOL; + } + fun init(moduleFragment: IrModuleFragment?, extensions: Collection) {} + fun resolveBySignatureInModule(signature: IdSignature, kind: TopLevelSymbolKind, moduleName: Name): IrSymbol fun postProcess() {} } 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 432fd54ea8c..177775d8b70 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 @@ -34,6 +34,7 @@ import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.library.IrLibrary import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.protobuf.CodedInputStream import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite.newInstance import org.jetbrains.kotlin.resolve.descriptorUtil.module @@ -64,6 +65,7 @@ abstract class KotlinIrLinker( private val modulesWithReachableTopLevels = mutableSetOf() + // TODO: replace with Map protected val deserializersForModules = mutableMapOf() abstract val fakeOverrideBuilder: FakeOverrideBuilder @@ -665,6 +667,23 @@ abstract class KotlinIrLinker( // symbolTable.noUnboundLeft("unbound after fake overrides:") } + private fun topLevelKindToSymbolKind(kind: IrDeserializer.TopLevelSymbolKind): BinarySymbolData.SymbolKind { + return when (kind) { + IrDeserializer.TopLevelSymbolKind.CLASS_SYMBOL -> BinarySymbolData.SymbolKind.CLASS_SYMBOL + IrDeserializer.TopLevelSymbolKind.PROPERTY_SYMBOL -> BinarySymbolData.SymbolKind.PROPERTY_SYMBOL + IrDeserializer.TopLevelSymbolKind.FUNCTION_SYMBOL -> BinarySymbolData.SymbolKind.FUNCTION_SYMBOL + IrDeserializer.TopLevelSymbolKind.TYPEALIAS_SYMBOL -> BinarySymbolData.SymbolKind.TYPEALIAS_SYMBOL + } + } + + override fun resolveBySignatureInModule(signature: IdSignature, kind: IrDeserializer.TopLevelSymbolKind, moduleName: Name): IrSymbol { + val moduleDeserializer = + deserializersForModules.entries.find { it.key.name == moduleName }?.value ?: error("No module for name '$moduleName' found") + assert(signature == signature.topLevelSignature()) { "Signature '$signature' has to be top level" } + if (signature !in moduleDeserializer) error("No signature $signature in module $moduleName") + return moduleDeserializer.deserializeIrSymbol(signature, topLevelKindToSymbolKind(kind)) + } + // The issue here is that an expect can not trigger its actual deserialization by reachability // because the expect can not see the actual higher in the module dependency dag. // So we force deserialization of actuals for all deserialized expect symbols here.