[Commonizer] Consider exportForwardDeclarations as dependency

This will make follow-up commits easier:
forward declarations are closer to dependencies than being part
of the library. They will be used in the module, bot not
directly provided.

This commit also enables tracking of provided dependency classifiers
in the CirTreeRoot and CirRootNode

^KT-47430
This commit is contained in:
sebastian.sellmair
2021-08-12 15:30:21 +02:00
committed by Space
parent 3d4e861f05
commit dda9bb93f6
11 changed files with 65 additions and 30 deletions
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.commonizer
import org.jetbrains.kotlin.commonizer.konan.NativeManifestDataProvider import org.jetbrains.kotlin.commonizer.konan.NativeManifestDataProvider
import org.jetbrains.kotlin.commonizer.mergedtree.CirFictitiousFunctionClassifiers import org.jetbrains.kotlin.commonizer.mergedtree.CirFictitiousFunctionClassifiers
import org.jetbrains.kotlin.commonizer.mergedtree.CirProvidedClassifiers 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.commonizer.stats.StatsCollector
import org.jetbrains.kotlin.storage.LockBasedStorageManager import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.StorageManager
@@ -25,6 +26,20 @@ data class CommonizerParameters(
) )
internal fun CommonizerParameters.dependencyClassifiers(target: CommonizerTarget): CirProvidedClassifiers { internal fun CommonizerParameters.dependencyClassifiers(target: CommonizerTarget): CirProvidedClassifiers {
val modulesProvider = dependenciesProvider[target] val targetModulesProvider = targetProviders.getOrNull(target)?.modulesProvider
return CirProvidedClassifiers.of(CirFictitiousFunctionClassifiers, CirProvidedClassifiers.by(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()
)
} }
@@ -26,14 +26,21 @@ interface CirProvidedClassifiers {
private class CompositeClassifiers(val delegates: List<CirProvidedClassifiers>) : CirProvidedClassifiers { private class CompositeClassifiers(val delegates: List<CirProvidedClassifiers>) : CirProvidedClassifiers {
override fun hasClassifier(classifierId: CirEntityId) = delegates.any { it.hasClassifier(classifierId) } override fun hasClassifier(classifierId: CirEntityId) = delegates.any { it.hasClassifier(classifierId) }
override fun classifier(classifierId: CirEntityId): CirProvided.Classifier? { override fun classifier(classifierId: CirEntityId): CirProvided.Classifier? {
var fallbackReturn: CirProvided.Classifier? = null
for (delegate in delegates) { 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 { companion object {
internal val FALLBACK_FORWARD_DECLARATION_CLASS =
CirProvided.RegularClass(emptyList(), emptyList(), Visibilities.Public, ClassKind.CLASS)
fun of(vararg delegates: CirProvidedClassifiers): CirProvidedClassifiers { fun of(vararg delegates: CirProvidedClassifiers): CirProvidedClassifiers {
val unwrappedDelegates: List<CirProvidedClassifiers> = delegates.fold(ArrayList()) { acc, delegate -> val unwrappedDelegates: List<CirProvidedClassifiers> = delegates.fold(ArrayList()) { acc, delegate ->
when (delegate) { when (delegate) {
@@ -12,9 +12,8 @@ import org.jetbrains.kotlin.commonizer.ModulesProvider.CInteropModuleAttributes
import org.jetbrains.kotlin.commonizer.cir.CirEntityId import org.jetbrains.kotlin.commonizer.cir.CirEntityId
import org.jetbrains.kotlin.commonizer.cir.CirName import org.jetbrains.kotlin.commonizer.cir.CirName
import org.jetbrains.kotlin.commonizer.cir.CirPackageName 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.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.SerializedMetadata
import org.jetbrains.kotlin.library.metadata.parsePackageFragment import org.jetbrains.kotlin.library.metadata.parsePackageFragment
import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.ProtoBuf
@@ -43,15 +42,8 @@ internal class CirProvidedClassifiersByModules private constructor(
companion object { companion object {
fun load(modulesProvider: ModulesProvider): CirProvidedClassifiers { fun load(modulesProvider: ModulesProvider): CirProvidedClassifiers {
val classifiers = THashMap<CirEntityId, CirProvided.Classifier>() val classifiers = THashMap<CirEntityId, CirProvided.Classifier>()
var hasForwardDeclarations = false
modulesProvider.moduleInfos.forEach { moduleInfo -> 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) val metadata = modulesProvider.loadModuleMetadata(moduleInfo.name)
readModule(metadata, classifiers::set) readModule(metadata, classifiers::set)
} }
@@ -59,11 +51,19 @@ internal class CirProvidedClassifiersByModules private constructor(
if (classifiers.isEmpty) if (classifiers.isEmpty)
return CirProvidedClassifiers.EMPTY return CirProvidedClassifiers.EMPTY
return CirProvidedClassifiersByModules(hasForwardDeclarations, classifiers) return CirProvidedClassifiersByModules(false, classifiers)
}
fun loadExportedForwardDeclarations(modulesProvider: ModulesProvider): CirProvidedClassifiers {
val classifiers = THashMap<CirEntityId, CirProvided.Classifier>()
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 syntheticClassId = CirEntityId.create(syntheticPackageName, className)
val aliasedClassId = CirEntityId.create(mainPackageName, className) val aliasedClassId = CirEntityId.create(mainPackageName, className)
consumer(aliasedClassId, CirProvided.ExportedForwardDeclarationClass(syntheticClassId)) val clazz = CirProvided.ExportedForwardDeclarationClass(syntheticClassId)
consumer(syntheticClassId, clazz)
consumer(aliasedClassId, clazz)
} }
} }
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.storage.NullableLazyValue import org.jetbrains.kotlin.storage.NullableLazyValue
class CirRootNode( class CirRootNode(
val dependencies: CirProvidedClassifiers,
override val targetDeclarations: CommonizedGroup<CirRoot>, override val targetDeclarations: CommonizedGroup<CirRoot>,
override val commonDeclaration: NullableLazyValue<CirRoot> override val commonDeclaration: NullableLazyValue<CirRoot>
) : CirNode<CirRoot, CirRoot> { ) : CirNode<CirRoot, CirRoot> {
@@ -16,13 +16,14 @@ import org.jetbrains.kotlin.storage.StorageManager
internal fun buildRootNode( internal fun buildRootNode(
storageManager: StorageManager, storageManager: StorageManager,
dependencies: CirProvidedClassifiers,
size: Int size: Int
): CirRootNode = buildNode( ): CirRootNode = buildNode(
storageManager = storageManager, storageManager = storageManager,
size = size, size = size,
nodeRelationship = null, nodeRelationship = null,
commonizerProducer = ::RootCommonizer, commonizerProducer = ::RootCommonizer,
nodeProducer = ::CirRootNode nodeProducer = { targetDeclarations, commonDeclaration -> CirRootNode(dependencies, targetDeclarations, commonDeclaration) }
) )
internal fun buildModuleNode( internal fun buildModuleNode(
@@ -6,12 +6,11 @@
package org.jetbrains.kotlin.commonizer.tree package org.jetbrains.kotlin.commonizer.tree
import org.jetbrains.kotlin.commonizer.cir.* import org.jetbrains.kotlin.commonizer.cir.*
import org.jetbrains.kotlin.commonizer.mergedtree.ConstructorApproximationKey import org.jetbrains.kotlin.commonizer.mergedtree.CirProvidedClassifiers
import org.jetbrains.kotlin.commonizer.mergedtree.FunctionApproximationKey
import org.jetbrains.kotlin.commonizer.mergedtree.PropertyApproximationKey
data class CirTreeRoot( data class CirTreeRoot(
val modules: List<CirTreeModule> = emptyList() val modules: List<CirTreeModule> = emptyList(),
val dependencies: CirProvidedClassifiers = CirProvidedClassifiers.EMPTY
) )
data class CirTreeModule( data class CirTreeModule(
@@ -11,7 +11,8 @@ import org.jetbrains.kotlin.commonizer.mergedtree.*
internal fun CirRootNode.assembleCirTree(): CirTreeRoot { internal fun CirRootNode.assembleCirTree(): CirTreeRoot {
return CirTreeRoot( return CirTreeRoot(
modules = modules.values.mapNotNull { it.assembleCirTree() } modules = modules.values.mapNotNull { it.assembleCirTree() },
dependencies = dependencies
) )
} }
@@ -23,10 +23,11 @@ internal class RootCirTreeDeserializer(
val commonModuleInfos = targetProvider.modulesProvider.moduleInfos val commonModuleInfos = targetProvider.modulesProvider.moduleInfos
.filter { moduleInfo -> moduleInfo.name in commonModuleNames } .filter { moduleInfo -> moduleInfo.name in commonModuleNames }
val dependencies = parameters.dependencyClassifiers(targetProvider.target)
val typeResolver = CirTypeResolver.create( val typeResolver = CirTypeResolver.create(
providedClassifiers = CirProvidedClassifiers.of( providedClassifiers = CirProvidedClassifiers.of(
CirProvidedClassifiers.by(targetProvider.modulesProvider), CirProvidedClassifiers.by(targetProvider.modulesProvider), dependencies
parameters.dependencyClassifiers(targetProvider.target)
) )
) )
@@ -34,7 +35,8 @@ internal class RootCirTreeDeserializer(
modules = commonModuleInfos.map { moduleInfo -> modules = commonModuleInfos.map { moduleInfo ->
val metadata = targetProvider.modulesProvider.loadModuleMetadata(moduleInfo.name) val metadata = targetProvider.modulesProvider.loadModuleMetadata(moduleInfo.name)
moduleDeserializer(metadata, typeResolver) moduleDeserializer(metadata, typeResolver)
} },
dependencies = dependencies
) )
} }
} }
@@ -24,7 +24,7 @@ internal data class TargetBuildingContext(
internal fun mergeCirTree( internal fun mergeCirTree(
storageManager: StorageManager, classifiers: CirKnownClassifiers, roots: TargetDependent<CirTreeRoot> storageManager: StorageManager, classifiers: CirKnownClassifiers, roots: TargetDependent<CirTreeRoot>
): CirRootNode { ): CirRootNode {
val node = buildRootNode(storageManager, roots.size) val node = buildRootNode(storageManager, classifiers.commonDependencies, roots.size)
roots.targets.withIndex().forEach { (targetIndex, target) -> roots.targets.withIndex().forEach { (targetIndex, target) ->
node.targetDeclarations[targetIndex] = CirRoot.create(target) node.targetDeclarations[targetIndex] = CirRoot.create(target)
node.buildModules( node.buildModules(
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.commonizer package org.jetbrains.kotlin.commonizer
import org.jetbrains.kotlin.commonizer.cir.CirRoot 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.mergedtree.CirRootNode
import org.jetbrains.kotlin.commonizer.tree.CirTreeRoot import org.jetbrains.kotlin.commonizer.tree.CirTreeRoot
import org.jetbrains.kotlin.commonizer.utils.CommonizedGroup import org.jetbrains.kotlin.commonizer.utils.CommonizedGroup
@@ -100,7 +101,9 @@ class CommonizerQueueTest {
deserializers = EagerTargetDependent(providedTargets) { CommonizerQueue.Deserializer { null } }, deserializers = EagerTargetDependent(providedTargets) { CommonizerQueue.Deserializer { null } },
commonizer = { inputs, output -> commonizer = { inputs, output ->
commonizerInvocations.add(CommonizerInvocation(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 = { _, _ -> }, serializer = { _, _ -> },
) )
@@ -146,7 +149,10 @@ class CommonizerQueueTest {
) { CommonizerQueue.Deserializer { null } }, ) { CommonizerQueue.Deserializer { null } },
commonizer = { inputs, output -> commonizer = { inputs, output ->
commonizerInvocations.add(CommonizerInvocation(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 = { _, _ -> }, serializer = { _, _ -> },
) )
@@ -71,7 +71,7 @@ class InlineTypeAliasCirNodeTransformerTest {
} }
private fun setup(typeAliasPointingTo: CirEntityId): CirRootNode { 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 { root.modules[CirName.create("test-module")] = buildModuleNode(storageManager, 1).apply {
packages[CirPackageName.create("under.test")] = buildPackageNode(storageManager, 2).apply { packages[CirPackageName.create("under.test")] = buildPackageNode(storageManager, 2).apply {