diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeclarationTable.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeclarationTable.kt index 6bfaa02591b..1a87986e2ec 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeclarationTable.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeclarationTable.kt @@ -13,13 +13,21 @@ import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.util.KotlinMangler import org.jetbrains.kotlin.ir.util.UniqId -class DescriptorTable { - private val descriptors = mutableMapOf() - fun put(descriptor: DeclarationDescriptor, uniqId: UniqId) { - descriptors.getOrPut(descriptor) { uniqId.index } - } +interface DescriptorTable { + fun put(descriptor: DeclarationDescriptor, uniqId: UniqId) + fun get(descriptor: DeclarationDescriptor): Long? - fun get(descriptor: DeclarationDescriptor) = descriptors[descriptor] + companion object { + fun createDefault() = object : DescriptorTable { + private val descriptors = mutableMapOf() + + override fun put(descriptor: DeclarationDescriptor, uniqId: UniqId) { + descriptors.getOrPut(descriptor) { uniqId.index } + } + + override fun get(descriptor: DeclarationDescriptor) = descriptors[descriptor] + } + } } interface UniqIdClashTracker { diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibMetadataIncrementalSerializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibMetadataIncrementalSerializer.kt index e107cb37fed..432d8fa38da 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibMetadataIncrementalSerializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibMetadataIncrementalSerializer.kt @@ -9,7 +9,6 @@ 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.backend.common.serialization.metadata.KlibMetadataSerializer -import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataVersion import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.ClassifierDescriptor @@ -19,7 +18,6 @@ import org.jetbrains.kotlin.library.SerializedMetadata import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.serialization.DescriptorSerializer @@ -32,7 +30,6 @@ class KlibMetadataIncrementalSerializer( ) : KlibMetadataSerializer(languageVersionSettings, metadataVersion, descriptorTable) { fun serializePackageFragment( - bindingContext: BindingContext, module: ModuleDescriptor, scope: Collection, fqName: FqName @@ -58,7 +55,7 @@ class KlibMetadataIncrementalSerializer( // This is no always the case, actually. // But marrying split package fragments with incremental compilation is an endeavour. // See monolithic serializer for details. - return serializeDescriptors(fqName, classifierDescriptors, topLevelDescriptors, bindingContext).single() + return serializeDescriptors(fqName, classifierDescriptors, topLevelDescriptors).single() } fun serializedMetadata( diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibMetadataMonolithicSerializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibMetadataMonolithicSerializer.kt index f98c24b05cb..ad3d7c81c22 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibMetadataMonolithicSerializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibMetadataMonolithicSerializer.kt @@ -10,7 +10,6 @@ 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.FqName -import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered @@ -20,15 +19,10 @@ import org.jetbrains.kotlin.serialization.DescriptorSerializer class KlibMetadataMonolithicSerializer( languageVersionSettings: LanguageVersionSettings, metadataVersion: BinaryVersion, - descriptorTable: DescriptorTable, - val bindingContext: BindingContext + descriptorTable: DescriptorTable ) : KlibMetadataSerializer(languageVersionSettings, metadataVersion, descriptorTable) { - protected fun serializePackageFragment(fqName: FqName, - module: ModuleDescriptor, - bindingContext: BindingContext - ): - List { + private fun serializePackageFragment(fqName: FqName, module: ModuleDescriptor): List { // TODO: ModuleDescriptor should be able to return // the package only with the contents of that module, without dependencies @@ -48,7 +42,7 @@ class KlibMetadataMonolithicSerializer( }.filter { !it.isExpectMember } ) - return serializeDescriptors(fqName, classifierDescriptors, topLevelDescriptors, bindingContext) + return serializeDescriptors(fqName, classifierDescriptors, topLevelDescriptors) } fun serializeModule(moduleDescriptor: ModuleDescriptor): SerializedMetadata { @@ -59,7 +53,7 @@ class KlibMetadataMonolithicSerializer( for (packageFqName in getPackagesFqNames(moduleDescriptor)) { val packageProtos = - serializePackageFragment(packageFqName, moduleDescriptor, bindingContext) + serializePackageFragment(packageFqName, moduleDescriptor) if (packageProtos.isEmpty()) continue val packageFqNameStr = packageFqName.asString() diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibMetadataSerializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibMetadataSerializer.kt index d9c3a1d281e..798ccc94488 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibMetadataSerializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibMetadataSerializer.kt @@ -15,7 +15,6 @@ 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.FqName -import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.serialization.DescriptorSerializer import org.jetbrains.kotlin.serialization.StringTableImpl @@ -69,8 +68,7 @@ abstract class KlibMetadataSerializer( packageProto: ProtoBuf.Package, classesProto: List>, fqName: FqName, - isEmpty: Boolean, - bindingContext: BindingContext + isEmpty: Boolean ): ProtoBuf.PackageFragment { val (stringTableProto, nameTableProto) = serializerExtension.stringTable.buildProto() @@ -130,8 +128,7 @@ abstract class KlibMetadataSerializer( protected fun serializeDescriptors( fqName: FqName, classifierDescriptors: List, - topLevelDescriptors: List, - bindingContext: BindingContext + topLevelDescriptors: List ): List { if (TOP_LEVEL_CLASS_DECLARATION_COUNT_PER_FILE == null && @@ -151,8 +148,7 @@ abstract class KlibMetadataSerializer( packageProto, serializeClasses(fqName, classifierDescriptors), fqName, - topLevelDescriptors.isEmpty() && classifierDescriptors.isEmpty(), - bindingContext + topLevelDescriptors.isEmpty() && classifierDescriptors.isEmpty() ) } ) @@ -178,8 +174,7 @@ abstract class KlibMetadataSerializer( packageProto, classesProto, fqName, - descriptors.isEmpty(), - bindingContext + descriptors.isEmpty() ) } } @@ -190,8 +185,7 @@ abstract class KlibMetadataSerializer( buildPackageProto(fqName, descriptors), emptyList(), fqName, - descriptors.isEmpty(), - bindingContext + descriptors.isEmpty() ) } } @@ -202,8 +196,7 @@ abstract class KlibMetadataSerializer( emptyPackageProto(), emptyList(), fqName, - true, - bindingContext + true ) } } diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt index 96e0e3f7c04..39e2c31b04f 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt @@ -345,7 +345,7 @@ fun serializeModuleIntoKlib( ) { assert(files.size == moduleFragment.files.size) - val descriptorTable = DescriptorTable() + val descriptorTable = DescriptorTable.createDefault() val serializedIr = JsIrModuleSerializer(emptyLoggingContext, moduleFragment.irBuiltins, descriptorTable).serializedIrModule(moduleFragment) @@ -361,7 +361,6 @@ fun serializeModuleIntoKlib( fun serializeScope(fqName: FqName, memberScope: Collection): ByteArray { return metadataSerializer.serializePackageFragment( - bindingContext, moduleDescriptor, memberScope, fqName diff --git a/konan/commonizer/build.gradle.kts b/konan/commonizer/build.gradle.kts index b8c3907ffb6..a33cdd42ea9 100644 --- a/konan/commonizer/build.gradle.kts +++ b/konan/commonizer/build.gradle.kts @@ -15,7 +15,8 @@ val mavenCompileScope by configurations.creating { description = "Kotlin/Native library commonizer" dependencies { - compileOnly(project(":compiler:frontend")) { isTransitive = true } + compileOnly(project(":compiler:frontend")) + compileOnly(project(":compiler:ir.serialization.common")) // This dependency is necessary to keep the right dependency record inside of POM file: mavenCompileScope(project(":kotlin-compiler")) diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cli.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cli.kt index 71b60770da3..95658eaed92 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cli.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cli.kt @@ -5,10 +5,15 @@ package org.jetbrains.kotlin.descriptors.commonizer +import org.jetbrains.kotlin.backend.common.serialization.DescriptorTable +import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataMonolithicSerializer +import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataVersion import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.commonizer.ModuleForCommonization.DeserializedModule import org.jetbrains.kotlin.descriptors.commonizer.ModuleForCommonization.SyntheticModule import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl +import org.jetbrains.kotlin.ir.util.UniqId import org.jetbrains.kotlin.konan.library.* import org.jetbrains.kotlin.konan.library.KonanFactories.DefaultDeserializedDescriptorFactory import org.jetbrains.kotlin.konan.properties.propertyList @@ -188,30 +193,45 @@ private fun saveModules( .associate { it.module.name to it.data } } + val serializer = KlibMetadataMonolithicSerializer( + languageVersionSettings = LanguageVersionSettingsImpl.DEFAULT, + metadataVersion = KlibMetadataVersion.INSTANCE, + descriptorTable = EmptyDescriptorTable + ) + val stdlibName = Name.special("<$KONAN_STDLIB_NAME>") - result.concreteTargets.forEach { target -> - val konanTarget = target.konanTarget!! - val targetLibsDestination = destination.resolve(KONAN_DISTRIBUTION_PLATFORM_LIBS_DIR).resolve(konanTarget.name) + fun serializeTarget(target: Target) { + val libsDestination: File + val newModulesManifestData: Map + + when (target) { + is InputTarget -> { + libsDestination = destination.resolve(KONAN_DISTRIBUTION_PLATFORM_LIBS_DIR).resolve(target.konanTarget!!.name) + newModulesManifestData = originalModulesManifestData.getValue(target) + } + is OutputTarget -> { + libsDestination = destination.resolve(KONAN_DISTRIBUTION_COMMON_LIBS_DIR) + newModulesManifestData = originalModulesManifestData.values.first() // just take the first one + } + } - val newModulesManifestData = originalModulesManifestData.getValue(target) val newModules = result.modulesByTargets.getValue(target) for (newModule in newModules) { val libraryName = newModule.name if (libraryName == stdlibName || libraryName == FORWARD_DECLARATIONS_MODULE_NAME) continue - // TODO: obtain serialization data -// val metadata = TODO() + val metadata = serializer.serializeModule(newModule) val manifestData = newModulesManifestData.getValue(newModule.name) - val libraryDestination = targetLibsDestination.resolve(libraryName.asString().trimStart('<').trimEnd('>')) + val libraryDestination = libsDestination.resolve(libraryName.asString().trimStart('<').trimEnd('>')) -// writeLibrary(metadata, manifestData, libraryDestination) - println("$manifestData - $libraryDestination") + writeLibrary(metadata, manifestData, libraryDestination) } } - TODO("serialize common target") + result.concreteTargets.forEach(::serializeTarget) + result.commonTarget.let(::serializeTarget) } private sealed class ModuleForCommonization(val module: ModuleDescriptorImpl) { @@ -237,26 +257,18 @@ private data class SensitiveManifestData( // note: versions can't be added here - if (dependencies.isNotEmpty()) - library.manifestProperties[KLIB_PROPERTY_DEPENDS] = dependencies.joinToString(separator = " ") - else - library.manifestProperties.remove(KLIB_PROPERTY_DEPENDS) + fun addOptionalProperty(name: String, condition: Boolean, value: () -> String) = + if (condition) + library.manifestProperties[name] = value() + else + library.manifestProperties.remove(name) - if (isInterop) - library.manifestProperties[KLIB_PROPERTY_INTEROP] = "true" - else - library.manifestProperties.remove(KLIB_PROPERTY_INTEROP) - - if (packageFqName != null) - library.manifestProperties[KLIB_PROPERTY_PACKAGE] = packageFqName - else - library.manifestProperties.remove(KLIB_PROPERTY_PACKAGE) - - if (exportForwardDeclarations.isNotEmpty()) - library.manifestProperties[KLIB_PROPERTY_EXPORT_FORWARD_DECLARATIONS] = - exportForwardDeclarations.joinToString(separator = " ") - else - library.manifestProperties.remove(KLIB_PROPERTY_EXPORT_FORWARD_DECLARATIONS) + addOptionalProperty(KLIB_PROPERTY_DEPENDS, dependencies.isNotEmpty()) { dependencies.joinToString(separator = " ") } + addOptionalProperty(KLIB_PROPERTY_INTEROP, isInterop) { "true" } + addOptionalProperty(KLIB_PROPERTY_PACKAGE, packageFqName != null) { packageFqName!! } + addOptionalProperty(KLIB_PROPERTY_EXPORT_FORWARD_DECLARATIONS, exportForwardDeclarations.isNotEmpty()) { + exportForwardDeclarations.joinToString(separator = " ") + } } companion object { @@ -271,12 +283,19 @@ private data class SensitiveManifestData( } } +private object EmptyDescriptorTable : DescriptorTable { + private const val DEFAULT_UNIQ_ID_INDEX = 0L + + override fun put(descriptor: DeclarationDescriptor, uniqId: UniqId) = error("unsupported") + override fun get(descriptor: DeclarationDescriptor): Long = DEFAULT_UNIQ_ID_INDEX +} + private fun writeLibrary( metadata: SerializedMetadata, manifestData: SensitiveManifestData, destination: File ) { - val library = KoltinLibraryWriterImpl(KFile(destination.path), manifestData.uniqueName, manifestData.versions, nopack = false) + val library = KoltinLibraryWriterImpl(KFile(destination.path), manifestData.uniqueName, manifestData.versions, nopack = true) library.addMetadata(metadata) manifestData.applyTo(library.base as BaseWriterImpl) library.commit()