[Commonizer] Provide union of forwardDeclarations as common dependencies
^KT-52050 Verification Pending The issue described in KT-52050 happened, because forwardDeclarations were not carried into next commonization steps. For commonization it is fair to choose the union of all modules forwardDeclarations as common dependency (instead of a union), since we can assume that all those forward declarations will be provided.
This commit is contained in:
committed by
Space
parent
99d995a313
commit
204bc4ca95
+17
@@ -103,6 +103,23 @@ class CommonizeNativeDistributionTest {
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `commonize - linux macos - linux macos mingw`() {
|
||||
val unixTarget = CommonizerTarget(LINUX_X64, MACOS_X64)
|
||||
val nativeTarget = CommonizerTarget(MINGW_X64, LINUX_X64, MACOS_X64)
|
||||
CliCommonizer(this::class.java.classLoader).commonizeNativeDistribution(
|
||||
konanHome = konanHome,
|
||||
outputTargets = setOf(unixTarget, nativeTarget),
|
||||
outputDirectory = temporaryOutputDirectory.root,
|
||||
logLevel = CommonizerLogLevel.Info
|
||||
)
|
||||
|
||||
assertTrue(
|
||||
resolveCommonizedDirectory(temporaryOutputDirectory.root, nativeTarget).isDirectory,
|
||||
"Expected directory for $nativeTarget"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `commonize - no outputTargets specified`() {
|
||||
CliCommonizer(this::class.java.classLoader).commonizeNativeDistribution(
|
||||
|
||||
@@ -27,20 +27,19 @@ data class CommonizerParameters(
|
||||
)
|
||||
|
||||
internal fun CommonizerParameters.dependencyClassifiers(target: CommonizerTarget): CirProvidedClassifiers {
|
||||
val targetModulesProvider = targetProviders.getOrNull(target)?.modulesProvider
|
||||
val dependenciesModulesProvider = dependenciesProvider[target]
|
||||
|
||||
val providedByTarget = if (targetModulesProvider != null)
|
||||
CirProvidedClassifiersByModules.loadExportedForwardDeclarations(targetModulesProvider) else null
|
||||
val exportedForwardDeclarations = target.withAllLeaves()
|
||||
.mapNotNull { targetOrLeaf -> targetProviders.getOrNull(targetOrLeaf)?.modulesProvider }
|
||||
.plus(listOfNotNull(dependenciesModulesProvider))
|
||||
.let { modulesProviders -> CirProvidedClassifiersByModules.loadExportedForwardDeclarations(modulesProviders) }
|
||||
|
||||
val providedByDependencies = if (dependenciesModulesProvider != null)
|
||||
CirProvidedClassifiers.of(
|
||||
CirProvidedClassifiersByModules.load(dependenciesModulesProvider),
|
||||
CirProvidedClassifiersByModules.loadExportedForwardDeclarations(dependenciesModulesProvider)
|
||||
) else null
|
||||
CirProvidedClassifiersByModules.load(dependenciesModulesProvider)
|
||||
else null
|
||||
|
||||
|
||||
return CirProvidedClassifiers.of(
|
||||
*listOfNotNull(CirFictitiousFunctionClassifiers, providedByTarget, providedByDependencies).toTypedArray()
|
||||
*listOfNotNull(CirFictitiousFunctionClassifiers, exportedForwardDeclarations, providedByDependencies).toTypedArray()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ class TargetProvider(
|
||||
interface ModulesProvider {
|
||||
open class ModuleInfo(
|
||||
val name: String,
|
||||
val originalLocation: File,
|
||||
val cInteropAttributes: CInteropModuleAttributes?
|
||||
)
|
||||
|
||||
|
||||
@@ -58,7 +58,6 @@ internal fun commonizeTarget(
|
||||
targetDependencies = availableTrees.mapValue(CirTreeRoot::dependencies),
|
||||
commonizedNodes = CirCommonizedClassifierNodes.default(),
|
||||
commonDependencies = parameters.dependencyClassifiers(output)
|
||||
|
||||
)
|
||||
|
||||
val mergedTree = mergeCirTree(parameters.storageManager, classifiers, availableTrees, parameters.settings)
|
||||
|
||||
+2
-4
@@ -14,10 +14,9 @@ import java.io.File
|
||||
internal class DefaultModulesProvider(libraries: Collection<NativeLibrary>) : ModulesProvider {
|
||||
internal class NativeModuleInfo(
|
||||
name: String,
|
||||
originalLocation: File,
|
||||
val dependencies: Set<String>,
|
||||
cInteropAttributes: ModulesProvider.CInteropModuleAttributes?
|
||||
) : ModuleInfo(name, originalLocation, cInteropAttributes)
|
||||
) : ModuleInfo(name, cInteropAttributes)
|
||||
|
||||
private val libraryMap: Map<String, NativeLibrary>
|
||||
private val moduleInfoMap: Map<String, NativeModuleInfo>
|
||||
@@ -30,7 +29,6 @@ internal class DefaultModulesProvider(libraries: Collection<NativeLibrary>) : Mo
|
||||
val manifestData = library.manifestData
|
||||
|
||||
val name = manifestData.uniqueName
|
||||
val location = File(library.library.libraryFile.path)
|
||||
val dependencies = manifestData.dependencies.toSet()
|
||||
|
||||
val cInteropAttributes = if (manifestData.isInterop) {
|
||||
@@ -39,7 +37,7 @@ internal class DefaultModulesProvider(libraries: Collection<NativeLibrary>) : Mo
|
||||
} else null
|
||||
|
||||
libraryMap.put(name, library)?.let { error("Duplicated libraries: $name") }
|
||||
moduleInfoMap[name] = NativeModuleInfo(name, location, dependencies, cInteropAttributes)
|
||||
moduleInfoMap[name] = NativeModuleInfo(name, dependencies, cInteropAttributes)
|
||||
}
|
||||
|
||||
this.libraryMap = libraryMap
|
||||
|
||||
+28
-19
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
|
||||
/** A set of classes and type aliases provided by libraries (either the libraries to commonize, or their dependency libraries)/ */
|
||||
interface CirProvidedClassifiers {
|
||||
sealed interface CirProvidedClassifiers {
|
||||
fun hasClassifier(classifierId: CirEntityId): Boolean
|
||||
fun classifier(classifierId: CirEntityId): CirProvided.Classifier?
|
||||
|
||||
@@ -24,24 +24,6 @@ interface CirProvidedClassifiers {
|
||||
override fun findTypeAliasesWithUnderlyingType(underlyingClassifier: CirEntityId) = emptyList<CirEntityId>()
|
||||
}
|
||||
|
||||
private class CompositeClassifiers(val delegates: List<CirProvidedClassifiers>) : 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 { classifier ->
|
||||
if (classifier !== FALLBACK_FORWARD_DECLARATION_CLASS) return classifier
|
||||
else fallbackReturn = classifier
|
||||
}
|
||||
}
|
||||
return fallbackReturn
|
||||
}
|
||||
|
||||
override fun findTypeAliasesWithUnderlyingType(underlyingClassifier: CirEntityId): List<CirEntityId> {
|
||||
return delegates.flatMap { it.findTypeAliasesWithUnderlyingType(underlyingClassifier) }
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
internal val FALLBACK_FORWARD_DECLARATION_CLASS =
|
||||
CirProvided.RegularClass(emptyList(), emptyList(), Visibilities.Public, ClassKind.CLASS)
|
||||
@@ -68,3 +50,30 @@ interface CirProvidedClassifiers {
|
||||
}
|
||||
}
|
||||
|
||||
internal operator fun CirProvidedClassifiers.plus(other: CirProvidedClassifiers): CirProvidedClassifiers {
|
||||
return when {
|
||||
this is CompositeClassifiers && other is CompositeClassifiers -> CompositeClassifiers(this.delegates + other.delegates)
|
||||
this is CompositeClassifiers -> CompositeClassifiers(this.delegates + other)
|
||||
other is CompositeClassifiers -> CompositeClassifiers(listOf(this) + other.delegates)
|
||||
else -> CompositeClassifiers(listOf(this, other))
|
||||
}
|
||||
}
|
||||
|
||||
private class CompositeClassifiers(val delegates: List<CirProvidedClassifiers>) : 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 { classifier ->
|
||||
if (classifier !== CirProvidedClassifiers.FALLBACK_FORWARD_DECLARATION_CLASS) return classifier
|
||||
else fallbackReturn = classifier
|
||||
}
|
||||
}
|
||||
return fallbackReturn
|
||||
}
|
||||
|
||||
override fun findTypeAliasesWithUnderlyingType(underlyingClassifier: CirEntityId): List<CirEntityId> {
|
||||
return delegates.flatMap { it.findTypeAliasesWithUnderlyingType(underlyingClassifier) }
|
||||
}
|
||||
}
|
||||
|
||||
+7
-2
@@ -68,10 +68,15 @@ internal class CirProvidedClassifiersByModules internal constructor(
|
||||
return CirProvidedClassifiersByModules(false, classifiers)
|
||||
}
|
||||
|
||||
fun loadExportedForwardDeclarations(modulesProvider: ModulesProvider): CirProvidedClassifiers {
|
||||
/**
|
||||
* Will load *all* forward declarations provided by all modules into a flat [CirProvidedClassifiers].
|
||||
* Note: This builds a union *not an intersection* of forward declarations.
|
||||
*/
|
||||
fun loadExportedForwardDeclarations(modulesProviders: List<ModulesProvider>): CirProvidedClassifiers {
|
||||
val classifiers = THashMap<CirEntityId, CirProvided.Classifier>()
|
||||
|
||||
modulesProvider.moduleInfos.mapNotNull { moduleInfo -> moduleInfo.cInteropAttributes }
|
||||
modulesProviders.flatMap { moduleProvider -> moduleProvider.moduleInfos }
|
||||
.mapNotNull { moduleInfo -> moduleInfo.cInteropAttributes }
|
||||
.forEach { attrs -> readExportedForwardDeclarations(attrs, classifiers::set) }
|
||||
|
||||
if (classifiers.isEmpty) return CirProvidedClassifiers.EMPTY
|
||||
|
||||
@@ -5,26 +5,23 @@
|
||||
|
||||
package org.jetbrains.kotlin.commonizer.mergedtree
|
||||
|
||||
import org.jetbrains.kotlin.commonizer.cir.CirClassRecursionMarker
|
||||
import org.jetbrains.kotlin.commonizer.cir.CirDeclaration
|
||||
import org.jetbrains.kotlin.commonizer.cir.CirEntityId
|
||||
import org.jetbrains.kotlin.commonizer.cir.CirTypeAliasRecursionMarker
|
||||
import org.jetbrains.kotlin.commonizer.core.*
|
||||
import org.jetbrains.kotlin.commonizer.CommonizerSettings
|
||||
import org.jetbrains.kotlin.commonizer.cir.*
|
||||
import org.jetbrains.kotlin.commonizer.utils.CommonizedGroup
|
||||
import org.jetbrains.kotlin.storage.NullableLazyValue
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
|
||||
internal fun buildRootNode(
|
||||
storageManager: StorageManager,
|
||||
dependencies: CirProvidedClassifiers,
|
||||
commonDependencies: CirProvidedClassifiers,
|
||||
size: Int
|
||||
): CirRootNode = buildNode(
|
||||
storageManager = storageManager,
|
||||
size = size,
|
||||
nodeRelationship = null,
|
||||
commonizerProducer = ::RootCommonizer,
|
||||
nodeProducer = { targetDeclarations, commonDeclaration -> CirRootNode(dependencies, targetDeclarations, commonDeclaration) }
|
||||
nodeProducer = { targetDeclarations, commonDeclaration -> CirRootNode(commonDependencies, targetDeclarations, commonDeclaration) }
|
||||
)
|
||||
|
||||
internal fun buildModuleNode(
|
||||
|
||||
+2
-2
@@ -103,7 +103,7 @@ fun InlineSourceBuilder.createCirTreeRootFromSourceCode(@Language("kotlin") sour
|
||||
fun InlineSourceBuilder.createCirProvidedClassifiers(module: InlineSourceBuilder.Module): CirProvidedClassifiers {
|
||||
val modulesProvider = object : ModulesProvider {
|
||||
override val moduleInfos: Collection<ModulesProvider.ModuleInfo> = listOf(
|
||||
ModulesProvider.ModuleInfo(name = "CirProvidedForTest", originalLocation = File("."), cInteropAttributes = null)
|
||||
ModulesProvider.ModuleInfo(name = "CirProvidedForTest", cInteropAttributes = null)
|
||||
)
|
||||
|
||||
override fun loadModuleMetadata(name: String): SerializedMetadata {
|
||||
@@ -122,4 +122,4 @@ fun InlineSourceBuilder.createCirProvidedClassifiers(builder: InlineSourceBuilde
|
||||
@InlineSourceBuilder.ModuleBuilderDsl
|
||||
fun InlineSourceBuilder.createCirProvidedClassifiersFromSourceCode(@Language("kotlin") sourceCode: String): CirProvidedClassifiers {
|
||||
return createCirProvidedClassifiers(createModule { source(sourceCode) })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ internal class MockModulesProvider private constructor(
|
||||
return SERIALIZER.serializeModule(module)
|
||||
}
|
||||
|
||||
private fun fakeModuleInfo(name: String) = ModuleInfo(name, File("/tmp/commonizer/mocks/$name"), null)
|
||||
private fun fakeModuleInfo(name: String) = ModuleInfo(name, null)
|
||||
|
||||
companion object {
|
||||
@JvmName("createByModuleNames")
|
||||
|
||||
Reference in New Issue
Block a user