[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
This commit is contained in:
Pavel Kunyavskiy
2023-10-16 17:13:02 +02:00
committed by Space Team
parent 9b9ddb760a
commit ad5831acc6
14 changed files with 50 additions and 30 deletions
@@ -8,6 +8,7 @@
package org.jetbrains.kotlin.ir.declarations package org.jetbrains.kotlin.ir.declarations
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.ir.IrElementBase import org.jetbrains.kotlin.ir.IrElementBase
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
@@ -25,6 +26,15 @@ abstract class IrPackageFragment : IrElementBase(), IrDeclarationContainer, IrSy
@ObsoleteDescriptorBasedAPI @ObsoleteDescriptorBasedAPI
abstract val packageFragmentDescriptor: PackageFragmentDescriptor 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 abstract var packageFqName: FqName
@Deprecated( @Deprecated(
@@ -47,6 +47,10 @@ class IrExternalPackageFragmentImpl(
override val packageFragmentDescriptor: PackageFragmentDescriptor override val packageFragmentDescriptor: PackageFragmentDescriptor
get() = symbol.descriptor get() = symbol.descriptor
@OptIn(ObsoleteDescriptorBasedAPI::class)
override val moduleDescriptor: ModuleDescriptor
get() = packageFragmentDescriptor.containingDeclaration
override val declarations: MutableList<IrDeclaration> = ArrayList() override val declarations: MutableList<IrDeclaration> = ArrayList()
@OptIn(ObsoleteDescriptorBasedAPI::class) @OptIn(ObsoleteDescriptorBasedAPI::class)
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.ir.declarations.impl package org.jetbrains.kotlin.ir.declarations.impl
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.ir.IrFileEntry import org.jetbrains.kotlin.ir.IrFileEntry
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
@@ -69,6 +70,15 @@ class IrFileImpl(
override val packageFragmentDescriptor: PackageFragmentDescriptor override val packageFragmentDescriptor: PackageFragmentDescriptor
get() = symbol.descriptor 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<IrDeclaration> = ArrayList() override val declarations: MutableList<IrDeclaration> = ArrayList()
override var annotations: List<IrConstructorCall> = emptyList() override var annotations: List<IrConstructorCall> = emptyList()
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.ir.overrides
import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
@@ -94,14 +93,13 @@ abstract class FakeOverrideBuilderStrategy(
protected abstract fun linkPropertyFakeOverride(property: IrPropertyWithLateBinding, manglerCompatibleMode: Boolean) protected abstract fun linkPropertyFakeOverride(property: IrPropertyWithLateBinding, manglerCompatibleMode: Boolean)
} }
@OptIn(ObsoleteDescriptorBasedAPI::class) // Because of the LazyIR, have to use descriptors here.
private fun IrOverridableMember.isPrivateToThisModule( private fun IrOverridableMember.isPrivateToThisModule(
thisClass: IrClass, memberClass: IrClass, friendModules: Map<String, Collection<String>>, thisClass: IrClass, memberClass: IrClass, friendModules: Map<String, Collection<String>>,
): Boolean { ): Boolean {
if (visibility != DescriptorVisibilities.INTERNAL) return false if (visibility != DescriptorVisibilities.INTERNAL) return false
val thisModule = thisClass.getPackageFragment().packageFragmentDescriptor.containingDeclaration val thisModule = thisClass.getPackageFragment().moduleDescriptor
val memberModule = memberClass.getPackageFragment().packageFragmentDescriptor.containingDeclaration val memberModule = memberClass.getPackageFragment().moduleDescriptor
return thisModule != memberModule && !isInFriendModules(thisModule, memberModule, friendModules) return thisModule != memberModule && !isInFriendModules(thisModule, memberModule, friendModules)
} }
@@ -5,10 +5,7 @@
package org.jetbrains.kotlin.ir.types.impl package org.jetbrains.kotlin.ir.types.impl
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.ir.IrFileEntry import org.jetbrains.kotlin.ir.IrFileEntry
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
@@ -50,6 +47,8 @@ object IrErrorClassImpl : IrClassImpl(
@ObsoleteDescriptorBasedAPI @ObsoleteDescriptorBasedAPI
override val packageFragmentDescriptor: PackageFragmentDescriptor override val packageFragmentDescriptor: PackageFragmentDescriptor
get() = TODO("Not yet implemented") get() = TODO("Not yet implemented")
override val moduleDescriptor: ModuleDescriptor
get() = TODO("Not yet implemented")
override var packageFqName: FqName override var packageFqName: FqName
get() = FqName.ROOT get() = FqName.ROOT
set(_) = TODO("Not yet implemented") set(_) = TODO("Not yet implemented")
@@ -263,7 +263,7 @@ private class KotlinLikeDumper(val p: Printer, val options: KotlinLikeDumpOption
if (options.printFileName) p.println("// FILE: ${declaration.name}") if (options.printFileName) p.println("// FILE: ${declaration.name}")
if (options.printFilePath) p.println("// path: ${declaration.path}") if (options.printFilePath) p.println("// path: ${declaration.path}")
declaration.printlnAnnotations("file") declaration.printlnAnnotations("file")
val packageFqName = declaration.packageFragmentDescriptor.fqName val packageFqName = declaration.packageFqName
if (!packageFqName.isRoot) { if (!packageFqName.isRoot) {
p.println("package ${packageFqName.asString()}") p.println("package ${packageFqName.asString()}")
} }
@@ -618,6 +618,14 @@ object IrTree : AbstractTreeBuilder() {
+symbol(packageFragmentSymbolType) +symbol(packageFragmentSymbolType)
+field("packageFragmentDescriptor", type(Packages.descriptors, "PackageFragmentDescriptor"), mutable = false) +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<FqName>()) +field("packageFqName", type<FqName>())
+field("fqName", type<FqName>()) { +field("fqName", type<FqName>()) {
baseGetter = code("packageFqName") baseGetter = code("packageFqName")
@@ -181,14 +181,14 @@ abstract class KotlinIrLinker(
override fun tryReferencingSimpleFunctionByLocalSignature(parent: IrDeclaration, idSignature: IdSignature): IrSimpleFunctionSymbol? { override fun tryReferencingSimpleFunctionByLocalSignature(parent: IrDeclaration, idSignature: IdSignature): IrSimpleFunctionSymbol? {
if (idSignature.isPubliclyVisible) return null if (idSignature.isPubliclyVisible) return null
val file = getFileOf(parent) val file = getFileOf(parent)
val moduleDescriptor = file.packageFragmentDescriptor.containingDeclaration val moduleDescriptor = file.moduleDescriptor
return resolveModuleDeserializer(moduleDescriptor, null).referenceSimpleFunctionByLocalSignature(file, idSignature) return resolveModuleDeserializer(moduleDescriptor, null).referenceSimpleFunctionByLocalSignature(file, idSignature)
} }
override fun tryReferencingPropertyByLocalSignature(parent: IrDeclaration, idSignature: IdSignature): IrPropertySymbol? { override fun tryReferencingPropertyByLocalSignature(parent: IrDeclaration, idSignature: IdSignature): IrPropertySymbol? {
if (idSignature.isPubliclyVisible) return null if (idSignature.isPubliclyVisible) return null
val file = getFileOf(parent) val file = getFileOf(parent)
val moduleDescriptor = file.packageFragmentDescriptor.containingDeclaration val moduleDescriptor = file.moduleDescriptor
return resolveModuleDeserializer(moduleDescriptor, null).referencePropertyByLocalSignature(file, idSignature) return resolveModuleDeserializer(moduleDescriptor, null).referencePropertyByLocalSignature(file, idSignature)
} }
@@ -90,7 +90,7 @@ val IrPackageFragment.konanLibrary: KotlinLibrary?
val moduleDescriptor = fileMetadata?.descriptors?.singleOrNull() as? ModuleDescriptor val moduleDescriptor = fileMetadata?.descriptors?.singleOrNull() as? ModuleDescriptor
moduleDescriptor?.konanLibrary?.let { return it } 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 // Any changes made to konanLibrary here should be ported to the containsDeclaration
// function in LlvmModuleSpecificationBase in LlvmModuleSpecificationImpl.kt // function in LlvmModuleSpecificationBase in LlvmModuleSpecificationImpl.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.Context
import org.jetbrains.kotlin.backend.konan.descriptors.isExpectMember import org.jetbrains.kotlin.backend.konan.descriptors.isExpectMember
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.declarations.IrPackageFragment import org.jetbrains.kotlin.ir.declarations.IrPackageFragment
import org.jetbrains.kotlin.library.metadata.CompiledKlibModuleOrigin import org.jetbrains.kotlin.library.metadata.CompiledKlibModuleOrigin
import org.jetbrains.kotlin.library.metadata.SyntheticModulesOrigin import org.jetbrains.kotlin.library.metadata.SyntheticModulesOrigin
import org.jetbrains.kotlin.library.metadata.klibModuleOrigin 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() { get() {
assert(!this.isExpectMember) { this } assert(!this.isExpectMember) { this }
val module = this.module val moduleOrigin = klibModuleOrigin
val moduleOrigin = module.klibModuleOrigin
when (moduleOrigin) { when (moduleOrigin) {
is CompiledKlibModuleOrigin -> return moduleOrigin is CompiledKlibModuleOrigin -> return moduleOrigin
SyntheticModulesOrigin -> error("Declaration is synthetic and can't be an origin of LLVM symbol:\n${this}") 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 internal val Context.standardLlvmSymbolsOrigin: CompiledKlibModuleOrigin get() = this.stdlibModule.llvmSymbolOrigin
@OptIn(ObsoleteDescriptorBasedAPI::class)
internal val IrPackageFragment.llvmSymbolOrigin internal val IrPackageFragment.llvmSymbolOrigin
get() = packageFragmentDescriptor.llvmSymbolOrigin get() = moduleDescriptor.llvmSymbolOrigin
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.target.supportsCodeCoverage 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. * "Umbrella" class of all the of the code coverage related logic.
@@ -75,7 +74,7 @@ internal class CoverageManager(val generationState: NativeGenerationState) {
@OptIn(ObsoleteDescriptorBasedAPI::class) @OptIn(ObsoleteDescriptorBasedAPI::class)
private fun fileCoverageFilter(file: IrFile) = 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]. * Walk [irModuleFragment] subtree and collect [FileRegionInfo] for files that are part of [coveredModules].
@@ -80,7 +80,7 @@ private abstract class BaseInteropIrTransformer(
builder.getCompilerMessageLocation() builder.getCompilerMessageLocation()
} }
val uniqueModuleName = irFile.packageFragmentDescriptor.module.name.asString() val uniqueModuleName = irFile.moduleDescriptor.name.asString()
.let { it.substring(1, it.lastIndex) } .let { it.substring(1, it.lastIndex) }
val uniqueFileName = irFile.fileEntry.name val uniqueFileName = irFile.fileEntry.name
val uniquePrefix = buildString { val uniquePrefix = buildString {
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.backend.common.reportWarning
import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.descriptors.isAbstract import org.jetbrains.kotlin.backend.konan.descriptors.isAbstract
import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName 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.ir.buildSimpleAnnotation
import org.jetbrains.kotlin.backend.konan.reportCompilationError import org.jetbrains.kotlin.backend.konan.reportCompilationError
import org.jetbrains.kotlin.descriptors.ClassKind 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.descriptors.Modality
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.builders.declarations.buildField 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.*
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
@@ -679,8 +676,7 @@ internal class TestProcessor (val context: Context) {
} }
// endregion // endregion
@OptIn(ObsoleteDescriptorBasedAPI::class) private fun shouldProcessFile(irFile: IrFile): Boolean = irFile.moduleDescriptor.let {
private fun shouldProcessFile(irFile: IrFile): Boolean = irFile.packageFragmentDescriptor.module.let {
// Process test annotations in source libraries too. // Process test annotations in source libraries too.
it in context.sourcesModules it in context.sourcesModules
} }
@@ -332,7 +332,7 @@ internal class KonanIrLinker(
fun getCachedDeclarationModuleDeserializer(declaration: IrDeclaration): KonanPartialModuleDeserializer? { fun getCachedDeclarationModuleDeserializer(declaration: IrDeclaration): KonanPartialModuleDeserializer? {
val packageFragment = declaration.getPackageFragment() val packageFragment = declaration.getPackageFragment()
val moduleDescriptor = packageFragment.packageFragmentDescriptor.containingDeclaration val moduleDescriptor = packageFragment.moduleDescriptor
val klib = packageFragment.konanLibrary val klib = packageFragment.konanLibrary
val declarationBeingCached = packageFragment is IrFile && klib != null && libraryBeingCached?.klib == klib val declarationBeingCached = packageFragment is IrFile && klib != null && libraryBeingCached?.klib == klib
&& libraryBeingCached.strategy.contains(packageFragment.path) && libraryBeingCached.strategy.contains(packageFragment.path)
@@ -394,7 +394,7 @@ internal class KonanIrLinker(
is IrFile -> packageFragment.path is IrFile -> packageFragment.path
is IrExternalPackageFragment -> { is IrExternalPackageFragment -> {
val moduleDescriptor = packageFragment.packageFragmentDescriptor.containingDeclaration val moduleDescriptor = packageFragment.moduleDescriptor
val moduleDeserializer = moduleDeserializers[moduleDescriptor] ?: error("No module deserializer for $moduleDescriptor") val moduleDeserializer = moduleDeserializers[moduleDescriptor] ?: error("No module deserializer for $moduleDescriptor")
moduleDeserializer.getFileNameOf(declaration) moduleDeserializer.getFileNameOf(declaration)
} }