[Commonizer] Fast-pass for library fragments absent for some targets
^KT-39897
This commit is contained in:
@@ -6,19 +6,20 @@
|
|||||||
package org.jetbrains.kotlin.descriptors.commonizer
|
package org.jetbrains.kotlin.descriptors.commonizer
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
sealed class Result
|
sealed class Result {
|
||||||
|
object NothingToCommonize : Result()
|
||||||
|
|
||||||
object NothingToCommonize : Result()
|
class Commonized(
|
||||||
|
val modulesByTargets: Map<Target, Collection<ModuleResult>>
|
||||||
class CommonizationPerformed(
|
) : Result() {
|
||||||
val modulesByTargets: Map<Target, Collection<ModuleDescriptor>>
|
val sharedTarget: OutputTarget by lazy { modulesByTargets.keys.filterIsInstance<OutputTarget>().single() }
|
||||||
) : Result() {
|
val leafTargets: Set<InputTarget> by lazy { modulesByTargets.keys.filterIsInstance<InputTarget>().toSet() }
|
||||||
val commonTarget: OutputTarget by lazy {
|
|
||||||
modulesByTargets.keys.filterIsInstance<OutputTarget>().single()
|
|
||||||
}
|
|
||||||
|
|
||||||
val concreteTargets: Set<InputTarget> by lazy {
|
|
||||||
modulesByTargets.keys.filterIsInstance<InputTarget>().toSet()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sealed class ModuleResult {
|
||||||
|
class Absent(val originalLocation: File) : ModuleResult()
|
||||||
|
class Commonized(val module: ModuleDescriptor) : ModuleResult()
|
||||||
|
}
|
||||||
|
|||||||
+7
-10
@@ -5,8 +5,10 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.descriptors.commonizer
|
package org.jetbrains.kotlin.descriptors.commonizer
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
class TargetProvider(
|
class TargetProvider(
|
||||||
val target: InputTarget,
|
val target: InputTarget,
|
||||||
@@ -19,20 +21,15 @@ interface BuiltInsProvider {
|
|||||||
fun loadBuiltIns(): KotlinBuiltIns
|
fun loadBuiltIns(): KotlinBuiltIns
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun wrap(builtIns: KotlinBuiltIns) = object : BuiltInsProvider {
|
val defaultBuiltInsProvider = object : BuiltInsProvider {
|
||||||
override fun loadBuiltIns() = builtIns
|
override fun loadBuiltIns() = DefaultBuiltIns.Instance
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ModulesProvider {
|
interface ModulesProvider {
|
||||||
|
class ModuleInfo(val name: String, val originalLocation: File)
|
||||||
|
|
||||||
|
fun loadModuleInfos(): Map<String, ModuleInfo>
|
||||||
fun loadModules(): Collection<ModuleDescriptor>
|
fun loadModules(): Collection<ModuleDescriptor>
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun wrap(modules: Collection<ModuleDescriptor>) = object : ModulesProvider {
|
|
||||||
override fun loadModules() = modules
|
|
||||||
}
|
|
||||||
|
|
||||||
fun wrap(vararg modules: ModuleDescriptor) = wrap(modules.toList())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-6
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode.Companion.
|
|||||||
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode.Companion.indexOfCommon
|
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode.Companion.indexOfCommon
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
|
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serves two goals:
|
* Serves two goals:
|
||||||
@@ -28,16 +27,17 @@ internal class DeclarationsBuilderVisitor1(
|
|||||||
check(data.isEmpty()) // root node may not have containing declarations
|
check(data.isEmpty()) // root node may not have containing declarations
|
||||||
check(components.targetComponents.size == node.dimension)
|
check(components.targetComponents.size == node.dimension)
|
||||||
|
|
||||||
val allTargets = (node.targetDeclarations + node.commonDeclaration()).map { it!!.target }
|
val allTargets: List<Target> = (node.targetDeclarations + node.commonDeclaration()).map { it!!.target }
|
||||||
|
val modulesByTargets: Map<Target, MutableList<ModuleDescriptorImpl>> = allTargets.associateWithTo(HashMap()) { mutableListOf() }
|
||||||
val modulesByTargets = HashMap<Target, MutableList<ModuleDescriptorImpl>>()
|
|
||||||
|
|
||||||
// collect module descriptors:
|
// collect module descriptors:
|
||||||
for (moduleNode in node.modules.values) {
|
for (moduleNode in node.modules.values) {
|
||||||
val modules = moduleNode.accept(this, noContainingDeclarations()).asListContaining<ModuleDescriptorImpl>()
|
val modules = moduleNode.accept(this, noContainingDeclarations()).asListContaining<ModuleDescriptorImpl>()
|
||||||
modules.forEachIndexed { index, module ->
|
modules.forEachIndexed { index, module ->
|
||||||
val target = allTargets[index]
|
if (module != null) {
|
||||||
modulesByTargets.getOrPut(target) { mutableListOf() }.addIfNotNull(module)
|
val target = allTargets[index]
|
||||||
|
modulesByTargets.getValue(target) += module
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,9 +50,9 @@ private fun parseTask(
|
|||||||
|
|
||||||
fun buildOngoingTask() {
|
fun buildOngoingTask() {
|
||||||
// check options completeness
|
// check options completeness
|
||||||
val missedMandatoryOptions = optionTypes.filterKeys { it !in options }.filterValues { it.mandatory }.keys
|
val missingMandatoryOptions = optionTypes.filterKeys { it !in options }.filterValues { it.mandatory }.keys
|
||||||
if (missedMandatoryOptions.isNotEmpty())
|
if (missingMandatoryOptions.isNotEmpty())
|
||||||
printUsageAndExit("Mandatory options not specified in task $taskAlias: " + missedMandatoryOptions.joinToString { "-$it" })
|
printUsageAndExit("Mandatory options not specified in task $taskAlias: " + missingMandatoryOptions.joinToString { "-$it" })
|
||||||
|
|
||||||
tasks += taskType.taskConstructor(options.values)
|
tasks += taskType.taskConstructor(options.values)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -20,7 +20,7 @@ class RootCommonizer : AbstractStandardCommonizer<CirRoot, CirRoot>() {
|
|||||||
override fun commonizationResult() = CirRootFactory.create(
|
override fun commonizationResult() = CirRootFactory.create(
|
||||||
target = OutputTarget(inputTargets),
|
target = OutputTarget(inputTargets),
|
||||||
builtInsClass = if (konanBuiltInsProvider != null) KonanBuiltIns::class.java.name else DefaultBuiltIns::class.java.name,
|
builtInsClass = if (konanBuiltInsProvider != null) KonanBuiltIns::class.java.name else DefaultBuiltIns::class.java.name,
|
||||||
builtInsProvider = konanBuiltInsProvider ?: BuiltInsProvider.wrap(DefaultBuiltIns.Instance)
|
builtInsProvider = konanBuiltInsProvider ?: BuiltInsProvider.defaultBuiltInsProvider
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun initialize(first: CirRoot) {
|
override fun initialize(first: CirRoot) {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.descriptors.commonizer
|
package org.jetbrains.kotlin.descriptors.commonizer
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.builder.DeclarationsBuilderVisitor1
|
import org.jetbrains.kotlin.descriptors.commonizer.builder.DeclarationsBuilderVisitor1
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.builder.DeclarationsBuilderVisitor2
|
import org.jetbrains.kotlin.descriptors.commonizer.builder.DeclarationsBuilderVisitor2
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.builder.createGlobalBuilderComponents
|
import org.jetbrains.kotlin.descriptors.commonizer.builder.createGlobalBuilderComponents
|
||||||
@@ -15,14 +14,15 @@ import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
|||||||
|
|
||||||
fun runCommonization(parameters: Parameters): Result {
|
fun runCommonization(parameters: Parameters): Result {
|
||||||
if (!parameters.hasAnythingToCommonize())
|
if (!parameters.hasAnythingToCommonize())
|
||||||
return NothingToCommonize
|
return Result.NothingToCommonize
|
||||||
|
|
||||||
val storageManager = LockBasedStorageManager("Declaration descriptors commonization")
|
val storageManager = LockBasedStorageManager("Declaration descriptors commonization")
|
||||||
|
|
||||||
// build merged tree:
|
// build merged tree:
|
||||||
val mergedTree = CirTreeMerger(storageManager, parameters).merge()
|
val mergeResult = CirTreeMerger(storageManager, parameters).merge()
|
||||||
|
|
||||||
// commonize:
|
// commonize:
|
||||||
|
val mergedTree = mergeResult.root
|
||||||
mergedTree.accept(CommonizationVisitor(mergedTree), Unit)
|
mergedTree.accept(CommonizationVisitor(mergedTree), Unit)
|
||||||
parameters.progressLogger?.invoke("Commonized declarations")
|
parameters.progressLogger?.invoke("Commonized declarations")
|
||||||
|
|
||||||
@@ -31,15 +31,21 @@ fun runCommonization(parameters: Parameters): Result {
|
|||||||
mergedTree.accept(DeclarationsBuilderVisitor1(components), emptyList())
|
mergedTree.accept(DeclarationsBuilderVisitor1(components), emptyList())
|
||||||
mergedTree.accept(DeclarationsBuilderVisitor2(components), emptyList())
|
mergedTree.accept(DeclarationsBuilderVisitor2(components), emptyList())
|
||||||
|
|
||||||
val modulesByTargets = LinkedHashMap<Target, Collection<ModuleDescriptor>>() // use linked hash map to preserve order
|
val modulesByTargets = LinkedHashMap<Target, Collection<ModuleResult>>() // use linked hash map to preserve order
|
||||||
components.targetComponents.forEach {
|
components.targetComponents.forEach { component ->
|
||||||
val target = it.target
|
val target = component.target
|
||||||
check(target !in modulesByTargets)
|
check(target !in modulesByTargets)
|
||||||
|
|
||||||
modulesByTargets[target] = components.cache.getAllModules(it.index)
|
val commonizedModules: List<ModuleResult.Commonized> = components.cache.getAllModules(component.index).map(ModuleResult::Commonized)
|
||||||
|
|
||||||
|
val absentModules: List<ModuleResult.Absent> = if (target is InputTarget)
|
||||||
|
mergeResult.absentModuleInfos.getValue(target).map { ModuleResult.Absent(it.originalLocation) }
|
||||||
|
else emptyList()
|
||||||
|
|
||||||
|
modulesByTargets[target] = commonizedModules + absentModules
|
||||||
}
|
}
|
||||||
|
|
||||||
parameters.progressLogger?.invoke("Prepared new descriptors")
|
parameters.progressLogger?.invoke("Prepared new descriptors")
|
||||||
|
|
||||||
return CommonizationPerformed(modulesByTargets)
|
return Result.Commonized(modulesByTargets)
|
||||||
}
|
}
|
||||||
|
|||||||
+26
-17
@@ -91,9 +91,9 @@ class NativeDistributionCommonizer(
|
|||||||
val stdlib = loadLibrary(stdlibPath)
|
val stdlib = loadLibrary(stdlibPath)
|
||||||
|
|
||||||
val result = targets.associate { target ->
|
val result = targets.associate { target ->
|
||||||
val inputTarget = InputTarget(target.name, target)
|
val leafTarget = InputTarget(target.name, target)
|
||||||
|
|
||||||
val platformLibs = inputTarget.platformLibrariesSource
|
val platformLibs = leafTarget.platformLibrariesSource
|
||||||
.takeIf { it.isDirectory }
|
.takeIf { it.isDirectory }
|
||||||
?.listFiles()
|
?.listFiles()
|
||||||
?.takeIf { it.isNotEmpty() }
|
?.takeIf { it.isNotEmpty() }
|
||||||
@@ -103,7 +103,7 @@ class NativeDistributionCommonizer(
|
|||||||
if (platformLibs.isEmpty())
|
if (platformLibs.isEmpty())
|
||||||
logger.warning("No platform libraries found for target $target. This target will be excluded from commonization.")
|
logger.warning("No platform libraries found for target $target. This target will be excluded from commonization.")
|
||||||
|
|
||||||
inputTarget to NativeDistributionLibraries(stdlib, platformLibs)
|
leafTarget to NativeDistributionLibraries(stdlib, platformLibs)
|
||||||
}
|
}
|
||||||
|
|
||||||
logProgress("Read lazy (uninitialized) libraries")
|
logProgress("Read lazy (uninitialized) libraries")
|
||||||
@@ -176,16 +176,16 @@ class NativeDistributionCommonizer(
|
|||||||
copyCommonStandardLibraries()
|
copyCommonStandardLibraries()
|
||||||
|
|
||||||
when (result) {
|
when (result) {
|
||||||
is NothingToCommonize -> {
|
is Result.NothingToCommonize -> {
|
||||||
// It may happen that all targets to be commonized (or at least all but one target) miss platform libraries.
|
// It may happen that all targets to be commonized (or at least all but one target) miss platform libraries.
|
||||||
// In such case commonizer will do nothing and return a special result value 'NothingToCommonize'.
|
// In such case commonizer will do nothing and return a special result value 'NothingToCommonize'.
|
||||||
// So, let's just copy platform libraries from those target where they are to the new destination.
|
// So, let's just copy platform libraries from the target where they are to the new destination.
|
||||||
originalLibrariesByTargets.forEach { (target, libraries) ->
|
originalLibrariesByTargets.forEach { (target, libraries) ->
|
||||||
copyTargetAsIs(target, libraries.platformLibs.size)
|
copyTargetAsIs(target, libraries.platformLibs.size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is CommonizationPerformed -> {
|
is Result.Commonized -> {
|
||||||
val serializer = KlibMetadataMonolithicSerializer(
|
val serializer = KlibMetadataMonolithicSerializer(
|
||||||
languageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
|
languageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
|
||||||
metadataVersion = KlibMetadataVersion.INSTANCE,
|
metadataVersion = KlibMetadataVersion.INSTANCE,
|
||||||
@@ -193,7 +193,7 @@ class NativeDistributionCommonizer(
|
|||||||
)
|
)
|
||||||
|
|
||||||
// 'targetsToCopy' are some targets with empty set of platform libraries
|
// 'targetsToCopy' are some targets with empty set of platform libraries
|
||||||
val targetsToCopy = originalLibrariesByTargets.keys - result.concreteTargets
|
val targetsToCopy = originalLibrariesByTargets.keys - result.leafTargets
|
||||||
if (targetsToCopy.isNotEmpty()) {
|
if (targetsToCopy.isNotEmpty()) {
|
||||||
targetsToCopy.forEach { target ->
|
targetsToCopy.forEach { target ->
|
||||||
val libraries = originalLibrariesByTargets.getValue(target)
|
val libraries = originalLibrariesByTargets.getValue(target)
|
||||||
@@ -201,11 +201,13 @@ class NativeDistributionCommonizer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val leafTargetNames = result.leafTargets.map { it.name }
|
||||||
val concreteTargetNames = result.concreteTargets.map { it.name }
|
val targetsToSerialize = result.leafTargets + result.sharedTarget
|
||||||
val targetsToSerialize = result.concreteTargets + result.commonTarget
|
|
||||||
targetsToSerialize.forEach { target ->
|
targetsToSerialize.forEach { target ->
|
||||||
val newModules = result.modulesByTargets.getValue(target)
|
val moduleResults: Collection<ModuleResult> = result.modulesByTargets.getValue(target)
|
||||||
|
val newModules: Collection<ModuleDescriptor> = moduleResults.mapNotNull { (it as? ModuleResult.Commonized)?.module }
|
||||||
|
val absentModuleLocations: List<File> =
|
||||||
|
moduleResults.mapNotNull { (it as? ModuleResult.Absent)?.originalLocation }
|
||||||
|
|
||||||
val manifestProvider: NativeManifestDataProvider
|
val manifestProvider: NativeManifestDataProvider
|
||||||
val starredTarget: String?
|
val starredTarget: String?
|
||||||
@@ -220,8 +222,8 @@ class NativeDistributionCommonizer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val targetName = concreteTargetNames.joinToString { if (it == starredTarget) "$it(*)" else it }
|
val targetName = leafTargetNames.joinToString { if (it == starredTarget) "$it(*)" else it }
|
||||||
serializeTarget(target, targetName, newModules, manifestProvider, serializer)
|
serializeTarget(target, targetName, newModules, absentModuleLocations, manifestProvider, serializer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -252,24 +254,26 @@ class NativeDistributionCommonizer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun copyTargetAsIs(target: InputTarget, platformLibrariesCount: Int) {
|
private fun copyTargetAsIs(leafTarget: InputTarget, librariesCount: Int) {
|
||||||
val librariesDestination = target.librariesDestination
|
val librariesDestination = leafTarget.librariesDestination
|
||||||
librariesDestination.mkdirs() // always create an empty directory even if there is nothing to copy
|
librariesDestination.mkdirs() // always create an empty directory even if there is nothing to copy
|
||||||
|
|
||||||
val librariesSource = target.platformLibrariesSource
|
val librariesSource = leafTarget.platformLibrariesSource
|
||||||
if (librariesSource.isDirectory) librariesSource.copyRecursively(librariesDestination)
|
if (librariesSource.isDirectory) librariesSource.copyRecursively(librariesDestination)
|
||||||
|
|
||||||
logProgress("Copied $platformLibrariesCount libraries for [${target.name}]")
|
logProgress("Copied $librariesCount libraries for [${leafTarget.name}]")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun serializeTarget(
|
private fun serializeTarget(
|
||||||
target: Target,
|
target: Target,
|
||||||
targetName: String,
|
targetName: String,
|
||||||
newModules: Collection<ModuleDescriptor>,
|
newModules: Collection<ModuleDescriptor>,
|
||||||
|
absentModuleLocations: List<File>,
|
||||||
manifestProvider: NativeManifestDataProvider,
|
manifestProvider: NativeManifestDataProvider,
|
||||||
serializer: KlibMetadataMonolithicSerializer
|
serializer: KlibMetadataMonolithicSerializer
|
||||||
) {
|
) {
|
||||||
val librariesDestination = target.librariesDestination
|
val librariesDestination = target.librariesDestination
|
||||||
|
librariesDestination.mkdirs() // always create an empty directory even if there is nothing to copy
|
||||||
|
|
||||||
for (newModule in newModules) {
|
for (newModule in newModules) {
|
||||||
val libraryName = newModule.name
|
val libraryName = newModule.name
|
||||||
@@ -286,6 +290,11 @@ class NativeDistributionCommonizer(
|
|||||||
writeLibrary(metadata, manifestData, libraryDestination)
|
writeLibrary(metadata, manifestData, libraryDestination)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (absentModuleLocation in absentModuleLocations) {
|
||||||
|
val libraryName = absentModuleLocation.name
|
||||||
|
absentModuleLocation.copyRecursively(librariesDestination.resolve(libraryName))
|
||||||
|
}
|
||||||
|
|
||||||
logProgress("Written libraries for [$targetName]")
|
logProgress("Written libraries for [$targetName]")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
@@ -10,11 +10,13 @@ import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
|||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.BuiltInsProvider
|
import org.jetbrains.kotlin.descriptors.commonizer.BuiltInsProvider
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.ModulesProvider
|
import org.jetbrains.kotlin.descriptors.commonizer.ModulesProvider
|
||||||
|
import org.jetbrains.kotlin.descriptors.commonizer.ModulesProvider.ModuleInfo
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.NativeFactories
|
import org.jetbrains.kotlin.descriptors.commonizer.utils.NativeFactories
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.createKotlinNativeForwardDeclarationsModule
|
import org.jetbrains.kotlin.descriptors.commonizer.utils.createKotlinNativeForwardDeclarationsModule
|
||||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||||
import org.jetbrains.kotlin.konan.library.KONAN_STDLIB_NAME
|
import org.jetbrains.kotlin.konan.library.KONAN_STDLIB_NAME
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
internal class NativeDistributionModulesProvider(
|
internal class NativeDistributionModulesProvider(
|
||||||
private val storageManager: StorageManager,
|
private val storageManager: StorageManager,
|
||||||
@@ -32,6 +34,15 @@ internal class NativeDistributionModulesProvider(
|
|||||||
return stdlib.builtIns
|
return stdlib.builtIns
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun loadModuleInfos(): Map<String, ModuleInfo> {
|
||||||
|
return libraries.platformLibs.associate { library ->
|
||||||
|
val name = library.manifestData.uniqueName
|
||||||
|
val location = File(library.library.libraryFile.path)
|
||||||
|
|
||||||
|
name to ModuleInfo(name, location)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun loadModules(): Collection<ModuleDescriptor> {
|
override fun loadModules(): Collection<ModuleDescriptor> {
|
||||||
val builtIns = loadBuiltIns()
|
val builtIns = loadBuiltIns()
|
||||||
val stdlib = builtIns.builtInsModule
|
val stdlib = builtIns.builtInsModule
|
||||||
|
|||||||
+26
-5
@@ -6,6 +6,8 @@
|
|||||||
package org.jetbrains.kotlin.descriptors.commonizer.mergedtree
|
package org.jetbrains.kotlin.descriptors.commonizer.mergedtree
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.descriptors.commonizer.InputTarget
|
||||||
|
import org.jetbrains.kotlin.descriptors.commonizer.ModulesProvider.ModuleInfo
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.Parameters
|
import org.jetbrains.kotlin.descriptors.commonizer.Parameters
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.TargetProvider
|
import org.jetbrains.kotlin.descriptors.commonizer.TargetProvider
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClass
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClass
|
||||||
@@ -23,26 +25,44 @@ class CirTreeMerger(
|
|||||||
private val storageManager: StorageManager,
|
private val storageManager: StorageManager,
|
||||||
private val parameters: Parameters
|
private val parameters: Parameters
|
||||||
) {
|
) {
|
||||||
|
class CirTreeMergeResult(
|
||||||
|
val root: CirRootNode,
|
||||||
|
val absentModuleInfos: Map<InputTarget, Collection<ModuleInfo>>
|
||||||
|
)
|
||||||
|
|
||||||
private val size = parameters.targetProviders.size
|
private val size = parameters.targetProviders.size
|
||||||
private lateinit var cacheRW: CirClassifiersCacheImpl
|
private lateinit var cacheRW: CirClassifiersCacheImpl
|
||||||
|
|
||||||
fun merge(): CirRootNode {
|
fun merge(): CirTreeMergeResult {
|
||||||
val rootNode: CirRootNode = buildRootNode(storageManager, size)
|
val rootNode: CirRootNode = buildRootNode(storageManager, size)
|
||||||
cacheRW = rootNode.cache
|
cacheRW = rootNode.cache
|
||||||
|
|
||||||
|
val allModuleInfos: List<Map<String, ModuleInfo>> = parameters.targetProviders.map { it.modulesProvider.loadModuleInfos() }
|
||||||
|
val commonModuleNames = allModuleInfos.map { it.keys }.reduce { a, b -> a intersect b }
|
||||||
|
|
||||||
parameters.targetProviders.forEachIndexed { targetIndex, targetProvider ->
|
parameters.targetProviders.forEachIndexed { targetIndex, targetProvider ->
|
||||||
processTarget(rootNode, targetIndex, targetProvider)
|
processTarget(rootNode, targetIndex, targetProvider, commonModuleNames)
|
||||||
parameters.progressLogger?.invoke("Loaded declarations for [${targetProvider.target.name}]")
|
parameters.progressLogger?.invoke("Loaded declarations for [${targetProvider.target.name}]")
|
||||||
System.gc()
|
System.gc()
|
||||||
}
|
}
|
||||||
|
|
||||||
return rootNode
|
val absentModuleInfos = allModuleInfos.mapIndexed { index, moduleInfos ->
|
||||||
|
val target = parameters.targetProviders[index].target
|
||||||
|
val absentInfos = moduleInfos.filterKeys { name -> name !in commonModuleNames }.values
|
||||||
|
target to absentInfos
|
||||||
|
}.toMap()
|
||||||
|
|
||||||
|
return CirTreeMergeResult(
|
||||||
|
root = rootNode,
|
||||||
|
absentModuleInfos = absentModuleInfos
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun processTarget(
|
private fun processTarget(
|
||||||
rootNode: CirRootNode,
|
rootNode: CirRootNode,
|
||||||
targetIndex: Int,
|
targetIndex: Int,
|
||||||
targetProvider: TargetProvider
|
targetProvider: TargetProvider,
|
||||||
|
commonModuleNames: Set<String>
|
||||||
) {
|
) {
|
||||||
rootNode.targetDeclarations[targetIndex] = CirRootFactory.create(
|
rootNode.targetDeclarations[targetIndex] = CirRootFactory.create(
|
||||||
targetProvider.target,
|
targetProvider.target,
|
||||||
@@ -54,7 +74,8 @@ class CirTreeMerger(
|
|||||||
val modules: MutableMap<Name, CirModuleNode> = rootNode.modules
|
val modules: MutableMap<Name, CirModuleNode> = rootNode.modules
|
||||||
|
|
||||||
moduleDescriptors.forEach { moduleDescriptor ->
|
moduleDescriptors.forEach { moduleDescriptor ->
|
||||||
processModule(modules, targetIndex, moduleDescriptor)
|
if (moduleDescriptor.name.asString().removeSurrounding("<", ">") in commonModuleNames)
|
||||||
|
processModule(modules, targetIndex, moduleDescriptor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -40,8 +40,8 @@ class AggregatedStatsCollector(
|
|||||||
"Lifted Up, %%",
|
"Lifted Up, %%",
|
||||||
"Commonized",
|
"Commonized",
|
||||||
"Commonized, %%",
|
"Commonized, %%",
|
||||||
"Missed in s. targets",
|
"Missing in s. targets",
|
||||||
"Missed in s. targets, %%",
|
"Missing in s. targets, %%",
|
||||||
"Failed: Other",
|
"Failed: Other",
|
||||||
"Failed: Other, %%",
|
"Failed: Other, %%",
|
||||||
"Total"
|
"Total"
|
||||||
|
|||||||
+21
-25
@@ -19,10 +19,8 @@ import org.jetbrains.kotlin.config.languageVersionSettings
|
|||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
|
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.SourceModuleRoot.Companion.COMMON_TARGET_NAME
|
import org.jetbrains.kotlin.descriptors.commonizer.SourceModuleRoot.Companion.COMMON_TARGET_NAME
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.assertCommonizationPerformed
|
import org.jetbrains.kotlin.descriptors.commonizer.utils.*
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.assertIsDirectory
|
import org.jetbrains.kotlin.descriptors.commonizer.utils.MockBuiltInsProvider
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.assertModulesAreEqual
|
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.assertValidModule
|
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.platform.CommonPlatforms
|
import org.jetbrains.kotlin.platform.CommonPlatforms
|
||||||
@@ -42,10 +40,6 @@ abstract class AbstractCommonizationFromSourcesTest : KtUsefulTestCase() {
|
|||||||
init {
|
init {
|
||||||
System.setProperty("java.awt.headless", "true")
|
System.setProperty("java.awt.headless", "true")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Collection<ModuleDescriptor>.eachModuleAsTarget() = mapIndexed { index, moduleDescriptor ->
|
|
||||||
InputTarget("target_$index") to moduleDescriptor
|
|
||||||
}.toMap().toCommonizationParameters()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getTestDataDir(): File {
|
private fun getTestDataDir(): File {
|
||||||
@@ -69,26 +63,28 @@ abstract class AbstractCommonizationFromSourcesTest : KtUsefulTestCase() {
|
|||||||
val result: Result = runCommonization(analyzedModules.toCommonizationParameters())
|
val result: Result = runCommonization(analyzedModules.toCommonizationParameters())
|
||||||
assertCommonizationPerformed(result)
|
assertCommonizationPerformed(result)
|
||||||
|
|
||||||
val commonTarget: OutputTarget = analyzedModules.commonizedCommonModule.target
|
val sharedTarget: OutputTarget = analyzedModules.commonizedCommonModule.target
|
||||||
assertEquals(commonTarget, result.commonTarget)
|
assertEquals(sharedTarget, result.sharedTarget)
|
||||||
|
|
||||||
val commonModuleAsExpected: ModuleDescriptor = analyzedModules.commonizedCommonModule.module
|
val sharedModuleAsExpected: ModuleDescriptor = analyzedModules.commonizedCommonModule.module
|
||||||
val commonModuleByCommonizer: ModuleDescriptor = result.modulesByTargets.getValue(commonTarget).single()
|
val sharedModuleByCommonizer: ModuleDescriptor =
|
||||||
|
(result.modulesByTargets.getValue(sharedTarget).single() as ModuleResult.Commonized).module
|
||||||
|
|
||||||
assertValidModule(commonModuleAsExpected)
|
assertValidModule(sharedModuleAsExpected)
|
||||||
assertValidModule(commonModuleByCommonizer)
|
assertValidModule(sharedModuleByCommonizer)
|
||||||
assertModulesAreEqual(commonModuleAsExpected, commonModuleByCommonizer, "\"$commonTarget\" target")
|
assertModulesAreEqual(sharedModuleAsExpected, sharedModuleByCommonizer, "\"$sharedTarget\" target")
|
||||||
|
|
||||||
val concreteTargets: Set<InputTarget> = analyzedModules.commonizedPlatformModules.keys
|
val leafTargets: Set<InputTarget> = analyzedModules.commonizedPlatformModules.keys
|
||||||
assertEquals(concreteTargets, result.concreteTargets)
|
assertEquals(leafTargets, result.leafTargets)
|
||||||
|
|
||||||
for (target in concreteTargets) {
|
for (leafTarget in leafTargets) {
|
||||||
val targetModuleAsExpected: ModuleDescriptor = analyzedModules.commonizedPlatformModules.getValue(target).module
|
val leafTargetModuleAsExpected: ModuleDescriptor = analyzedModules.commonizedPlatformModules.getValue(leafTarget).module
|
||||||
val targetModuleByCommonizer: ModuleDescriptor = result.modulesByTargets.getValue(target).single()
|
val leafTargetModuleByCommonizer: ModuleDescriptor =
|
||||||
|
(result.modulesByTargets.getValue(leafTarget).single() as ModuleResult.Commonized).module
|
||||||
|
|
||||||
assertValidModule(targetModuleAsExpected)
|
assertValidModule(leafTargetModuleAsExpected)
|
||||||
assertValidModule(targetModuleByCommonizer)
|
assertValidModule(leafTargetModuleByCommonizer)
|
||||||
assertModulesAreEqual(targetModuleAsExpected, targetModuleByCommonizer, "\"$target\" target")
|
assertModulesAreEqual(leafTargetModuleAsExpected, leafTargetModuleByCommonizer, "\"$leafTarget\" target")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -327,8 +323,8 @@ private fun Map<InputTarget, ModuleDescriptor>.toCommonizationParameters(): Para
|
|||||||
TargetProvider(
|
TargetProvider(
|
||||||
target = target,
|
target = target,
|
||||||
builtInsClass = moduleDescriptor.builtIns::class.java,
|
builtInsClass = moduleDescriptor.builtIns::class.java,
|
||||||
builtInsProvider = BuiltInsProvider.wrap(moduleDescriptor.builtIns),
|
builtInsProvider = MockBuiltInsProvider(moduleDescriptor.builtIns),
|
||||||
modulesProvider = ModulesProvider.wrap(moduleDescriptor)
|
modulesProvider = MockModulesProvider(moduleDescriptor)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+106
-36
@@ -5,10 +5,9 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.descriptors.commonizer
|
package org.jetbrains.kotlin.descriptors.commonizer
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.AbstractCommonizationFromSourcesTest.Companion.eachModuleAsTarget
|
import org.jetbrains.kotlin.descriptors.commonizer.utils.MockModulesProvider
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.assertCommonizationPerformed
|
import org.jetbrains.kotlin.descriptors.commonizer.utils.assertCommonizationPerformed
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.mockEmptyModule
|
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import kotlin.contracts.ExperimentalContracts
|
import kotlin.contracts.ExperimentalContracts
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
@@ -17,49 +16,120 @@ import kotlin.test.assertEquals
|
|||||||
class CommonizerFacadeTest {
|
class CommonizerFacadeTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun nothingToCommonize0() {
|
fun nothingToCommonize0() = doTestNothingToCommonize(
|
||||||
val modules = listOf<ModuleDescriptor>()
|
emptyMap()
|
||||||
|
)
|
||||||
val result = runCommonization(modules.eachModuleAsTarget())
|
|
||||||
|
|
||||||
assertEquals(NothingToCommonize, result)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun nothingToCommonize1() {
|
fun nothingToCommonize1() = doTestNothingToCommonize(
|
||||||
val modules = listOf(
|
mapOf(
|
||||||
mockEmptyModule("<foo>")
|
"target1" to listOf("foo")
|
||||||
)
|
)
|
||||||
|
)
|
||||||
val result = runCommonization(modules.eachModuleAsTarget())
|
|
||||||
|
|
||||||
assertEquals(NothingToCommonize, result)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun commonized() {
|
fun commonized1() = doTestSuccessfulCommonization(
|
||||||
val modules = listOf(
|
mapOf(
|
||||||
mockEmptyModule("<foo>"),
|
"target1" to listOf("foo"),
|
||||||
mockEmptyModule("<foo>")
|
"target2" to listOf("foo")
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
|
||||||
val result = runCommonization(modules.eachModuleAsTarget())
|
@Test
|
||||||
|
fun commonized2() = doTestSuccessfulCommonization(
|
||||||
|
mapOf(
|
||||||
|
"target1" to listOf("foo", "bar"),
|
||||||
|
"target2" to listOf("bar", "foo")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
assertCommonizationPerformed(result)
|
@Test
|
||||||
|
fun commonizedWithDifferentModules() = doTestSuccessfulCommonization(
|
||||||
|
mapOf(
|
||||||
|
"target1" to listOf("foo"),
|
||||||
|
"target2" to listOf("bar")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
assertSingleModuleForTarget("<foo>", result.modulesByTargets.getValue(result.commonTarget))
|
@Test
|
||||||
|
fun commonizedWithAbsentModules() = doTestSuccessfulCommonization(
|
||||||
|
mapOf(
|
||||||
|
"target1" to listOf("foo", "bar"),
|
||||||
|
"target2" to listOf("foo", "qix")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
assertEquals(2, result.concreteTargets.size)
|
companion object {
|
||||||
for (target in result.concreteTargets) {
|
private fun Map<String, List<String>>.toCommonizationParameters() = Parameters().also {
|
||||||
assertSingleModuleForTarget("<foo>", result.modulesByTargets.getValue(target))
|
forEach { (targetName, moduleNames) ->
|
||||||
|
it.addTarget(
|
||||||
|
TargetProvider(
|
||||||
|
target = InputTarget(targetName),
|
||||||
|
builtInsClass = DefaultBuiltIns::class.java,
|
||||||
|
builtInsProvider = BuiltInsProvider.defaultBuiltInsProvider,
|
||||||
|
modulesProvider = MockModulesProvider(moduleNames)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun doTestNothingToCommonize(originalModules: Map<String, List<String>>) {
|
||||||
|
val result = runCommonization(originalModules.toCommonizationParameters())
|
||||||
|
assertEquals(Result.NothingToCommonize, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun doTestSuccessfulCommonization(originalModules: Map<String, List<String>>) {
|
||||||
|
val result = runCommonization(originalModules.toCommonizationParameters())
|
||||||
|
assertCommonizationPerformed(result)
|
||||||
|
|
||||||
|
val expectedCommonModuleNames = mutableSetOf<String>()
|
||||||
|
originalModules.values.forEachIndexed { index, moduleNames ->
|
||||||
|
if (index == 0)
|
||||||
|
expectedCommonModuleNames.addAll(moduleNames)
|
||||||
|
else
|
||||||
|
expectedCommonModuleNames.retainAll(moduleNames)
|
||||||
|
}
|
||||||
|
assertModulesMatch(
|
||||||
|
expectedCommonizedModuleNames = expectedCommonModuleNames,
|
||||||
|
expectedAbsentModuleNames = emptySet(),
|
||||||
|
actualModuleResults = result.modulesByTargets.getValue(result.sharedTarget)
|
||||||
|
)
|
||||||
|
|
||||||
|
result.leafTargets.forEach { target ->
|
||||||
|
val allModuleNames = originalModules.getValue(target.name).toSet()
|
||||||
|
val expectedAbsentModuleNames = allModuleNames - expectedCommonModuleNames
|
||||||
|
|
||||||
|
assertModulesMatch(
|
||||||
|
expectedCommonizedModuleNames = expectedCommonModuleNames,
|
||||||
|
expectedAbsentModuleNames = expectedAbsentModuleNames,
|
||||||
|
actualModuleResults = result.modulesByTargets.getValue(target)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun assertModulesMatch(
|
||||||
|
expectedCommonizedModuleNames: Set<String>,
|
||||||
|
expectedAbsentModuleNames: Set<String>,
|
||||||
|
actualModuleResults: Collection<ModuleResult>
|
||||||
|
) {
|
||||||
|
assertEquals(expectedCommonizedModuleNames.size + expectedAbsentModuleNames.size, actualModuleResults.size)
|
||||||
|
|
||||||
|
val actualCommonizedModuleNames = mutableSetOf<String>()
|
||||||
|
val actualAbsentModuleNames = mutableSetOf<String>()
|
||||||
|
|
||||||
|
actualModuleResults.forEach { moduleResult ->
|
||||||
|
when (moduleResult) {
|
||||||
|
is ModuleResult.Commonized -> {
|
||||||
|
actualCommonizedModuleNames += moduleResult.module.name.asString().removeSurrounding("<", ">")
|
||||||
|
}
|
||||||
|
is ModuleResult.Absent -> {
|
||||||
|
actualAbsentModuleNames += moduleResult.originalLocation.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(expectedCommonizedModuleNames, actualCommonizedModuleNames)
|
||||||
|
assertEquals(expectedAbsentModuleNames, actualAbsentModuleNames)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun assertSingleModuleForTarget(
|
|
||||||
@Suppress("SameParameterValue") expectedModuleName: String,
|
|
||||||
modules: Collection<ModuleDescriptor>
|
|
||||||
) {
|
|
||||||
assertEquals(1, modules.size)
|
|
||||||
assertEquals(expectedModuleName, modules.single().name.asString())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -9,12 +9,12 @@ import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
|||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns
|
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns
|
||||||
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
|
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.BuiltInsProvider
|
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.InputTarget
|
import org.jetbrains.kotlin.descriptors.commonizer.InputTarget
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.OutputTarget
|
import org.jetbrains.kotlin.descriptors.commonizer.OutputTarget
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.Target
|
import org.jetbrains.kotlin.descriptors.commonizer.Target
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirRoot
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirRoot
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirRootFactory
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirRootFactory
|
||||||
|
import org.jetbrains.kotlin.descriptors.commonizer.utils.MockBuiltInsProvider
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
@@ -167,7 +167,7 @@ class RootCommonizerTest : AbstractCommonizerTest<CirRoot, CirRoot>() {
|
|||||||
fun KotlinBuiltIns.toMock(target: Target) = CirRootFactory.create(
|
fun KotlinBuiltIns.toMock(target: Target) = CirRootFactory.create(
|
||||||
target = target,
|
target = target,
|
||||||
builtInsClass = this::class.java.name,
|
builtInsClass = this::class.java.name,
|
||||||
builtInsProvider = BuiltInsProvider.wrap(this)
|
builtInsProvider = MockBuiltInsProvider(this)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-5
@@ -6,9 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.descriptors.commonizer.utils
|
package org.jetbrains.kotlin.descriptors.commonizer.utils
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.CommonizationPerformed
|
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.Result
|
import org.jetbrains.kotlin.descriptors.commonizer.Result
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||||
import org.jetbrains.kotlin.test.util.DescriptorValidator.*
|
import org.jetbrains.kotlin.test.util.DescriptorValidator.*
|
||||||
import org.jetbrains.kotlin.types.ErrorUtils
|
import org.jetbrains.kotlin.types.ErrorUtils
|
||||||
@@ -26,11 +24,11 @@ fun assertIsDirectory(file: File) {
|
|||||||
@ExperimentalContracts
|
@ExperimentalContracts
|
||||||
fun assertCommonizationPerformed(result: Result) {
|
fun assertCommonizationPerformed(result: Result) {
|
||||||
contract {
|
contract {
|
||||||
returns() implies (result is CommonizationPerformed)
|
returns() implies (result is Result.Commonized)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result !is CommonizationPerformed)
|
if (result !is Result.Commonized)
|
||||||
fail("$result is not instance of ${CommonizationPerformed::class}")
|
fail("$result is not instance of ${Result.Commonized::class}")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExperimentalContracts
|
@ExperimentalContracts
|
||||||
|
|||||||
@@ -6,9 +6,13 @@
|
|||||||
package org.jetbrains.kotlin.descriptors.commonizer.utils
|
package org.jetbrains.kotlin.descriptors.commonizer.utils
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||||
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
|
import org.jetbrains.kotlin.descriptors.commonizer.BuiltInsProvider
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.InputTarget
|
import org.jetbrains.kotlin.descriptors.commonizer.InputTarget
|
||||||
|
import org.jetbrains.kotlin.descriptors.commonizer.ModulesProvider
|
||||||
|
import org.jetbrains.kotlin.descriptors.commonizer.ModulesProvider.ModuleInfo
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.builder.*
|
import org.jetbrains.kotlin.descriptors.commonizer.builder.*
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirClassNode
|
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirClassNode
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirClassifiersCache
|
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirClassifiersCache
|
||||||
@@ -19,6 +23,7 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
|||||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
|
import java.io.File
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
// expected special name for module
|
// expected special name for module
|
||||||
@@ -118,3 +123,28 @@ internal val EMPTY_CLASSIFIERS_CACHE = object : CirClassifiersCache {
|
|||||||
override val classes: Map<FqName, CirClassNode> get() = emptyMap()
|
override val classes: Map<FqName, CirClassNode> get() = emptyMap()
|
||||||
override val typeAliases: Map<FqName, CirTypeAliasNode> get() = emptyMap()
|
override val typeAliases: Map<FqName, CirTypeAliasNode> get() = emptyMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class MockBuiltInsProvider(private val builtIns: KotlinBuiltIns) : BuiltInsProvider {
|
||||||
|
override fun loadBuiltIns() = builtIns
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class MockModulesProvider : ModulesProvider {
|
||||||
|
private val moduleInfos: Map<String, ModuleInfo>
|
||||||
|
private val modules: Map<String, ModuleDescriptor>
|
||||||
|
|
||||||
|
constructor(moduleNames: Collection<String>) {
|
||||||
|
moduleInfos = moduleNames.associateWith { name -> fakeModuleInfo(name) }
|
||||||
|
modules = moduleNames.associateWith { name -> mockEmptyModule("<$name>") }
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(module: ModuleDescriptor) {
|
||||||
|
val name = module.name.asString().removeSurrounding("<", ">")
|
||||||
|
moduleInfos = mapOf(name to fakeModuleInfo(name))
|
||||||
|
modules = mapOf(name to module)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun loadModuleInfos() = moduleInfos
|
||||||
|
override fun loadModules() = modules.values
|
||||||
|
|
||||||
|
private fun fakeModuleInfo(name: String) = ModuleInfo(name, File("/tmp/commonizer/mocks/$name"))
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user