[Commonizer] CommonizerParameters: Require TargetProviders as constructor argument

This commit is contained in:
sebastian.sellmair
2021-03-24 20:02:15 +01:00
parent 79c6b406ba
commit 0a35d75039
8 changed files with 71 additions and 97 deletions
@@ -9,34 +9,35 @@ import org.jetbrains.kotlin.commonizer.konan.NativeManifestDataProvider
import org.jetbrains.kotlin.commonizer.stats.StatsCollector
class CommonizerParameters(
val targetProviders: List<TargetProvider>,
val resultsConsumer: ResultsConsumer,
val manifestDataProvider: TargetDependent<NativeManifestDataProvider>,
val commonManifestProvider: NativeManifestDataProvider,
val commonDependencyModulesProvider: ModulesProvider? = null,
val statsCollector: StatsCollector? = null,
val progressLogger: ((String) -> Unit)? = null
) {
// use linked hash map to preserve order
private val _targetProviders = LinkedHashMap<CommonizerTarget, TargetProvider>()
val targetProviders: List<TargetProvider> get() = _targetProviders.values.toList()
internal val commonTarget: SharedCommonizerTarget = SharedCommonizerTarget(targetProviders.map { it.target }.toSet())
fun addTarget(targetProvider: TargetProvider): CommonizerParameters {
require(targetProvider.target !in _targetProviders) { "Target ${targetProvider.target} is already added" }
_targetProviders[targetProvider.target] = targetProvider
return this
}
fun getCommonModuleNames(): Set<String> {
if (_targetProviders.size < 2) return emptySet() // too few targets
val allModuleNames: List<Set<String>> = _targetProviders.values.map { targetProvider ->
targetProvider.modulesProvider.loadModuleInfos().mapTo(HashSet()) { it.name }
internal val manifestDataProvider: TargetDependent<NativeManifestDataProvider>
get() = TargetDependent { target ->
if (target == commonTarget) return@TargetDependent commonManifestProvider
this.targetProviders.firstOrNull { it.target == target }?.manifestProvider?.let { return@TargetDependent it }
null
}
return allModuleNames.reduce { a, b -> a intersect b } // there are modules that are present in every target
}
fun CommonizerParameters.getCommonModuleNames(): Set<String> {
if (targetProviders.size < 2) return emptySet() // too few targets
val allModuleNames: List<Set<String>> = targetProviders.map { targetProvider ->
targetProvider.modulesProvider.loadModuleInfos().mapTo(HashSet()) { it.name }
}
fun hasAnythingToCommonize(): Boolean {
return getCommonModuleNames().isNotEmpty()
}
return allModuleNames.reduce { a, b -> a intersect b } // there are modules that are present in every target
}
fun CommonizerParameters.hasAnythingToCommonize(): Boolean {
return getCommonModuleNames().isNotEmpty()
}
@@ -5,13 +5,15 @@
package org.jetbrains.kotlin.commonizer
import org.jetbrains.kotlin.commonizer.konan.NativeManifestDataProvider
import org.jetbrains.kotlin.library.SerializedMetadata
import java.io.File
class TargetProvider(
val target: CommonizerTarget,
val modulesProvider: ModulesProvider,
val dependencyModulesProvider: ModulesProvider?
val dependencyModulesProvider: ModulesProvider?,
val manifestProvider: NativeManifestDataProvider
)
interface ModulesProvider {
@@ -42,32 +42,23 @@ internal class LibraryCommonizer internal constructor(
private fun commonizeAndSaveResults(allLibraries: TargetDependent<NativeLibrariesToCommonize>) {
val parameters = CommonizerParameters(
targetProviders = commonTarget.targets.mapNotNull { target -> createTargetProvider(target, allLibraries[target]) },
resultsConsumer = resultsConsumer,
manifestDataProvider = TargetDependentNativeManifestDataProvider(allLibraries),
commonManifestProvider = CommonNativeManifestDataProvider(commonTarget.targets.map { allLibraries[it] }),
commonDependencyModulesProvider = DefaultModulesProvider.create(dependencies.getLibraries(commonTarget)),
statsCollector = statsCollector,
progressLogger = progressLogger::log
)
commonTarget.targets.forEach { target ->
parameters.addTarget(target, allLibraries[target])
}
runCommonization(parameters)
}
private fun CommonizerParameters.addTarget(target: CommonizerTarget, libraries: NativeLibrariesToCommonize) {
if (libraries.libraries.isEmpty()) return
val modulesProvider = DefaultModulesProvider.create(libraries)
val dependencyModuleProvider = DefaultModulesProvider.create(dependencies.getLibraries(target))
addTarget(
TargetProvider(
target = target,
modulesProvider = modulesProvider,
dependencyModulesProvider = dependencyModuleProvider
)
private fun createTargetProvider(target: CommonizerTarget, libraries: NativeLibrariesToCommonize): TargetProvider? {
if (libraries.libraries.isEmpty()) return null
return TargetProvider(
target = target,
modulesProvider = DefaultModulesProvider.create(libraries),
dependencyModulesProvider = DefaultModulesProvider.create(dependencies.getLibraries(target)),
manifestProvider = libraries,
)
}
@@ -17,17 +17,6 @@ interface NativeManifestDataProvider {
fun getManifest(libraryName: String): NativeSensitiveManifestData
}
internal fun TargetDependentNativeManifestDataProvider(
libraries: TargetDependent<NativeLibrariesToCommonize>
): TargetDependent<NativeManifestDataProvider> {
return TargetDependent { target ->
when (target) {
is LeafCommonizerTarget -> libraries[target]
is SharedCommonizerTarget -> CommonNativeManifestDataProvider(target.targets.map { libraries[it] })
}
}
}
/**
* A separate Kotlin/Native library.
*/
@@ -5,12 +5,9 @@
package org.jetbrains.kotlin.commonizer.mergedtree.mergers
import org.jetbrains.kotlin.commonizer.CommonizerParameters
import org.jetbrains.kotlin.commonizer.CommonizerTarget
import org.jetbrains.kotlin.commonizer.ModulesProvider
import org.jetbrains.kotlin.commonizer.*
import org.jetbrains.kotlin.commonizer.mergedtree.*
import org.jetbrains.kotlin.commonizer.metadata.CirTypeResolver
import org.jetbrains.kotlin.commonizer.prettyName
import org.jetbrains.kotlin.storage.StorageManager
internal class RootMerger(
@@ -206,24 +206,20 @@ private class AnalyzedModules(
fun toCommonizerParameters(
resultsConsumer: ResultsConsumer,
manifestDataProvider: TargetDependent<NativeManifestDataProvider> = MockNativeManifestDataProvider()
manifestDataProvider: NativeManifestDataProvider = MockNativeManifestDataProvider()
) = CommonizerParameters(
resultsConsumer, manifestDataProvider,
commonDependencyModulesProvider = dependencyModules[sharedTarget]?.let(MockModulesProvider::create)
).also { parameters ->
leafTargets.forEach { leafTarget ->
val originalModule = originalModules.getValue(leafTarget)
parameters.addTarget(
TargetProvider(
target = leafTarget,
modulesProvider = MockModulesProvider.create(originalModule),
dependencyModulesProvider = dependencyModules[leafTarget]?.let(MockModulesProvider::create)
)
targetProviders = leafTargets.map { leafTarget ->
TargetProvider(
target = leafTarget,
modulesProvider = MockModulesProvider.create(originalModules.getValue(leafTarget)),
dependencyModulesProvider = dependencyModules[leafTarget]?.let(MockModulesProvider::create),
manifestProvider = manifestDataProvider
)
}
}
},
resultsConsumer = resultsConsumer,
commonManifestProvider = manifestDataProvider,
commonDependencyModulesProvider = dependencyModules[sharedTarget]?.let(MockModulesProvider::create)
)
companion object {
fun create(
@@ -64,20 +64,22 @@ class CommonizerFacadeTest {
)
companion object {
private fun Map<String, List<String>>.toCommonizerParameters(
resultsConsumer: ResultsConsumer,
manifestDataProvider: TargetDependent<NativeManifestDataProvider> = MockNativeManifestDataProvider()
) = CommonizerParameters(resultsConsumer, manifestDataProvider).also { parameters ->
forEach { (targetName, moduleNames) ->
parameters.addTarget(
TargetProvider(
target = LeafCommonizerTarget(targetName),
modulesProvider = MockModulesProvider.create(moduleNames),
dependencyModulesProvider = null
)
manifestDataProvider: NativeManifestDataProvider = MockNativeManifestDataProvider()
) = CommonizerParameters(
targetProviders = map { (targetName, moduleNames) ->
TargetProvider(
target = LeafCommonizerTarget(targetName),
modulesProvider = MockModulesProvider.create(moduleNames),
dependencyModulesProvider = null,
manifestProvider = manifestDataProvider,
)
}
}
},
resultsConsumer = resultsConsumer,
commonManifestProvider = manifestDataProvider
)
private fun doTestNothingToCommonize(originalModules: Map<String, List<String>>) {
val results = MockResultsConsumer()
@@ -17,7 +17,6 @@ import org.jetbrains.kotlin.commonizer.ResultsConsumer.ModuleResult
import org.jetbrains.kotlin.commonizer.cir.*
import org.jetbrains.kotlin.commonizer.konan.NativeManifestDataProvider
import org.jetbrains.kotlin.commonizer.konan.NativeSensitiveManifestData
import org.jetbrains.kotlin.commonizer.konan.TargetDependentNativeManifestDataProvider
import org.jetbrains.kotlin.commonizer.mergedtree.*
import org.jetbrains.kotlin.library.KotlinLibraryVersioning
import org.jetbrains.kotlin.library.SerializedMetadata
@@ -176,20 +175,17 @@ fun MockNativeManifestDataProvider(
exportForwardDeclarations: List<String> = emptyList(),
nativeTargets: Collection<String> = emptyList(),
shortName: String? = "mock"
): TargetDependent<NativeManifestDataProvider> = TargetDependent {
object : NativeManifestDataProvider {
override fun getManifest(libraryName: String): NativeSensitiveManifestData {
return NativeSensitiveManifestData(
uniqueName = uniqueName,
versions = versions,
dependencies = dependencies,
isInterop = isInterop,
packageFqName = packageFqName,
exportForwardDeclarations = exportForwardDeclarations,
nativeTargets = nativeTargets,
shortName = shortName
)
}
): NativeManifestDataProvider = object : NativeManifestDataProvider {
override fun getManifest(libraryName: String): NativeSensitiveManifestData {
return NativeSensitiveManifestData(
uniqueName = uniqueName,
versions = versions,
dependencies = dependencies,
isInterop = isInterop,
packageFqName = packageFqName,
exportForwardDeclarations = exportForwardDeclarations,
nativeTargets = nativeTargets,
shortName = shortName
)
}
}