diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/CommonizerParameters.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/CommonizerParameters.kt index 140432a49d9..b5b868ccb6e 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/CommonizerParameters.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/CommonizerParameters.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.commonizer import org.jetbrains.kotlin.commonizer.konan.NativeManifestDataProvider import org.jetbrains.kotlin.commonizer.mergedtree.CirFictitiousFunctionClassifiers import org.jetbrains.kotlin.commonizer.mergedtree.CirProvidedClassifiers +import org.jetbrains.kotlin.commonizer.mergedtree.CirProvidedClassifiersByModules import org.jetbrains.kotlin.commonizer.stats.StatsCollector import org.jetbrains.kotlin.storage.LockBasedStorageManager import org.jetbrains.kotlin.storage.StorageManager @@ -25,6 +26,20 @@ data class CommonizerParameters( ) internal fun CommonizerParameters.dependencyClassifiers(target: CommonizerTarget): CirProvidedClassifiers { - val modulesProvider = dependenciesProvider[target] - return CirProvidedClassifiers.of(CirFictitiousFunctionClassifiers, CirProvidedClassifiers.by(modulesProvider)) + val targetModulesProvider = targetProviders.getOrNull(target)?.modulesProvider + val dependenciesModulesProvider = dependenciesProvider[target] + + val providedByTarget = if (targetModulesProvider != null) + CirProvidedClassifiersByModules.loadExportedForwardDeclarations(targetModulesProvider) else null + + val providedByDependencies = if (dependenciesModulesProvider != null) + CirProvidedClassifiers.of( + CirProvidedClassifiersByModules.load(dependenciesModulesProvider), + CirProvidedClassifiersByModules.loadExportedForwardDeclarations(dependenciesModulesProvider) + ) else null + + + return CirProvidedClassifiers.of( + *listOfNotNull(CirFictitiousFunctionClassifiers, providedByTarget, providedByDependencies).toTypedArray() + ) } diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirProvidedClassifiers.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirProvidedClassifiers.kt index f0236466fcf..aacf5cec00f 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirProvidedClassifiers.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirProvidedClassifiers.kt @@ -26,14 +26,21 @@ interface CirProvidedClassifiers { private class CompositeClassifiers(val delegates: List) : CirProvidedClassifiers { override fun hasClassifier(classifierId: CirEntityId) = delegates.any { it.hasClassifier(classifierId) } override fun classifier(classifierId: CirEntityId): CirProvided.Classifier? { + var fallbackReturn: CirProvided.Classifier? = null for (delegate in delegates) { - delegate.classifier(classifierId)?.let { return it } + delegate.classifier(classifierId)?.let { classifier -> + if (classifier !== FALLBACK_FORWARD_DECLARATION_CLASS) return classifier + else fallbackReturn = classifier + } } - return null + return fallbackReturn } } companion object { + internal val FALLBACK_FORWARD_DECLARATION_CLASS = + CirProvided.RegularClass(emptyList(), emptyList(), Visibilities.Public, ClassKind.CLASS) + fun of(vararg delegates: CirProvidedClassifiers): CirProvidedClassifiers { val unwrappedDelegates: List = delegates.fold(ArrayList()) { acc, delegate -> when (delegate) { diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirProvidedClassifiersByModules.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirProvidedClassifiersByModules.kt index b56610f5e08..65ddef7d243 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirProvidedClassifiersByModules.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirProvidedClassifiersByModules.kt @@ -12,9 +12,8 @@ import org.jetbrains.kotlin.commonizer.ModulesProvider.CInteropModuleAttributes import org.jetbrains.kotlin.commonizer.cir.CirEntityId import org.jetbrains.kotlin.commonizer.cir.CirName import org.jetbrains.kotlin.commonizer.cir.CirPackageName +import org.jetbrains.kotlin.commonizer.mergedtree.CirProvidedClassifiers.Companion.FALLBACK_FORWARD_DECLARATION_CLASS import org.jetbrains.kotlin.commonizer.utils.* -import org.jetbrains.kotlin.descriptors.ClassKind -import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.library.SerializedMetadata import org.jetbrains.kotlin.library.metadata.parsePackageFragment import org.jetbrains.kotlin.metadata.ProtoBuf @@ -43,15 +42,8 @@ internal class CirProvidedClassifiersByModules private constructor( companion object { fun load(modulesProvider: ModulesProvider): CirProvidedClassifiers { val classifiers = THashMap() - var hasForwardDeclarations = false modulesProvider.moduleInfos.forEach { moduleInfo -> - moduleInfo.cInteropAttributes?.let { cInteropAttributes -> - // this is a C-interop module - hasForwardDeclarations = true - readExportedForwardDeclarations(cInteropAttributes, classifiers::set) - } - val metadata = modulesProvider.loadModuleMetadata(moduleInfo.name) readModule(metadata, classifiers::set) } @@ -59,11 +51,19 @@ internal class CirProvidedClassifiersByModules private constructor( if (classifiers.isEmpty) return CirProvidedClassifiers.EMPTY - return CirProvidedClassifiersByModules(hasForwardDeclarations, classifiers) + return CirProvidedClassifiersByModules(false, classifiers) + } + + fun loadExportedForwardDeclarations(modulesProvider: ModulesProvider): CirProvidedClassifiers { + val classifiers = THashMap() + + modulesProvider.moduleInfos.mapNotNull { moduleInfo -> moduleInfo.cInteropAttributes } + .forEach { attrs -> readExportedForwardDeclarations(attrs, classifiers::set) } + + if (classifiers.isEmpty) return CirProvidedClassifiers.EMPTY + return CirProvidedClassifiersByModules(true, classifiers) } - private val FALLBACK_FORWARD_DECLARATION_CLASS = - CirProvided.RegularClass(emptyList(), emptyList(), Visibilities.Public, ClassKind.CLASS) } } @@ -84,7 +84,10 @@ private fun readExportedForwardDeclarations( val syntheticClassId = CirEntityId.create(syntheticPackageName, className) val aliasedClassId = CirEntityId.create(mainPackageName, className) - consumer(aliasedClassId, CirProvided.ExportedForwardDeclarationClass(syntheticClassId)) + val clazz = CirProvided.ExportedForwardDeclarationClass(syntheticClassId) + + consumer(syntheticClassId, clazz) + consumer(aliasedClassId, clazz) } } diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirRootNode.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirRootNode.kt index 13dc652a0a9..56e8a510319 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirRootNode.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirRootNode.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.commonizer.utils.CommonizedGroup import org.jetbrains.kotlin.storage.NullableLazyValue class CirRootNode( + val dependencies: CirProvidedClassifiers, override val targetDeclarations: CommonizedGroup, override val commonDeclaration: NullableLazyValue ) : CirNode { diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/nodeBuilders.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/nodeBuilders.kt index cdf5841897b..c1b58115656 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/nodeBuilders.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/nodeBuilders.kt @@ -16,13 +16,14 @@ import org.jetbrains.kotlin.storage.StorageManager internal fun buildRootNode( storageManager: StorageManager, + dependencies: CirProvidedClassifiers, size: Int ): CirRootNode = buildNode( storageManager = storageManager, size = size, nodeRelationship = null, commonizerProducer = ::RootCommonizer, - nodeProducer = ::CirRootNode + nodeProducer = { targetDeclarations, commonDeclaration -> CirRootNode(dependencies, targetDeclarations, commonDeclaration) } ) internal fun buildModuleNode( diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/tree/CirTree.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/tree/CirTree.kt index 5aee3a6b476..4c3962249a2 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/tree/CirTree.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/tree/CirTree.kt @@ -6,12 +6,11 @@ package org.jetbrains.kotlin.commonizer.tree import org.jetbrains.kotlin.commonizer.cir.* -import org.jetbrains.kotlin.commonizer.mergedtree.ConstructorApproximationKey -import org.jetbrains.kotlin.commonizer.mergedtree.FunctionApproximationKey -import org.jetbrains.kotlin.commonizer.mergedtree.PropertyApproximationKey +import org.jetbrains.kotlin.commonizer.mergedtree.CirProvidedClassifiers data class CirTreeRoot( - val modules: List = emptyList() + val modules: List = emptyList(), + val dependencies: CirProvidedClassifiers = CirProvidedClassifiers.EMPTY ) data class CirTreeModule( diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/tree/assembelCirTree.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/tree/assembelCirTree.kt index c1fbe569471..210d0b48eea 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/tree/assembelCirTree.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/tree/assembelCirTree.kt @@ -11,7 +11,8 @@ import org.jetbrains.kotlin.commonizer.mergedtree.* internal fun CirRootNode.assembleCirTree(): CirTreeRoot { return CirTreeRoot( - modules = modules.values.mapNotNull { it.assembleCirTree() } + modules = modules.values.mapNotNull { it.assembleCirTree() }, + dependencies = dependencies ) } diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/tree/deserializer/RootCirTreeDeserializer.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/tree/deserializer/RootCirTreeDeserializer.kt index 933e6175d70..d5dc198dda1 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/tree/deserializer/RootCirTreeDeserializer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/tree/deserializer/RootCirTreeDeserializer.kt @@ -23,10 +23,11 @@ internal class RootCirTreeDeserializer( val commonModuleInfos = targetProvider.modulesProvider.moduleInfos .filter { moduleInfo -> moduleInfo.name in commonModuleNames } + val dependencies = parameters.dependencyClassifiers(targetProvider.target) + val typeResolver = CirTypeResolver.create( providedClassifiers = CirProvidedClassifiers.of( - CirProvidedClassifiers.by(targetProvider.modulesProvider), - parameters.dependencyClassifiers(targetProvider.target) + CirProvidedClassifiers.by(targetProvider.modulesProvider), dependencies ) ) @@ -34,7 +35,8 @@ internal class RootCirTreeDeserializer( modules = commonModuleInfos.map { moduleInfo -> val metadata = targetProvider.modulesProvider.loadModuleMetadata(moduleInfo.name) moduleDeserializer(metadata, typeResolver) - } + }, + dependencies = dependencies ) } } diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/tree/mergeCirTree.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/tree/mergeCirTree.kt index 6eb5ce57975..e9baf46b09d 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/tree/mergeCirTree.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/tree/mergeCirTree.kt @@ -24,7 +24,7 @@ internal data class TargetBuildingContext( internal fun mergeCirTree( storageManager: StorageManager, classifiers: CirKnownClassifiers, roots: TargetDependent ): CirRootNode { - val node = buildRootNode(storageManager, roots.size) + val node = buildRootNode(storageManager, classifiers.commonDependencies, roots.size) roots.targets.withIndex().forEach { (targetIndex, target) -> node.targetDeclarations[targetIndex] = CirRoot.create(target) node.buildModules( diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/CommonizerQueueTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/CommonizerQueueTest.kt index 5310c45026c..0e7dd634d22 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/CommonizerQueueTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/CommonizerQueueTest.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.commonizer import org.jetbrains.kotlin.commonizer.cir.CirRoot +import org.jetbrains.kotlin.commonizer.mergedtree.CirProvidedClassifiers import org.jetbrains.kotlin.commonizer.mergedtree.CirRootNode import org.jetbrains.kotlin.commonizer.tree.CirTreeRoot import org.jetbrains.kotlin.commonizer.utils.CommonizedGroup @@ -100,7 +101,9 @@ class CommonizerQueueTest { deserializers = EagerTargetDependent(providedTargets) { CommonizerQueue.Deserializer { null } }, commonizer = { inputs, output -> commonizerInvocations.add(CommonizerInvocation(inputs, output)) - CirRootNode(CommonizedGroup(0), storageManager.createNullableLazyValue { CirRoot.create(output) }) + CirRootNode( + CirProvidedClassifiers.EMPTY, CommonizedGroup(0), storageManager.createNullableLazyValue { CirRoot.create(output) } + ) }, serializer = { _, _ -> }, ) @@ -146,7 +149,10 @@ class CommonizerQueueTest { ) { CommonizerQueue.Deserializer { null } }, commonizer = { inputs, output -> commonizerInvocations.add(CommonizerInvocation(inputs, output)) - CirRootNode(CommonizedGroup(0), LockBasedStorageManager.NO_LOCKS.createNullableLazyValue { CirRoot.create(output) }) + CirRootNode( + CirProvidedClassifiers.EMPTY, + CommonizedGroup(0), LockBasedStorageManager.NO_LOCKS.createNullableLazyValue { CirRoot.create(output) } + ) }, serializer = { _, _ -> }, ) diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/transformer/InlineTypeAliasCirNodeTransformerTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/transformer/InlineTypeAliasCirNodeTransformerTest.kt index d9174122f89..93a5e7c36f1 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/transformer/InlineTypeAliasCirNodeTransformerTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/transformer/InlineTypeAliasCirNodeTransformerTest.kt @@ -71,7 +71,7 @@ class InlineTypeAliasCirNodeTransformerTest { } private fun setup(typeAliasPointingTo: CirEntityId): CirRootNode { - val root = buildRootNode(storageManager, 1) + val root = buildRootNode(storageManager, CirProvidedClassifiers.EMPTY, 1) root.modules[CirName.create("test-module")] = buildModuleNode(storageManager, 1).apply { packages[CirPackageName.create("under.test")] = buildPackageNode(storageManager, 2).apply {