Support serializing a module's own descriptors without dependencies

The KlibMetadataSerializer used to serialize all package fragments that a module
could provide, including those coming from the module's dependencies. In order
to produce a klib from a module that is analyzed by the K2MetadataCompiler, the
serializer needs to take just the own package fragments of the module, excluding
those of the dependencies.
This commit is contained in:
Sergey Igushkin
2019-12-23 16:32:30 +03:00
parent ed6034e449
commit 1129b2d3eb
2 changed files with 23 additions and 10 deletions
@@ -1,8 +1,6 @@
package org.jetbrains.kotlin.backend.common.serialization.metadata
import org.jetbrains.kotlin.backend.common.serialization.DescriptorTable
import org.jetbrains.kotlin.backend.common.serialization.isExpectMember
import org.jetbrains.kotlin.backend.common.serialization.isSerializableExpectClass
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.library.SerializedMetadata
@@ -20,15 +18,18 @@ class KlibMetadataMonolithicSerializer(
languageVersionSettings: LanguageVersionSettings,
metadataVersion: BinaryVersion,
descriptorTable: DescriptorTable,
skipExpects: Boolean
) : KlibMetadataSerializer(languageVersionSettings, metadataVersion, descriptorTable, skipExpects) {
skipExpects: Boolean,
includeOnlyModuleContent: Boolean = false
) : KlibMetadataSerializer(languageVersionSettings, metadataVersion, descriptorTable, skipExpects, includeOnlyModuleContent) {
private fun serializePackageFragment(fqName: FqName, module: ModuleDescriptor): List<ProtoBuf.PackageFragment> {
// TODO: ModuleDescriptor should be able to return
// the package only with the contents of that module, without dependencies
val fragments = if (includeOnlyModuleContent) {
module.packageFragmentProviderForModuleContentWithoutDependencies.getPackageFragments(fqName)
} else {
module.getPackage(fqName).fragments.filter { it.module == module }
}
val fragments = module.getPackage(fqName).fragments.filter { it.module == module }
if (fragments.isEmpty()) return emptyList()
val classifierDescriptors = DescriptorSerializer.sort(
@@ -12,13 +12,13 @@ import org.jetbrains.kotlin.backend.common.serialization.newDescriptorUniqId
import org.jetbrains.kotlin.config.AnalysisFlags
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.serialization.DescriptorSerializer
@@ -34,7 +34,8 @@ abstract class KlibMetadataSerializer(
val languageVersionSettings: LanguageVersionSettings,
val metadataVersion: BinaryVersion,
val descriptorTable: DescriptorTable,
val skipExpects: Boolean = false
val skipExpects: Boolean = false,
val includeOnlyModuleContent: Boolean = false
) {
lateinit var serializerContext: SerializerContext
@@ -234,9 +235,16 @@ abstract class KlibMetadataSerializer(
protected fun getPackagesFqNames(module: ModuleDescriptor): Set<FqName> {
val result = mutableSetOf<FqName>()
fun getSubPackagesOfModule(fqName: FqName) =
if (includeOnlyModuleContent) {
module.packageFragmentProviderForModuleContentWithoutDependencies.getSubPackagesOf(fqName) { true }
} else {
module.getSubPackagesOf(fqName) { true }
}
fun getSubPackages(fqName: FqName) {
result.add(fqName)
module.getSubPackagesOf(fqName) { true }.forEach { getSubPackages(it) }
getSubPackagesOfModule(fqName).forEach { getSubPackages(it) }
}
getSubPackages(FqName.ROOT)
@@ -292,3 +300,7 @@ fun DeclarationDescriptor.extractFileId(): Int? = when (this) {
is DeserializedPropertyDescriptor -> proto.getExtension(KlibMetadataProtoBuf.propertyFile)
else -> null
}
internal val ModuleDescriptor.packageFragmentProviderForModuleContentWithoutDependencies: PackageFragmentProvider
get() = (this as? ModuleDescriptorImpl)?.packageFragmentProviderForModuleContentWithoutDependencies
?: error("Can't get a module content package fragments, it's not a ${ModuleDescriptorImpl::class.simpleName}.")