[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
|
@Test
|
||||||
fun `commonize - no outputTargets specified`() {
|
fun `commonize - no outputTargets specified`() {
|
||||||
CliCommonizer(this::class.java.classLoader).commonizeNativeDistribution(
|
CliCommonizer(this::class.java.classLoader).commonizeNativeDistribution(
|
||||||
|
|||||||
@@ -27,20 +27,19 @@ data class CommonizerParameters(
|
|||||||
)
|
)
|
||||||
|
|
||||||
internal fun CommonizerParameters.dependencyClassifiers(target: CommonizerTarget): CirProvidedClassifiers {
|
internal fun CommonizerParameters.dependencyClassifiers(target: CommonizerTarget): CirProvidedClassifiers {
|
||||||
val targetModulesProvider = targetProviders.getOrNull(target)?.modulesProvider
|
|
||||||
val dependenciesModulesProvider = dependenciesProvider[target]
|
val dependenciesModulesProvider = dependenciesProvider[target]
|
||||||
|
|
||||||
val providedByTarget = if (targetModulesProvider != null)
|
val exportedForwardDeclarations = target.withAllLeaves()
|
||||||
CirProvidedClassifiersByModules.loadExportedForwardDeclarations(targetModulesProvider) else null
|
.mapNotNull { targetOrLeaf -> targetProviders.getOrNull(targetOrLeaf)?.modulesProvider }
|
||||||
|
.plus(listOfNotNull(dependenciesModulesProvider))
|
||||||
|
.let { modulesProviders -> CirProvidedClassifiersByModules.loadExportedForwardDeclarations(modulesProviders) }
|
||||||
|
|
||||||
val providedByDependencies = if (dependenciesModulesProvider != null)
|
val providedByDependencies = if (dependenciesModulesProvider != null)
|
||||||
CirProvidedClassifiers.of(
|
CirProvidedClassifiersByModules.load(dependenciesModulesProvider)
|
||||||
CirProvidedClassifiersByModules.load(dependenciesModulesProvider),
|
else null
|
||||||
CirProvidedClassifiersByModules.loadExportedForwardDeclarations(dependenciesModulesProvider)
|
|
||||||
) else null
|
|
||||||
|
|
||||||
|
|
||||||
return CirProvidedClassifiers.of(
|
return CirProvidedClassifiers.of(
|
||||||
*listOfNotNull(CirFictitiousFunctionClassifiers, providedByTarget, providedByDependencies).toTypedArray()
|
*listOfNotNull(CirFictitiousFunctionClassifiers, exportedForwardDeclarations, providedByDependencies).toTypedArray()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ class TargetProvider(
|
|||||||
interface ModulesProvider {
|
interface ModulesProvider {
|
||||||
open class ModuleInfo(
|
open class ModuleInfo(
|
||||||
val name: String,
|
val name: String,
|
||||||
val originalLocation: File,
|
|
||||||
val cInteropAttributes: CInteropModuleAttributes?
|
val cInteropAttributes: CInteropModuleAttributes?
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,6 @@ internal fun commonizeTarget(
|
|||||||
targetDependencies = availableTrees.mapValue(CirTreeRoot::dependencies),
|
targetDependencies = availableTrees.mapValue(CirTreeRoot::dependencies),
|
||||||
commonizedNodes = CirCommonizedClassifierNodes.default(),
|
commonizedNodes = CirCommonizedClassifierNodes.default(),
|
||||||
commonDependencies = parameters.dependencyClassifiers(output)
|
commonDependencies = parameters.dependencyClassifiers(output)
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
val mergedTree = mergeCirTree(parameters.storageManager, classifiers, availableTrees, parameters.settings)
|
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 DefaultModulesProvider(libraries: Collection<NativeLibrary>) : ModulesProvider {
|
||||||
internal class NativeModuleInfo(
|
internal class NativeModuleInfo(
|
||||||
name: String,
|
name: String,
|
||||||
originalLocation: File,
|
|
||||||
val dependencies: Set<String>,
|
val dependencies: Set<String>,
|
||||||
cInteropAttributes: ModulesProvider.CInteropModuleAttributes?
|
cInteropAttributes: ModulesProvider.CInteropModuleAttributes?
|
||||||
) : ModuleInfo(name, originalLocation, cInteropAttributes)
|
) : ModuleInfo(name, cInteropAttributes)
|
||||||
|
|
||||||
private val libraryMap: Map<String, NativeLibrary>
|
private val libraryMap: Map<String, NativeLibrary>
|
||||||
private val moduleInfoMap: Map<String, NativeModuleInfo>
|
private val moduleInfoMap: Map<String, NativeModuleInfo>
|
||||||
@@ -30,7 +29,6 @@ internal class DefaultModulesProvider(libraries: Collection<NativeLibrary>) : Mo
|
|||||||
val manifestData = library.manifestData
|
val manifestData = library.manifestData
|
||||||
|
|
||||||
val name = manifestData.uniqueName
|
val name = manifestData.uniqueName
|
||||||
val location = File(library.library.libraryFile.path)
|
|
||||||
val dependencies = manifestData.dependencies.toSet()
|
val dependencies = manifestData.dependencies.toSet()
|
||||||
|
|
||||||
val cInteropAttributes = if (manifestData.isInterop) {
|
val cInteropAttributes = if (manifestData.isInterop) {
|
||||||
@@ -39,7 +37,7 @@ internal class DefaultModulesProvider(libraries: Collection<NativeLibrary>) : Mo
|
|||||||
} else null
|
} else null
|
||||||
|
|
||||||
libraryMap.put(name, library)?.let { error("Duplicated libraries: $name") }
|
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
|
this.libraryMap = libraryMap
|
||||||
|
|||||||
+28
-19
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind
|
|||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
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)/ */
|
/** 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 hasClassifier(classifierId: CirEntityId): Boolean
|
||||||
fun classifier(classifierId: CirEntityId): CirProvided.Classifier?
|
fun classifier(classifierId: CirEntityId): CirProvided.Classifier?
|
||||||
|
|
||||||
@@ -24,24 +24,6 @@ interface CirProvidedClassifiers {
|
|||||||
override fun findTypeAliasesWithUnderlyingType(underlyingClassifier: CirEntityId) = emptyList<CirEntityId>()
|
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 {
|
companion object {
|
||||||
internal val FALLBACK_FORWARD_DECLARATION_CLASS =
|
internal val FALLBACK_FORWARD_DECLARATION_CLASS =
|
||||||
CirProvided.RegularClass(emptyList(), emptyList(), Visibilities.Public, ClassKind.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)
|
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>()
|
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) }
|
.forEach { attrs -> readExportedForwardDeclarations(attrs, classifiers::set) }
|
||||||
|
|
||||||
if (classifiers.isEmpty) return CirProvidedClassifiers.EMPTY
|
if (classifiers.isEmpty) return CirProvidedClassifiers.EMPTY
|
||||||
|
|||||||
@@ -5,26 +5,23 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.commonizer.mergedtree
|
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.core.*
|
||||||
import org.jetbrains.kotlin.commonizer.CommonizerSettings
|
import org.jetbrains.kotlin.commonizer.CommonizerSettings
|
||||||
|
import org.jetbrains.kotlin.commonizer.cir.*
|
||||||
import org.jetbrains.kotlin.commonizer.utils.CommonizedGroup
|
import org.jetbrains.kotlin.commonizer.utils.CommonizedGroup
|
||||||
import org.jetbrains.kotlin.storage.NullableLazyValue
|
import org.jetbrains.kotlin.storage.NullableLazyValue
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
|
|
||||||
internal fun buildRootNode(
|
internal fun buildRootNode(
|
||||||
storageManager: StorageManager,
|
storageManager: StorageManager,
|
||||||
dependencies: CirProvidedClassifiers,
|
commonDependencies: 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 = { targetDeclarations, commonDeclaration -> CirRootNode(dependencies, targetDeclarations, commonDeclaration) }
|
nodeProducer = { targetDeclarations, commonDeclaration -> CirRootNode(commonDependencies, targetDeclarations, commonDeclaration) }
|
||||||
)
|
)
|
||||||
|
|
||||||
internal fun buildModuleNode(
|
internal fun buildModuleNode(
|
||||||
|
|||||||
+2
-2
@@ -103,7 +103,7 @@ fun InlineSourceBuilder.createCirTreeRootFromSourceCode(@Language("kotlin") sour
|
|||||||
fun InlineSourceBuilder.createCirProvidedClassifiers(module: InlineSourceBuilder.Module): CirProvidedClassifiers {
|
fun InlineSourceBuilder.createCirProvidedClassifiers(module: InlineSourceBuilder.Module): CirProvidedClassifiers {
|
||||||
val modulesProvider = object : ModulesProvider {
|
val modulesProvider = object : ModulesProvider {
|
||||||
override val moduleInfos: Collection<ModulesProvider.ModuleInfo> = listOf(
|
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 {
|
override fun loadModuleMetadata(name: String): SerializedMetadata {
|
||||||
@@ -122,4 +122,4 @@ fun InlineSourceBuilder.createCirProvidedClassifiers(builder: InlineSourceBuilde
|
|||||||
@InlineSourceBuilder.ModuleBuilderDsl
|
@InlineSourceBuilder.ModuleBuilderDsl
|
||||||
fun InlineSourceBuilder.createCirProvidedClassifiersFromSourceCode(@Language("kotlin") sourceCode: String): CirProvidedClassifiers {
|
fun InlineSourceBuilder.createCirProvidedClassifiersFromSourceCode(@Language("kotlin") sourceCode: String): CirProvidedClassifiers {
|
||||||
return createCirProvidedClassifiers(createModule { source(sourceCode) })
|
return createCirProvidedClassifiers(createModule { source(sourceCode) })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ internal class MockModulesProvider private constructor(
|
|||||||
return SERIALIZER.serializeModule(module)
|
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 {
|
companion object {
|
||||||
@JvmName("createByModuleNames")
|
@JvmName("createByModuleNames")
|
||||||
|
|||||||
Reference in New Issue
Block a user