[Commonizer] More fine-grained control of commonized module dependencies
- Reduce usage of 'isUnderStandardKotlinPackages' check in commonizer source code - Rely on common module dependencies supplied via commonizer Parameters which not only Kotlin standard library but may also include common fragments of other libraries
This commit is contained in:
@@ -16,16 +16,13 @@ class Parameters(
|
|||||||
|
|
||||||
val targetProviders: List<TargetProvider> get() = _targetProviders.values.toList()
|
val targetProviders: List<TargetProvider> get() = _targetProviders.values.toList()
|
||||||
|
|
||||||
// only for test purposes
|
// common module dependencies (ex: Kotlin stdlib)
|
||||||
internal var extendedLookupForBuiltInsClassifiers: Boolean = false
|
var dependeeModulesProvider: ModulesProvider? = null
|
||||||
set(value) {
|
set(value) {
|
||||||
check(!field || value)
|
check(field == null)
|
||||||
field = value
|
field = value
|
||||||
}
|
}
|
||||||
|
|
||||||
// only for test purposes
|
|
||||||
internal var commonModulesProvider: ModulesProvider? = null
|
|
||||||
|
|
||||||
fun addTarget(targetProvider: TargetProvider): Parameters {
|
fun addTarget(targetProvider: TargetProvider): Parameters {
|
||||||
require(targetProvider.target !in _targetProviders) { "Target ${targetProvider.target} is already added" }
|
require(targetProvider.target !in _targetProviders) { "Target ${targetProvider.target} is already added" }
|
||||||
_targetProviders[targetProvider.target] = targetProvider
|
_targetProviders[targetProvider.target] = targetProvider
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ class TargetProvider(
|
|||||||
val target: InputTarget,
|
val target: InputTarget,
|
||||||
val builtInsClass: Class<out KotlinBuiltIns>,
|
val builtInsClass: Class<out KotlinBuiltIns>,
|
||||||
val builtInsProvider: BuiltInsProvider,
|
val builtInsProvider: BuiltInsProvider,
|
||||||
val modulesProvider: ModulesProvider
|
val modulesProvider: ModulesProvider,
|
||||||
|
val dependeeModulesProvider: ModulesProvider?
|
||||||
)
|
)
|
||||||
|
|
||||||
interface BuiltInsProvider {
|
interface BuiltInsProvider {
|
||||||
@@ -40,5 +41,5 @@ interface ModulesProvider {
|
|||||||
)
|
)
|
||||||
|
|
||||||
fun loadModuleInfos(): Map<String, ModuleInfo>
|
fun loadModuleInfos(): Map<String, ModuleInfo>
|
||||||
fun loadModules(): Map<String, ModuleDescriptor>
|
fun loadModules(dependencies: Collection<ModuleDescriptor>): Map<String, ModuleDescriptor>
|
||||||
}
|
}
|
||||||
|
|||||||
+98
-63
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.descriptors.commonizer.builder
|
|||||||
|
|
||||||
import gnu.trove.THashMap
|
import gnu.trove.THashMap
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.builtins.StandardNames
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.Parameters
|
import org.jetbrains.kotlin.descriptors.commonizer.Parameters
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.Target
|
import org.jetbrains.kotlin.descriptors.commonizer.Target
|
||||||
@@ -133,68 +134,84 @@ class TargetDeclarationsBuilderComponents(
|
|||||||
val storageManager: StorageManager,
|
val storageManager: StorageManager,
|
||||||
val target: Target,
|
val target: Target,
|
||||||
val builtIns: KotlinBuiltIns,
|
val builtIns: KotlinBuiltIns,
|
||||||
val lazyModulesLookupTable: NotNullLazyValue<MutableMap<String, ModuleDescriptor?>>,
|
val lazyClassifierLookupTable: NotNullLazyValue<LazyClassifierLookupTable>,
|
||||||
val isCommon: Boolean,
|
|
||||||
val index: Int,
|
val index: Int,
|
||||||
private val cache: DeclarationsBuilderCache
|
private val cache: DeclarationsBuilderCache
|
||||||
) {
|
) {
|
||||||
// only for test purposes
|
|
||||||
internal var extendedLookupForBuiltInsClassifiers: Boolean = false
|
|
||||||
|
|
||||||
// N.B. this function may create new classifiers for types from Kotlin/Native forward declarations packages
|
// N.B. this function may create new classifiers for types from Kotlin/Native forward declarations packages
|
||||||
fun findClassOrTypeAlias(classId: ClassId): ClassifierDescriptorWithTypeParameters {
|
fun findClassOrTypeAlias(classifierId: ClassId): ClassifierDescriptorWithTypeParameters {
|
||||||
return when {
|
return if (classifierId.packageFqName.isUnderKotlinNativeSyntheticPackages) {
|
||||||
classId.packageFqName.isUnderStandardKotlinPackages -> {
|
// that's a synthetic Kotlin/Native classifier that was exported as forward declaration in one or more modules,
|
||||||
// look up for classifier in built-ins module:
|
// but did not match any existing class or typealias
|
||||||
val builtInsModule = builtIns.builtInsModule
|
cache.getOrPutForwardDeclarationsModule(index) {
|
||||||
|
// N.B. forward declarations module is created only on demand
|
||||||
// TODO: this works fine for Native as far as built-ins module contains full Native stdlib, but this is not enough for JVM and JS
|
createKotlinNativeForwardDeclarationsModule(
|
||||||
val classifier = builtInsModule.resolveClassOrTypeAlias(classId)
|
storageManager = storageManager,
|
||||||
if (classifier != null)
|
builtIns = builtIns
|
||||||
return classifier
|
)
|
||||||
|
}.resolveClassOrTypeAlias(classifierId)
|
||||||
if (extendedLookupForBuiltInsClassifiers) {
|
?: error("Classifier ${classifierId.asString()} not found for $target")
|
||||||
return findOriginalClassOrTypeAlias(classId)
|
} else {
|
||||||
?: error("Classifier ${classId.asString()} not found neither in built-ins module $builtInsModule nor in original modules for $target")
|
cache.getCachedClassifier(classifierId, index) // first, look up in created descriptors cache
|
||||||
}
|
?: lazyClassifierLookupTable().resolveClassOrTypeAlias(classifierId) // then, attempt to load the original classifier
|
||||||
|
?: error("Classifier ${classifierId.asString()} not found for $target")
|
||||||
error("Classifier ${classId.asString()} not found in built-ins module $builtInsModule for $target")
|
|
||||||
}
|
|
||||||
classId.packageFqName.isUnderKotlinNativeSyntheticPackages -> {
|
|
||||||
// that's a synthetic Kotlin/Native classifier that was exported as forward declaration in one or more modules,
|
|
||||||
// but did not match any existing class or typealias
|
|
||||||
cache.getOrPutForwardDeclarationsModule(index) {
|
|
||||||
// N.B. forward declarations module is created only on demand
|
|
||||||
createKotlinNativeForwardDeclarationsModule(
|
|
||||||
storageManager = storageManager,
|
|
||||||
builtIns = builtIns
|
|
||||||
)
|
|
||||||
}.resolveClassOrTypeAlias(classId)
|
|
||||||
?: error("Classifier ${classId.asString()} not found for $target")
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
cache.getCachedClassifier(classId, index) // first, look up in created descriptors cache
|
|
||||||
?: findOriginalClassOrTypeAlias(classId) // then, attempt to load the original classifier
|
|
||||||
?: error("Classifier ${classId.asString()} not found for $target")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun findOriginalClassOrTypeAlias(classId: ClassId): ClassifierDescriptorWithTypeParameters? {
|
class LazyClassifierLookupTable(lazyModules: Map<String, List<ModuleDescriptor>>) {
|
||||||
if (classId.packageFqName.isRoot)
|
private val table = THashMap<String, List<ModuleDescriptor>>()
|
||||||
return null
|
private val allModules: Collection<ModuleDescriptor>
|
||||||
|
|
||||||
// first, guess containing module and look up in it
|
init {
|
||||||
val classifier = lazyModulesLookupTable()
|
// add "module:" prefix for each key representing a module name, not a package name
|
||||||
.guessModuleByPackageFqName(classId.packageFqName)
|
lazyModules.forEach { (moduleName, modules) -> table[MODULE_NAME_PREFIX + moduleName.toLowerCase()] = modules }
|
||||||
?.resolveClassOrTypeAlias(classId)
|
allModules = lazyModules.values.flatten()
|
||||||
|
}
|
||||||
|
|
||||||
// if failed, then look up though all modules
|
fun resolveClassOrTypeAlias(classifierId: ClassId): ClassifierDescriptorWithTypeParameters? {
|
||||||
return classifier
|
if (table.isEmpty) return null
|
||||||
?: lazyModulesLookupTable().values
|
|
||||||
.asSequence()
|
val packageFqName = classifierId.packageFqName
|
||||||
.mapNotNull { it?.resolveClassOrTypeAlias(classId) }
|
if (packageFqName.isRoot) return null
|
||||||
.firstOrNull()
|
|
||||||
|
val packageFqNameRaw = packageFqName.asString()
|
||||||
|
table[packageFqNameRaw]?.let { modules ->
|
||||||
|
for (module in modules)
|
||||||
|
return module.resolveClassOrTypeAlias(classifierId) ?: continue
|
||||||
|
}
|
||||||
|
|
||||||
|
val packageFqNameFragments = packageFqNameRaw.split('.')
|
||||||
|
val moduleNameForLookup = when (packageFqNameFragments[0]) {
|
||||||
|
"kotlin" -> "kotlin"
|
||||||
|
"platform" -> if (packageFqNameFragments.size == 2) packageFqNameFragments[1].toLowerCase() else null
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to find the classifier by guessing its container module
|
||||||
|
if (moduleNameForLookup != null) {
|
||||||
|
table[MODULE_NAME_PREFIX + moduleNameForLookup]?.let { modules ->
|
||||||
|
for (module in modules) {
|
||||||
|
val classifier = module.resolveClassOrTypeAlias(classifierId) ?: continue
|
||||||
|
table[packageFqNameRaw] = modules // cache to speed-up the further look-ups
|
||||||
|
return classifier
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// last resort: brute force
|
||||||
|
for (module in allModules) {
|
||||||
|
val classifier = module.resolveClassOrTypeAlias(classifierId) ?: continue
|
||||||
|
table[packageFqNameRaw] = listOf(module) // cache to speed-up the further look-ups
|
||||||
|
return classifier
|
||||||
|
}
|
||||||
|
|
||||||
|
table[packageFqNameRaw] = null // cache to speed-up the further look-ups
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val MODULE_NAME_PREFIX = "module:"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,6 +221,10 @@ fun CirRootNode.createGlobalBuilderComponents(
|
|||||||
): GlobalDeclarationsBuilderComponents {
|
): GlobalDeclarationsBuilderComponents {
|
||||||
val cache = DeclarationsBuilderCache(dimension)
|
val cache = DeclarationsBuilderCache(dimension)
|
||||||
|
|
||||||
|
val lazyCommonDependeeModules = storageManager.createLazyValue {
|
||||||
|
parameters.dependeeModulesProvider?.loadModules(emptyList()).orEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
val targetContexts = (0 until dimension).map { index ->
|
val targetContexts = (0 until dimension).map { index ->
|
||||||
val isCommon = index == indexOfCommon
|
val isCommon = index == indexOfCommon
|
||||||
|
|
||||||
@@ -216,24 +237,38 @@ fun CirRootNode.createGlobalBuilderComponents(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val lazyModulesLookupTable = storageManager.createLazyValue {
|
val lazyModulesLookupTable = storageManager.createLazyValue {
|
||||||
val source = if (isCommon)
|
val result = mutableMapOf<String, MutableList<ModuleDescriptor>>()
|
||||||
parameters.commonModulesProvider?.loadModules() ?: emptyMap()
|
|
||||||
else
|
val commonDependeeModules: Map<String, ModuleDescriptor> = lazyCommonDependeeModules()
|
||||||
parameters.targetProviders[index].modulesProvider.loadModules()
|
|
||||||
THashMap(source)
|
if (!isCommon) {
|
||||||
|
with(parameters.targetProviders[index]) {
|
||||||
|
val targetDependeeModules: Map<String, ModuleDescriptor> =
|
||||||
|
dependeeModulesProvider?.loadModules(commonDependeeModules.values).orEmpty()
|
||||||
|
|
||||||
|
val targetModules: Map<String, ModuleDescriptor> =
|
||||||
|
modulesProvider.loadModules(targetDependeeModules.values + commonDependeeModules.values)
|
||||||
|
|
||||||
|
targetModules.forEach { (moduleName, module) -> result.getOrPut(moduleName) { mutableListOf() } += module }
|
||||||
|
targetDependeeModules.forEach { (moduleName, module) -> result.getOrPut(moduleName) { mutableListOf() } += module }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
commonDependeeModules.forEach { (moduleName, module) -> result.getOrPut(moduleName) { mutableListOf() } += module }
|
||||||
|
|
||||||
|
result.getOrPut(StandardNames.BUILT_INS_PACKAGE_FQ_NAME.asString()) { mutableListOf() } += builtIns.builtInsModule
|
||||||
|
|
||||||
|
LazyClassifierLookupTable(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetDeclarationsBuilderComponents(
|
TargetDeclarationsBuilderComponents(
|
||||||
storageManager = storageManager,
|
storageManager = storageManager,
|
||||||
target = root.target,
|
target = root.target,
|
||||||
builtIns = builtIns,
|
builtIns = builtIns,
|
||||||
lazyModulesLookupTable = lazyModulesLookupTable,
|
lazyClassifierLookupTable = lazyModulesLookupTable,
|
||||||
isCommon = isCommon,
|
|
||||||
index = index,
|
index = index,
|
||||||
cache = cache
|
cache = cache
|
||||||
).also {
|
)
|
||||||
it.extendedLookupForBuiltInsClassifiers = parameters.extendedLookupForBuiltInsClassifiers
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return GlobalDeclarationsBuilderComponents(storageManager, targetContexts, cache, parameters.statsCollector)
|
return GlobalDeclarationsBuilderComponents(storageManager, targetContexts, cache, parameters.statsCollector)
|
||||||
|
|||||||
+29
-29
@@ -55,13 +55,13 @@ class NativeDistributionCommonizer(
|
|||||||
clockMark.reset()
|
clockMark.reset()
|
||||||
|
|
||||||
// 1. load libraries
|
// 1. load libraries
|
||||||
val librariesByTargets = loadLibraries()
|
val allLibraries = loadLibraries()
|
||||||
|
|
||||||
// 2. run commonization
|
// 2. run commonization
|
||||||
val result = commonize(librariesByTargets)
|
val result = commonize(allLibraries)
|
||||||
|
|
||||||
// 3. write new libraries
|
// 3. write new libraries
|
||||||
saveModules(librariesByTargets, result)
|
saveModules(allLibraries, result)
|
||||||
|
|
||||||
logTotal()
|
logTotal()
|
||||||
}
|
}
|
||||||
@@ -86,29 +86,29 @@ class NativeDistributionCommonizer(
|
|||||||
|
|
||||||
private fun logTotal() = logger.log("TOTAL: ${clockMark.elapsedSinceStart()}")
|
private fun logTotal() = logger.log("TOTAL: ${clockMark.elapsedSinceStart()}")
|
||||||
|
|
||||||
private fun loadLibraries(): Map<InputTarget, NativeDistributionLibraries> {
|
private fun loadLibraries(): AllNativeLibraries {
|
||||||
val stdlibPath = repository.resolve(konanCommonLibraryPath(KONAN_STDLIB_NAME))
|
val stdlibPath = repository.resolve(konanCommonLibraryPath(KONAN_STDLIB_NAME))
|
||||||
val stdlib = loadLibrary(stdlibPath)
|
val stdlib = NativeLibrary(loadLibrary(stdlibPath))
|
||||||
|
|
||||||
val result = targets.associate { target ->
|
val librariesByTargets = targets.associate { target ->
|
||||||
val leafTarget = InputTarget(target.name, target)
|
val leafTarget = InputTarget(target.name, target)
|
||||||
|
|
||||||
val platformLibs = leafTarget.platformLibrariesSource
|
val platformLibs = leafTarget.platformLibrariesSource
|
||||||
.takeIf { it.isDirectory }
|
.takeIf { it.isDirectory }
|
||||||
?.listFiles()
|
?.listFiles()
|
||||||
?.takeIf { it.isNotEmpty() }
|
?.takeIf { it.isNotEmpty() }
|
||||||
?.map { loadLibrary(it) }
|
?.map { NativeLibrary(loadLibrary(it)) }
|
||||||
.orEmpty()
|
.orEmpty()
|
||||||
|
|
||||||
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.")
|
||||||
|
|
||||||
leafTarget to NativeDistributionLibraries(stdlib, platformLibs)
|
leafTarget to NativeLibrariesToCommonize(platformLibs)
|
||||||
}
|
}
|
||||||
|
|
||||||
logProgress("Read lazy (uninitialized) libraries")
|
logProgress("Read lazy (uninitialized) libraries")
|
||||||
|
|
||||||
return result
|
return AllNativeLibraries(stdlib, librariesByTargets)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadLibrary(location: File): KotlinLibrary {
|
private fun loadLibrary(location: File): KotlinLibrary {
|
||||||
@@ -136,7 +136,7 @@ class NativeDistributionCommonizer(
|
|||||||
return library
|
return library
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun commonize(librariesByTargets: Map<InputTarget, NativeDistributionLibraries>): Result {
|
private fun commonize(allLibraries: AllNativeLibraries): Result {
|
||||||
val statsCollector = when (statsType) {
|
val statsCollector = when (statsType) {
|
||||||
RAW -> RawStatsCollector(targets, FileStatsOutput(destination, "raw"))
|
RAW -> RawStatsCollector(targets, FileStatsOutput(destination, "raw"))
|
||||||
AGGREGATED -> AggregatedStatsCollector(targets, FileStatsOutput(destination, "aggregated"))
|
AGGREGATED -> AggregatedStatsCollector(targets, FileStatsOutput(destination, "aggregated"))
|
||||||
@@ -144,20 +144,23 @@ class NativeDistributionCommonizer(
|
|||||||
}
|
}
|
||||||
statsCollector.use {
|
statsCollector.use {
|
||||||
val parameters = Parameters(statsCollector, ::logProgress).apply {
|
val parameters = Parameters(statsCollector, ::logProgress).apply {
|
||||||
librariesByTargets.forEach { (target, libraries) ->
|
val storageManager = LockBasedStorageManager("Commonized modules")
|
||||||
if (libraries.platformLibs.isEmpty()) return@forEach
|
|
||||||
|
|
||||||
val provider = NativeDistributionModulesProvider(
|
val stdlibProvider = NativeDistributionStdlibProvider(storageManager, allLibraries.stdlib)
|
||||||
storageManager = LockBasedStorageManager("Target $target"),
|
dependeeModulesProvider = stdlibProvider
|
||||||
libraries = libraries
|
|
||||||
)
|
allLibraries.librariesByTargets.forEach { (target, librariesToCommonize) ->
|
||||||
|
if (librariesToCommonize.libraries.isEmpty()) return@forEach
|
||||||
|
|
||||||
|
val modulesProvider = NativeDistributionModulesProvider(storageManager, librariesToCommonize)
|
||||||
|
|
||||||
addTarget(
|
addTarget(
|
||||||
TargetProvider(
|
TargetProvider(
|
||||||
target = target,
|
target = target,
|
||||||
builtInsClass = KonanBuiltIns::class.java,
|
builtInsClass = KonanBuiltIns::class.java,
|
||||||
builtInsProvider = provider,
|
builtInsProvider = stdlibProvider,
|
||||||
modulesProvider = provider
|
modulesProvider = modulesProvider,
|
||||||
|
dependeeModulesProvider = null // stdlib is already set as common dependency
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -167,10 +170,7 @@ class NativeDistributionCommonizer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun saveModules(
|
private fun saveModules(originalLibraries: AllNativeLibraries, result: Result) {
|
||||||
originalLibrariesByTargets: Map<InputTarget, NativeDistributionLibraries>,
|
|
||||||
result: Result
|
|
||||||
) {
|
|
||||||
// optimization: stdlib and endorsed libraries effectively remain the same across all Kotlin/Native targets,
|
// optimization: stdlib and endorsed libraries effectively remain the same across all Kotlin/Native targets,
|
||||||
// so they can be just copied to the new destination without running serializer
|
// so they can be just copied to the new destination without running serializer
|
||||||
copyCommonStandardLibraries()
|
copyCommonStandardLibraries()
|
||||||
@@ -180,8 +180,8 @@ class NativeDistributionCommonizer(
|
|||||||
// 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 the 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) ->
|
originalLibraries.librariesByTargets.forEach { (target, librariesToCommonize) ->
|
||||||
copyTargetAsIs(target, libraries.platformLibs.size)
|
copyTargetAsIs(target, librariesToCommonize.libraries.size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,11 +194,11 @@ 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.leafTargets
|
val targetsToCopy = originalLibraries.librariesByTargets.keys - result.leafTargets
|
||||||
if (targetsToCopy.isNotEmpty()) {
|
if (targetsToCopy.isNotEmpty()) {
|
||||||
targetsToCopy.forEach { target ->
|
targetsToCopy.forEach { target ->
|
||||||
val libraries = originalLibrariesByTargets.getValue(target)
|
val librariesToCommonize = originalLibraries.librariesByTargets.getValue(target)
|
||||||
copyTargetAsIs(target, libraries.platformLibs.size)
|
copyTargetAsIs(target, librariesToCommonize.libraries.size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,11 +214,11 @@ class NativeDistributionCommonizer(
|
|||||||
val starredTarget: String?
|
val starredTarget: String?
|
||||||
when (target) {
|
when (target) {
|
||||||
is InputTarget -> {
|
is InputTarget -> {
|
||||||
manifestProvider = originalLibrariesByTargets.getValue(target)
|
manifestProvider = originalLibraries.librariesByTargets.getValue(target)
|
||||||
starredTarget = target.name
|
starredTarget = target.name
|
||||||
}
|
}
|
||||||
is OutputTarget -> {
|
is OutputTarget -> {
|
||||||
manifestProvider = CommonNativeManifestDataProvider(originalLibrariesByTargets.values)
|
manifestProvider = CommonNativeManifestDataProvider(originalLibraries.librariesByTargets.values)
|
||||||
starredTarget = null
|
starredTarget = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+27
-26
@@ -5,38 +5,26 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.descriptors.commonizer.konan
|
package org.jetbrains.kotlin.descriptors.commonizer.konan
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
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.ModulesProvider
|
import org.jetbrains.kotlin.descriptors.commonizer.ModulesProvider
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.ModulesProvider.CInteropModuleAttributes
|
import org.jetbrains.kotlin.descriptors.commonizer.ModulesProvider.CInteropModuleAttributes
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.ModulesProvider.ModuleInfo
|
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.descriptors.commonizer.utils.strip
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
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.storage.StorageManager
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
internal class NativeDistributionModulesProvider(
|
internal class NativeDistributionModulesProvider(
|
||||||
private val storageManager: StorageManager,
|
private val storageManager: StorageManager,
|
||||||
private val libraries: NativeDistributionLibraries
|
private val librariesToCommonize: NativeLibrariesToCommonize
|
||||||
) : BuiltInsProvider, ModulesProvider {
|
) : ModulesProvider {
|
||||||
override fun loadBuiltIns(): KotlinBuiltIns {
|
|
||||||
val stdlib = NativeFactories.DefaultDeserializedDescriptorFactory.createDescriptorAndNewBuiltIns(
|
|
||||||
library = libraries.stdlib.library,
|
|
||||||
languageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
|
|
||||||
storageManager = storageManager,
|
|
||||||
packageAccessHandler = null
|
|
||||||
)
|
|
||||||
stdlib.setDependencies(listOf(stdlib))
|
|
||||||
|
|
||||||
return stdlib.builtIns
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun loadModuleInfos(): Map<String, ModuleInfo> {
|
override fun loadModuleInfos(): Map<String, ModuleInfo> {
|
||||||
return libraries.platformLibs.associate { library ->
|
return librariesToCommonize.libraries.associate { library ->
|
||||||
val manifestData = library.manifestData
|
val manifestData = library.manifestData
|
||||||
|
|
||||||
val name = manifestData.uniqueName
|
val name = manifestData.uniqueName
|
||||||
@@ -54,11 +42,18 @@ internal class NativeDistributionModulesProvider(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun loadModules(): Map<String, ModuleDescriptor> {
|
override fun loadModules(dependencies: Collection<ModuleDescriptor>): Map<String, ModuleDescriptor> {
|
||||||
val builtIns = loadBuiltIns()
|
check(dependencies.isNotEmpty()) { "At least Kotlin/Native stdlib should be provided" }
|
||||||
val stdlib = builtIns.builtInsModule
|
|
||||||
|
|
||||||
val platformModulesMap = libraries.platformLibs.associate { library ->
|
val dependenciesMap = mutableMapOf<String, MutableList<ModuleDescriptorImpl>>()
|
||||||
|
dependencies.forEach { dependency ->
|
||||||
|
val name = dependency.name.strip()
|
||||||
|
dependenciesMap.getOrPut(name) { mutableListOf() } += dependency as ModuleDescriptorImpl
|
||||||
|
}
|
||||||
|
|
||||||
|
val builtIns = dependencies.first().builtIns
|
||||||
|
|
||||||
|
val platformModulesMap = librariesToCommonize.libraries.associate { library ->
|
||||||
val name = library.manifestData.uniqueName
|
val name = library.manifestData.uniqueName
|
||||||
val module = NativeFactories.DefaultDeserializedDescriptorFactory.createDescriptorOptionalBuiltIns(
|
val module = NativeFactories.DefaultDeserializedDescriptorFactory.createDescriptorOptionalBuiltIns(
|
||||||
library = library.library,
|
library = library.library,
|
||||||
@@ -78,11 +73,17 @@ internal class NativeDistributionModulesProvider(
|
|||||||
)
|
)
|
||||||
|
|
||||||
platformModulesMap.forEach { (name, module) ->
|
platformModulesMap.forEach { (name, module) ->
|
||||||
val dependencies = libraries.getManifest(name)
|
val moduleDependencies = mutableListOf<ModuleDescriptorImpl>()
|
||||||
.dependencies
|
moduleDependencies += module
|
||||||
.map { if (it == KONAN_STDLIB_NAME) stdlib else platformModulesMap.getValue(it) }
|
|
||||||
|
|
||||||
module.setDependencies(listOf(module) + dependencies + forwardDeclarations)
|
librariesToCommonize.getManifest(name).dependencies.forEach {
|
||||||
|
moduleDependencies.addIfNotNull(platformModulesMap[it])
|
||||||
|
moduleDependencies += dependenciesMap[it].orEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
|
moduleDependencies += forwardDeclarations
|
||||||
|
|
||||||
|
module.setDependencies(moduleDependencies)
|
||||||
}
|
}
|
||||||
|
|
||||||
return platformModulesMap
|
return platformModulesMap
|
||||||
|
|||||||
+46
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 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.descriptors.commonizer.konan
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
||||||
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.commonizer.BuiltInsProvider
|
||||||
|
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.konan.library.KONAN_STDLIB_NAME
|
||||||
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
internal class NativeDistributionStdlibProvider(
|
||||||
|
private val storageManager: StorageManager,
|
||||||
|
private val stdlib: NativeLibrary
|
||||||
|
) : BuiltInsProvider, ModulesProvider {
|
||||||
|
private val moduleInfo = ModuleInfo(
|
||||||
|
name = KONAN_STDLIB_NAME,
|
||||||
|
originalLocation = File(stdlib.library.libraryFile.absolutePath),
|
||||||
|
cInteropAttributes = null
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun loadBuiltIns(): KotlinBuiltIns = loadStdlibModule().builtIns
|
||||||
|
override fun loadModuleInfos(): Map<String, ModuleInfo> = mapOf(KONAN_STDLIB_NAME to moduleInfo)
|
||||||
|
|
||||||
|
override fun loadModules(dependencies: Collection<ModuleDescriptor>): Map<String, ModuleDescriptor> {
|
||||||
|
check(dependencies.isEmpty())
|
||||||
|
return mapOf(KONAN_STDLIB_NAME to loadStdlibModule())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadStdlibModule() =
|
||||||
|
NativeFactories.DefaultDeserializedDescriptorFactory.createDescriptorAndNewBuiltIns(
|
||||||
|
library = stdlib.library,
|
||||||
|
languageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
|
||||||
|
storageManager = storageManager,
|
||||||
|
packageAccessHandler = null
|
||||||
|
).apply {
|
||||||
|
setDependencies(listOf(this))
|
||||||
|
}
|
||||||
|
}
|
||||||
+17
-15
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.descriptors.commonizer.konan
|
package org.jetbrains.kotlin.descriptors.commonizer.konan
|
||||||
|
|
||||||
import gnu.trove.THashMap
|
import gnu.trove.THashMap
|
||||||
|
import org.jetbrains.kotlin.descriptors.commonizer.InputTarget
|
||||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
|
|
||||||
internal interface NativeManifestDataProvider {
|
internal interface NativeManifestDataProvider {
|
||||||
@@ -13,33 +14,34 @@ internal interface NativeManifestDataProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A separate Kotlin/Native library from the distribution.
|
* A separate Kotlin/Native library.
|
||||||
*/
|
*/
|
||||||
internal class NativeDistributionLibrary(
|
internal class NativeLibrary(
|
||||||
val library: KotlinLibrary
|
val library: KotlinLibrary
|
||||||
) {
|
) {
|
||||||
val manifestData = NativeSensitiveManifestData.readFrom(library)
|
val manifestData = NativeSensitiveManifestData.readFrom(library)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A collection of Kotlin/Native libraries for a certain Native target + stdlib from the distribution.
|
* A collection of Kotlin/Native libraries for a certain Native target.
|
||||||
*/
|
*/
|
||||||
internal class NativeDistributionLibraries(
|
internal class NativeLibrariesToCommonize(val libraries: List<NativeLibrary>) : NativeManifestDataProvider {
|
||||||
val stdlib: NativeDistributionLibrary,
|
|
||||||
val platformLibs: List<NativeDistributionLibrary>
|
|
||||||
) : NativeManifestDataProvider {
|
|
||||||
constructor(stdlib: KotlinLibrary, platformLibs: List<KotlinLibrary>) : this(
|
|
||||||
NativeDistributionLibrary(stdlib),
|
|
||||||
platformLibs.map(::NativeDistributionLibrary)
|
|
||||||
)
|
|
||||||
|
|
||||||
private val manifestIndex: Map<String, NativeSensitiveManifestData> = buildManifestIndex()
|
private val manifestIndex: Map<String, NativeSensitiveManifestData> = buildManifestIndex()
|
||||||
|
|
||||||
override fun getManifest(libraryName: String) = manifestIndex.getValue(libraryName)
|
override fun getManifest(libraryName: String) = manifestIndex.getValue(libraryName)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun create(libraries: List<KotlinLibrary>) = NativeLibrariesToCommonize(libraries.map(::NativeLibrary))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class AllNativeLibraries(
|
||||||
|
val stdlib: NativeLibrary,
|
||||||
|
val librariesByTargets: Map<InputTarget, NativeLibrariesToCommonize>
|
||||||
|
)
|
||||||
|
|
||||||
internal class CommonNativeManifestDataProvider(
|
internal class CommonNativeManifestDataProvider(
|
||||||
libraryGroups: Collection<NativeDistributionLibraries>
|
libraryGroups: Collection<NativeLibrariesToCommonize>
|
||||||
) : NativeManifestDataProvider {
|
) : NativeManifestDataProvider {
|
||||||
private val manifestIndex: Map<String, NativeSensitiveManifestData>
|
private val manifestIndex: Map<String, NativeSensitiveManifestData>
|
||||||
|
|
||||||
@@ -66,5 +68,5 @@ internal class CommonNativeManifestDataProvider(
|
|||||||
override fun getManifest(libraryName: String) = manifestIndex.getValue(libraryName)
|
override fun getManifest(libraryName: String) = manifestIndex.getValue(libraryName)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun NativeDistributionLibraries.buildManifestIndex(): MutableMap<String, NativeSensitiveManifestData> =
|
private fun NativeLibrariesToCommonize.buildManifestIndex(): MutableMap<String, NativeSensitiveManifestData> =
|
||||||
(platformLibs + stdlib).map { it.manifestData }.associateByTo(THashMap()) { it.uniqueName }
|
libraries.map { it.manifestData }.associateByTo(THashMap()) { it.uniqueName }
|
||||||
+32
-13
@@ -59,14 +59,26 @@ class CirTreeMerger(
|
|||||||
private val size = parameters.targetProviders.size
|
private val size = parameters.targetProviders.size
|
||||||
|
|
||||||
fun merge(): CirTreeMergeResult {
|
fun merge(): CirTreeMergeResult {
|
||||||
|
val result = processRoot()
|
||||||
|
System.gc()
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processRoot(): CirTreeMergeResult {
|
||||||
val rootNode: CirRootNode = buildRootNode(storageManager, size)
|
val rootNode: CirRootNode = buildRootNode(storageManager, size)
|
||||||
|
|
||||||
|
// remember any exported forward declarations from common fragments of dependee modules
|
||||||
|
parameters.dependeeModulesProvider?.loadModuleInfos()?.values?.forEach(::processCInteropModuleAttributes)
|
||||||
|
|
||||||
|
// load common dependencies
|
||||||
|
val dependeeModules = parameters.dependeeModulesProvider?.loadModules(emptyList())?.values.orEmpty()
|
||||||
|
|
||||||
val allModuleInfos: List<Map<String, ModuleInfo>> = parameters.targetProviders.map { it.modulesProvider.loadModuleInfos() }
|
val allModuleInfos: List<Map<String, ModuleInfo>> = parameters.targetProviders.map { it.modulesProvider.loadModuleInfos() }
|
||||||
val commonModuleNames = allModuleInfos.map { it.keys }.reduce { a, b -> a intersect b }
|
val commonModuleNames = allModuleInfos.map { it.keys }.reduce { a, b -> a intersect b }
|
||||||
|
|
||||||
parameters.targetProviders.forEachIndexed { targetIndex, targetProvider ->
|
parameters.targetProviders.forEachIndexed { targetIndex, targetProvider ->
|
||||||
val commonModuleInfos = allModuleInfos[targetIndex].filterKeys { it in commonModuleNames }
|
val commonModuleInfos = allModuleInfos[targetIndex].filterKeys { it in commonModuleNames }
|
||||||
processTarget(rootNode, targetIndex, targetProvider, commonModuleInfos)
|
processTarget(rootNode, targetIndex, targetProvider, commonModuleInfos, dependeeModules)
|
||||||
parameters.progressLogger?.invoke("Loaded declarations for [${targetProvider.target.name}]")
|
parameters.progressLogger?.invoke("Loaded declarations for [${targetProvider.target.name}]")
|
||||||
System.gc()
|
System.gc()
|
||||||
}
|
}
|
||||||
@@ -87,7 +99,8 @@ class CirTreeMerger(
|
|||||||
rootNode: CirRootNode,
|
rootNode: CirRootNode,
|
||||||
targetIndex: Int,
|
targetIndex: Int,
|
||||||
targetProvider: TargetProvider,
|
targetProvider: TargetProvider,
|
||||||
commonModuleInfos: Map<String, ModuleInfo>
|
commonModuleInfos: Map<String, ModuleInfo>,
|
||||||
|
dependeeModules: Collection<ModuleDescriptor>
|
||||||
) {
|
) {
|
||||||
rootNode.targetDeclarations[targetIndex] = CirRootFactory.create(
|
rootNode.targetDeclarations[targetIndex] = CirRootFactory.create(
|
||||||
targetProvider.target,
|
targetProvider.target,
|
||||||
@@ -95,7 +108,10 @@ class CirTreeMerger(
|
|||||||
targetProvider.builtInsProvider
|
targetProvider.builtInsProvider
|
||||||
)
|
)
|
||||||
|
|
||||||
val moduleDescriptors: Map<String, ModuleDescriptor> = targetProvider.modulesProvider.loadModules()
|
val targetDependeeModules = targetProvider.dependeeModulesProvider?.loadModules(dependeeModules)?.values.orEmpty()
|
||||||
|
val allDependeeModules = targetDependeeModules + dependeeModules
|
||||||
|
|
||||||
|
val moduleDescriptors: Map<String, ModuleDescriptor> = targetProvider.modulesProvider.loadModules(allDependeeModules)
|
||||||
val modules: MutableMap<Name, CirModuleNode> = rootNode.modules
|
val modules: MutableMap<Name, CirModuleNode> = rootNode.modules
|
||||||
|
|
||||||
moduleDescriptors.forEach { (name, moduleDescriptor) ->
|
moduleDescriptors.forEach { (name, moduleDescriptor) ->
|
||||||
@@ -110,16 +126,7 @@ class CirTreeMerger(
|
|||||||
moduleInfo: ModuleInfo,
|
moduleInfo: ModuleInfo,
|
||||||
moduleDescriptor: ModuleDescriptor
|
moduleDescriptor: ModuleDescriptor
|
||||||
) {
|
) {
|
||||||
moduleInfo.cInteropAttributes?.let { cInteropAttributes ->
|
processCInteropModuleAttributes(moduleInfo)
|
||||||
val exportForwardDeclarations = cInteropAttributes.exportForwardDeclarations.takeIf { it.isNotEmpty() } ?: return@let
|
|
||||||
val mainPackageFqName = FqName(cInteropAttributes.mainPackageFqName).intern()
|
|
||||||
|
|
||||||
exportForwardDeclarations.forEach { classFqName ->
|
|
||||||
// Class has synthetic package FQ name (cnames/objcnames). Need to transfer it to the main package.
|
|
||||||
val className = Name.identifier(classFqName.substringAfterLast('.')).intern()
|
|
||||||
cache.addExportedForwardDeclaration(internedClassId(mainPackageFqName, className))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val moduleName: Name = moduleDescriptor.name.intern()
|
val moduleName: Name = moduleDescriptor.name.intern()
|
||||||
val moduleNode: CirModuleNode = modules.getOrPut(moduleName) {
|
val moduleNode: CirModuleNode = modules.getOrPut(moduleName) {
|
||||||
@@ -258,4 +265,16 @@ class CirTreeMerger(
|
|||||||
}
|
}
|
||||||
typeAliasNode.targetDeclarations[targetIndex] = CirTypeAliasFactory.create(typeAliasDescriptor)
|
typeAliasNode.targetDeclarations[targetIndex] = CirTypeAliasFactory.create(typeAliasDescriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun processCInteropModuleAttributes(moduleInfo: ModuleInfo) {
|
||||||
|
val cInteropAttributes = moduleInfo.cInteropAttributes ?: return
|
||||||
|
val exportForwardDeclarations = cInteropAttributes.exportForwardDeclarations.takeIf { it.isNotEmpty() } ?: return
|
||||||
|
val mainPackageFqName = FqName(cInteropAttributes.mainPackageFqName).intern()
|
||||||
|
|
||||||
|
exportForwardDeclarations.forEach { classFqName ->
|
||||||
|
// Class has synthetic package FQ name (cnames/objcnames). Need to transfer it to the main package.
|
||||||
|
val className = Name.identifier(classFqName.substringAfterLast('.')).intern()
|
||||||
|
cache.addExportedForwardDeclaration(internedClassId(mainPackageFqName, className))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-4
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.descriptors.commonizer.mergedtree
|
package org.jetbrains.kotlin.descriptors.commonizer.mergedtree
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.metadata.impl.ClassifierAliasingPackageFragmentDescriptor
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.metadata.impl.ExportedForwardDeclarationsPackageFragmentDescriptor
|
import org.jetbrains.kotlin.backend.common.serialization.metadata.impl.ExportedForwardDeclarationsPackageFragmentDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.*
|
import org.jetbrains.kotlin.descriptors.commonizer.utils.*
|
||||||
@@ -69,12 +70,9 @@ internal fun ModuleDescriptor.collectNonEmptyPackageMemberScopes(collector: (FqN
|
|||||||
val packageFragmentProvider = this.packageFragmentProvider
|
val packageFragmentProvider = this.packageFragmentProvider
|
||||||
|
|
||||||
fun recurse(packageFqName: FqName) {
|
fun recurse(packageFqName: FqName) {
|
||||||
if (packageFqName.isUnderStandardKotlinPackages || packageFqName.isUnderKotlinNativeSyntheticPackages)
|
|
||||||
return
|
|
||||||
|
|
||||||
val ownPackageFragments = packageFragmentProvider.packageFragments(packageFqName)
|
val ownPackageFragments = packageFragmentProvider.packageFragments(packageFqName)
|
||||||
val ownPackageMemberScopes = ownPackageFragments.asSequence()
|
val ownPackageMemberScopes = ownPackageFragments.asSequence()
|
||||||
.filter { it !is ExportedForwardDeclarationsPackageFragmentDescriptor }
|
.filter { it !is ExportedForwardDeclarationsPackageFragmentDescriptor && it !is ClassifierAliasingPackageFragmentDescriptor }
|
||||||
.map { it.getMemberScope() }
|
.map { it.getMemberScope() }
|
||||||
.filter { it != MemberScope.Empty }
|
.filter { it != MemberScope.Empty }
|
||||||
.toList(ownPackageFragments.size)
|
.toList(ownPackageFragments.size)
|
||||||
|
|||||||
@@ -10,18 +10,17 @@ import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.serialization.konan.impl.ForwardDeclarationsFqNames
|
import org.jetbrains.kotlin.serialization.konan.impl.ForwardDeclarationsFqNames
|
||||||
|
|
||||||
internal val DEPRECATED_ANNOTATION_FQN: FqName = FqName(Deprecated::class.java.name).intern()
|
internal val DEPRECATED_ANNOTATION_FQN: FqName = FqName(Deprecated::class.java.name).intern()
|
||||||
internal val DEPRECATED_ANNOTATION_CID: ClassId = internedClassId(DEPRECATED_ANNOTATION_FQN)
|
internal val DEPRECATED_ANNOTATION_CID: ClassId = internedClassId(DEPRECATED_ANNOTATION_FQN)
|
||||||
|
|
||||||
internal val STANDARD_KOTLIN_PACKAGE_FQNS: List<FqName> = listOf(
|
private val STANDARD_KOTLIN_PACKAGES = listOf(
|
||||||
StandardNames.BUILT_INS_PACKAGE_FQ_NAME.intern(),
|
StandardNames.BUILT_INS_PACKAGE_FQ_NAME.asString(),
|
||||||
FqName("kotlinx").intern()
|
"kotlinx"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val STANDARD_KOTLIN_PACKAGES = STANDARD_KOTLIN_PACKAGE_FQNS.map { it.asString() }
|
|
||||||
|
|
||||||
private val KOTLIN_NATIVE_SYNTHETIC_PACKAGES = ForwardDeclarationsFqNames.syntheticPackages
|
private val KOTLIN_NATIVE_SYNTHETIC_PACKAGES = ForwardDeclarationsFqNames.syntheticPackages
|
||||||
.map { fqName ->
|
.map { fqName ->
|
||||||
check(!fqName.isRoot)
|
check(!fqName.isRoot)
|
||||||
@@ -37,6 +36,9 @@ private val OBJC_INTEROP_CALLABLE_ANNOTATIONS = listOf(
|
|||||||
"ObjCFactory"
|
"ObjCFactory"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
internal fun Name.strip(): String =
|
||||||
|
asString().removeSurrounding("<", ">")
|
||||||
|
|
||||||
internal val FqName.isUnderStandardKotlinPackages: Boolean
|
internal val FqName.isUnderStandardKotlinPackages: Boolean
|
||||||
get() = hasAnyPrefix(STANDARD_KOTLIN_PACKAGES)
|
get() = hasAnyPrefix(STANDARD_KOTLIN_PACKAGES)
|
||||||
|
|
||||||
|
|||||||
+21
-69
@@ -5,25 +5,20 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.descriptors.commonizer.utils
|
package org.jetbrains.kotlin.descriptors.commonizer.utils
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.metadata.impl.ExportedForwardDeclarationsPackageFragmentDescriptor
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
|
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters
|
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
import org.jetbrains.kotlin.descriptors.packageFragments
|
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.konan.util.KlibMetadataFactories
|
import org.jetbrains.kotlin.konan.util.KlibMetadataFactories
|
||||||
import org.jetbrains.kotlin.library.metadata.NativeTypeTransformer
|
import org.jetbrains.kotlin.library.metadata.NativeTypeTransformer
|
||||||
import org.jetbrains.kotlin.library.metadata.NullFlexibleTypeDeserializer
|
import org.jetbrains.kotlin.library.metadata.NullFlexibleTypeDeserializer
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
|
||||||
import org.jetbrains.kotlin.serialization.konan.impl.KlibResolvedModuleDescriptorsFactoryImpl
|
import org.jetbrains.kotlin.serialization.konan.impl.KlibResolvedModuleDescriptorsFactoryImpl
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
|
|
||||||
internal val ModuleDescriptor.packageFragmentProvider
|
internal val ModuleDescriptor.packageFragmentProvider: PackageFragmentProvider
|
||||||
get() = (this as ModuleDescriptorImpl).packageFragmentProviderForModuleContentWithoutDependencies
|
get() = (this as ModuleDescriptorImpl).packageFragmentProviderForModuleContentWithoutDependencies
|
||||||
|
|
||||||
internal fun createKotlinNativeForwardDeclarationsModule(
|
internal fun createKotlinNativeForwardDeclarationsModule(
|
||||||
@@ -42,73 +37,30 @@ internal fun ModuleDescriptor.resolveClassOrTypeAlias(classId: ClassId): Classif
|
|||||||
if (relativeClassName.isRoot)
|
if (relativeClassName.isRoot)
|
||||||
return null
|
return null
|
||||||
|
|
||||||
var memberScope: MemberScope = getPackage(classId.packageFqName).memberScope
|
return packageFragmentProvider.packageFragments(classId.packageFqName).asSequence().mapNotNull { packageFragment ->
|
||||||
|
var memberScope = packageFragment.getMemberScope()
|
||||||
|
|
||||||
val classifierName = if ('.' in relativeClassName.asString()) {
|
val classifierName = if ('.' in relativeClassName.asString()) {
|
||||||
// resolve member scope of the nested class
|
// resolve member scope of the nested class
|
||||||
relativeClassName.pathSegments().reduce { first, second ->
|
relativeClassName.pathSegments().reduce { first, second ->
|
||||||
memberScope = (memberScope.getContributedClassifier(
|
memberScope = (memberScope.getContributedClassifier(
|
||||||
first,
|
first,
|
||||||
NoLookupLocation.FOR_ALREADY_TRACKED
|
NoLookupLocation.FOR_ALREADY_TRACKED
|
||||||
) as? ClassDescriptor)?.unsubstitutedMemberScope ?: return null
|
) as? ClassDescriptor)?.unsubstitutedMemberScope ?: return@mapNotNull null
|
||||||
|
|
||||||
second
|
second
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
relativeClassName.shortName()
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
relativeClassName.shortName()
|
|
||||||
}
|
|
||||||
|
|
||||||
return memberScope.getContributedClassifier(
|
memberScope.getContributedClassifier(
|
||||||
classifierName,
|
classifierName,
|
||||||
NoLookupLocation.FOR_ALREADY_TRACKED
|
NoLookupLocation.FOR_ALREADY_TRACKED
|
||||||
) as? ClassifierDescriptorWithTypeParameters
|
) as? ClassifierDescriptorWithTypeParameters
|
||||||
|
}.firstOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun MutableMap<String, ModuleDescriptor?>.guessModuleByPackageFqName(packageFqName: FqName): ModuleDescriptor? {
|
internal const val MODULE_NAME_PREFIX = "module:"
|
||||||
if (isEmpty()) return null
|
|
||||||
|
|
||||||
val packageFqNameRaw = packageFqName.asString()
|
|
||||||
if (containsKey(packageFqNameRaw)) {
|
|
||||||
return this[packageFqNameRaw] // might return null if this is a previously cached result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun guessByEnding(): ModuleDescriptor? {
|
|
||||||
return entries
|
|
||||||
.firstOrNull { (name, _) -> name.endsWith(packageFqNameRaw, ignoreCase = true) }
|
|
||||||
?.value
|
|
||||||
}
|
|
||||||
|
|
||||||
fun guessBySmartEnding(): ModuleDescriptor? {
|
|
||||||
val packageFqNameFragments = packageFqNameRaw.split('.')
|
|
||||||
if (packageFqNameFragments.size < 2) return null
|
|
||||||
|
|
||||||
return entries.firstOrNull { (name, _) ->
|
|
||||||
var startIndex = 0
|
|
||||||
for (fragment in packageFqNameFragments) {
|
|
||||||
val index = name.indexOf(fragment, startIndex = startIndex, ignoreCase = true)
|
|
||||||
if (index < startIndex)
|
|
||||||
return@firstOrNull false
|
|
||||||
else
|
|
||||||
startIndex = index + fragment.length
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}?.value
|
|
||||||
}
|
|
||||||
|
|
||||||
val candidate = guessByEnding() ?: guessBySmartEnding()
|
|
||||||
this[packageFqNameRaw] = candidate // cache to speed-up the further look-ups
|
|
||||||
return candidate
|
|
||||||
}
|
|
||||||
|
|
||||||
internal val ModuleDescriptor.hasSomethingUnderStandardKotlinPackages: Boolean
|
|
||||||
get() {
|
|
||||||
val packageFragmentProvider = packageFragmentProvider
|
|
||||||
return STANDARD_KOTLIN_PACKAGE_FQNS.any { fqName ->
|
|
||||||
packageFragmentProvider.packageFragments(fqName).any { packageFragment ->
|
|
||||||
packageFragment !is ExportedForwardDeclarationsPackageFragmentDescriptor
|
|
||||||
&& packageFragment.getMemberScope() != MemberScope.Empty
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal val NativeFactories = KlibMetadataFactories(::KonanBuiltIns, NullFlexibleTypeDeserializer, NativeTypeTransformer())
|
internal val NativeFactories = KlibMetadataFactories(::KonanBuiltIns, NullFlexibleTypeDeserializer, NativeTypeTransformer())
|
||||||
|
|||||||
-12
@@ -1,12 +0,0 @@
|
|||||||
// this is to avoid missing Kotlin/Native stdlib
|
|
||||||
package kotlinx.cinterop
|
|
||||||
|
|
||||||
// fake classes with the default constructor and no member scope
|
|
||||||
abstract class CStructVar
|
|
||||||
class CPointer<T>
|
|
||||||
@Suppress("FINAL_UPPER_BOUND") class UByteVarOf<T : UByte>
|
|
||||||
class UByte
|
|
||||||
|
|
||||||
// fake typealiases
|
|
||||||
typealias CArrayPointer<T> = CPointer<T>
|
|
||||||
typealias UByteVar = UByteVarOf<UByte>
|
|
||||||
-12
@@ -1,12 +0,0 @@
|
|||||||
// this is to avoid missing Kotlin/Native stdlib
|
|
||||||
package kotlinx.cinterop
|
|
||||||
|
|
||||||
// fake classes with the default constructor and no member scope
|
|
||||||
abstract class CStructVar
|
|
||||||
class CPointer<T>
|
|
||||||
@Suppress("FINAL_UPPER_BOUND") class UByteVarOf<T : UByte>
|
|
||||||
class UByte
|
|
||||||
|
|
||||||
// fake typealiases
|
|
||||||
typealias CArrayPointer<T> = CPointer<T>
|
|
||||||
typealias UByteVar = UByteVarOf<UByte>
|
|
||||||
-12
@@ -1,12 +0,0 @@
|
|||||||
// this is to avoid missing Kotlin/Native stdlib
|
|
||||||
package kotlinx.cinterop
|
|
||||||
|
|
||||||
// fake classes with the default constructor and no member scope
|
|
||||||
abstract class CStructVar
|
|
||||||
class CPointer<T>
|
|
||||||
@Suppress("FINAL_UPPER_BOUND") class UByteVarOf<T : UByte>
|
|
||||||
class UByte
|
|
||||||
|
|
||||||
// fake typealiases
|
|
||||||
typealias CArrayPointer<T> = CPointer<T>
|
|
||||||
typealias UByteVar = UByteVarOf<UByte>
|
|
||||||
-12
@@ -1,12 +0,0 @@
|
|||||||
// this is to avoid missing Kotlin/Native stdlib
|
|
||||||
package kotlinx.cinterop
|
|
||||||
|
|
||||||
// fake classes with the default constructor and no member scope
|
|
||||||
abstract class CStructVar
|
|
||||||
class CPointer<T>
|
|
||||||
@Suppress("FINAL_UPPER_BOUND") class UByteVarOf<T : UByte>
|
|
||||||
class UByte
|
|
||||||
|
|
||||||
// fake typealiases
|
|
||||||
typealias CArrayPointer<T> = CPointer<T>
|
|
||||||
typealias UByteVar = UByteVarOf<UByte>
|
|
||||||
-6
@@ -1,6 +0,0 @@
|
|||||||
// this is to avoid missing Kotlin/Native stdlib
|
|
||||||
package kotlinx.cinterop
|
|
||||||
|
|
||||||
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
|
|
||||||
@Retention(AnnotationRetention.BINARY)
|
|
||||||
annotation class ObjCMethod() // fake annotation class without properties
|
|
||||||
-6
@@ -1,6 +0,0 @@
|
|||||||
// this is to avoid missing Kotlin/Native stdlib
|
|
||||||
package kotlinx.cinterop
|
|
||||||
|
|
||||||
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
|
|
||||||
@Retention(AnnotationRetention.BINARY)
|
|
||||||
annotation class ObjCMethod() // fake annotation class without properties
|
|
||||||
-6
@@ -1,6 +0,0 @@
|
|||||||
// this is to avoid missing Kotlin/Native stdlib
|
|
||||||
package kotlinx.cinterop
|
|
||||||
|
|
||||||
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
|
|
||||||
@Retention(AnnotationRetention.BINARY)
|
|
||||||
annotation class ObjCMethod() // fake annotation class without properties
|
|
||||||
+190
-168
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
|||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.SourceModuleRoot.Companion.COMMON_TARGET_NAME
|
import org.jetbrains.kotlin.descriptors.commonizer.SourceModuleRoot.Companion.SHARED_TARGET_NAME
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ClassCollector
|
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ClassCollector
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.FunctionCollector
|
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.FunctionCollector
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.collectMembers
|
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.collectMembers
|
||||||
@@ -30,10 +30,8 @@ import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
|||||||
import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
|
import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.platform.CommonPlatforms
|
import org.jetbrains.kotlin.platform.CommonPlatforms
|
||||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||||
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||||
import org.jetbrains.kotlin.test.KotlinTestUtils.*
|
import org.jetbrains.kotlin.test.KotlinTestUtils.*
|
||||||
import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase
|
import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase
|
||||||
@@ -70,10 +68,10 @@ abstract class AbstractCommonizationFromSourcesTest : KtUsefulTestCase() {
|
|||||||
val result: Result = runCommonization(analyzedModules.toCommonizationParameters())
|
val result: Result = runCommonization(analyzedModules.toCommonizationParameters())
|
||||||
assertCommonizationPerformed(result)
|
assertCommonizationPerformed(result)
|
||||||
|
|
||||||
val sharedTarget: OutputTarget = analyzedModules.commonizedCommonModule.target
|
val sharedTarget: OutputTarget = analyzedModules.sharedTarget
|
||||||
assertEquals(sharedTarget, result.sharedTarget)
|
assertEquals(sharedTarget, result.sharedTarget)
|
||||||
|
|
||||||
val sharedModuleAsExpected: ModuleDescriptor = analyzedModules.commonizedCommonModule.module
|
val sharedModuleAsExpected: ModuleDescriptor = analyzedModules.commonizedModules.getValue(sharedTarget)
|
||||||
val sharedModuleByCommonizer: ModuleDescriptor =
|
val sharedModuleByCommonizer: ModuleDescriptor =
|
||||||
(result.modulesByTargets.getValue(sharedTarget).single() as ModuleResult.Commonized).module
|
(result.modulesByTargets.getValue(sharedTarget).single() as ModuleResult.Commonized).module
|
||||||
|
|
||||||
@@ -81,11 +79,11 @@ abstract class AbstractCommonizationFromSourcesTest : KtUsefulTestCase() {
|
|||||||
assertValidModule(sharedModuleByCommonizer)
|
assertValidModule(sharedModuleByCommonizer)
|
||||||
assertModulesAreEqual(sharedModuleAsExpected, sharedModuleByCommonizer, "\"$sharedTarget\" target")
|
assertModulesAreEqual(sharedModuleAsExpected, sharedModuleByCommonizer, "\"$sharedTarget\" target")
|
||||||
|
|
||||||
val leafTargets: Set<InputTarget> = analyzedModules.commonizedPlatformModules.keys
|
val leafTargets: Set<InputTarget> = analyzedModules.leafTargets
|
||||||
assertEquals(leafTargets, result.leafTargets)
|
assertEquals(leafTargets, result.leafTargets)
|
||||||
|
|
||||||
for (leafTarget in leafTargets) {
|
for (leafTarget in leafTargets) {
|
||||||
val leafTargetModuleAsExpected: ModuleDescriptor = analyzedModules.commonizedPlatformModules.getValue(leafTarget).module
|
val leafTargetModuleAsExpected: ModuleDescriptor = analyzedModules.commonizedModules.getValue(leafTarget)
|
||||||
val leafTargetModuleByCommonizer: ModuleDescriptor =
|
val leafTargetModuleByCommonizer: ModuleDescriptor =
|
||||||
(result.modulesByTargets.getValue(leafTarget).single() as ModuleResult.Commonized).module
|
(result.modulesByTargets.getValue(leafTarget).single() as ModuleResult.Commonized).module
|
||||||
|
|
||||||
@@ -98,117 +96,196 @@ abstract class AbstractCommonizationFromSourcesTest : KtUsefulTestCase() {
|
|||||||
|
|
||||||
private data class SourceModuleRoot(
|
private data class SourceModuleRoot(
|
||||||
val targetName: String,
|
val targetName: String,
|
||||||
val root: File
|
val location: File
|
||||||
) {
|
) {
|
||||||
init {
|
init {
|
||||||
assertIsDirectory(root)
|
assertIsDirectory(location)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun load(directory: File): SourceModuleRoot = SourceModuleRoot(
|
fun load(directory: File): SourceModuleRoot = SourceModuleRoot(
|
||||||
targetName = directory.name,
|
targetName = directory.name,
|
||||||
root = directory
|
location = directory
|
||||||
)
|
)
|
||||||
|
|
||||||
const val COMMON_TARGET_NAME = "common"
|
const val SHARED_TARGET_NAME = "common"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SourceModuleRoots(
|
private class SourceModuleRoots(
|
||||||
val originalPlatformRoots: Map<String, SourceModuleRoot>,
|
val originalRoots: Map<InputTarget, SourceModuleRoot>,
|
||||||
val commonizedPlatformRoots: Map<String, SourceModuleRoot>,
|
val commonizedRoots: Map<Target, SourceModuleRoot>,
|
||||||
val commonizedCommonRoot: SourceModuleRoot
|
val dependeeRoots: Map<Target, SourceModuleRoot>
|
||||||
) {
|
) {
|
||||||
|
val leafTargets: Set<InputTarget> = originalRoots.keys
|
||||||
|
val sharedTarget: OutputTarget
|
||||||
|
|
||||||
init {
|
init {
|
||||||
check(originalPlatformRoots.isNotEmpty())
|
check(leafTargets.size >= 2)
|
||||||
check(COMMON_TARGET_NAME !in originalPlatformRoots)
|
check(leafTargets.none { it.name == SHARED_TARGET_NAME })
|
||||||
check(originalPlatformRoots.keys == commonizedPlatformRoots.keys)
|
|
||||||
check(commonizedCommonRoot.targetName == COMMON_TARGET_NAME)
|
val sharedTargets = commonizedRoots.keys.filterIsInstance<OutputTarget>()
|
||||||
|
check(sharedTargets.size == 1)
|
||||||
|
|
||||||
|
sharedTarget = sharedTargets.single()
|
||||||
|
check(sharedTarget.targets == leafTargets)
|
||||||
|
|
||||||
|
val allTargets = leafTargets + sharedTarget
|
||||||
|
check(commonizedRoots.keys == allTargets)
|
||||||
|
check(allTargets.containsAll(dependeeRoots.keys))
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun load(dataDir: File): SourceModuleRoots = try {
|
fun load(dataDir: File): SourceModuleRoots = try {
|
||||||
val originalRoots = listRoots(dataDir, ORIGINAL_ROOTS_DIR)
|
val originalRoots = listRoots(dataDir, ORIGINAL_ROOTS_DIR).mapKeys { InputTarget(it.key) }
|
||||||
val commonizedRoots = listRoots(dataDir, COMMONIZED_ROOTS_DIR)
|
|
||||||
|
|
||||||
SourceModuleRoots(
|
val leafTargets = originalRoots.keys
|
||||||
originalPlatformRoots = originalRoots,
|
val sharedTarget = OutputTarget(leafTargets)
|
||||||
commonizedPlatformRoots = commonizedRoots - COMMON_TARGET_NAME,
|
|
||||||
commonizedCommonRoot = commonizedRoots.getValue(COMMON_TARGET_NAME)
|
fun getTarget(targetName: String): Target =
|
||||||
)
|
if (targetName == SHARED_TARGET_NAME) sharedTarget else leafTargets.first { it.name == targetName }
|
||||||
|
|
||||||
|
val commonizedRoots = listRoots(dataDir, COMMONIZED_ROOTS_DIR).mapKeys { getTarget(it.key) }
|
||||||
|
val dependeeRoots = listRoots(dataDir, DEPENDEE_ROOTS_DIR).mapKeys { getTarget(it.key) }
|
||||||
|
|
||||||
|
SourceModuleRoots(originalRoots, commonizedRoots, dependeeRoots)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
fail("Source module misconfiguration in $dataDir", cause = e)
|
fail("Source module misconfiguration in $dataDir", cause = e)
|
||||||
}
|
}
|
||||||
|
|
||||||
private const val ORIGINAL_ROOTS_DIR = "original"
|
private const val ORIGINAL_ROOTS_DIR = "original"
|
||||||
private const val COMMONIZED_ROOTS_DIR = "commonized"
|
private const val COMMONIZED_ROOTS_DIR = "commonized"
|
||||||
|
private const val DEPENDEE_ROOTS_DIR = "dependee"
|
||||||
|
|
||||||
private fun listRoots(dataDir: File, rootsDirName: String): Map<String, SourceModuleRoot> =
|
private fun listRoots(dataDir: File, rootsDirName: String): Map<String, SourceModuleRoot> =
|
||||||
dataDir.resolve(rootsDirName).listFiles()?.toSet().orEmpty().map(SourceModuleRoot::load).associateBy { it.targetName }
|
dataDir.resolve(rootsDirName).listFiles()?.toSet().orEmpty().map(SourceModuleRoot::load).associateBy { it.targetName }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class AnalyzedModule<T : Target>(
|
private class AnalyzedModuleDependencies(
|
||||||
val target: T,
|
val regularDependencies: Map<Target, List<ModuleDescriptor>>,
|
||||||
val module: ModuleDescriptor
|
val expectByDependencies: List<ModuleDescriptor>
|
||||||
) {
|
) {
|
||||||
companion object {
|
fun withExpectByDependency(dependency: ModuleDescriptor) =
|
||||||
fun <T : Target> create(
|
AnalyzedModuleDependencies(
|
||||||
target: T,
|
regularDependencies = regularDependencies,
|
||||||
sourceModuleRoot: SourceModuleRoot,
|
expectByDependencies = expectByDependencies + dependency
|
||||||
commonSourceModuleRoot: SourceModuleRoot? = null,
|
)
|
||||||
parentDisposable: Disposable
|
|
||||||
): AnalyzedModule<T> {
|
|
||||||
val moduleName: String = sourceModuleRoot.root.parentFile.parentFile.name
|
|
||||||
check(Name.isValidIdentifier(moduleName))
|
|
||||||
|
|
||||||
return AnalyzedModule(
|
companion object {
|
||||||
target = target,
|
val EMPTY = AnalyzedModuleDependencies(emptyMap(), emptyList())
|
||||||
module = analyze(
|
|
||||||
moduleName = moduleName,
|
fun create(regularDependencies: Map<Target, ModuleDescriptor>, expectByDependencies: List<ModuleDescriptor>) =
|
||||||
moduleRoot = sourceModuleRoot.root,
|
AnalyzedModuleDependencies(regularDependencies.mapValues { listOf(it.value) }, expectByDependencies)
|
||||||
commonModuleRoot = commonSourceModuleRoot?.root,
|
}
|
||||||
parentDisposable = parentDisposable
|
}
|
||||||
|
|
||||||
|
private class AnalyzedModules(
|
||||||
|
val originalModules: Map<Target, ModuleDescriptor>,
|
||||||
|
val commonizedModules: Map<Target, ModuleDescriptor>,
|
||||||
|
val dependeeModules: Map<Target, ModuleDescriptor>
|
||||||
|
) {
|
||||||
|
val leafTargets: Set<InputTarget>
|
||||||
|
val sharedTarget: OutputTarget
|
||||||
|
|
||||||
|
init {
|
||||||
|
originalModules.keys.let { targets ->
|
||||||
|
check(targets.isNotEmpty())
|
||||||
|
|
||||||
|
leafTargets = targets.filterIsInstance<InputTarget>().toSet()
|
||||||
|
check(targets.size == leafTargets.size)
|
||||||
|
}
|
||||||
|
|
||||||
|
sharedTarget = OutputTarget(leafTargets)
|
||||||
|
val allTargets = leafTargets + sharedTarget
|
||||||
|
|
||||||
|
check(commonizedModules.keys == allTargets)
|
||||||
|
check(allTargets.containsAll(dependeeModules.keys))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun toCommonizationParameters(): Parameters {
|
||||||
|
val parameters = Parameters()
|
||||||
|
|
||||||
|
leafTargets.forEach { leafTarget ->
|
||||||
|
val originalModule = originalModules.getValue(leafTarget)
|
||||||
|
|
||||||
|
parameters.addTarget(
|
||||||
|
TargetProvider(
|
||||||
|
target = leafTarget,
|
||||||
|
builtInsClass = originalModule.builtIns::class.java,
|
||||||
|
builtInsProvider = MockBuiltInsProvider(originalModule.builtIns),
|
||||||
|
modulesProvider = MockModulesProvider(originalModule),
|
||||||
|
dependeeModulesProvider = dependeeModules[leafTarget]?.let(::MockModulesProvider)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun analyze(
|
parameters.dependeeModulesProvider = dependeeModules[sharedTarget]?.let(::MockModulesProvider)
|
||||||
moduleName: String,
|
|
||||||
moduleRoot: File,
|
|
||||||
commonModuleRoot: File?,
|
|
||||||
parentDisposable: Disposable
|
|
||||||
): ModuleDescriptor {
|
|
||||||
val commonModule: ModuleDescriptor? = if (commonModuleRoot != null) {
|
|
||||||
analyzeModule(
|
|
||||||
moduleName = "common" + moduleName.capitalize(),
|
|
||||||
moduleRoot = commonModuleRoot,
|
|
||||||
dependencyContainer = null, // common module does not have any specific dependencies
|
|
||||||
parentDisposable = parentDisposable
|
|
||||||
)
|
|
||||||
} else null
|
|
||||||
|
|
||||||
val module: ModuleDescriptor = analyzeModule(
|
return parameters
|
||||||
moduleName = moduleName,
|
}
|
||||||
moduleRoot = moduleRoot,
|
|
||||||
dependencyContainer = commonModule?.let(::CommonizedCommonDependenciesContainer), // platform module has dependencies to common module
|
companion object {
|
||||||
parentDisposable = parentDisposable
|
fun create(
|
||||||
|
sourceModuleRoots: SourceModuleRoots,
|
||||||
|
parentDisposable: Disposable
|
||||||
|
): AnalyzedModules = with(sourceModuleRoots) {
|
||||||
|
// first, build the modules that are are the dependencies for "original" and "commonized" modules
|
||||||
|
val dependeeModules =
|
||||||
|
createModules(sharedTarget, dependeeRoots, AnalyzedModuleDependencies.EMPTY, parentDisposable, isDependeeModule = true)
|
||||||
|
|
||||||
|
val dependencies = AnalyzedModuleDependencies.create(
|
||||||
|
regularDependencies = dependeeModules,
|
||||||
|
expectByDependencies = listOfNotNull(dependeeModules[sharedTarget])
|
||||||
)
|
)
|
||||||
|
|
||||||
if (commonModule != null) {
|
// then, build "original" and "commonized" modules
|
||||||
check(commonModule in module.expectedByModules)
|
val originalModules = createModules(sharedTarget, originalRoots, dependencies, parentDisposable)
|
||||||
check(commonModule in module.allDependencyModules)
|
val commonizedModules = createModules(sharedTarget, commonizedRoots, dependencies, parentDisposable)
|
||||||
|
|
||||||
|
return AnalyzedModules(originalModules, commonizedModules, dependeeModules)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createModules(
|
||||||
|
sharedTarget: OutputTarget,
|
||||||
|
moduleRoots: Map<out Target, SourceModuleRoot>,
|
||||||
|
dependencies: AnalyzedModuleDependencies,
|
||||||
|
parentDisposable: Disposable,
|
||||||
|
isDependeeModule: Boolean = false
|
||||||
|
): Map<Target, ModuleDescriptor> {
|
||||||
|
val result = mutableMapOf<Target, ModuleDescriptor>()
|
||||||
|
|
||||||
|
var dependenciesForOthers = dependencies
|
||||||
|
|
||||||
|
// first, process the common module
|
||||||
|
moduleRoots[sharedTarget]?.let { moduleRoot ->
|
||||||
|
val commonModule = createModule(sharedTarget, sharedTarget, moduleRoot, dependencies, parentDisposable, isDependeeModule)
|
||||||
|
result[sharedTarget] = commonModule
|
||||||
|
dependenciesForOthers = dependencies.withExpectByDependency(commonModule)
|
||||||
}
|
}
|
||||||
|
|
||||||
return module
|
// then, all platform modules
|
||||||
|
moduleRoots.filterKeys { it != sharedTarget }.forEach { (leafTarget, moduleRoot) ->
|
||||||
|
result[leafTarget] =
|
||||||
|
createModule(sharedTarget, leafTarget, moduleRoot, dependenciesForOthers, parentDisposable, isDependeeModule)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun analyzeModule(
|
private fun createModule(
|
||||||
moduleName: String,
|
sharedTarget: OutputTarget,
|
||||||
moduleRoot: File,
|
currentTarget: Target,
|
||||||
dependencyContainer: CommonDependenciesContainer?,
|
moduleRoot: SourceModuleRoot,
|
||||||
parentDisposable: Disposable
|
dependencies: AnalyzedModuleDependencies,
|
||||||
|
parentDisposable: Disposable,
|
||||||
|
isDependeeModule: Boolean
|
||||||
): ModuleDescriptor {
|
): ModuleDescriptor {
|
||||||
|
val moduleName: String = moduleRoot.location.parentFile.parentFile.name.let {
|
||||||
|
if (isDependeeModule) "dependee-$it" else it
|
||||||
|
}
|
||||||
|
check(Name.isValidIdentifier(moduleName))
|
||||||
|
|
||||||
val configuration: CompilerConfiguration = newConfiguration()
|
val configuration: CompilerConfiguration = newConfiguration()
|
||||||
configuration.put(CommonConfigurationKeys.MODULE_NAME, moduleName)
|
configuration.put(CommonConfigurationKeys.MODULE_NAME, moduleName)
|
||||||
|
|
||||||
@@ -220,7 +297,7 @@ private class AnalyzedModule<T : Target>(
|
|||||||
|
|
||||||
val psiFactory = KtPsiFactory(environment.project)
|
val psiFactory = KtPsiFactory(environment.project)
|
||||||
|
|
||||||
val psiFiles: List<KtFile> = moduleRoot.walkTopDown()
|
val psiFiles: List<KtFile> = moduleRoot.location.walkTopDown()
|
||||||
.filter { it.isFile }
|
.filter { it.isFile }
|
||||||
.map { psiFactory.createFile(it.name, doLoadFile(it)) }
|
.map { psiFactory.createFile(it.name, doLoadFile(it)) }
|
||||||
.toList()
|
.toList()
|
||||||
@@ -231,105 +308,68 @@ private class AnalyzedModule<T : Target>(
|
|||||||
dependOnBuiltIns = true,
|
dependOnBuiltIns = true,
|
||||||
languageVersionSettings = environment.configuration.languageVersionSettings,
|
languageVersionSettings = environment.configuration.languageVersionSettings,
|
||||||
targetPlatform = CommonPlatforms.defaultCommonPlatform,
|
targetPlatform = CommonPlatforms.defaultCommonPlatform,
|
||||||
dependenciesContainer = dependencyContainer
|
dependenciesContainer = DependenciesContainerImpl(sharedTarget, currentTarget, dependencies)
|
||||||
) { content ->
|
) { content ->
|
||||||
environment.createPackagePartProvider(content.moduleContentScope)
|
environment.createPackagePartProvider(content.moduleContentScope)
|
||||||
}.moduleDescriptor
|
}.moduleDescriptor
|
||||||
|
|
||||||
module.accept(PatchingTestDescriptorVisitor, Unit)
|
if (!isDependeeModule)
|
||||||
|
module.accept(PatchingTestDescriptorVisitor, Unit)
|
||||||
|
|
||||||
return module
|
return module
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class AnalyzedModules(
|
private class DependenciesContainerImpl(
|
||||||
val originalPlatformModules: Map<InputTarget, AnalyzedModule<InputTarget>>,
|
sharedTarget: OutputTarget,
|
||||||
val commonizedPlatformModules: Map<InputTarget, AnalyzedModule<InputTarget>>,
|
currentTarget: Target,
|
||||||
val commonizedCommonModule: AnalyzedModule<OutputTarget>
|
dependencies: AnalyzedModuleDependencies
|
||||||
) {
|
) : CommonDependenciesContainer {
|
||||||
|
private val moduleInfoToModule = mutableMapOf<ModuleInfo, ModuleDescriptor>()
|
||||||
|
private val expectByModuleInfos = mutableListOf<ModuleInfo>()
|
||||||
|
private val regularModuleInfos = mutableListOf<ModuleInfo>()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
check(originalPlatformModules.isNotEmpty())
|
if (currentTarget != sharedTarget) {
|
||||||
check(originalPlatformModules.keys == commonizedPlatformModules.keys)
|
dependencies.expectByDependencies.forEach { expectByDependency ->
|
||||||
}
|
val moduleInfo = ModuleInfoImpl(expectByDependency, emptyList())
|
||||||
|
moduleInfoToModule[moduleInfo] = expectByDependency
|
||||||
fun toCommonizationParameters(): Parameters {
|
expectByModuleInfos += moduleInfo
|
||||||
val parameters = originalPlatformModules.mapValues { it.value.module }.toCommonizationParameters()
|
}
|
||||||
parameters.commonModulesProvider = MockModulesProvider(commonizedCommonModule.module)
|
|
||||||
return parameters
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun create(
|
|
||||||
sourceModuleRoots: SourceModuleRoots,
|
|
||||||
parentDisposable: Disposable
|
|
||||||
): AnalyzedModules {
|
|
||||||
val originalPlatformModules: Map<InputTarget, AnalyzedModule<InputTarget>> = createInputTargetModules(
|
|
||||||
sourceModuleRoots = sourceModuleRoots.originalPlatformRoots,
|
|
||||||
parentDisposable = parentDisposable
|
|
||||||
)
|
|
||||||
|
|
||||||
val commonizedCommonModule: AnalyzedModule<OutputTarget> = AnalyzedModule.create(
|
|
||||||
target = OutputTarget(originalPlatformModules.keys),
|
|
||||||
sourceModuleRoot = sourceModuleRoots.commonizedCommonRoot,
|
|
||||||
parentDisposable = parentDisposable
|
|
||||||
)
|
|
||||||
|
|
||||||
val commonizedPlatformModules: Map<InputTarget, AnalyzedModule<InputTarget>> = createInputTargetModules(
|
|
||||||
sourceModuleRoots = sourceModuleRoots.commonizedPlatformRoots,
|
|
||||||
commonSourceModuleRoot = sourceModuleRoots.commonizedCommonRoot,
|
|
||||||
parentDisposable = parentDisposable
|
|
||||||
)
|
|
||||||
|
|
||||||
return AnalyzedModules(
|
|
||||||
originalPlatformModules = originalPlatformModules,
|
|
||||||
commonizedPlatformModules = commonizedPlatformModules,
|
|
||||||
commonizedCommonModule = commonizedCommonModule
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createInputTargetModules(
|
dependencies.regularDependencies[currentTarget]?.forEach { regularDependency ->
|
||||||
sourceModuleRoots: Map<String, SourceModuleRoot>,
|
val moduleInfo = ModuleInfoImpl(regularDependency, expectByModuleInfos)
|
||||||
commonSourceModuleRoot: SourceModuleRoot? = null,
|
moduleInfoToModule[moduleInfo] = regularDependency
|
||||||
parentDisposable: Disposable
|
regularModuleInfos += moduleInfo
|
||||||
): Map<InputTarget, AnalyzedModule<InputTarget>> = sourceModuleRoots.map { (targetName, sourceModuleRoot) ->
|
}
|
||||||
AnalyzedModule.create(
|
|
||||||
target = InputTarget(targetName),
|
|
||||||
sourceModuleRoot = sourceModuleRoot,
|
|
||||||
commonSourceModuleRoot = commonSourceModuleRoot,
|
|
||||||
parentDisposable = parentDisposable
|
|
||||||
)
|
|
||||||
}.associateBy { it.target }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class CommonizedCommonDependenciesContainer(
|
regularModuleInfos += expectByModuleInfos
|
||||||
private val commonModule: ModuleDescriptor
|
|
||||||
) : CommonDependenciesContainer {
|
|
||||||
private val commonModuleInfo = object : ModuleInfo {
|
|
||||||
override val name: Name get() = commonModule.name
|
|
||||||
|
|
||||||
override fun dependencies(): List<ModuleInfo> = listOf(this)
|
|
||||||
override fun dependencyOnBuiltIns(): ModuleInfo.DependencyOnBuiltIns = ModuleInfo.DependencyOnBuiltIns.LAST
|
|
||||||
|
|
||||||
override val platform: TargetPlatform get() = CommonPlatforms.defaultCommonPlatform
|
|
||||||
override val analyzerServices: PlatformDependentAnalyzerServices get() = CommonPlatformAnalyzerServices
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override val moduleInfos: List<ModuleInfo> get() = listOf(commonModuleInfo)
|
private inner class ModuleInfoImpl(
|
||||||
|
private val module: ModuleDescriptor,
|
||||||
|
private val regularDependencies: List<ModuleInfo>
|
||||||
|
) : ModuleInfo {
|
||||||
|
override val name get() = module.name
|
||||||
|
|
||||||
override fun moduleDescriptorForModuleInfo(moduleInfo: ModuleInfo): ModuleDescriptor {
|
override fun dependencies() = listOf(this) + regularDependencies
|
||||||
if (moduleInfo !== commonModuleInfo)
|
override fun dependencyOnBuiltIns() = ModuleInfo.DependencyOnBuiltIns.LAST
|
||||||
error("Unknown module info $moduleInfo")
|
|
||||||
|
|
||||||
return commonModule
|
override val platform get() = CommonPlatforms.defaultCommonPlatform
|
||||||
|
override val analyzerServices get() = CommonPlatformAnalyzerServices
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val moduleInfos: List<ModuleInfo> get() = regularModuleInfos
|
||||||
|
override val friendModuleInfos: List<ModuleInfo> get() = emptyList()
|
||||||
|
override val refinesModuleInfos: List<ModuleInfo> get() = expectByModuleInfos
|
||||||
|
|
||||||
|
override fun moduleDescriptorForModuleInfo(moduleInfo: ModuleInfo) =
|
||||||
|
moduleInfoToModule[moduleInfo] ?: error("Unknown module info $moduleInfo")
|
||||||
|
|
||||||
override fun registerDependencyForAllModules(moduleInfo: ModuleInfo, descriptorForModule: ModuleDescriptorImpl) = Unit
|
override fun registerDependencyForAllModules(moduleInfo: ModuleInfo, descriptorForModule: ModuleDescriptorImpl) = Unit
|
||||||
override fun packageFragmentProviderForModuleInfo(moduleInfo: ModuleInfo): PackageFragmentProvider? = null
|
override fun packageFragmentProviderForModuleInfo(moduleInfo: ModuleInfo): PackageFragmentProvider? = null
|
||||||
|
|
||||||
override val friendModuleInfos: List<ModuleInfo> get() = emptyList()
|
|
||||||
override val refinesModuleInfos: List<ModuleInfo> get() = listOf(commonModuleInfo)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private object PatchingTestDescriptorVisitor : DeclarationDescriptorVisitorEmptyBodies<Unit, Unit>() {
|
private object PatchingTestDescriptorVisitor : DeclarationDescriptorVisitorEmptyBodies<Unit, Unit>() {
|
||||||
@@ -368,21 +408,3 @@ private object PatchingTestDescriptorVisitor : DeclarationDescriptorVisitorEmpty
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Map<InputTarget, ModuleDescriptor>.toCommonizationParameters(): Parameters = Parameters().also { parameters ->
|
|
||||||
forEach { (target, moduleDescriptor) ->
|
|
||||||
if (!parameters.extendedLookupForBuiltInsClassifiers) {
|
|
||||||
if (moduleDescriptor.hasSomethingUnderStandardKotlinPackages)
|
|
||||||
parameters.extendedLookupForBuiltInsClassifiers = true
|
|
||||||
}
|
|
||||||
|
|
||||||
parameters.addTarget(
|
|
||||||
TargetProvider(
|
|
||||||
target = target,
|
|
||||||
builtInsClass = moduleDescriptor.builtIns::class.java,
|
|
||||||
builtInsProvider = MockBuiltInsProvider(moduleDescriptor.builtIns),
|
|
||||||
modulesProvider = MockModulesProvider(moduleDescriptor)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
+2
-1
@@ -67,7 +67,8 @@ class CommonizerFacadeTest {
|
|||||||
target = InputTarget(targetName),
|
target = InputTarget(targetName),
|
||||||
builtInsClass = DefaultBuiltIns::class.java,
|
builtInsClass = DefaultBuiltIns::class.java,
|
||||||
builtInsProvider = BuiltInsProvider.defaultBuiltInsProvider,
|
builtInsProvider = BuiltInsProvider.defaultBuiltInsProvider,
|
||||||
modulesProvider = MockModulesProvider(moduleNames)
|
modulesProvider = MockModulesProvider(moduleNames),
|
||||||
|
dependeeModulesProvider = null
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,8 +46,7 @@ internal fun mockClassType(
|
|||||||
storageManager = LockBasedStorageManager.NO_LOCKS,
|
storageManager = LockBasedStorageManager.NO_LOCKS,
|
||||||
target = InputTarget("Arbitrary target"),
|
target = InputTarget("Arbitrary target"),
|
||||||
builtIns = DefaultBuiltIns.Instance,
|
builtIns = DefaultBuiltIns.Instance,
|
||||||
lazyModulesLookupTable = LockBasedStorageManager.NO_LOCKS.createLazyValue { mutableMapOf() },
|
lazyClassifierLookupTable = LockBasedStorageManager.NO_LOCKS.createLazyValue { LazyClassifierLookupTable(emptyMap()) },
|
||||||
isCommon = false,
|
|
||||||
index = 0,
|
index = 0,
|
||||||
cache = DeclarationsBuilderCache(1)
|
cache = DeclarationsBuilderCache(1)
|
||||||
)
|
)
|
||||||
@@ -173,7 +172,7 @@ internal class MockModulesProvider : ModulesProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun loadModuleInfos() = moduleInfos
|
override fun loadModuleInfos() = moduleInfos
|
||||||
override fun loadModules() = modules
|
override fun loadModules(dependencies: Collection<ModuleDescriptor>): Map<String, ModuleDescriptor> = modules
|
||||||
|
|
||||||
private fun fakeModuleInfo(name: String) = ModuleInfo(name, File("/tmp/commonizer/mocks/$name"), null)
|
private fun fakeModuleInfo(name: String) = ModuleInfo(name, File("/tmp/commonizer/mocks/$name"), null)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user