From ad5831acc668444411c06b22f47b1195c7347f45 Mon Sep 17 00:00:00 2001 From: Pavel Kunyavskiy Date: Mon, 16 Oct 2023 17:13:02 +0200 Subject: [PATCH] [IR] Add a method to get ModuleDescriptor from IrPackageFragment Ideally, instead of this method, there should be a link to IrModuleFragment. Unfortunately, it would require to big refactoring, as some of IrPackageFragment implementations doesn't have any IrModuleFragment inside, and are not located inside any IrModuleFragment. So for now, we just implement and use everywhere a single way of getting the module descriptor, which respects a IrModuleFragment link if it exists, and fallbacks to descriptor-based method if it doesn't. ^KT-62623 --- .../kotlin/ir/declarations/IrPackageFragment.kt | 10 ++++++++++ .../impl/IrExternalPackageFragmentImpl.kt | 4 ++++ .../kotlin/ir/declarations/impl/IrFileImpl.kt | 10 ++++++++++ .../ir/overrides/FakeOverrideBuilderStrategy.kt | 6 ++---- .../kotlin/ir/types/impl/IrErrorClassImpl.kt | 7 +++---- .../org/jetbrains/kotlin/ir/util/dumpKotlinLike.kt | 2 +- .../src/org/jetbrains/kotlin/ir/generator/IrTree.kt | 8 ++++++++ .../backend/common/serialization/KotlinIrLinker.kt | 4 ++-- .../jetbrains/kotlin/backend/konan/ir/NewIrUtils.kt | 2 +- .../jetbrains/kotlin/backend/konan/llvm/Imports.kt | 12 ++++-------- .../backend/konan/llvm/coverage/CoverageManager.kt | 3 +-- .../kotlin/backend/konan/lower/InteropLowering.kt | 2 +- .../kotlin/backend/konan/lower/TestProcessor.kt | 6 +----- .../backend/konan/serialization/KonanIrLinker.kt | 4 ++-- 14 files changed, 50 insertions(+), 30 deletions(-) diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrPackageFragment.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrPackageFragment.kt index 14e0ea6b818..6097b679291 100644 --- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrPackageFragment.kt +++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrPackageFragment.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.ir.declarations +import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor import org.jetbrains.kotlin.ir.IrElementBase import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI @@ -25,6 +26,15 @@ abstract class IrPackageFragment : IrElementBase(), IrDeclarationContainer, IrSy @ObsoleteDescriptorBasedAPI abstract val packageFragmentDescriptor: PackageFragmentDescriptor + /** + * This should be a link to [IrModuleFragment] instead. + * + * Unfortunately, some package fragments (e.g. some synthetic ones and + * [IrExternalPackageFragment]) + * are not located in any IR module, but still have a module descriptor. + */ + abstract val moduleDescriptor: ModuleDescriptor + abstract var packageFqName: FqName @Deprecated( diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrExternalPackageFragmentImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrExternalPackageFragmentImpl.kt index 700b7611ab0..a41392766fc 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrExternalPackageFragmentImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrExternalPackageFragmentImpl.kt @@ -47,6 +47,10 @@ class IrExternalPackageFragmentImpl( override val packageFragmentDescriptor: PackageFragmentDescriptor get() = symbol.descriptor + @OptIn(ObsoleteDescriptorBasedAPI::class) + override val moduleDescriptor: ModuleDescriptor + get() = packageFragmentDescriptor.containingDeclaration + override val declarations: MutableList = ArrayList() @OptIn(ObsoleteDescriptorBasedAPI::class) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrFileImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrFileImpl.kt index 552458dd328..93efec29c50 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrFileImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrFileImpl.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.ir.declarations.impl +import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor import org.jetbrains.kotlin.ir.IrFileEntry import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI @@ -69,6 +70,15 @@ class IrFileImpl( override val packageFragmentDescriptor: PackageFragmentDescriptor get() = symbol.descriptor + @OptIn(ObsoleteDescriptorBasedAPI::class) + override val moduleDescriptor: ModuleDescriptor + get() { + return if (this::module.isInitialized) + module.descriptor + else + packageFragmentDescriptor.containingDeclaration + } + override val declarations: MutableList = ArrayList() override var annotations: List = emptyList() diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/FakeOverrideBuilderStrategy.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/FakeOverrideBuilderStrategy.kt index 0da2b0fa495..7b2a9e33417 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/FakeOverrideBuilderStrategy.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/FakeOverrideBuilderStrategy.kt @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.ir.overrides import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.ModuleDescriptor -import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol @@ -94,14 +93,13 @@ abstract class FakeOverrideBuilderStrategy( protected abstract fun linkPropertyFakeOverride(property: IrPropertyWithLateBinding, manglerCompatibleMode: Boolean) } -@OptIn(ObsoleteDescriptorBasedAPI::class) // Because of the LazyIR, have to use descriptors here. private fun IrOverridableMember.isPrivateToThisModule( thisClass: IrClass, memberClass: IrClass, friendModules: Map>, ): Boolean { if (visibility != DescriptorVisibilities.INTERNAL) return false - val thisModule = thisClass.getPackageFragment().packageFragmentDescriptor.containingDeclaration - val memberModule = memberClass.getPackageFragment().packageFragmentDescriptor.containingDeclaration + val thisModule = thisClass.getPackageFragment().moduleDescriptor + val memberModule = memberClass.getPackageFragment().moduleDescriptor return thisModule != memberModule && !isInFriendModules(thisModule, memberModule, friendModules) } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrErrorClassImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrErrorClassImpl.kt index 3f56e4bf2cf..f06a39038c2 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrErrorClassImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrErrorClassImpl.kt @@ -5,10 +5,7 @@ package org.jetbrains.kotlin.ir.types.impl -import org.jetbrains.kotlin.descriptors.ClassKind -import org.jetbrains.kotlin.descriptors.DescriptorVisibilities -import org.jetbrains.kotlin.descriptors.Modality -import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor +import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.IrFileEntry import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET @@ -50,6 +47,8 @@ object IrErrorClassImpl : IrClassImpl( @ObsoleteDescriptorBasedAPI override val packageFragmentDescriptor: PackageFragmentDescriptor get() = TODO("Not yet implemented") + override val moduleDescriptor: ModuleDescriptor + get() = TODO("Not yet implemented") override var packageFqName: FqName get() = FqName.ROOT set(_) = TODO("Not yet implemented") diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/dumpKotlinLike.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/dumpKotlinLike.kt index a4b0b4dda3c..0c00bfb6727 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/dumpKotlinLike.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/dumpKotlinLike.kt @@ -263,7 +263,7 @@ private class KotlinLikeDumper(val p: Printer, val options: KotlinLikeDumpOption if (options.printFileName) p.println("// FILE: ${declaration.name}") if (options.printFilePath) p.println("// path: ${declaration.path}") declaration.printlnAnnotations("file") - val packageFqName = declaration.packageFragmentDescriptor.fqName + val packageFqName = declaration.packageFqName if (!packageFqName.isRoot) { p.println("package ${packageFqName.asString()}") } diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/IrTree.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/IrTree.kt index ed50bae9cd4..16fa63991b9 100644 --- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/IrTree.kt +++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/IrTree.kt @@ -618,6 +618,14 @@ object IrTree : AbstractTreeBuilder() { +symbol(packageFragmentSymbolType) +field("packageFragmentDescriptor", type(Packages.descriptors, "PackageFragmentDescriptor"), mutable = false) + +field("moduleDescriptor", type(Packages.descriptors, "ModuleDescriptor"), mutable = false) { + kdoc = """ + This should be a link to [IrModuleFragment] instead. + + Unfortunately, some package fragments (e.g. some synthetic ones and [IrExternalPackageFragment]) + are not located in any IR module, but still have a module descriptor. + """.trimIndent() + } +field("packageFqName", type()) +field("fqName", type()) { baseGetter = code("packageFqName") 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 9d28034ab96..0d9cd386acb 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 @@ -181,14 +181,14 @@ abstract class KotlinIrLinker( override fun tryReferencingSimpleFunctionByLocalSignature(parent: IrDeclaration, idSignature: IdSignature): IrSimpleFunctionSymbol? { if (idSignature.isPubliclyVisible) return null val file = getFileOf(parent) - val moduleDescriptor = file.packageFragmentDescriptor.containingDeclaration + val moduleDescriptor = file.moduleDescriptor return resolveModuleDeserializer(moduleDescriptor, null).referenceSimpleFunctionByLocalSignature(file, idSignature) } override fun tryReferencingPropertyByLocalSignature(parent: IrDeclaration, idSignature: IdSignature): IrPropertySymbol? { if (idSignature.isPubliclyVisible) return null val file = getFileOf(parent) - val moduleDescriptor = file.packageFragmentDescriptor.containingDeclaration + val moduleDescriptor = file.moduleDescriptor return resolveModuleDeserializer(moduleDescriptor, null).referencePropertyByLocalSignature(file, idSignature) } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/NewIrUtils.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/NewIrUtils.kt index 490e9046f60..f394e946d6d 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/NewIrUtils.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/NewIrUtils.kt @@ -90,7 +90,7 @@ val IrPackageFragment.konanLibrary: KotlinLibrary? val moduleDescriptor = fileMetadata?.descriptors?.singleOrNull() as? ModuleDescriptor moduleDescriptor?.konanLibrary?.let { return it } } - return this.packageFragmentDescriptor.containingDeclaration.konanLibrary + return this.moduleDescriptor.konanLibrary } // Any changes made to konanLibrary here should be ported to the containsDeclaration // function in LlvmModuleSpecificationBase in LlvmModuleSpecificationImpl.kt diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/Imports.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/Imports.kt index 58a6b856afb..b59df988c20 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/Imports.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/Imports.kt @@ -7,20 +7,17 @@ package org.jetbrains.kotlin.backend.konan.llvm import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.descriptors.isExpectMember -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI +import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.ir.declarations.IrPackageFragment import org.jetbrains.kotlin.library.metadata.CompiledKlibModuleOrigin import org.jetbrains.kotlin.library.metadata.SyntheticModulesOrigin import org.jetbrains.kotlin.library.metadata.klibModuleOrigin -import org.jetbrains.kotlin.resolve.descriptorUtil.module -internal val DeclarationDescriptor.llvmSymbolOrigin: CompiledKlibModuleOrigin +private val ModuleDescriptor.llvmSymbolOrigin: CompiledKlibModuleOrigin get() { assert(!this.isExpectMember) { this } - val module = this.module - val moduleOrigin = module.klibModuleOrigin + val moduleOrigin = klibModuleOrigin when (moduleOrigin) { is CompiledKlibModuleOrigin -> return moduleOrigin SyntheticModulesOrigin -> error("Declaration is synthetic and can't be an origin of LLVM symbol:\n${this}") @@ -29,6 +26,5 @@ internal val DeclarationDescriptor.llvmSymbolOrigin: CompiledKlibModuleOrigin internal val Context.standardLlvmSymbolsOrigin: CompiledKlibModuleOrigin get() = this.stdlibModule.llvmSymbolOrigin -@OptIn(ObsoleteDescriptorBasedAPI::class) internal val IrPackageFragment.llvmSymbolOrigin - get() = packageFragmentDescriptor.llvmSymbolOrigin \ No newline at end of file + get() = moduleDescriptor.llvmSymbolOrigin \ No newline at end of file diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/CoverageManager.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/CoverageManager.kt index 9f9e90d2b4d..6b7887e9632 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/CoverageManager.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/CoverageManager.kt @@ -15,7 +15,6 @@ import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.target.supportsCodeCoverage -import org.jetbrains.kotlin.resolve.descriptorUtil.module /** * "Umbrella" class of all the of the code coverage related logic. @@ -75,7 +74,7 @@ internal class CoverageManager(val generationState: NativeGenerationState) { @OptIn(ObsoleteDescriptorBasedAPI::class) private fun fileCoverageFilter(file: IrFile) = - file.packageFragmentDescriptor.module in coveredModules + file.moduleDescriptor in coveredModules /** * Walk [irModuleFragment] subtree and collect [FileRegionInfo] for files that are part of [coveredModules]. diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InteropLowering.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InteropLowering.kt index a2515a9a61a..637d47f1b49 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InteropLowering.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InteropLowering.kt @@ -80,7 +80,7 @@ private abstract class BaseInteropIrTransformer( builder.getCompilerMessageLocation() } - val uniqueModuleName = irFile.packageFragmentDescriptor.module.name.asString() + val uniqueModuleName = irFile.moduleDescriptor.name.asString() .let { it.substring(1, it.lastIndex) } val uniqueFileName = irFile.fileEntry.name val uniquePrefix = buildString { diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/TestProcessor.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/TestProcessor.kt index 3de7c8af537..badae71419e 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/TestProcessor.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/TestProcessor.kt @@ -11,7 +11,6 @@ import org.jetbrains.kotlin.backend.common.reportWarning import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.descriptors.isAbstract import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName -import org.jetbrains.kotlin.backend.konan.getIncludedLibraryDescriptors import org.jetbrains.kotlin.backend.konan.ir.buildSimpleAnnotation import org.jetbrains.kotlin.backend.konan.reportCompilationError import org.jetbrains.kotlin.descriptors.ClassKind @@ -19,10 +18,8 @@ import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement -import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.builders.declarations.buildField -import org.jetbrains.kotlin.ir.builders.declarations.buildFun import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl @@ -679,8 +676,7 @@ internal class TestProcessor (val context: Context) { } // endregion - @OptIn(ObsoleteDescriptorBasedAPI::class) - private fun shouldProcessFile(irFile: IrFile): Boolean = irFile.packageFragmentDescriptor.module.let { + private fun shouldProcessFile(irFile: IrFile): Boolean = irFile.moduleDescriptor.let { // Process test annotations in source libraries too. it in context.sourcesModules } 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 e1726eccb13..ed347c6b5ab 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 @@ -332,7 +332,7 @@ internal class KonanIrLinker( fun getCachedDeclarationModuleDeserializer(declaration: IrDeclaration): KonanPartialModuleDeserializer? { val packageFragment = declaration.getPackageFragment() - val moduleDescriptor = packageFragment.packageFragmentDescriptor.containingDeclaration + val moduleDescriptor = packageFragment.moduleDescriptor val klib = packageFragment.konanLibrary val declarationBeingCached = packageFragment is IrFile && klib != null && libraryBeingCached?.klib == klib && libraryBeingCached.strategy.contains(packageFragment.path) @@ -394,7 +394,7 @@ internal class KonanIrLinker( is IrFile -> packageFragment.path is IrExternalPackageFragment -> { - val moduleDescriptor = packageFragment.packageFragmentDescriptor.containingDeclaration + val moduleDescriptor = packageFragment.moduleDescriptor val moduleDeserializer = moduleDeserializers[moduleDescriptor] ?: error("No module deserializer for $moduleDescriptor") moduleDeserializer.getFileNameOf(declaration) }