[Commonizer] Implement associative commonization
^KT-47301 Verification Pending
This commit is contained in:
committed by
Space
parent
5fdbcb3dd1
commit
42f60d981f
@@ -9,27 +9,22 @@ 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.stats.StatsCollector
|
||||
import org.jetbrains.kotlin.commonizer.utils.ProgressLogger
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.util.Logger
|
||||
|
||||
data class CommonizerParameters(
|
||||
val outputTarget: SharedCommonizerTarget,
|
||||
val outputTargets: Set<SharedCommonizerTarget>,
|
||||
val manifestProvider: TargetDependent<NativeManifestDataProvider>,
|
||||
val dependenciesProvider: TargetDependent<ModulesProvider?>,
|
||||
val targetProviders: TargetDependent<TargetProvider?>,
|
||||
val resultsConsumer: ResultsConsumer,
|
||||
val storageManager: StorageManager = LockBasedStorageManager.NO_LOCKS,
|
||||
val statsCollector: StatsCollector? = null,
|
||||
val logger: ProgressLogger? = null,
|
||||
val logger: Logger? = null,
|
||||
)
|
||||
|
||||
internal fun CommonizerParameters.dependencyClassifiers(target: CommonizerTarget): CirProvidedClassifiers {
|
||||
val modules = outputTarget.withAllAncestors()
|
||||
.sortedBy { it.level }
|
||||
.filter { it == target || it isAncestorOf target }
|
||||
.mapNotNull { compatibleTarget -> dependenciesProvider[compatibleTarget] }
|
||||
|
||||
return modules.fold<ModulesProvider, CirProvidedClassifiers>(CirFictitiousFunctionClassifiers) { classifiers, module ->
|
||||
CirProvidedClassifiers.of(classifiers, CirProvidedClassifiers.by(module))
|
||||
}
|
||||
val modulesProvider = dependenciesProvider[target]
|
||||
return CirProvidedClassifiers.of(CirFictitiousFunctionClassifiers, CirProvidedClassifiers.by(modulesProvider))
|
||||
}
|
||||
|
||||
internal fun CommonizerParameters.with(logger: ProgressLogger?) = copy(logger = logger)
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.commonizer
|
||||
|
||||
import org.jetbrains.kotlin.commonizer.mergedtree.CirRootNode
|
||||
import org.jetbrains.kotlin.commonizer.tree.CirTreeRoot
|
||||
import org.jetbrains.kotlin.commonizer.tree.assembleCirTree
|
||||
import org.jetbrains.kotlin.storage.NullableLazyValue
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
|
||||
private typealias OutputCommonizerTarget = SharedCommonizerTarget
|
||||
private typealias InputCommonizerTarget = CommonizerTarget
|
||||
|
||||
internal fun CommonizerQueue(parameters: CommonizerParameters): CommonizerQueue {
|
||||
return CommonizerQueue(
|
||||
storageManager = parameters.storageManager,
|
||||
outputTargets = parameters.outputTargets,
|
||||
deserializers = parameters.targetProviders.mapTargets { target ->
|
||||
CommonizerQueue.Deserializer { deserializeTarget(parameters, target) }
|
||||
},
|
||||
commonizer = { inputs, output -> commonizeTarget(parameters, inputs, output) },
|
||||
serializer = { declarations, outputTarget -> serializeTarget(parameters, declarations, outputTarget) },
|
||||
inputTargetsSelector = DefaultInputTargetsSelector
|
||||
)
|
||||
}
|
||||
|
||||
internal class CommonizerQueue(
|
||||
private val storageManager: StorageManager,
|
||||
private val outputTargets: Set<OutputCommonizerTarget>,
|
||||
private val deserializers: TargetDependent<Deserializer>,
|
||||
private val commonizer: Commonizer,
|
||||
private val serializer: Serializer,
|
||||
private val inputTargetsSelector: InputTargetsSelector
|
||||
) {
|
||||
|
||||
fun interface Deserializer {
|
||||
operator fun invoke(): CirTreeRoot?
|
||||
}
|
||||
|
||||
fun interface Commonizer {
|
||||
operator fun invoke(inputs: TargetDependent<CirTreeRoot?>, output: SharedCommonizerTarget): CirRootNode?
|
||||
}
|
||||
|
||||
fun interface Serializer {
|
||||
operator fun invoke(declarations: CirRootNode, outputTarget: OutputCommonizerTarget)
|
||||
}
|
||||
|
||||
/**
|
||||
* Targets that can just be deserialized and do not need to be commonized.
|
||||
* All leaf targets are expected to be provided.
|
||||
* Previously commonized targets can also be provided
|
||||
*/
|
||||
private val deserializedTargets: MutableMap<InputCommonizerTarget, NullableLazyValue<CirTreeRoot>> =
|
||||
deserializers.toMap().mapValuesTo(mutableMapOf()) { (_, deserializer) ->
|
||||
storageManager.createNullableLazyValue { deserializer() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Targets that created using commonization.
|
||||
* The roots are lazy and will be removed as no further pending target requires it's input
|
||||
*/
|
||||
private val commonizedTargets: MutableMap<OutputCommonizerTarget, NullableLazyValue<CirTreeRoot>> = mutableMapOf()
|
||||
|
||||
/**
|
||||
* Represents dependency relationships between input and output targets.
|
||||
* Dependencies will be removed if the target was commonized.
|
||||
*/
|
||||
private val targetDependencies: MutableMap<OutputCommonizerTarget, Set<InputCommonizerTarget>> = mutableMapOf()
|
||||
|
||||
val retainedDeserializedTargets: Set<InputCommonizerTarget> get() = deserializedTargets.keys
|
||||
|
||||
val retainedCommonizedTargets: Set<OutputCommonizerTarget> get() = commonizedTargets.keys
|
||||
|
||||
val retainedTargetDependencies: Map<OutputCommonizerTarget, Set<InputCommonizerTarget>> get() = targetDependencies.toMap()
|
||||
|
||||
val pendingOutputTargets: Set<CommonizerTarget> get() = targetDependencies.keys
|
||||
|
||||
/**
|
||||
* Runs all tasks/targets in this queue
|
||||
*/
|
||||
fun invokeAll() {
|
||||
outputTargets.forEach { outputTarget -> invokeTarget(outputTarget) }
|
||||
assert(deserializedTargets.isEmpty()) { "Expected 'deserializedTargets' to be empty. Found ${deserializedTargets.keys}" }
|
||||
assert(commonizedTargets.isEmpty()) { "Expected 'commonizedTargets' to be empty. Found ${commonizedTargets.keys}" }
|
||||
assert(targetDependencies.isEmpty()) { "Expected 'targetDependencies' to be empty. Found $targetDependencies" }
|
||||
}
|
||||
|
||||
fun invokeTarget(outputTarget: OutputCommonizerTarget) {
|
||||
commonizedTargets[outputTarget]?.invoke()
|
||||
}
|
||||
|
||||
private fun enqueue(outputTarget: OutputCommonizerTarget) {
|
||||
registerTargetDependencies(outputTarget)
|
||||
|
||||
commonizedTargets[outputTarget] = storageManager.createNullableLazyValue {
|
||||
commonize(outputTarget)
|
||||
}
|
||||
}
|
||||
|
||||
private fun commonize(target: SharedCommonizerTarget): CirTreeRoot? {
|
||||
val inputTargets = targetDependencies.getValue(target)
|
||||
|
||||
val inputDeclarations = EagerTargetDependent(inputTargets) { inputTarget ->
|
||||
(deserializedTargets[inputTarget] ?: commonizedTargets[inputTarget]
|
||||
?: throw IllegalStateException("Missing inputTarget $inputTarget")).invoke()
|
||||
}
|
||||
|
||||
return commonizer(inputDeclarations, target)
|
||||
.also { removeTargetDependencies(target) }
|
||||
?.also { commonizedDeclarations -> serializer(commonizedDeclarations, target) }
|
||||
?.assembleCirTree()
|
||||
|
||||
}
|
||||
|
||||
private fun registerTargetDependencies(outputTarget: OutputCommonizerTarget) {
|
||||
targetDependencies[outputTarget] = inputTargetsSelector(outputTargets + deserializers.targets, outputTarget)
|
||||
}
|
||||
|
||||
private fun removeTargetDependencies(target: OutputCommonizerTarget) {
|
||||
targetDependencies.remove(target) ?: return
|
||||
val referencedDependencyTargets = targetDependencies.values.flatten().toSet()
|
||||
|
||||
// Release all commonized targets that are not pending anymore (are already invoked)
|
||||
// and that are not listed as input target dependency for any further commonization
|
||||
// Release all commonized targets that no one intends to use any further.
|
||||
commonizedTargets.keys
|
||||
.filter { it !in referencedDependencyTargets && it !in pendingOutputTargets }
|
||||
.forEach(commonizedTargets::remove)
|
||||
|
||||
// Release all deserialized targets that are not referenced as any further dependency anymore.
|
||||
// Release all deserialized targets that no one intends to use any further
|
||||
deserializedTargets.keys
|
||||
.filter { it !in referencedDependencyTargets }
|
||||
.forEach(deserializedTargets::remove)
|
||||
}
|
||||
|
||||
init {
|
||||
outputTargets.forEach(this::enqueue)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.commonizer
|
||||
|
||||
import org.jetbrains.kotlin.commonizer.utils.isProperSubsetOf
|
||||
import org.jetbrains.kotlin.commonizer.utils.isSubsetOf
|
||||
|
||||
internal fun interface InputTargetsSelector {
|
||||
operator fun invoke(inputTargets: Set<CommonizerTarget>, outputTarget: SharedCommonizerTarget): Set<CommonizerTarget>
|
||||
}
|
||||
|
||||
internal operator fun InputTargetsSelector.invoke(
|
||||
parameters: CommonizerParameters,
|
||||
outputTarget: SharedCommonizerTarget
|
||||
): Set<CommonizerTarget> {
|
||||
return invoke(parameters.outputTargets + parameters.targetProviders.targets, outputTarget)
|
||||
}
|
||||
|
||||
internal object DefaultInputTargetsSelector : InputTargetsSelector {
|
||||
override fun invoke(inputTargets: Set<CommonizerTarget>, outputTarget: SharedCommonizerTarget): Set<CommonizerTarget> {
|
||||
|
||||
val subsetInputTargets = inputTargets
|
||||
.filter { inputTarget -> inputTarget != outputTarget && inputTarget.allLeaves() isSubsetOf outputTarget.allLeaves() }
|
||||
.sortedBy { it.allLeaves().size }
|
||||
|
||||
val disjointSubsetInputTargets = subsetInputTargets
|
||||
.filter { inputTarget ->
|
||||
subsetInputTargets.none { potentialSuperSet -> inputTarget.allLeaves() isProperSubsetOf potentialSuperSet.allLeaves() }
|
||||
}
|
||||
|
||||
return outputTarget.allLeaves().fold(setOf()) { selectedInputTargets, outputLeafTarget ->
|
||||
if (outputLeafTarget in selectedInputTargets.allLeaves()) return@fold selectedInputTargets
|
||||
selectedInputTargets + (disjointSubsetInputTargets.firstOrNull { inputTarget -> outputLeafTarget in inputTarget.allLeaves() }
|
||||
?: failedSelectingInputTargets(inputTargets, outputTarget))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun failedSelectingInputTargets(inputTargets: Set<CommonizerTarget>, outputTarget: SharedCommonizerTarget): Nothing {
|
||||
throw IllegalArgumentException(
|
||||
"Failed selecting input targets for $outputTarget\n" +
|
||||
"inputTargets=$inputTargets\n" +
|
||||
"missing leaf targets: ${outputTarget.allLeaves() - inputTargets.allLeaves()}"
|
||||
)
|
||||
}
|
||||
+7
-7
@@ -8,16 +8,16 @@ package org.jetbrains.kotlin.commonizer.cli
|
||||
import org.jetbrains.kotlin.commonizer.SharedCommonizerTarget
|
||||
import org.jetbrains.kotlin.commonizer.parseCommonizerTarget
|
||||
|
||||
internal object OutputCommonizerTargetOptionType : OptionType<SharedCommonizerTarget>(
|
||||
alias = "output-commonizer-target",
|
||||
description = "Shared commonizer target representing the commonized output hierarchy",
|
||||
mandatory = false
|
||||
internal object OutputCommonizerTargetsOptionType : OptionType<Set<SharedCommonizerTarget>>(
|
||||
alias = "output-targets",
|
||||
description = "Shared commonizer target representing the commonized output hierarchy", // TODO NOW
|
||||
mandatory = true
|
||||
) {
|
||||
override fun parse(rawValue: String, onError: (reason: String) -> Nothing): Option<SharedCommonizerTarget> {
|
||||
override fun parse(rawValue: String, onError: (reason: String) -> Nothing): Option<Set<SharedCommonizerTarget>> {
|
||||
return try {
|
||||
Option(this, parseCommonizerTarget(rawValue) as SharedCommonizerTarget)
|
||||
Option(this, rawValue.split(";").map(::parseCommonizerTarget).map { it as SharedCommonizerTarget }.toSet())
|
||||
} catch (t: Throwable) {
|
||||
onError("Failed parsing output-commonizer-target ($rawValue): ${t.message}")
|
||||
onError("Failed parsing output-target ($rawValue): ${t.message}")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ internal enum class TaskType(
|
||||
NativeDistributionOptionType,
|
||||
OutputOptionType,
|
||||
NativeTargetsOptionType,
|
||||
OutputCommonizerTargetOptionType,
|
||||
OutputCommonizerTargetsOptionType,
|
||||
BooleanOptionType(
|
||||
"copy-stdlib",
|
||||
"Boolean (default false);\nwhether to copy Kotlin/Native endorsed libraries to the destination",
|
||||
@@ -52,7 +52,7 @@ internal enum class TaskType(
|
||||
OutputOptionType,
|
||||
InputLibrariesOptionType,
|
||||
DependencyLibrariesOptionType,
|
||||
OutputCommonizerTargetOptionType,
|
||||
OutputCommonizerTargetsOptionType,
|
||||
LogLevelOptionType
|
||||
),
|
||||
::NativeKlibCommonize
|
||||
|
||||
@@ -3,18 +3,19 @@
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@file:Suppress("DuplicatedCode")
|
||||
|
||||
package org.jetbrains.kotlin.commonizer.cli
|
||||
|
||||
import org.jetbrains.kotlin.commonizer.*
|
||||
import org.jetbrains.kotlin.commonizer.konan.*
|
||||
import org.jetbrains.kotlin.commonizer.konan.LibraryCommonizer
|
||||
import org.jetbrains.kotlin.commonizer.konan.ModuleSerializer
|
||||
import org.jetbrains.kotlin.commonizer.repository.*
|
||||
import org.jetbrains.kotlin.commonizer.stats.FileStatsOutput
|
||||
import org.jetbrains.kotlin.commonizer.stats.StatsCollector
|
||||
import org.jetbrains.kotlin.commonizer.stats.StatsType
|
||||
import org.jetbrains.kotlin.commonizer.utils.ProgressLogger
|
||||
import org.jetbrains.kotlin.konan.library.KONAN_DISTRIBUTION_KLIB_DIR
|
||||
import org.jetbrains.kotlin.konan.library.KONAN_DISTRIBUTION_PLATFORM_LIBS_DIR
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import java.io.File
|
||||
|
||||
internal class NativeDistributionListTargets(options: Collection<Option<*>>) : Task(options) {
|
||||
@@ -48,35 +49,31 @@ internal class NativeKlibCommonize(options: Collection<Option<*>>) : Task(option
|
||||
val destination = getMandatory<File, OutputOptionType>()
|
||||
val targetLibraries = getMandatory<List<File>, InputLibrariesOptionType>()
|
||||
val dependencyLibraries = getOptional<List<CommonizerDependency>, DependencyLibrariesOptionType>().orEmpty()
|
||||
val outputCommonizerTarget = compatGetOutputTarget()
|
||||
val outputTargets = getMandatory<Set<SharedCommonizerTarget>, OutputCommonizerTargetsOptionType>()
|
||||
val statsType = getOptional<StatsType, StatsTypeOptionType> { it == "log-stats" } ?: StatsType.NONE
|
||||
val logLevel = getOptional<CommonizerLogLevel, LogLevelOptionType>() ?: CommonizerLogLevel.Quiet
|
||||
|
||||
|
||||
val konanTargets = outputCommonizerTarget.konanTargets
|
||||
val konanTargets = outputTargets.konanTargets
|
||||
val commonizerTargets = konanTargets.map(::CommonizerTarget)
|
||||
|
||||
val logger = ProgressLogger(CliLoggerAdapter(logLevel, 2))
|
||||
val logger = CliLoggerAdapter(logLevel, 2)
|
||||
val libraryLoader = DefaultNativeLibraryLoader(logger)
|
||||
val statsCollector = StatsCollector(statsType, commonizerTargets)
|
||||
val repository = FilesRepository(targetLibraries.toSet(), libraryLoader)
|
||||
|
||||
val resultsConsumer = buildResultsConsumer {
|
||||
this add ModuleSerializer(destination, HierarchicalCommonizerOutputLayout)
|
||||
this add CopyUnconsumedModulesAsIsConsumer(
|
||||
repository, destination, commonizerTargets.toSet(), NativeDistributionCommonizerOutputLayout
|
||||
)
|
||||
this add LoggingResultsConsumer(outputCommonizerTarget)
|
||||
this add ModuleSerializer(destination)
|
||||
}
|
||||
|
||||
LibraryCommonizer(
|
||||
outputTarget = outputCommonizerTarget,
|
||||
outputTargets = outputTargets,
|
||||
repository = repository,
|
||||
dependencies = StdlibRepository(distribution, libraryLoader) +
|
||||
CommonizerDependencyRepository(dependencyLibraries.toSet(), libraryLoader),
|
||||
resultsConsumer = resultsConsumer,
|
||||
statsCollector = statsCollector,
|
||||
progressLogger = logger
|
||||
logger = logger
|
||||
).run()
|
||||
|
||||
statsCollector?.writeTo(FileStatsOutput(destination, statsType.name.lowercase()))
|
||||
@@ -90,40 +87,30 @@ internal class NativeDistributionCommonize(options: Collection<Option<*>>) : Tas
|
||||
val distribution = KonanDistribution(getMandatory<File, NativeDistributionOptionType>())
|
||||
val destination = getMandatory<File, OutputOptionType>()
|
||||
|
||||
val outputTarget = compatGetOutputTarget()
|
||||
val outputLayout = if (getOptional<SharedCommonizerTarget, OutputCommonizerTargetOptionType>() != null)
|
||||
HierarchicalCommonizerOutputLayout
|
||||
else NativeDistributionCommonizerOutputLayout
|
||||
val outputTargets = getMandatory<Set<SharedCommonizerTarget>, OutputCommonizerTargetsOptionType>()
|
||||
|
||||
|
||||
val copyStdlib = getOptional<Boolean, BooleanOptionType> { it == "copy-stdlib" } ?: false
|
||||
val copyEndorsedLibs = getOptional<Boolean, BooleanOptionType> { it == "copy-endorsed-libs" } ?: false
|
||||
val statsType = getOptional<StatsType, StatsTypeOptionType> { it == "log-stats" } ?: StatsType.NONE
|
||||
val logLevel = getOptional<CommonizerLogLevel, LogLevelOptionType>() ?: CommonizerLogLevel.Quiet
|
||||
|
||||
val logger = ProgressLogger(CliLoggerAdapter(logLevel, 2))
|
||||
val logger = CliLoggerAdapter(logLevel, 2)
|
||||
val libraryLoader = DefaultNativeLibraryLoader(logger)
|
||||
val repository = KonanDistributionRepository(distribution, outputTarget.konanTargets, libraryLoader)
|
||||
val statsCollector = StatsCollector(statsType, outputTarget.withAllAncestors().toList())
|
||||
val repository = KonanDistributionRepository(distribution, outputTargets.konanTargets, libraryLoader)
|
||||
val statsCollector = StatsCollector(statsType, outputTargets.allLeaves().toList())
|
||||
|
||||
val resultsConsumer = buildResultsConsumer {
|
||||
this add ModuleSerializer(destination, outputLayout)
|
||||
this add CopyUnconsumedModulesAsIsConsumer(repository, destination, outputTarget.allLeaves(), outputLayout)
|
||||
if (copyStdlib) this add CopyStdlibResultsConsumer(distribution, destination)
|
||||
if (copyEndorsedLibs) this add CopyEndorsedLibrairesResultsConsumer(distribution, destination)
|
||||
this add LoggingResultsConsumer(outputTarget)
|
||||
this add ModuleSerializer(destination)
|
||||
}
|
||||
|
||||
val descriptionSuffix = estimateLibrariesCount(repository, outputTarget.allLeaves()).let { " ($it items)" }
|
||||
logger.log("${logPrefix}Preparing commonized Kotlin/Native libraries for $outputTarget$descriptionSuffix")
|
||||
val descriptionSuffix = estimateLibrariesCount(repository, outputTargets.allLeaves()).let { " ($it items)" }
|
||||
logger.log("${logPrefix}Preparing commonized Kotlin/Native libraries for ${outputTargets.allLeaves()}$descriptionSuffix")
|
||||
|
||||
LibraryCommonizer(
|
||||
outputTarget = outputTarget,
|
||||
outputTargets = outputTargets,
|
||||
repository = repository,
|
||||
dependencies = StdlibRepository(distribution, libraryLoader),
|
||||
resultsConsumer = resultsConsumer,
|
||||
statsCollector = statsCollector,
|
||||
progressLogger = logger
|
||||
logger = logger
|
||||
).run()
|
||||
|
||||
statsCollector?.writeTo(FileStatsOutput(destination, statsType.name.lowercase()))
|
||||
@@ -136,10 +123,4 @@ internal class NativeDistributionCommonize(options: Collection<Option<*>>) : Tas
|
||||
}
|
||||
}
|
||||
|
||||
private fun Task.compatGetOutputTarget(): SharedCommonizerTarget {
|
||||
getOptional<SharedCommonizerTarget, OutputCommonizerTargetOptionType>()?.let { return it }
|
||||
val konanTargets = getOptional<List<KonanTarget>, NativeTargetsOptionType>() ?: throw IllegalArgumentException(
|
||||
"Missing ${OutputCommonizerTargetOptionType.alias} or deprecated ${NativeTargetsOptionType.alias} option was specified"
|
||||
)
|
||||
return SharedCommonizerTarget(konanTargets)
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ package org.jetbrains.kotlin.commonizer
|
||||
* @return Set of module names that is available across all children targets
|
||||
*/
|
||||
internal fun CommonizerParameters.commonModuleNames(target: CommonizerTarget): Set<String> {
|
||||
val supportedTargets = target.withAllAncestors().mapNotNull(targetProviders::getOrNull)
|
||||
val supportedTargets = target.withAllLeaves().mapNotNull(targetProviders::getOrNull)
|
||||
if (supportedTargets.isEmpty()) return emptySet() // Nothing to do
|
||||
|
||||
val allModuleNames: List<Set<String>> = supportedTargets.toList().map { targetProvider ->
|
||||
@@ -23,8 +23,8 @@ internal fun CommonizerParameters.commonModuleNames(target: CommonizerTarget): S
|
||||
* @return Set of module names that this [targetProvider] shares with *at least* one other target
|
||||
*/
|
||||
internal fun CommonizerParameters.commonModuleNames(targetProvider: TargetProvider): Set<String> {
|
||||
return outputTarget.withAllAncestors()
|
||||
.filter { target -> target isAncestorOf targetProvider.target }
|
||||
return outputTargets
|
||||
.filter { target -> (target.allLeaves() intersect targetProvider.target.allLeaves()).isNotEmpty() }
|
||||
.map { target -> commonModuleNames(target) }
|
||||
.fold(emptySet()) { acc, names -> acc + names }
|
||||
}
|
||||
|
||||
@@ -6,22 +6,24 @@
|
||||
package org.jetbrains.kotlin.commonizer.core
|
||||
|
||||
import org.jetbrains.kotlin.commonizer.CommonizerTarget
|
||||
import org.jetbrains.kotlin.commonizer.LeafCommonizerTarget
|
||||
import org.jetbrains.kotlin.commonizer.SharedCommonizerTarget
|
||||
import org.jetbrains.kotlin.commonizer.allLeaves
|
||||
import org.jetbrains.kotlin.commonizer.cir.CirRoot
|
||||
|
||||
class RootCommonizer : AbstractStandardCommonizer<CirRoot, CirRoot>() {
|
||||
private val targets = mutableSetOf<CommonizerTarget>()
|
||||
private val targets = mutableSetOf<LeafCommonizerTarget>()
|
||||
|
||||
override fun commonizationResult() = CirRoot.create(
|
||||
target = SharedCommonizerTarget(targets)
|
||||
)
|
||||
|
||||
override fun initialize(first: CirRoot) {
|
||||
targets += first.target
|
||||
targets += first.target.allLeaves()
|
||||
}
|
||||
|
||||
override fun doCommonizeWith(next: CirRoot): Boolean {
|
||||
targets += next.target
|
||||
targets += next.target.allLeaves()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,126 +6,79 @@
|
||||
package org.jetbrains.kotlin.commonizer
|
||||
|
||||
import kotlinx.metadata.klib.ChunkedKlibModuleFragmentWriteStrategy
|
||||
import org.jetbrains.kotlin.commonizer.ResultsConsumer.ModuleResult
|
||||
import org.jetbrains.kotlin.commonizer.ResultsConsumer.ModuleResult.Missing
|
||||
import org.jetbrains.kotlin.commonizer.ResultsConsumer.Status
|
||||
import org.jetbrains.kotlin.commonizer.core.CommonizationVisitor
|
||||
import org.jetbrains.kotlin.commonizer.mergedtree.CirCommonizedClassifierNodes
|
||||
import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers
|
||||
import org.jetbrains.kotlin.commonizer.mergedtree.CirNode.Companion.indexOfCommon
|
||||
import org.jetbrains.kotlin.commonizer.mergedtree.CirNode.Companion.targetIndices
|
||||
import org.jetbrains.kotlin.commonizer.mergedtree.CirRootNode
|
||||
import org.jetbrains.kotlin.commonizer.metadata.CirTreeSerializer.serializeSingleTarget
|
||||
import org.jetbrains.kotlin.commonizer.metadata.CirTreeSerializer
|
||||
import org.jetbrains.kotlin.commonizer.transformer.Checked.Companion.invoke
|
||||
import org.jetbrains.kotlin.commonizer.transformer.InlineTypeAliasCirNodeTransformer
|
||||
import org.jetbrains.kotlin.commonizer.tree.CirTreeRoot
|
||||
import org.jetbrains.kotlin.commonizer.tree.assembleCirTree
|
||||
import org.jetbrains.kotlin.commonizer.tree.deserializeCirTree
|
||||
import org.jetbrains.kotlin.commonizer.tree.defaultCirTreeRootDeserializer
|
||||
import org.jetbrains.kotlin.commonizer.tree.mergeCirTree
|
||||
import org.jetbrains.kotlin.commonizer.utils.progress
|
||||
import org.jetbrains.kotlin.library.SerializedMetadata
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
|
||||
fun runCommonization(parameters: CommonizerParameters) {
|
||||
if (!parameters.containsCommonModuleNames()) {
|
||||
parameters.resultsConsumer.allConsumed(parameters, Status.NOTHING_TO_DO)
|
||||
return
|
||||
}
|
||||
|
||||
val storageManager = LockBasedStorageManager("Declarations commonization")
|
||||
commonize(parameters, storageManager, parameters.outputTarget)
|
||||
CommonizerQueue(parameters).invokeAll()
|
||||
parameters.resultsConsumer.allConsumed(parameters, Status.DONE)
|
||||
}
|
||||
|
||||
private fun commonize(
|
||||
parameters: CommonizerParameters,
|
||||
storageManager: StorageManager,
|
||||
target: SharedCommonizerTarget,
|
||||
): CirRootNode? {
|
||||
val cirTrees = getCirTree(parameters, storageManager, target)
|
||||
parameters.logProgress("Built declaration tree for $target")
|
||||
|
||||
// build merged tree:
|
||||
val classifiers = CirKnownClassifiers(
|
||||
commonizedNodes = CirCommonizedClassifierNodes.default(),
|
||||
commonDependencies = parameters.dependencyClassifiers(target)
|
||||
)
|
||||
|
||||
val mergedTree = merge(storageManager, classifiers, cirTrees) ?: return null
|
||||
InlineTypeAliasCirNodeTransformer(storageManager, classifiers).invoke(mergedTree)
|
||||
mergedTree.accept(CommonizationVisitor(classifiers, mergedTree), Unit)
|
||||
parameters.logProgress("Commonized declarations for $target")
|
||||
|
||||
serialize(parameters, mergedTree, target)
|
||||
|
||||
return mergedTree
|
||||
}
|
||||
|
||||
private fun getCirTree(
|
||||
parameters: CommonizerParameters, storageManager: StorageManager, target: SharedCommonizerTarget
|
||||
): TargetDependent<CirTreeRoot?> {
|
||||
return EagerTargetDependent(target.targets) { childTarget ->
|
||||
when (childTarget) {
|
||||
is LeafCommonizerTarget -> deserialize(parameters, childTarget)
|
||||
is SharedCommonizerTarget -> commonize(parameters.fork(), storageManager, childTarget)?.assembleCirTree().also {
|
||||
parameters.logProgress("Commonized target $childTarget")
|
||||
}
|
||||
}
|
||||
internal fun deserializeTarget(parameters: CommonizerParameters, target: TargetProvider): CirTreeRoot {
|
||||
return parameters.logger.progress(target.target, "Deserialized declarations") {
|
||||
defaultCirTreeRootDeserializer(parameters, target)
|
||||
}
|
||||
}
|
||||
|
||||
private fun deserialize(parameters: CommonizerParameters, target: CommonizerTarget): CirTreeRoot? {
|
||||
internal fun deserializeTarget(parameters: CommonizerParameters, target: CommonizerTarget): CirTreeRoot? {
|
||||
val targetProvider = parameters.targetProviders[target] ?: return null
|
||||
return deserializeCirTree(parameters, targetProvider)
|
||||
return deserializeTarget(parameters, targetProvider)
|
||||
}
|
||||
|
||||
private fun merge(
|
||||
storageManager: StorageManager, classifiers: CirKnownClassifiers, cirTrees: TargetDependent<CirTreeRoot?>,
|
||||
internal fun commonizeTarget(
|
||||
parameters: CommonizerParameters,
|
||||
inputs: TargetDependent<CirTreeRoot?>,
|
||||
output: CommonizerTarget
|
||||
): CirRootNode? {
|
||||
val availableTrees = cirTrees.filterNonNull()
|
||||
/* Nothing to merge */
|
||||
if (availableTrees.size == 0) return null
|
||||
parameters.logger.progress(output, "Commonized declarations from ${inputs.targets}") {
|
||||
val availableTrees = inputs.filterNonNull()
|
||||
/* Nothing to merge */
|
||||
if (availableTrees.size == 0) return null
|
||||
|
||||
return mergeCirTree(storageManager, classifiers, availableTrees)
|
||||
}
|
||||
val classifiers = CirKnownClassifiers(
|
||||
commonizedNodes = CirCommonizedClassifierNodes.default(),
|
||||
commonDependencies = parameters.dependencyClassifiers(output)
|
||||
)
|
||||
|
||||
private fun serialize(parameters: CommonizerParameters, mergedTree: CirRootNode, commonTarget: CommonizerTarget) {
|
||||
for (targetIndex in mergedTree.targetIndices) {
|
||||
val target = mergedTree.targetDeclarations[targetIndex]?.target ?: continue
|
||||
serializeMissingModules(parameters, target)
|
||||
if (target is LeafCommonizerTarget) {
|
||||
serialize(parameters, mergedTree, target, targetIndex)
|
||||
}
|
||||
val mergedTree = mergeCirTree(parameters.storageManager, classifiers, availableTrees)
|
||||
InlineTypeAliasCirNodeTransformer(parameters.storageManager, classifiers).invoke(mergedTree)
|
||||
mergedTree.accept(CommonizationVisitor(classifiers, mergedTree), Unit)
|
||||
|
||||
return mergedTree
|
||||
}
|
||||
serialize(parameters, mergedTree, commonTarget, mergedTree.indexOfCommon)
|
||||
}
|
||||
|
||||
private fun serialize(parameters: CommonizerParameters, mergedTree: CirRootNode, target: CommonizerTarget, targetIndex: Int) {
|
||||
serializeSingleTarget(mergedTree, targetIndex, parameters.statsCollector) { metadataModule ->
|
||||
internal fun serializeTarget(
|
||||
parameters: CommonizerParameters,
|
||||
commonized: CirRootNode,
|
||||
outputTarget: SharedCommonizerTarget
|
||||
): Unit = parameters.logger.progress(outputTarget, "Serialized target") {
|
||||
CirTreeSerializer.serializeSingleTarget(commonized, commonized.indexOfCommon, parameters.statsCollector) { metadataModule ->
|
||||
val libraryName = metadataModule.name
|
||||
val serializedMetadata = with(metadataModule.write(KLIB_FRAGMENT_WRITE_STRATEGY)) {
|
||||
val serializedMetadata = with(metadataModule.write(ChunkedKlibModuleFragmentWriteStrategy())) {
|
||||
SerializedMetadata(header, fragments, fragmentNames)
|
||||
}
|
||||
val manifestData = parameters.manifestProvider[target].buildManifest(libraryName)
|
||||
parameters.resultsConsumer.consume(parameters, target, ModuleResult.Commonized(libraryName, serializedMetadata, manifestData))
|
||||
val manifestData = parameters.manifestProvider[outputTarget].buildManifest(libraryName)
|
||||
parameters.resultsConsumer.consume(
|
||||
parameters, outputTarget,
|
||||
ResultsConsumer.ModuleResult.Commonized(libraryName, serializedMetadata, manifestData)
|
||||
)
|
||||
}
|
||||
parameters.resultsConsumer.targetConsumed(parameters, target)
|
||||
parameters.resultsConsumer.targetConsumed(parameters, outputTarget)
|
||||
}
|
||||
|
||||
private fun serializeMissingModules(parameters: CommonizerParameters, requestedTarget: CommonizerTarget) {
|
||||
val targetProvider = parameters.targetProviders.getOrNull(requestedTarget) ?: return
|
||||
val commonModuleNames = parameters.commonModuleNames(targetProvider)
|
||||
|
||||
targetProvider.modulesProvider.loadModuleInfos()
|
||||
.filter { it.name !in commonModuleNames }
|
||||
.forEach { missingModule ->
|
||||
parameters.resultsConsumer.consume(parameters, requestedTarget, Missing(missingModule.originalLocation))
|
||||
}
|
||||
}
|
||||
|
||||
private fun CommonizerParameters.fork(): CommonizerParameters = with(logger?.fork())
|
||||
|
||||
private fun CommonizerParameters.logProgress(message: String) = logger?.progress(message)
|
||||
|
||||
private val KLIB_FRAGMENT_WRITE_STRATEGY = ChunkedKlibModuleFragmentWriteStrategy()
|
||||
|
||||
|
||||
-60
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@file:Suppress("FunctionName")
|
||||
|
||||
package org.jetbrains.kotlin.commonizer.konan
|
||||
|
||||
import org.jetbrains.kotlin.commonizer.CommonizerParameters
|
||||
import org.jetbrains.kotlin.commonizer.KonanDistribution
|
||||
import org.jetbrains.kotlin.commonizer.ResultsConsumer
|
||||
import org.jetbrains.kotlin.commonizer.klibDir
|
||||
import org.jetbrains.kotlin.konan.library.KONAN_DISTRIBUTION_COMMON_LIBS_DIR
|
||||
import org.jetbrains.kotlin.konan.library.KONAN_STDLIB_NAME
|
||||
import java.io.File
|
||||
|
||||
internal fun CopyStdlibResultsConsumer(
|
||||
konanDistribution: KonanDistribution,
|
||||
destination: File
|
||||
): ResultsConsumer {
|
||||
return CopyLibrariesFromKonanDistributionResultsConsumer(
|
||||
konanDistribution,
|
||||
destination,
|
||||
invokeWhenCopied = { logger?.progress("Copied standard library") },
|
||||
copyFileIf = { file -> file.endsWith(KONAN_STDLIB_NAME) }
|
||||
)
|
||||
}
|
||||
|
||||
internal fun CopyEndorsedLibrairesResultsConsumer(
|
||||
konanDistribution: KonanDistribution,
|
||||
destination: File,
|
||||
): ResultsConsumer {
|
||||
return CopyLibrariesFromKonanDistributionResultsConsumer(
|
||||
konanDistribution,
|
||||
destination,
|
||||
invokeWhenCopied = { logger?.progress("Copied endorsed libraries") },
|
||||
copyFileIf = { file -> !file.endsWith(KONAN_STDLIB_NAME) }
|
||||
)
|
||||
}
|
||||
|
||||
private class CopyLibrariesFromKonanDistributionResultsConsumer(
|
||||
private val konanDistribution: KonanDistribution,
|
||||
private val destination: File,
|
||||
private val invokeWhenCopied: CommonizerParameters.() -> Unit = {},
|
||||
private val copyFileIf: (File) -> Boolean = { true }
|
||||
) : ResultsConsumer {
|
||||
override fun allConsumed(parameters: CommonizerParameters, status: ResultsConsumer.Status) {
|
||||
konanDistribution.klibDir
|
||||
.resolve(KONAN_DISTRIBUTION_COMMON_LIBS_DIR)
|
||||
.listFiles().orEmpty()
|
||||
.filter { it.isDirectory }
|
||||
.filterNot(copyFileIf)
|
||||
.forEach { libraryOrigin ->
|
||||
val libraryDestination = destination.resolve(KONAN_DISTRIBUTION_COMMON_LIBS_DIR).resolve(libraryOrigin.name)
|
||||
libraryOrigin.copyRecursively(libraryDestination)
|
||||
}
|
||||
parameters.invokeWhenCopied()
|
||||
}
|
||||
}
|
||||
-44
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.commonizer.konan
|
||||
|
||||
import org.jetbrains.kotlin.commonizer.*
|
||||
import org.jetbrains.kotlin.commonizer.repository.Repository
|
||||
import java.io.File
|
||||
|
||||
internal class CopyUnconsumedModulesAsIsConsumer(
|
||||
private val repository: Repository,
|
||||
private val destination: File,
|
||||
private val targets: Set<LeafCommonizerTarget>,
|
||||
private val outputLayout: CommonizerOutputLayout,
|
||||
) : ResultsConsumer {
|
||||
|
||||
private val consumedTargets = mutableSetOf<LeafCommonizerTarget>()
|
||||
|
||||
override fun targetConsumed(parameters: CommonizerParameters, target: CommonizerTarget) {
|
||||
if (target is LeafCommonizerTarget) {
|
||||
consumedTargets += target
|
||||
}
|
||||
}
|
||||
|
||||
override fun allConsumed(parameters: CommonizerParameters, status: ResultsConsumer.Status) {
|
||||
when (status) {
|
||||
ResultsConsumer.Status.NOTHING_TO_DO -> targets.forEach { target -> copyTargetAsIs(parameters, target) }
|
||||
ResultsConsumer.Status.DONE -> targets.minus(consumedTargets).forEach { target -> copyTargetAsIs(parameters, target) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun copyTargetAsIs(parameters: CommonizerParameters, target: LeafCommonizerTarget) {
|
||||
val libraries = repository.getLibraries(target)
|
||||
val librariesDestination = outputLayout.getTargetDirectory(destination, target)
|
||||
librariesDestination.mkdirs() // always create an empty directory even if there is nothing to copy
|
||||
libraries.map { it.library.libraryFile.absolutePath }.map(::File).forEach { libraryFile ->
|
||||
libraryFile.copyRecursively(destination.resolve(libraryFile.name))
|
||||
}
|
||||
|
||||
parameters.logger?.progress("Copied ${libraries.size} libraries for ${target.prettyName}")
|
||||
}
|
||||
}
|
||||
@@ -8,55 +8,61 @@ package org.jetbrains.kotlin.commonizer.konan
|
||||
import org.jetbrains.kotlin.commonizer.*
|
||||
import org.jetbrains.kotlin.commonizer.repository.Repository
|
||||
import org.jetbrains.kotlin.commonizer.stats.StatsCollector
|
||||
import org.jetbrains.kotlin.commonizer.utils.ProgressLogger
|
||||
import org.jetbrains.kotlin.commonizer.utils.progress
|
||||
import org.jetbrains.kotlin.util.Logger
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
|
||||
|
||||
internal class LibraryCommonizer internal constructor(
|
||||
private val outputTarget: SharedCommonizerTarget,
|
||||
private val outputTargets: Set<SharedCommonizerTarget>,
|
||||
private val repository: Repository,
|
||||
private val dependencies: Repository,
|
||||
private val resultsConsumer: ResultsConsumer,
|
||||
private val statsCollector: StatsCollector?,
|
||||
private val progressLogger: ProgressLogger
|
||||
private val logger: Logger
|
||||
) {
|
||||
|
||||
fun run() {
|
||||
checkPreconditions()
|
||||
val allLibraries = loadLibraries()
|
||||
commonizeAndSaveResults(allLibraries)
|
||||
progressLogger.logTotal()
|
||||
logger.progress("Commonized all targets") {
|
||||
checkPreconditions()
|
||||
val allLibraries = loadLibraries()
|
||||
commonizeAndSaveResults(allLibraries)
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadLibraries(): TargetDependent<NativeLibrariesToCommonize?> {
|
||||
val libraries = EagerTargetDependent(outputTarget.allLeaves()) { target ->
|
||||
repository.getLibraries(target).toList().ifNotEmpty { NativeLibrariesToCommonize(target, this) }
|
||||
}
|
||||
return logger.progress("Resolved all libraries for commonization") {
|
||||
val libraries = EagerTargetDependent(outputTargets.allLeaves()) { target ->
|
||||
repository.getLibraries(target).toList().ifNotEmpty { NativeLibrariesToCommonize(target, this) }
|
||||
}
|
||||
|
||||
libraries.forEachWithTarget { target, librariesOrNull ->
|
||||
if (librariesOrNull == null)
|
||||
progressLogger.warning(
|
||||
"No libraries found for target ${target.prettyName}. This target will be excluded from commonization."
|
||||
)
|
||||
libraries.forEachWithTarget { target, librariesOrNull ->
|
||||
if (librariesOrNull == null)
|
||||
logger.warning(
|
||||
"No libraries found for target ${target}. This target will be excluded from commonization."
|
||||
)
|
||||
}
|
||||
libraries
|
||||
}
|
||||
|
||||
progressLogger.progress("Resolved libraries to be commonized")
|
||||
return libraries
|
||||
}
|
||||
|
||||
private fun commonizeAndSaveResults(libraries: TargetDependent<NativeLibrariesToCommonize?>) {
|
||||
val parameters = CommonizerParameters(
|
||||
outputTarget = outputTarget,
|
||||
targetProviders = libraries.map { target, targetLibraries -> createTargetProvider(target, targetLibraries) },
|
||||
manifestProvider = createManifestProvider(libraries),
|
||||
dependenciesProvider = createDependenciesProvider(),
|
||||
resultsConsumer = resultsConsumer,
|
||||
statsCollector = statsCollector,
|
||||
logger = progressLogger
|
||||
runCommonization(
|
||||
CommonizerParameters(
|
||||
outputTargets = outputTargets,
|
||||
targetProviders = libraries.map { target, targetLibraries -> createTargetProvider(target, targetLibraries) },
|
||||
manifestProvider = createManifestProvider(libraries),
|
||||
dependenciesProvider = createDependenciesProvider(),
|
||||
resultsConsumer = resultsConsumer,
|
||||
statsCollector = statsCollector,
|
||||
logger = logger
|
||||
)
|
||||
)
|
||||
runCommonization(parameters)
|
||||
}
|
||||
|
||||
private fun createTargetProvider(target: CommonizerTarget, libraries: NativeLibrariesToCommonize?): TargetProvider? {
|
||||
private fun createTargetProvider(
|
||||
target: CommonizerTarget,
|
||||
libraries: NativeLibrariesToCommonize?
|
||||
): TargetProvider? {
|
||||
if (libraries == null) return null
|
||||
return TargetProvider(
|
||||
target = target,
|
||||
@@ -65,7 +71,7 @@ internal class LibraryCommonizer internal constructor(
|
||||
}
|
||||
|
||||
private fun createDependenciesProvider(): TargetDependent<ModulesProvider?> {
|
||||
return TargetDependent(outputTarget.withAllAncestors()) { target ->
|
||||
return TargetDependent(outputTargets + outputTargets.allLeaves()) { target ->
|
||||
DefaultModulesProvider.create(dependencies.getLibraries(target))
|
||||
}
|
||||
}
|
||||
@@ -73,7 +79,7 @@ internal class LibraryCommonizer internal constructor(
|
||||
private fun createManifestProvider(
|
||||
libraries: TargetDependent<NativeLibrariesToCommonize?>
|
||||
): TargetDependent<NativeManifestDataProvider> {
|
||||
return TargetDependent(outputTarget.withAllAncestors()) { target ->
|
||||
return TargetDependent(outputTargets) { target ->
|
||||
when (target) {
|
||||
is LeafCommonizerTarget -> libraries[target] ?: error("Can't provide manifest for missing target $target")
|
||||
is SharedCommonizerTarget -> NativeManifestDataProvider(
|
||||
@@ -84,9 +90,11 @@ internal class LibraryCommonizer internal constructor(
|
||||
}
|
||||
|
||||
private fun checkPreconditions() {
|
||||
/* TODO
|
||||
when (outputTarget.allLeaves().size) {
|
||||
0 -> progressLogger.fatal("No targets specified")
|
||||
1 -> progressLogger.fatal("Too few targets specified: $outputTarget")
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.commonizer.konan
|
||||
|
||||
import org.jetbrains.kotlin.commonizer.*
|
||||
|
||||
internal class LoggingResultsConsumer(
|
||||
private val outputCommonizerTarget: SharedCommonizerTarget
|
||||
) : ResultsConsumer {
|
||||
override fun targetConsumed(parameters: CommonizerParameters, target: CommonizerTarget) {
|
||||
parameters.logger?.progress("Written libraries for ${outputCommonizerTarget.prettyName(target)}")
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.commonizer.konan
|
||||
|
||||
import org.jetbrains.kotlin.commonizer.CommonizerOutputLayout
|
||||
import org.jetbrains.kotlin.commonizer.CommonizerOutputFileLayout
|
||||
import org.jetbrains.kotlin.commonizer.CommonizerParameters
|
||||
import org.jetbrains.kotlin.commonizer.CommonizerTarget
|
||||
import org.jetbrains.kotlin.commonizer.ResultsConsumer
|
||||
@@ -18,10 +18,9 @@ import java.io.File
|
||||
|
||||
internal class ModuleSerializer(
|
||||
private val destination: File,
|
||||
private val outputLayout: CommonizerOutputLayout,
|
||||
) : ResultsConsumer {
|
||||
override fun consume(parameters: CommonizerParameters, target: CommonizerTarget, moduleResult: ResultsConsumer.ModuleResult) {
|
||||
val librariesDestination = outputLayout.getTargetDirectory(destination, target)
|
||||
val librariesDestination = CommonizerOutputFileLayout.getCommonizedDirectory(destination, target)
|
||||
when (moduleResult) {
|
||||
is ResultsConsumer.ModuleResult.Commonized -> {
|
||||
val libraryDestination = librariesDestination.resolve(moduleResult.fileSystemCompatibleLibraryName)
|
||||
|
||||
+5
-2
@@ -5,8 +5,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.commonizer.repository
|
||||
|
||||
import org.jetbrains.kotlin.commonizer.*
|
||||
import org.jetbrains.kotlin.commonizer.CommonizerTarget
|
||||
import org.jetbrains.kotlin.commonizer.KonanDistribution
|
||||
import org.jetbrains.kotlin.commonizer.NativeLibraryLoader
|
||||
import org.jetbrains.kotlin.commonizer.konan.NativeLibrary
|
||||
import org.jetbrains.kotlin.commonizer.stdlib
|
||||
|
||||
internal class StdlibRepository(
|
||||
private val konanDistribution: KonanDistribution,
|
||||
@@ -18,6 +21,6 @@ internal class StdlibRepository(
|
||||
}
|
||||
|
||||
override fun getLibraries(target: CommonizerTarget): Set<NativeLibrary> {
|
||||
return if (target is SharedCommonizerTarget) setOf(stdlib) else emptySet()
|
||||
return setOf(stdlib)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,10 @@
|
||||
package org.jetbrains.kotlin.commonizer.tree
|
||||
|
||||
import org.jetbrains.kotlin.commonizer.CommonizerParameters
|
||||
import org.jetbrains.kotlin.commonizer.CommonizerTarget
|
||||
import org.jetbrains.kotlin.commonizer.TargetProvider
|
||||
import org.jetbrains.kotlin.commonizer.tree.deserializer.*
|
||||
import org.jetbrains.kotlin.commonizer.utils.progress
|
||||
|
||||
internal val defaultCirTreeModuleDeserializer = CirTreeModuleDeserializer(
|
||||
packageDeserializer = CirTreePackageDeserializer(
|
||||
@@ -25,8 +27,3 @@ internal val defaultCirTreeModuleDeserializer = CirTreeModuleDeserializer(
|
||||
internal val defaultCirTreeRootDeserializer = RootCirTreeDeserializer(
|
||||
defaultCirTreeModuleDeserializer
|
||||
)
|
||||
|
||||
|
||||
internal fun deserializeCirTree(parameters: CommonizerParameters, target: TargetProvider): CirTreeRoot {
|
||||
return defaultCirTreeRootDeserializer(parameters, target)
|
||||
}
|
||||
|
||||
@@ -5,36 +5,25 @@
|
||||
|
||||
package org.jetbrains.kotlin.commonizer.utils
|
||||
|
||||
import org.jetbrains.kotlin.commonizer.cli.CliLoggerAdapter
|
||||
import org.jetbrains.kotlin.commonizer.CommonizerLogLevel
|
||||
import org.jetbrains.kotlin.commonizer.CommonizerTarget
|
||||
import org.jetbrains.kotlin.util.Logger
|
||||
|
||||
class ProgressLogger(
|
||||
private val wrapped: Logger = CliLoggerAdapter(CommonizerLogLevel.Info, 0),
|
||||
private val indent: Int = 0,
|
||||
) : Logger by wrapped {
|
||||
private val clockMark = ResettableClockMark()
|
||||
private var finished = false
|
||||
private const val ansiReset = "\u001B[0m"
|
||||
private const val ansiTimeColor = "\u001B[36m"
|
||||
private const val ansiTargetColor = "\u001B[32m"
|
||||
|
||||
private val prefix = " ".repeat(indent) + " * "
|
||||
|
||||
init {
|
||||
clockMark.reset()
|
||||
require(indent >= 0) { "Required indent >= 1" }
|
||||
}
|
||||
|
||||
fun progress(message: String) {
|
||||
check(!finished)
|
||||
wrapped.log("$prefix$message in ${clockMark.elapsedSinceLast()}")
|
||||
}
|
||||
|
||||
fun logTotal() {
|
||||
check(!finished)
|
||||
wrapped.log("TOTAL: ${clockMark.elapsedSinceStart()}")
|
||||
finished = true
|
||||
}
|
||||
|
||||
fun fork(): ProgressLogger {
|
||||
return ProgressLogger(this, indent + 1)
|
||||
internal inline fun <T> Logger?.progress(message: String, action: () -> T): T {
|
||||
val clock = ResettableClockMark()
|
||||
clock.reset()
|
||||
try {
|
||||
return action()
|
||||
} finally {
|
||||
this?.log("$message ${ansiTimeColor}in ${clock.elapsedSinceLast()}$ansiReset")
|
||||
}
|
||||
}
|
||||
|
||||
internal inline fun <T> Logger?.progress(
|
||||
target: CommonizerTarget, message: String, action: () -> T
|
||||
): T {
|
||||
return progress("[$ansiTargetColor$target$ansiReset]: $message", action)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.commonizer.utils
|
||||
|
||||
infix fun <T> Set<T>.isSubsetOf(other: Set<T>): Boolean {
|
||||
if (this === other) return true
|
||||
return other.containsAll(this)
|
||||
}
|
||||
|
||||
infix fun <T> Set<T>.isProperSubsetOf(other: Set<T>): Boolean {
|
||||
if (this == other) return false
|
||||
return other.containsAll(this)
|
||||
}
|
||||
+8
-14
@@ -84,17 +84,6 @@ abstract class AbstractCommonizationFromSourcesTest : KtUsefulTestCase() {
|
||||
(results.modulesByTargets.getValue(sharedTarget).single() as ModuleResult.Commonized).metadata
|
||||
|
||||
assertModulesAreEqual(sharedModuleAsExpected, sharedModuleByCommonizer, sharedTarget)
|
||||
|
||||
val leafTargets: Set<LeafCommonizerTarget> = analyzedModules.leafTargets
|
||||
assertEquals(leafTargets, results.leafTargets)
|
||||
|
||||
for (leafTarget in leafTargets) {
|
||||
val leafTargetModuleAsExpected: SerializedMetadata = analyzedModules.commonizedModules.getValue(leafTarget)
|
||||
val leafTargetModuleByCommonizer: SerializedMetadata =
|
||||
(results.modulesByTargets.getValue(leafTarget).single() as ModuleResult.Commonized).metadata
|
||||
|
||||
assertModulesAreEqual(leafTargetModuleAsExpected, leafTargetModuleByCommonizer, leafTarget)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,9 +197,14 @@ private class AnalyzedModules(
|
||||
resultsConsumer: ResultsConsumer,
|
||||
manifestDataProvider: (CommonizerTarget) -> NativeManifestDataProvider = { MockNativeManifestDataProvider(it) }
|
||||
) = CommonizerParameters(
|
||||
outputTarget = SharedCommonizerTarget(leafTargets.toSet()),
|
||||
manifestProvider = TargetDependent(sharedTarget.withAllAncestors(), manifestDataProvider),
|
||||
dependenciesProvider = TargetDependent(sharedTarget.withAllAncestors()) { dependencyModules[it]?.let(MockModulesProvider::create) },
|
||||
outputTargets = setOf(SharedCommonizerTarget(leafTargets.toSet())),
|
||||
manifestProvider = TargetDependent(sharedTarget.withAllLeaves(), manifestDataProvider),
|
||||
dependenciesProvider = TargetDependent(sharedTarget.withAllLeaves()) { target ->
|
||||
dependencyModules
|
||||
.filter { (registeredTarget, _) -> target in registeredTarget.withAllLeaves() }
|
||||
.values.flatten()
|
||||
.let(MockModulesProvider::create)
|
||||
},
|
||||
targetProviders = TargetDependent(leafTargets) { leafTarget ->
|
||||
TargetProvider(
|
||||
target = leafTarget,
|
||||
|
||||
+25
-19
@@ -25,7 +25,7 @@ data class HierarchicalCommonizationResult(
|
||||
abstract class AbstractInlineSourcesCommonizationTest : KtInlineSourceCommonizerTestCase() {
|
||||
|
||||
data class Parameters(
|
||||
val outputTarget: SharedCommonizerTarget,
|
||||
val outputTargets: Set<SharedCommonizerTarget>,
|
||||
val dependencies: TargetDependent<List<InlineSourceBuilder.Module>>,
|
||||
val targets: List<Target>
|
||||
)
|
||||
@@ -41,7 +41,7 @@ abstract class AbstractInlineSourcesCommonizationTest : KtInlineSourceCommonizer
|
||||
|
||||
@InlineSourcesCommonizationTestDsl
|
||||
class ParametersBuilder(private val parentInlineSourceBuilder: InlineSourceBuilder) {
|
||||
private var outputTarget: SharedCommonizerTarget? = null
|
||||
private var outputTargets: MutableSet<SharedCommonizerTarget>? = null
|
||||
|
||||
private val dependencies: MutableMap<CommonizerTarget, MutableList<InlineSourceBuilder.Module>> = LinkedHashMap()
|
||||
|
||||
@@ -52,8 +52,12 @@ abstract class AbstractInlineSourcesCommonizationTest : KtInlineSourceCommonizer
|
||||
|
||||
|
||||
@InlineSourcesCommonizationTestDsl
|
||||
fun outputTarget(target: String) {
|
||||
outputTarget = parseCommonizerTarget(target) as SharedCommonizerTarget
|
||||
fun outputTarget(vararg targets: String) {
|
||||
val outputTargets = outputTargets ?: mutableSetOf()
|
||||
targets.forEach { target ->
|
||||
outputTargets += parseCommonizerTarget(target) as SharedCommonizerTarget
|
||||
}
|
||||
this.outputTargets = outputTargets
|
||||
}
|
||||
|
||||
@InlineSourcesCommonizationTestDsl
|
||||
@@ -67,18 +71,20 @@ abstract class AbstractInlineSourcesCommonizationTest : KtInlineSourceCommonizer
|
||||
}
|
||||
|
||||
@InlineSourcesCommonizationTestDsl
|
||||
fun registerDependency(target: CommonizerTarget, builder: InlineSourceBuilder.ModuleBuilder.() -> Unit) {
|
||||
val dependenciesList = dependencies.getOrPut(target) { mutableListOf() }
|
||||
val dependency = inlineSourceBuilderFactory[target].createModule {
|
||||
builder()
|
||||
name = "${target.prettyName}-dependency-${dependenciesList.size}-$name"
|
||||
fun registerDependency(vararg targets: CommonizerTarget, builder: InlineSourceBuilder.ModuleBuilder.() -> Unit) {
|
||||
targets.forEach { target ->
|
||||
val dependenciesList = dependencies.getOrPut(target) { mutableListOf() }
|
||||
val dependency = inlineSourceBuilderFactory[target].createModule {
|
||||
builder()
|
||||
name = "$target-dependency-${dependenciesList.size}-$name"
|
||||
}
|
||||
dependenciesList.add(dependency)
|
||||
}
|
||||
dependenciesList.add(dependency)
|
||||
}
|
||||
|
||||
@InlineSourcesCommonizationTestDsl
|
||||
fun registerDependency(target: String, builder: InlineSourceBuilder.ModuleBuilder.() -> Unit) {
|
||||
registerDependency(parseCommonizerTarget(target), builder)
|
||||
fun registerDependency(vararg targets: String, builder: InlineSourceBuilder.ModuleBuilder.() -> Unit) {
|
||||
registerDependency(targets = targets.map(::parseCommonizerTarget).toTypedArray(), builder)
|
||||
}
|
||||
|
||||
@InlineSourcesCommonizationTestDsl
|
||||
@@ -96,7 +102,7 @@ abstract class AbstractInlineSourcesCommonizationTest : KtInlineSourceCommonizer
|
||||
}
|
||||
|
||||
fun build(): Parameters = Parameters(
|
||||
outputTarget = outputTarget ?: SharedCommonizerTarget(targets.map { it.target }.toSet()),
|
||||
outputTargets = outputTargets ?: setOf(SharedCommonizerTarget(targets.map { it.target }.allLeaves())),
|
||||
dependencies = dependencies.toTargetDependent(),
|
||||
targets = targets.toList()
|
||||
)
|
||||
@@ -111,7 +117,7 @@ abstract class AbstractInlineSourcesCommonizationTest : KtInlineSourceCommonizer
|
||||
override fun createModule(builder: InlineSourceBuilder.ModuleBuilder.() -> Unit): InlineSourceBuilder.Module {
|
||||
return inlineSourceBuilder.createModule {
|
||||
dependencies.toMap()
|
||||
.filterKeys { dependencyTarget -> dependencyTarget.isEqualOrAncestorOf(target) }.values.flatten()
|
||||
.filterKeys { dependencyTarget -> target in dependencyTarget.withAllLeaves() }.values.flatten()
|
||||
.forEach { dependencyModule -> dependency(dependencyModule) }
|
||||
builder()
|
||||
}
|
||||
@@ -155,16 +161,16 @@ abstract class AbstractInlineSourcesCommonizationTest : KtInlineSourceCommonizer
|
||||
manifestDataProvider: (CommonizerTarget) -> NativeManifestDataProvider = { MockNativeManifestDataProvider(it) }
|
||||
): CommonizerParameters {
|
||||
return CommonizerParameters(
|
||||
outputTarget = outputTarget,
|
||||
manifestProvider = TargetDependent(outputTarget.withAllAncestors(), manifestDataProvider),
|
||||
dependenciesProvider = TargetDependent(outputTarget.withAllAncestors()) { target ->
|
||||
outputTargets = outputTargets,
|
||||
manifestProvider = TargetDependent(outputTargets, manifestDataProvider),
|
||||
dependenciesProvider = TargetDependent(outputTargets.withAllLeaves()) { target ->
|
||||
val explicitDependencies = dependencies.getOrNull(target).orEmpty().map { module -> createModuleDescriptor(module) }
|
||||
val implicitDependencies = listOfNotNull(if (target == outputTarget) DefaultBuiltIns.Instance.builtInsModule else null)
|
||||
val implicitDependencies = listOfNotNull(DefaultBuiltIns.Instance.builtInsModule)
|
||||
val dependencies = explicitDependencies + implicitDependencies
|
||||
if (dependencies.isEmpty()) null
|
||||
else MockModulesProvider.create(dependencies)
|
||||
},
|
||||
targetProviders = TargetDependent(outputTarget.allLeaves()) { commonizerTarget ->
|
||||
targetProviders = TargetDependent(outputTargets.allLeaves()) { commonizerTarget ->
|
||||
val target = targets.singleOrNull { it.target == commonizerTarget } ?: return@TargetDependent null
|
||||
TargetProvider(
|
||||
target = commonizerTarget,
|
||||
|
||||
@@ -70,12 +70,12 @@ class CommonizerFacadeTest {
|
||||
manifestDataProvider: (CommonizerTarget) -> NativeManifestDataProvider = { MockNativeManifestDataProvider(it) }
|
||||
): CommonizerParameters {
|
||||
val targetDependentModuleNames = mapKeys { (targetName, _) -> LeafCommonizerTarget(targetName) }.toTargetDependent()
|
||||
val sharedTarget = SharedCommonizerTarget(targetDependentModuleNames.targets.toSet())
|
||||
val sharedTarget = SharedCommonizerTarget(targetDependentModuleNames.targets.allLeaves())
|
||||
|
||||
return CommonizerParameters(
|
||||
outputTarget = sharedTarget,
|
||||
dependenciesProvider = TargetDependent(sharedTarget.withAllAncestors()) { null },
|
||||
manifestProvider = TargetDependent(sharedTarget.withAllAncestors(), manifestDataProvider),
|
||||
outputTargets = setOf(sharedTarget),
|
||||
dependenciesProvider = TargetDependent(sharedTarget.withAllLeaves()) { null },
|
||||
manifestProvider = TargetDependent(sharedTarget.withAllLeaves(), manifestDataProvider),
|
||||
targetProviders = targetDependentModuleNames.map { target, moduleNames ->
|
||||
TargetProvider(
|
||||
target = target,
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.commonizer
|
||||
|
||||
import org.jetbrains.kotlin.commonizer.cir.CirRoot
|
||||
import org.jetbrains.kotlin.commonizer.mergedtree.CirRootNode
|
||||
import org.jetbrains.kotlin.commonizer.tree.CirTreeRoot
|
||||
import org.jetbrains.kotlin.commonizer.utils.CommonizedGroup
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class CommonizerQueueTest {
|
||||
|
||||
@Test
|
||||
fun `test retained targets`() {
|
||||
val queue = CommonizerQueue(
|
||||
storageManager = LockBasedStorageManager.NO_LOCKS,
|
||||
outputTargets = setOf("(a, b)", "(a, b, c)").map(::parseCommonizerTarget).map { it as SharedCommonizerTarget }.toSet(),
|
||||
deserializers = EagerTargetDependent(
|
||||
setOf("a", "b", "c").map(::parseCommonizerTarget)
|
||||
) { CommonizerQueue.Deserializer { null } },
|
||||
commonizer = { _, _ -> null },
|
||||
serializer = { _, _ -> },
|
||||
inputTargetsSelector = DefaultInputTargetsSelector
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
setOf("a", "b", "c"), queue.retainedDeserializedTargets.map { it.identityString }.toSet(),
|
||||
"Expected all targets a, b, c to be retained in the beginning"
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
setOf("(a, b)", "(a, b, c)"), queue.retainedCommonizedTargets.map { it.identityString }.toSet(),
|
||||
"Expected all output targets to be retained in the beginning"
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
setOf("(a, b)", "(a, b, c)"), queue.retainedTargetDependencies.keys.map { it.identityString }.toSet(),
|
||||
"Expected all output targets to declare its dependencies"
|
||||
)
|
||||
|
||||
queue.invokeTarget(parseCommonizerTarget("(a, b)") as SharedCommonizerTarget)
|
||||
|
||||
assertEquals(
|
||||
setOf("c"), queue.retainedDeserializedTargets.map { it.identityString }.toSet(),
|
||||
"Expected only target 'c' to be retained after commonizing (a, b)"
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
setOf("(a, b)", "(a, b, c)"), queue.retainedCommonizedTargets.map { it.identityString }.toSet(),
|
||||
"Expected all output targets to be retained after commonizing (a, b)"
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
setOf("(a, b, c)"), queue.retainedTargetDependencies.keys.map { it.identityString }.toSet(),
|
||||
"Expected remaining targets to declare its dependencies"
|
||||
)
|
||||
|
||||
assertEquals(queue.pendingOutputTargets, queue.retainedTargetDependencies.keys)
|
||||
|
||||
queue.invokeTarget(parseCommonizerTarget("(a, b, c)") as SharedCommonizerTarget)
|
||||
|
||||
assertEquals(
|
||||
emptySet(), queue.retainedDeserializedTargets,
|
||||
"Expected no retained deserialized targets"
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
emptySet(), queue.retainedCommonizedTargets,
|
||||
"Expected no retained commonized targets"
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
emptySet(), queue.retainedTargetDependencies.keys,
|
||||
"Expected no retained target dependencies"
|
||||
)
|
||||
|
||||
assertEquals(queue.pendingOutputTargets, queue.retainedTargetDependencies.keys)
|
||||
|
||||
queue.invokeAll()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test commonizer being called`() {
|
||||
data class CommonizerInvocation(val inputs: TargetDependent<CirTreeRoot?>, val output: SharedCommonizerTarget)
|
||||
|
||||
val commonizerInvocations = mutableListOf<CommonizerInvocation>()
|
||||
val storageManager = LockBasedStorageManager.NO_LOCKS
|
||||
val providedTargets = setOf("a", "b", "c").map(::parseCommonizerTarget).toSet()
|
||||
val abOutputTarget = parseCommonizerTarget("(a, b)") as SharedCommonizerTarget
|
||||
val abcOutputTarget = parseCommonizerTarget("(a, b, c)") as SharedCommonizerTarget
|
||||
val outputTargets = setOf(abOutputTarget, abcOutputTarget)
|
||||
|
||||
val queue = CommonizerQueue(
|
||||
storageManager = storageManager,
|
||||
outputTargets = outputTargets,
|
||||
deserializers = EagerTargetDependent(providedTargets) { CommonizerQueue.Deserializer { null } },
|
||||
commonizer = { inputs, output ->
|
||||
commonizerInvocations.add(CommonizerInvocation(inputs, output))
|
||||
CirRootNode(CommonizedGroup(0), storageManager.createNullableLazyValue { CirRoot.create(output) })
|
||||
},
|
||||
serializer = { _, _ -> },
|
||||
inputTargetsSelector = DefaultInputTargetsSelector
|
||||
)
|
||||
|
||||
queue.invokeAll()
|
||||
|
||||
assertEquals(
|
||||
2, commonizerInvocations.size,
|
||||
"Expected 2 commonizer invocations"
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
outputTargets, commonizerInvocations.map { it.output }.toSet(),
|
||||
"Expected specified output targets to be invoked"
|
||||
)
|
||||
|
||||
val abInvocation = commonizerInvocations.single { it.output == abOutputTarget }
|
||||
assertEquals(
|
||||
DefaultInputTargetsSelector(providedTargets + outputTargets, abOutputTarget),
|
||||
abInvocation.inputs.targets.toSet(),
|
||||
"Expected commonizer being invoked with selected targets for abInvocation"
|
||||
)
|
||||
|
||||
val abcInvocation = commonizerInvocations.single { it.output == abcOutputTarget }
|
||||
assertEquals(
|
||||
DefaultInputTargetsSelector(providedTargets + outputTargets, abcOutputTarget),
|
||||
abcInvocation.inputs.targets.toSet(),
|
||||
"Expected commonizer being invoked with selected targets for abcInvocation"
|
||||
)
|
||||
}
|
||||
}
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.commonizer
|
||||
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFailsWith
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class DefaultInputTargetsSelectorTest {
|
||||
|
||||
@Test
|
||||
fun `missing leaf targets`() {
|
||||
val inputTargets = setOf(LeafCommonizerTarget("a"), LeafCommonizerTarget("b"))
|
||||
|
||||
val exception = assertFailsWith<IllegalArgumentException> {
|
||||
DefaultInputTargetsSelector(inputTargets, parseCommonizerTarget("(a, b, c)") as SharedCommonizerTarget)
|
||||
}
|
||||
|
||||
assertTrue(
|
||||
exception.message.orEmpty().contains(inputTargets.toString()),
|
||||
"Expected error message to contain all input targets. Found ${exception.message}"
|
||||
)
|
||||
|
||||
assertTrue(
|
||||
exception.message.orEmpty().contains(parseCommonizerTarget("(a, b, c)").toString()),
|
||||
"Expected error message to contain output target. Found ${exception.message}"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `sample 0`() {
|
||||
val inputTargets = setOf(
|
||||
LeafCommonizerTarget("a"),
|
||||
LeafCommonizerTarget("b"),
|
||||
LeafCommonizerTarget("c"),
|
||||
LeafCommonizerTarget("d"),
|
||||
SharedCommonizerTarget(LeafCommonizerTarget("c"), LeafCommonizerTarget("d"))
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
setOf(LeafCommonizerTarget("a"), LeafCommonizerTarget("b")),
|
||||
DefaultInputTargetsSelector(inputTargets, parseCommonizerTarget("(a, b)") as SharedCommonizerTarget)
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
setOf(LeafCommonizerTarget("a"), LeafCommonizerTarget("b"), LeafCommonizerTarget("c")),
|
||||
DefaultInputTargetsSelector(inputTargets, parseCommonizerTarget("(a, b, c)") as SharedCommonizerTarget)
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
setOf(LeafCommonizerTarget("a"), LeafCommonizerTarget("b"), parseCommonizerTarget("(c, d)")),
|
||||
DefaultInputTargetsSelector(inputTargets, parseCommonizerTarget("(a, b, c, d)") as SharedCommonizerTarget)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `sample 1`() {
|
||||
val inputTargets = setOf(
|
||||
parseCommonizerTarget("(a, b)"),
|
||||
parseCommonizerTarget("(a, b, c)"),
|
||||
parseCommonizerTarget("(a, b, c, d)"),
|
||||
parseCommonizerTarget("(c, d)"),
|
||||
parseCommonizerTarget("(c, d, e)"),
|
||||
parseCommonizerTarget("f")
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
setOf("(a, b, c, d)", "f").map(::parseCommonizerTarget).toSet(),
|
||||
DefaultInputTargetsSelector(inputTargets, parseCommonizerTarget("(a, b, c, d, f)") as SharedCommonizerTarget)
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
setOf("(a, b, c, d)", "(c, d, e)").map(::parseCommonizerTarget).toSet(),
|
||||
DefaultInputTargetsSelector(inputTargets, parseCommonizerTarget("(a, b, c, d, e)") as SharedCommonizerTarget)
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
setOf("(a, b, c, d)", "(c, d, e)", "f").map(::parseCommonizerTarget).toSet(),
|
||||
DefaultInputTargetsSelector(inputTargets, parseCommonizerTarget("(a, b, c, d, e, f)") as SharedCommonizerTarget)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `empty outputTarget`() {
|
||||
assertEquals(
|
||||
emptySet(),
|
||||
DefaultInputTargetsSelector(emptySet(), parseCommonizerTarget("()") as SharedCommonizerTarget)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `single leaf outputTarget`() {
|
||||
assertEquals(
|
||||
setOf(LeafCommonizerTarget("a")),
|
||||
DefaultInputTargetsSelector(setOf(LeafCommonizerTarget("a")), parseCommonizerTarget("(a)") as SharedCommonizerTarget)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `exact output available`() {
|
||||
assertEquals(
|
||||
setOf(parseCommonizerTarget("(a, b)"), parseCommonizerTarget("(c, d)")),
|
||||
DefaultInputTargetsSelector(
|
||||
setOf("a", "b", "c", "d", "(a, b)", "(c, d)", "(a, b, c, d)").map(::parseCommonizerTarget).toSet(),
|
||||
parseCommonizerTarget("(a, b, c, d)") as SharedCommonizerTarget
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
-36
@@ -41,24 +41,6 @@ class FunctionReturnTypeCommonizationTest : AbstractInlineSourcesCommonizationTe
|
||||
result.assertCommonized(
|
||||
"(a,b)", ""
|
||||
)
|
||||
|
||||
result.assertCommonized(
|
||||
"a", """
|
||||
class A {
|
||||
class B
|
||||
}
|
||||
fun x(): A.B = TODO()
|
||||
"""
|
||||
)
|
||||
|
||||
result.assertCommonized(
|
||||
"b", """
|
||||
interface A {
|
||||
class B
|
||||
}
|
||||
fun x(): A.B = TODO()
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -98,23 +80,5 @@ class FunctionReturnTypeCommonizationTest : AbstractInlineSourcesCommonizationTe
|
||||
expect fun x(): A.B
|
||||
"""
|
||||
)
|
||||
|
||||
result.assertCommonized(
|
||||
"a", """
|
||||
interface A {
|
||||
class B
|
||||
}
|
||||
fun x(): A.B = TODO()
|
||||
"""
|
||||
)
|
||||
|
||||
result.assertCommonized(
|
||||
"b", """
|
||||
interface A {
|
||||
class B
|
||||
}
|
||||
fun x(): A.B = TODO()
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-3
@@ -18,13 +18,11 @@ class HierarchicalClassAndTypeAliasCommonizationTest : AbstractInlineSourcesComm
|
||||
}
|
||||
|
||||
result.assertCommonized("(a, b)", "expect class X")
|
||||
result.assertCommonized("a", "typealias X = Int")
|
||||
result.assertCommonized("b", "class X")
|
||||
}
|
||||
|
||||
fun `test commonization of typeAlias and class hierarchically`() {
|
||||
val result = commonize {
|
||||
outputTarget("((a, b), (c, d))")
|
||||
outputTarget("(a, b)", "(c, d)", "(a, b, c, d)")
|
||||
simpleSingleSourceTarget("a", "typealias X = Int")
|
||||
simpleSingleSourceTarget("b", "typealias X = Long")
|
||||
simpleSingleSourceTarget("c", "class X")
|
||||
|
||||
+2
-48
@@ -12,7 +12,7 @@ class HierarchicalClassCommonizationTest : AbstractInlineSourcesCommonizationTes
|
||||
|
||||
fun `test simple class`() {
|
||||
val result = commonize {
|
||||
outputTarget("((a,b), (c,d), e)")
|
||||
outputTarget("(a, b)", "(c, d)", "(a, b, c, d)", "(a, b, c, d, e)")
|
||||
simpleSingleSourceTarget("a", "class X")
|
||||
simpleSingleSourceTarget("b", "class X")
|
||||
simpleSingleSourceTarget("c", "class X")
|
||||
@@ -20,12 +20,6 @@ class HierarchicalClassCommonizationTest : AbstractInlineSourcesCommonizationTes
|
||||
simpleSingleSourceTarget("e", "class X")
|
||||
}
|
||||
|
||||
result.assertCommonized("a", "class X")
|
||||
result.assertCommonized("b", "class X")
|
||||
result.assertCommonized("c", "class X")
|
||||
result.assertCommonized("d", "class X")
|
||||
result.assertCommonized("e", "class X")
|
||||
|
||||
result.assertCommonized("(a,b)", "expect class X expect constructor()")
|
||||
result.assertCommonized("(c,d)", "expect class X expect constructor()")
|
||||
result.assertCommonized("(a,b)", "expect class X expect constructor()")
|
||||
@@ -34,7 +28,7 @@ class HierarchicalClassCommonizationTest : AbstractInlineSourcesCommonizationTes
|
||||
|
||||
fun `test sample class`() {
|
||||
val result = commonize {
|
||||
outputTarget("((a,b), (c,d))")
|
||||
outputTarget("(a, b)", "(c, d)", "(a, b, c, d)")
|
||||
simpleSingleSourceTarget(
|
||||
"a", """
|
||||
class X {
|
||||
@@ -76,46 +70,6 @@ class HierarchicalClassCommonizationTest : AbstractInlineSourcesCommonizationTes
|
||||
)
|
||||
}
|
||||
|
||||
result.assertCommonized(
|
||||
"a", """
|
||||
class X {
|
||||
val a: Int = 42
|
||||
val ab: Int = 42
|
||||
val abcd: Int = 42
|
||||
}
|
||||
"""
|
||||
)
|
||||
|
||||
result.assertCommonized(
|
||||
"b", """
|
||||
class X {
|
||||
val b: Int = 42
|
||||
val ab: Int = 42
|
||||
val abcd: Int = 42
|
||||
}
|
||||
"""
|
||||
)
|
||||
|
||||
result.assertCommonized(
|
||||
"c", """
|
||||
class X {
|
||||
val c: Int = 42
|
||||
val cd: Int = 42
|
||||
val abcd: Int = 42
|
||||
}
|
||||
"""
|
||||
)
|
||||
|
||||
result.assertCommonized(
|
||||
"d", """
|
||||
class X {
|
||||
val d: Int = 42
|
||||
val cd: Int = 42
|
||||
val abcd: Int = 42
|
||||
}
|
||||
"""
|
||||
)
|
||||
|
||||
result.assertCommonized(
|
||||
"(a,b)", """
|
||||
expect class X expect constructor() {
|
||||
|
||||
+13
-56
@@ -12,7 +12,7 @@ class HierarchicalFunctionCommonizationTest : AbstractInlineSourcesCommonization
|
||||
|
||||
fun `test simple function 1`() {
|
||||
val result = commonize {
|
||||
outputTarget("((a,b), (c,d))")
|
||||
outputTarget("(a,b)", "(c,d)", "(a, b, c, d)")
|
||||
simpleSingleSourceTarget("a", "fun x(): Int = 42")
|
||||
simpleSingleSourceTarget("b", "fun x(): Int = 42")
|
||||
simpleSingleSourceTarget("c", "fun x(): Int = 42")
|
||||
@@ -22,15 +22,11 @@ class HierarchicalFunctionCommonizationTest : AbstractInlineSourcesCommonization
|
||||
result.assertCommonized("((a,b), (c,d))", "expect fun x(): Int")
|
||||
result.assertCommonized("(a,b)", "expect fun x(): Int")
|
||||
result.assertCommonized("(c,d)", "expect fun x(): Int")
|
||||
result.assertCommonized("a", "actual fun x(): Int = 42")
|
||||
result.assertCommonized("b", "actual fun x(): Int = 42")
|
||||
result.assertCommonized("c", "actual fun x(): Int = 42")
|
||||
result.assertCommonized("d", "actual fun x(): Int = 42")
|
||||
}
|
||||
|
||||
fun `test simple function 2`() {
|
||||
val result = commonize {
|
||||
outputTarget("((a,b), c)")
|
||||
outputTarget("(a, b)", "(a, b, c)")
|
||||
simpleSingleSourceTarget("a", "fun x(): Int = 42")
|
||||
simpleSingleSourceTarget("b", "fun x(): Int = 42")
|
||||
simpleSingleSourceTarget("c", "fun x(): Int = 42")
|
||||
@@ -38,14 +34,11 @@ class HierarchicalFunctionCommonizationTest : AbstractInlineSourcesCommonization
|
||||
|
||||
result.assertCommonized("((a,b), c)", "expect fun x(): Int")
|
||||
result.assertCommonized("(a,b)", "expect fun x(): Int")
|
||||
result.assertCommonized("a", "fun x(): Int = 42")
|
||||
result.assertCommonized("b", "fun x(): Int = 42")
|
||||
result.assertCommonized("c", "fun x(): Int = 42")
|
||||
}
|
||||
|
||||
fun `test function with returnType`() {
|
||||
val result = commonize {
|
||||
outputTarget("((a,b), (c,d))")
|
||||
outputTarget("(a, b)", "(c, d)", "(a, b, c, d)")
|
||||
simpleSingleSourceTarget(
|
||||
"a", """
|
||||
interface ABCD
|
||||
@@ -73,34 +66,6 @@ class HierarchicalFunctionCommonizationTest : AbstractInlineSourcesCommonization
|
||||
)
|
||||
}
|
||||
|
||||
result.assertCommonized(
|
||||
"a", """
|
||||
interface ABCD
|
||||
fun x(): ABCD = TODO()
|
||||
"""
|
||||
)
|
||||
|
||||
result.assertCommonized(
|
||||
"b", """
|
||||
interface ABCD
|
||||
fun x(): ABCD = TODO()
|
||||
"""
|
||||
)
|
||||
|
||||
result.assertCommonized(
|
||||
"c", """
|
||||
interface ABCD
|
||||
fun x(): ABCD = TODO()
|
||||
"""
|
||||
)
|
||||
|
||||
result.assertCommonized(
|
||||
"d", """
|
||||
interface ABCD
|
||||
fun x(): ABCD = TODO()
|
||||
"""
|
||||
)
|
||||
|
||||
result.assertCommonized(
|
||||
"(a, b)", """
|
||||
expect interface ABCD
|
||||
@@ -125,18 +90,14 @@ class HierarchicalFunctionCommonizationTest : AbstractInlineSourcesCommonization
|
||||
|
||||
fun `test function with returnType from dependency 1`() {
|
||||
val result = commonize {
|
||||
outputTarget("((a,b), (c,d))")
|
||||
registerDependency("((a,b), (c,d))") { source("interface ABCD") }
|
||||
outputTarget("(a, b)", "(c, d)", "(a, b, c, d)")
|
||||
registerDependency("a", "b", "c", "d", "(a, b)", "(c, d)", "(a, b, c, d)") { source("interface ABCD") }
|
||||
simpleSingleSourceTarget("a", "fun x(): ABCD = TODO()")
|
||||
simpleSingleSourceTarget("b", "fun x(): ABCD = TODO()")
|
||||
simpleSingleSourceTarget("c", "fun x(): ABCD = TODO()")
|
||||
simpleSingleSourceTarget("d", "fun x(): ABCD = TODO()")
|
||||
}
|
||||
|
||||
result.assertCommonized("a", "fun x(): ABCD")
|
||||
result.assertCommonized("b", "fun x(): ABCD")
|
||||
result.assertCommonized("c", "fun x(): ABCD")
|
||||
result.assertCommonized("d", "fun x(): ABCD")
|
||||
result.assertCommonized("(c, d)", "expect fun x(): ABCD")
|
||||
result.assertCommonized("(a, b)", "expect fun x(): ABCD")
|
||||
result.assertCommonized("((a,b), (c,d))", "expect fun x(): ABCD")
|
||||
@@ -144,8 +105,9 @@ class HierarchicalFunctionCommonizationTest : AbstractInlineSourcesCommonization
|
||||
|
||||
fun `test function with returnType from dependency 2`() {
|
||||
val result = commonize {
|
||||
outputTarget("((a,b), (c,d))")
|
||||
registerDependency("(a,b)") { source("interface ABCD") }
|
||||
outputTarget("(a, b)", "(c, d)", "(a, b, c, d)")
|
||||
registerDependency("a", "b", "c", "d") { source("interface ABCD") }
|
||||
registerDependency("(a, b)") { source("interface ABCD") }
|
||||
registerDependency("(c,d)") { source("interface ABCD") }
|
||||
simpleSingleSourceTarget("a", "fun x(): ABCD = TODO()")
|
||||
simpleSingleSourceTarget("b", "fun x(): ABCD = TODO()")
|
||||
@@ -153,28 +115,23 @@ class HierarchicalFunctionCommonizationTest : AbstractInlineSourcesCommonization
|
||||
simpleSingleSourceTarget("d", "fun x(): ABCD = TODO()")
|
||||
}
|
||||
|
||||
result.assertCommonized("a", "fun x(): ABCD")
|
||||
result.assertCommonized("b", "fun x(): ABCD")
|
||||
result.assertCommonized("c", "fun x(): ABCD")
|
||||
result.assertCommonized("d", "fun x(): ABCD")
|
||||
result.assertCommonized("(c, d)", "expect fun x(): ABCD")
|
||||
result.assertCommonized("(a, b)", "expect fun x(): ABCD")
|
||||
|
||||
// ABCD is not given as dependency on (a, b, c, d) -> can't be commonized
|
||||
result.assertCommonized("((a,b), (c,d))", "")
|
||||
}
|
||||
|
||||
fun `test function with returnType from dependency 3`() {
|
||||
val result = commonize {
|
||||
outputTarget("((a,b), c)")
|
||||
registerDependency("((a,b), c)") { source("interface ABCD") }
|
||||
registerDependency("(a,b)") { source("interface ABCD") }
|
||||
outputTarget("(a, b)", "(a, b, c)")
|
||||
registerDependency("(a, b, c)") { source("interface ABCD") }
|
||||
registerDependency("a", "b", "c", "(a, b)") { source("interface ABCD") }
|
||||
simpleSingleSourceTarget("a", "fun x(): ABCD = TODO()")
|
||||
simpleSingleSourceTarget("b", "fun x(): ABCD = TODO()")
|
||||
simpleSingleSourceTarget("c", "fun x(): ABCD = TODO()")
|
||||
}
|
||||
|
||||
result.assertCommonized("a", "fun x(): ABCD")
|
||||
result.assertCommonized("b", "fun x(): ABCD")
|
||||
result.assertCommonized("c", "fun x(): ABCD")
|
||||
result.assertCommonized("(a, b)", "expect fun x(): ABCD")
|
||||
result.assertCommonized("((a,b), c)", "expect fun x(): ABCD")
|
||||
}
|
||||
|
||||
+10
-37
@@ -17,7 +17,7 @@ class HierarchicalModuleCommonizationTest : AbstractInlineSourcesCommonizationTe
|
||||
|
||||
fun `test common modules hierarchically`() {
|
||||
val result = commonize {
|
||||
outputTarget("((a, b), c)")
|
||||
outputTarget("(a, b)", "(a, b, c)")
|
||||
|
||||
target("a") {
|
||||
module {
|
||||
@@ -67,20 +67,20 @@ class HierarchicalModuleCommonizationTest : AbstractInlineSourcesCommonizationTe
|
||||
}
|
||||
|
||||
|
||||
result.assertCommonized("((a, b), c)") {
|
||||
result.assertCommonized("(a, b, c)") {
|
||||
name = "foo"
|
||||
source("expect val foo: Int")
|
||||
}
|
||||
|
||||
assertEquals(
|
||||
1, result.results[parseCommonizerTarget("((a, b), c)")].orEmpty().size,
|
||||
1, result.results[parseCommonizerTarget("(a, b, c)")].orEmpty().size,
|
||||
"Expected only a single module"
|
||||
)
|
||||
}
|
||||
|
||||
fun `test module commonization with empty root not sharing any module`() {
|
||||
val result = commonize {
|
||||
outputTarget("((a, b), c)")
|
||||
outputTarget("(a, b)", "(a, b, c)")
|
||||
|
||||
target("a") {
|
||||
module {
|
||||
@@ -110,14 +110,14 @@ class HierarchicalModuleCommonizationTest : AbstractInlineSourcesCommonizationTe
|
||||
}
|
||||
|
||||
assertTrue(
|
||||
result.results[parseCommonizerTarget("((a, b), c)")].orEmpty().isEmpty(),
|
||||
"Expected empty result for ((a, b), c)"
|
||||
result.results[parseCommonizerTarget("(a, b, c)")].orEmpty().isEmpty(),
|
||||
"Expected empty result for (a, b, c)"
|
||||
)
|
||||
}
|
||||
|
||||
fun `test no common modules`() {
|
||||
val result = commonize(Status.NOTHING_TO_DO) {
|
||||
outputTarget("((a, b), c)")
|
||||
outputTarget("(a, b)", "(a, b, c)")
|
||||
|
||||
target("a") {
|
||||
module {
|
||||
@@ -146,7 +146,7 @@ class HierarchicalModuleCommonizationTest : AbstractInlineSourcesCommonizationTe
|
||||
|
||||
fun `test propagation`() {
|
||||
val result = commonize {
|
||||
outputTarget("(((a, b), c), d)")
|
||||
outputTarget("(a, b)", "(a, b, c)", "(a, b, c, d)")
|
||||
|
||||
target("a") {
|
||||
module {
|
||||
@@ -170,12 +170,12 @@ class HierarchicalModuleCommonizationTest : AbstractInlineSourcesCommonizationTe
|
||||
}
|
||||
}
|
||||
|
||||
result.assertCommonized("((a, b), c)") {
|
||||
result.assertCommonized("(a, b, c)") {
|
||||
name = "foo"
|
||||
source("expect val foo: Int")
|
||||
}
|
||||
|
||||
result.assertCommonized("(((a, b), c), d)") {
|
||||
result.assertCommonized("(a, b, c, d)") {
|
||||
name = "foo"
|
||||
source("expect val foo: Int")
|
||||
}
|
||||
@@ -212,36 +212,9 @@ class HierarchicalModuleCommonizationTest : AbstractInlineSourcesCommonizationTe
|
||||
|
||||
assertEquals(1, result.results[parseCommonizerTarget("(a, b)")]?.size, "Expected only one commonized module")
|
||||
|
||||
|
||||
result.assertCommonized("(a, b)") {
|
||||
name = "shared"
|
||||
source("expect class Shared expect constructor()")
|
||||
}
|
||||
|
||||
result.assertCommonized("a") {
|
||||
name = "shared"
|
||||
source("class Shared constructor()")
|
||||
}
|
||||
|
||||
result.assertCommonized("b") {
|
||||
name = "shared"
|
||||
source("class Shared constructor()")
|
||||
}
|
||||
|
||||
val targetAResults = result.results[parseCommonizerTarget("a")].orEmpty()
|
||||
assertEquals(2, targetAResults.size, "Expected 'Missing' and 'Commonized' results for target a")
|
||||
val targetAMissingModule = kotlin.test.assertNotNull(
|
||||
targetAResults.filterIsInstance<Missing>().singleOrNull(),
|
||||
"Expected 'Missing' result for target a"
|
||||
)
|
||||
assertEquals("onlyInA", targetAMissingModule.libraryName)
|
||||
|
||||
val targetBResults = result.results[parseCommonizerTarget("b")].orEmpty()
|
||||
assertEquals(2, targetBResults.size, "Expected 'Missing' and 'Commonized' results for target b")
|
||||
val targetBMissingModule = kotlin.test.assertNotNull(
|
||||
targetBResults.filterIsInstance<Missing>().singleOrNull(),
|
||||
"Expected 'Missing' result for target b"
|
||||
)
|
||||
assertEquals("onlyInB", targetBMissingModule.libraryName)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-85
@@ -12,7 +12,7 @@ class HierarchicalPackageCommonizationTest : AbstractInlineSourcesCommonizationT
|
||||
|
||||
fun `test package with dummy`() {
|
||||
val result = commonize {
|
||||
outputTarget("((a,b), (c,d))")
|
||||
outputTarget("(a, b)", "(c, d)", "(a, b, c, d)")
|
||||
|
||||
target("a") {
|
||||
module {
|
||||
@@ -107,90 +107,6 @@ class HierarchicalPackageCommonizationTest : AbstractInlineSourcesCommonizationT
|
||||
}
|
||||
}
|
||||
|
||||
result.assertCommonized("a") {
|
||||
source(
|
||||
"""
|
||||
package pkg.abcd
|
||||
val dummy = "me"
|
||||
""", "abcd.kt"
|
||||
)
|
||||
source(
|
||||
"""
|
||||
package pkg.ab
|
||||
val dummy = "me"
|
||||
""", "ab.kt"
|
||||
)
|
||||
source(
|
||||
"""
|
||||
package pkg.a
|
||||
val dummy = "me"
|
||||
""", "a.kt"
|
||||
)
|
||||
}
|
||||
|
||||
result.assertCommonized("b") {
|
||||
source(
|
||||
"""
|
||||
package pkg.abcd
|
||||
val dummy = "me"
|
||||
""", "abcd.kt"
|
||||
)
|
||||
source(
|
||||
"""
|
||||
package pkg.ab
|
||||
val dummy = "me"
|
||||
""", "ab.kt"
|
||||
)
|
||||
source(
|
||||
"""
|
||||
package pkg.b
|
||||
val dummy = "me"
|
||||
""", "b.kt"
|
||||
)
|
||||
}
|
||||
|
||||
result.assertCommonized("c") {
|
||||
source(
|
||||
"""
|
||||
package pkg.abcd
|
||||
val dummy = "me"
|
||||
""", "abcd.kt"
|
||||
)
|
||||
source(
|
||||
"""
|
||||
package pkg.cd
|
||||
val dummy = "me"
|
||||
""", "cd.kt"
|
||||
)
|
||||
source(
|
||||
"""
|
||||
package pkg.c
|
||||
val dummy = "me"
|
||||
""", "c.kt"
|
||||
)
|
||||
}
|
||||
|
||||
result.assertCommonized("d") {
|
||||
source(
|
||||
"""
|
||||
package pkg.abcd
|
||||
val dummy = "me"
|
||||
""", "abcd.kt"
|
||||
)
|
||||
source(
|
||||
"""
|
||||
package pkg.cd
|
||||
val dummy = "me"
|
||||
""", "cd.kt"
|
||||
)
|
||||
source(
|
||||
"""
|
||||
package pkg.d
|
||||
val dummy = "me"
|
||||
""", "d.kt"
|
||||
)
|
||||
}
|
||||
|
||||
result.assertCommonized("(a,b)") {
|
||||
source(
|
||||
"""
|
||||
|
||||
+1
-5
@@ -12,7 +12,7 @@ class HierarchicalPropertyCommonizationTest : AbstractInlineSourcesCommonization
|
||||
|
||||
fun `test simple property`() {
|
||||
val result = commonize {
|
||||
outputTarget("((a, b), (c, d))")
|
||||
outputTarget("(a, b)", "(c, d)", "(a, b, c, d)")
|
||||
simpleSingleSourceTarget("a", "val x: Int = 42")
|
||||
simpleSingleSourceTarget("b", "val x: Int = 42")
|
||||
simpleSingleSourceTarget("c", "val x: Int = 42")
|
||||
@@ -22,10 +22,6 @@ class HierarchicalPropertyCommonizationTest : AbstractInlineSourcesCommonization
|
||||
result.assertCommonized("((a,b), (c,d))", "expect val x: Int")
|
||||
result.assertCommonized("(a, b)", "expect val x: Int")
|
||||
result.assertCommonized("(c, d)", "expect val x: Int")
|
||||
result.assertCommonized("a", "val x: Int = 42")
|
||||
result.assertCommonized("b", "val x: Int = 42")
|
||||
result.assertCommonized("c", "val x: Int = 42")
|
||||
result.assertCommonized("d", "val x: Int = 42")
|
||||
}
|
||||
|
||||
fun `test same typeAliased property`() {
|
||||
|
||||
+4
-17
@@ -12,7 +12,7 @@ class HierarchicalTypeAliasCommonizationTest : AbstractInlineSourcesCommonizatio
|
||||
|
||||
fun `test simple type alias`() {
|
||||
val result = commonize {
|
||||
outputTarget("((a,b), (c,d))")
|
||||
outputTarget("(a, b)", "(c, d)", "(a, b, c, d)")
|
||||
simpleSingleSourceTarget("a", "typealias X = Int")
|
||||
simpleSingleSourceTarget("b", "typealias X = Int")
|
||||
simpleSingleSourceTarget("c", "typealias X = Int")
|
||||
@@ -22,12 +22,6 @@ class HierarchicalTypeAliasCommonizationTest : AbstractInlineSourcesCommonizatio
|
||||
result.assertCommonized("((a,b), (c,d))", "typealias X = Int")
|
||||
result.assertCommonized("(a,b)", "typealias X = Int")
|
||||
result.assertCommonized("(c, d)", "typealias X = Int")
|
||||
|
||||
/* Special case: For now, leaves should depend on commonized platform libraries */
|
||||
result.assertCommonized("a", "")
|
||||
result.assertCommonized("b", "")
|
||||
result.assertCommonized("c", "")
|
||||
result.assertCommonized("d", "")
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,7 +44,7 @@ class HierarchicalTypeAliasCommonizationTest : AbstractInlineSourcesCommonizatio
|
||||
|
||||
fun `test typealias to different classes`() {
|
||||
val result = commonize {
|
||||
outputTarget("(((a,b), (c,d)), (e,f))")
|
||||
outputTarget("(a, b)", "(c, d)", "(e, f)", "(a, b, c, d)", "(a, b, c, d, e, f)")
|
||||
simpleSingleSourceTarget(
|
||||
"a", """
|
||||
class AB
|
||||
@@ -79,13 +73,6 @@ class HierarchicalTypeAliasCommonizationTest : AbstractInlineSourcesCommonizatio
|
||||
simpleSingleSourceTarget("f", """class x""")
|
||||
}
|
||||
|
||||
result.assertCommonized("a", """class AB""")
|
||||
result.assertCommonized("b", """class AB""")
|
||||
result.assertCommonized("c", """class CD""")
|
||||
result.assertCommonized("d", """class CD""")
|
||||
result.assertCommonized("e", """class x""")
|
||||
result.assertCommonized("f", """class x""")
|
||||
|
||||
result.assertCommonized(
|
||||
"(a,b)", """
|
||||
expect class AB expect constructor()
|
||||
@@ -111,7 +98,7 @@ class HierarchicalTypeAliasCommonizationTest : AbstractInlineSourcesCommonizatio
|
||||
"(e,f)", """expect class x expect constructor()"""
|
||||
)
|
||||
|
||||
result.assertCommonized("((a,b), (c,d))", """expect class x expect constructor()""")
|
||||
result.assertCommonized("(((a,b), (c,d)), (e,f))", """expect class x expect constructor()""")
|
||||
result.assertCommonized("(a, b, c, d)", """expect class x expect constructor()""")
|
||||
result.assertCommonized("(a, b, c, d, e, f)", """expect class x expect constructor()""")
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -21,11 +21,10 @@ class SingleTargetPropagationTest : AbstractInlineSourcesCommonizationTest() {
|
||||
@Test
|
||||
fun `test single native target in hierarchy`() {
|
||||
val result = commonize {
|
||||
outputTarget("((a, b), (c, d))")
|
||||
outputTarget("(a, b)", "(c, d)", "(a, b, c, d)")
|
||||
simpleSingleSourceTarget("a", """class A""")
|
||||
}
|
||||
|
||||
result.assertCommonized("a", "class A")
|
||||
result.assertCommonized("(a,b)", "expect class A expect constructor()")
|
||||
result.assertCommonized("((a, b), (c, d))", "expect class A expect constructor()")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user