[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()
|
||||
|
||||
// only for test purposes
|
||||
internal var extendedLookupForBuiltInsClassifiers: Boolean = false
|
||||
// common module dependencies (ex: Kotlin stdlib)
|
||||
var dependeeModulesProvider: ModulesProvider? = null
|
||||
set(value) {
|
||||
check(!field || value)
|
||||
check(field == null)
|
||||
field = value
|
||||
}
|
||||
|
||||
// only for test purposes
|
||||
internal var commonModulesProvider: ModulesProvider? = null
|
||||
|
||||
fun addTarget(targetProvider: TargetProvider): Parameters {
|
||||
require(targetProvider.target !in _targetProviders) { "Target ${targetProvider.target} is already added" }
|
||||
_targetProviders[targetProvider.target] = targetProvider
|
||||
|
||||
@@ -14,7 +14,8 @@ class TargetProvider(
|
||||
val target: InputTarget,
|
||||
val builtInsClass: Class<out KotlinBuiltIns>,
|
||||
val builtInsProvider: BuiltInsProvider,
|
||||
val modulesProvider: ModulesProvider
|
||||
val modulesProvider: ModulesProvider,
|
||||
val dependeeModulesProvider: ModulesProvider?
|
||||
)
|
||||
|
||||
interface BuiltInsProvider {
|
||||
@@ -40,5 +41,5 @@ interface ModulesProvider {
|
||||
)
|
||||
|
||||
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 org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.Parameters
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.Target
|
||||
@@ -133,68 +134,84 @@ class TargetDeclarationsBuilderComponents(
|
||||
val storageManager: StorageManager,
|
||||
val target: Target,
|
||||
val builtIns: KotlinBuiltIns,
|
||||
val lazyModulesLookupTable: NotNullLazyValue<MutableMap<String, ModuleDescriptor?>>,
|
||||
val isCommon: Boolean,
|
||||
val lazyClassifierLookupTable: NotNullLazyValue<LazyClassifierLookupTable>,
|
||||
val index: Int,
|
||||
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
|
||||
fun findClassOrTypeAlias(classId: ClassId): ClassifierDescriptorWithTypeParameters {
|
||||
return when {
|
||||
classId.packageFqName.isUnderStandardKotlinPackages -> {
|
||||
// look up for classifier in built-ins module:
|
||||
val builtInsModule = builtIns.builtInsModule
|
||||
|
||||
// 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
|
||||
val classifier = builtInsModule.resolveClassOrTypeAlias(classId)
|
||||
if (classifier != null)
|
||||
return classifier
|
||||
|
||||
if (extendedLookupForBuiltInsClassifiers) {
|
||||
return findOriginalClassOrTypeAlias(classId)
|
||||
?: error("Classifier ${classId.asString()} not found neither in built-ins module $builtInsModule nor in original modules 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")
|
||||
}
|
||||
fun findClassOrTypeAlias(classifierId: ClassId): ClassifierDescriptorWithTypeParameters {
|
||||
return if (classifierId.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(classifierId)
|
||||
?: error("Classifier ${classifierId.asString()} not found for $target")
|
||||
} else {
|
||||
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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun findOriginalClassOrTypeAlias(classId: ClassId): ClassifierDescriptorWithTypeParameters? {
|
||||
if (classId.packageFqName.isRoot)
|
||||
return null
|
||||
class LazyClassifierLookupTable(lazyModules: Map<String, List<ModuleDescriptor>>) {
|
||||
private val table = THashMap<String, List<ModuleDescriptor>>()
|
||||
private val allModules: Collection<ModuleDescriptor>
|
||||
|
||||
// first, guess containing module and look up in it
|
||||
val classifier = lazyModulesLookupTable()
|
||||
.guessModuleByPackageFqName(classId.packageFqName)
|
||||
?.resolveClassOrTypeAlias(classId)
|
||||
init {
|
||||
// add "module:" prefix for each key representing a module name, not a package name
|
||||
lazyModules.forEach { (moduleName, modules) -> table[MODULE_NAME_PREFIX + moduleName.toLowerCase()] = modules }
|
||||
allModules = lazyModules.values.flatten()
|
||||
}
|
||||
|
||||
// if failed, then look up though all modules
|
||||
return classifier
|
||||
?: lazyModulesLookupTable().values
|
||||
.asSequence()
|
||||
.mapNotNull { it?.resolveClassOrTypeAlias(classId) }
|
||||
.firstOrNull()
|
||||
fun resolveClassOrTypeAlias(classifierId: ClassId): ClassifierDescriptorWithTypeParameters? {
|
||||
if (table.isEmpty) return null
|
||||
|
||||
val packageFqName = classifierId.packageFqName
|
||||
if (packageFqName.isRoot) return null
|
||||
|
||||
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 {
|
||||
val cache = DeclarationsBuilderCache(dimension)
|
||||
|
||||
val lazyCommonDependeeModules = storageManager.createLazyValue {
|
||||
parameters.dependeeModulesProvider?.loadModules(emptyList()).orEmpty()
|
||||
}
|
||||
|
||||
val targetContexts = (0 until dimension).map { index ->
|
||||
val isCommon = index == indexOfCommon
|
||||
|
||||
@@ -216,24 +237,38 @@ fun CirRootNode.createGlobalBuilderComponents(
|
||||
}
|
||||
|
||||
val lazyModulesLookupTable = storageManager.createLazyValue {
|
||||
val source = if (isCommon)
|
||||
parameters.commonModulesProvider?.loadModules() ?: emptyMap()
|
||||
else
|
||||
parameters.targetProviders[index].modulesProvider.loadModules()
|
||||
THashMap(source)
|
||||
val result = mutableMapOf<String, MutableList<ModuleDescriptor>>()
|
||||
|
||||
val commonDependeeModules: Map<String, ModuleDescriptor> = lazyCommonDependeeModules()
|
||||
|
||||
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(
|
||||
storageManager = storageManager,
|
||||
target = root.target,
|
||||
builtIns = builtIns,
|
||||
lazyModulesLookupTable = lazyModulesLookupTable,
|
||||
isCommon = isCommon,
|
||||
lazyClassifierLookupTable = lazyModulesLookupTable,
|
||||
index = index,
|
||||
cache = cache
|
||||
).also {
|
||||
it.extendedLookupForBuiltInsClassifiers = parameters.extendedLookupForBuiltInsClassifiers
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
return GlobalDeclarationsBuilderComponents(storageManager, targetContexts, cache, parameters.statsCollector)
|
||||
|
||||
+29
-29
@@ -55,13 +55,13 @@ class NativeDistributionCommonizer(
|
||||
clockMark.reset()
|
||||
|
||||
// 1. load libraries
|
||||
val librariesByTargets = loadLibraries()
|
||||
val allLibraries = loadLibraries()
|
||||
|
||||
// 2. run commonization
|
||||
val result = commonize(librariesByTargets)
|
||||
val result = commonize(allLibraries)
|
||||
|
||||
// 3. write new libraries
|
||||
saveModules(librariesByTargets, result)
|
||||
saveModules(allLibraries, result)
|
||||
|
||||
logTotal()
|
||||
}
|
||||
@@ -86,29 +86,29 @@ class NativeDistributionCommonizer(
|
||||
|
||||
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 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 platformLibs = leafTarget.platformLibrariesSource
|
||||
.takeIf { it.isDirectory }
|
||||
?.listFiles()
|
||||
?.takeIf { it.isNotEmpty() }
|
||||
?.map { loadLibrary(it) }
|
||||
?.map { NativeLibrary(loadLibrary(it)) }
|
||||
.orEmpty()
|
||||
|
||||
if (platformLibs.isEmpty())
|
||||
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")
|
||||
|
||||
return result
|
||||
return AllNativeLibraries(stdlib, librariesByTargets)
|
||||
}
|
||||
|
||||
private fun loadLibrary(location: File): KotlinLibrary {
|
||||
@@ -136,7 +136,7 @@ class NativeDistributionCommonizer(
|
||||
return library
|
||||
}
|
||||
|
||||
private fun commonize(librariesByTargets: Map<InputTarget, NativeDistributionLibraries>): Result {
|
||||
private fun commonize(allLibraries: AllNativeLibraries): Result {
|
||||
val statsCollector = when (statsType) {
|
||||
RAW -> RawStatsCollector(targets, FileStatsOutput(destination, "raw"))
|
||||
AGGREGATED -> AggregatedStatsCollector(targets, FileStatsOutput(destination, "aggregated"))
|
||||
@@ -144,20 +144,23 @@ class NativeDistributionCommonizer(
|
||||
}
|
||||
statsCollector.use {
|
||||
val parameters = Parameters(statsCollector, ::logProgress).apply {
|
||||
librariesByTargets.forEach { (target, libraries) ->
|
||||
if (libraries.platformLibs.isEmpty()) return@forEach
|
||||
val storageManager = LockBasedStorageManager("Commonized modules")
|
||||
|
||||
val provider = NativeDistributionModulesProvider(
|
||||
storageManager = LockBasedStorageManager("Target $target"),
|
||||
libraries = libraries
|
||||
)
|
||||
val stdlibProvider = NativeDistributionStdlibProvider(storageManager, allLibraries.stdlib)
|
||||
dependeeModulesProvider = stdlibProvider
|
||||
|
||||
allLibraries.librariesByTargets.forEach { (target, librariesToCommonize) ->
|
||||
if (librariesToCommonize.libraries.isEmpty()) return@forEach
|
||||
|
||||
val modulesProvider = NativeDistributionModulesProvider(storageManager, librariesToCommonize)
|
||||
|
||||
addTarget(
|
||||
TargetProvider(
|
||||
target = target,
|
||||
builtInsClass = KonanBuiltIns::class.java,
|
||||
builtInsProvider = provider,
|
||||
modulesProvider = provider
|
||||
builtInsProvider = stdlibProvider,
|
||||
modulesProvider = modulesProvider,
|
||||
dependeeModulesProvider = null // stdlib is already set as common dependency
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -167,10 +170,7 @@ class NativeDistributionCommonizer(
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveModules(
|
||||
originalLibrariesByTargets: Map<InputTarget, NativeDistributionLibraries>,
|
||||
result: Result
|
||||
) {
|
||||
private fun saveModules(originalLibraries: AllNativeLibraries, result: Result) {
|
||||
// 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
|
||||
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.
|
||||
// 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.
|
||||
originalLibrariesByTargets.forEach { (target, libraries) ->
|
||||
copyTargetAsIs(target, libraries.platformLibs.size)
|
||||
originalLibraries.librariesByTargets.forEach { (target, librariesToCommonize) ->
|
||||
copyTargetAsIs(target, librariesToCommonize.libraries.size)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,11 +194,11 @@ class NativeDistributionCommonizer(
|
||||
)
|
||||
|
||||
// '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()) {
|
||||
targetsToCopy.forEach { target ->
|
||||
val libraries = originalLibrariesByTargets.getValue(target)
|
||||
copyTargetAsIs(target, libraries.platformLibs.size)
|
||||
val librariesToCommonize = originalLibraries.librariesByTargets.getValue(target)
|
||||
copyTargetAsIs(target, librariesToCommonize.libraries.size)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,11 +214,11 @@ class NativeDistributionCommonizer(
|
||||
val starredTarget: String?
|
||||
when (target) {
|
||||
is InputTarget -> {
|
||||
manifestProvider = originalLibrariesByTargets.getValue(target)
|
||||
manifestProvider = originalLibraries.librariesByTargets.getValue(target)
|
||||
starredTarget = target.name
|
||||
}
|
||||
is OutputTarget -> {
|
||||
manifestProvider = CommonNativeManifestDataProvider(originalLibrariesByTargets.values)
|
||||
manifestProvider = CommonNativeManifestDataProvider(originalLibraries.librariesByTargets.values)
|
||||
starredTarget = null
|
||||
}
|
||||
}
|
||||
|
||||
+27
-26
@@ -5,38 +5,26 @@
|
||||
|
||||
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.CInteropModuleAttributes
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.ModulesProvider.ModuleInfo
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.NativeFactories
|
||||
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.konan.library.KONAN_STDLIB_NAME
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import java.io.File
|
||||
|
||||
internal class NativeDistributionModulesProvider(
|
||||
private val storageManager: StorageManager,
|
||||
private val libraries: NativeDistributionLibraries
|
||||
) : BuiltInsProvider, 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
|
||||
}
|
||||
|
||||
private val librariesToCommonize: NativeLibrariesToCommonize
|
||||
) : ModulesProvider {
|
||||
override fun loadModuleInfos(): Map<String, ModuleInfo> {
|
||||
return libraries.platformLibs.associate { library ->
|
||||
return librariesToCommonize.libraries.associate { library ->
|
||||
val manifestData = library.manifestData
|
||||
|
||||
val name = manifestData.uniqueName
|
||||
@@ -54,11 +42,18 @@ internal class NativeDistributionModulesProvider(
|
||||
}
|
||||
}
|
||||
|
||||
override fun loadModules(): Map<String, ModuleDescriptor> {
|
||||
val builtIns = loadBuiltIns()
|
||||
val stdlib = builtIns.builtInsModule
|
||||
override fun loadModules(dependencies: Collection<ModuleDescriptor>): Map<String, ModuleDescriptor> {
|
||||
check(dependencies.isNotEmpty()) { "At least Kotlin/Native stdlib should be provided" }
|
||||
|
||||
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 module = NativeFactories.DefaultDeserializedDescriptorFactory.createDescriptorOptionalBuiltIns(
|
||||
library = library.library,
|
||||
@@ -78,11 +73,17 @@ internal class NativeDistributionModulesProvider(
|
||||
)
|
||||
|
||||
platformModulesMap.forEach { (name, module) ->
|
||||
val dependencies = libraries.getManifest(name)
|
||||
.dependencies
|
||||
.map { if (it == KONAN_STDLIB_NAME) stdlib else platformModulesMap.getValue(it) }
|
||||
val moduleDependencies = mutableListOf<ModuleDescriptorImpl>()
|
||||
moduleDependencies += module
|
||||
|
||||
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
|
||||
|
||||
+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
|
||||
|
||||
import gnu.trove.THashMap
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.InputTarget
|
||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||
|
||||
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 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(
|
||||
val stdlib: NativeDistributionLibrary,
|
||||
val platformLibs: List<NativeDistributionLibrary>
|
||||
) : NativeManifestDataProvider {
|
||||
constructor(stdlib: KotlinLibrary, platformLibs: List<KotlinLibrary>) : this(
|
||||
NativeDistributionLibrary(stdlib),
|
||||
platformLibs.map(::NativeDistributionLibrary)
|
||||
)
|
||||
|
||||
internal class NativeLibrariesToCommonize(val libraries: List<NativeLibrary>) : NativeManifestDataProvider {
|
||||
private val manifestIndex: Map<String, NativeSensitiveManifestData> = buildManifestIndex()
|
||||
|
||||
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(
|
||||
libraryGroups: Collection<NativeDistributionLibraries>
|
||||
libraryGroups: Collection<NativeLibrariesToCommonize>
|
||||
) : NativeManifestDataProvider {
|
||||
private val manifestIndex: Map<String, NativeSensitiveManifestData>
|
||||
|
||||
@@ -66,5 +68,5 @@ internal class CommonNativeManifestDataProvider(
|
||||
override fun getManifest(libraryName: String) = manifestIndex.getValue(libraryName)
|
||||
}
|
||||
|
||||
private fun NativeDistributionLibraries.buildManifestIndex(): MutableMap<String, NativeSensitiveManifestData> =
|
||||
(platformLibs + stdlib).map { it.manifestData }.associateByTo(THashMap()) { it.uniqueName }
|
||||
private fun NativeLibrariesToCommonize.buildManifestIndex(): MutableMap<String, NativeSensitiveManifestData> =
|
||||
libraries.map { it.manifestData }.associateByTo(THashMap()) { it.uniqueName }
|
||||
+32
-13
@@ -59,14 +59,26 @@ class CirTreeMerger(
|
||||
private val size = parameters.targetProviders.size
|
||||
|
||||
fun merge(): CirTreeMergeResult {
|
||||
val result = processRoot()
|
||||
System.gc()
|
||||
return result
|
||||
}
|
||||
|
||||
private fun processRoot(): CirTreeMergeResult {
|
||||
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 commonModuleNames = allModuleInfos.map { it.keys }.reduce { a, b -> a intersect b }
|
||||
|
||||
parameters.targetProviders.forEachIndexed { targetIndex, targetProvider ->
|
||||
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}]")
|
||||
System.gc()
|
||||
}
|
||||
@@ -87,7 +99,8 @@ class CirTreeMerger(
|
||||
rootNode: CirRootNode,
|
||||
targetIndex: Int,
|
||||
targetProvider: TargetProvider,
|
||||
commonModuleInfos: Map<String, ModuleInfo>
|
||||
commonModuleInfos: Map<String, ModuleInfo>,
|
||||
dependeeModules: Collection<ModuleDescriptor>
|
||||
) {
|
||||
rootNode.targetDeclarations[targetIndex] = CirRootFactory.create(
|
||||
targetProvider.target,
|
||||
@@ -95,7 +108,10 @@ class CirTreeMerger(
|
||||
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
|
||||
|
||||
moduleDescriptors.forEach { (name, moduleDescriptor) ->
|
||||
@@ -110,16 +126,7 @@ class CirTreeMerger(
|
||||
moduleInfo: ModuleInfo,
|
||||
moduleDescriptor: ModuleDescriptor
|
||||
) {
|
||||
moduleInfo.cInteropAttributes?.let { cInteropAttributes ->
|
||||
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))
|
||||
}
|
||||
}
|
||||
processCInteropModuleAttributes(moduleInfo)
|
||||
|
||||
val moduleName: Name = moduleDescriptor.name.intern()
|
||||
val moduleNode: CirModuleNode = modules.getOrPut(moduleName) {
|
||||
@@ -258,4 +265,16 @@ class CirTreeMerger(
|
||||
}
|
||||
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
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.serialization.metadata.impl.ClassifierAliasingPackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.serialization.metadata.impl.ExportedForwardDeclarationsPackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.*
|
||||
@@ -69,12 +70,9 @@ internal fun ModuleDescriptor.collectNonEmptyPackageMemberScopes(collector: (FqN
|
||||
val packageFragmentProvider = this.packageFragmentProvider
|
||||
|
||||
fun recurse(packageFqName: FqName) {
|
||||
if (packageFqName.isUnderStandardKotlinPackages || packageFqName.isUnderKotlinNativeSyntheticPackages)
|
||||
return
|
||||
|
||||
val ownPackageFragments = packageFragmentProvider.packageFragments(packageFqName)
|
||||
val ownPackageMemberScopes = ownPackageFragments.asSequence()
|
||||
.filter { it !is ExportedForwardDeclarationsPackageFragmentDescriptor }
|
||||
.filter { it !is ExportedForwardDeclarationsPackageFragmentDescriptor && it !is ClassifierAliasingPackageFragmentDescriptor }
|
||||
.map { it.getMemberScope() }
|
||||
.filter { it != MemberScope.Empty }
|
||||
.toList(ownPackageFragments.size)
|
||||
|
||||
@@ -10,18 +10,17 @@ import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.serialization.konan.impl.ForwardDeclarationsFqNames
|
||||
|
||||
internal val DEPRECATED_ANNOTATION_FQN: FqName = FqName(Deprecated::class.java.name).intern()
|
||||
internal val DEPRECATED_ANNOTATION_CID: ClassId = internedClassId(DEPRECATED_ANNOTATION_FQN)
|
||||
|
||||
internal val STANDARD_KOTLIN_PACKAGE_FQNS: List<FqName> = listOf(
|
||||
StandardNames.BUILT_INS_PACKAGE_FQ_NAME.intern(),
|
||||
FqName("kotlinx").intern()
|
||||
private val STANDARD_KOTLIN_PACKAGES = listOf(
|
||||
StandardNames.BUILT_INS_PACKAGE_FQ_NAME.asString(),
|
||||
"kotlinx"
|
||||
)
|
||||
|
||||
private val STANDARD_KOTLIN_PACKAGES = STANDARD_KOTLIN_PACKAGE_FQNS.map { it.asString() }
|
||||
|
||||
private val KOTLIN_NATIVE_SYNTHETIC_PACKAGES = ForwardDeclarationsFqNames.syntheticPackages
|
||||
.map { fqName ->
|
||||
check(!fqName.isRoot)
|
||||
@@ -37,6 +36,9 @@ private val OBJC_INTEROP_CALLABLE_ANNOTATIONS = listOf(
|
||||
"ObjCFactory"
|
||||
)
|
||||
|
||||
internal fun Name.strip(): String =
|
||||
asString().removeSurrounding("<", ">")
|
||||
|
||||
internal val FqName.isUnderStandardKotlinPackages: Boolean
|
||||
get() = hasAnyPrefix(STANDARD_KOTLIN_PACKAGES)
|
||||
|
||||
|
||||
+21
-69
@@ -5,25 +5,20 @@
|
||||
|
||||
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.konan.KonanBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.packageFragments
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.konan.util.KlibMetadataFactories
|
||||
import org.jetbrains.kotlin.library.metadata.NativeTypeTransformer
|
||||
import org.jetbrains.kotlin.library.metadata.NullFlexibleTypeDeserializer
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
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.storage.StorageManager
|
||||
|
||||
internal val ModuleDescriptor.packageFragmentProvider
|
||||
internal val ModuleDescriptor.packageFragmentProvider: PackageFragmentProvider
|
||||
get() = (this as ModuleDescriptorImpl).packageFragmentProviderForModuleContentWithoutDependencies
|
||||
|
||||
internal fun createKotlinNativeForwardDeclarationsModule(
|
||||
@@ -42,73 +37,30 @@ internal fun ModuleDescriptor.resolveClassOrTypeAlias(classId: ClassId): Classif
|
||||
if (relativeClassName.isRoot)
|
||||
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()) {
|
||||
// resolve member scope of the nested class
|
||||
relativeClassName.pathSegments().reduce { first, second ->
|
||||
memberScope = (memberScope.getContributedClassifier(
|
||||
first,
|
||||
NoLookupLocation.FOR_ALREADY_TRACKED
|
||||
) as? ClassDescriptor)?.unsubstitutedMemberScope ?: return null
|
||||
val classifierName = if ('.' in relativeClassName.asString()) {
|
||||
// resolve member scope of the nested class
|
||||
relativeClassName.pathSegments().reduce { first, second ->
|
||||
memberScope = (memberScope.getContributedClassifier(
|
||||
first,
|
||||
NoLookupLocation.FOR_ALREADY_TRACKED
|
||||
) as? ClassDescriptor)?.unsubstitutedMemberScope ?: return@mapNotNull null
|
||||
|
||||
second
|
||||
second
|
||||
}
|
||||
} else {
|
||||
relativeClassName.shortName()
|
||||
}
|
||||
} else {
|
||||
relativeClassName.shortName()
|
||||
}
|
||||
|
||||
return memberScope.getContributedClassifier(
|
||||
classifierName,
|
||||
NoLookupLocation.FOR_ALREADY_TRACKED
|
||||
) as? ClassifierDescriptorWithTypeParameters
|
||||
memberScope.getContributedClassifier(
|
||||
classifierName,
|
||||
NoLookupLocation.FOR_ALREADY_TRACKED
|
||||
) as? ClassifierDescriptorWithTypeParameters
|
||||
}.firstOrNull()
|
||||
}
|
||||
|
||||
internal fun MutableMap<String, ModuleDescriptor?>.guessModuleByPackageFqName(packageFqName: FqName): ModuleDescriptor? {
|
||||
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 const val MODULE_NAME_PREFIX = "module:"
|
||||
|
||||
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.languageVersionSettings
|
||||
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.FunctionCollector
|
||||
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.name.Name
|
||||
import org.jetbrains.kotlin.platform.CommonPlatforms
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils.*
|
||||
import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase
|
||||
@@ -70,10 +68,10 @@ abstract class AbstractCommonizationFromSourcesTest : KtUsefulTestCase() {
|
||||
val result: Result = runCommonization(analyzedModules.toCommonizationParameters())
|
||||
assertCommonizationPerformed(result)
|
||||
|
||||
val sharedTarget: OutputTarget = analyzedModules.commonizedCommonModule.target
|
||||
val sharedTarget: OutputTarget = analyzedModules.sharedTarget
|
||||
assertEquals(sharedTarget, result.sharedTarget)
|
||||
|
||||
val sharedModuleAsExpected: ModuleDescriptor = analyzedModules.commonizedCommonModule.module
|
||||
val sharedModuleAsExpected: ModuleDescriptor = analyzedModules.commonizedModules.getValue(sharedTarget)
|
||||
val sharedModuleByCommonizer: ModuleDescriptor =
|
||||
(result.modulesByTargets.getValue(sharedTarget).single() as ModuleResult.Commonized).module
|
||||
|
||||
@@ -81,11 +79,11 @@ abstract class AbstractCommonizationFromSourcesTest : KtUsefulTestCase() {
|
||||
assertValidModule(sharedModuleByCommonizer)
|
||||
assertModulesAreEqual(sharedModuleAsExpected, sharedModuleByCommonizer, "\"$sharedTarget\" target")
|
||||
|
||||
val leafTargets: Set<InputTarget> = analyzedModules.commonizedPlatformModules.keys
|
||||
val leafTargets: Set<InputTarget> = analyzedModules.leafTargets
|
||||
assertEquals(leafTargets, result.leafTargets)
|
||||
|
||||
for (leafTarget in leafTargets) {
|
||||
val leafTargetModuleAsExpected: ModuleDescriptor = analyzedModules.commonizedPlatformModules.getValue(leafTarget).module
|
||||
val leafTargetModuleAsExpected: ModuleDescriptor = analyzedModules.commonizedModules.getValue(leafTarget)
|
||||
val leafTargetModuleByCommonizer: ModuleDescriptor =
|
||||
(result.modulesByTargets.getValue(leafTarget).single() as ModuleResult.Commonized).module
|
||||
|
||||
@@ -98,117 +96,196 @@ abstract class AbstractCommonizationFromSourcesTest : KtUsefulTestCase() {
|
||||
|
||||
private data class SourceModuleRoot(
|
||||
val targetName: String,
|
||||
val root: File
|
||||
val location: File
|
||||
) {
|
||||
init {
|
||||
assertIsDirectory(root)
|
||||
assertIsDirectory(location)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun load(directory: File): SourceModuleRoot = SourceModuleRoot(
|
||||
targetName = directory.name,
|
||||
root = directory
|
||||
location = directory
|
||||
)
|
||||
|
||||
const val COMMON_TARGET_NAME = "common"
|
||||
const val SHARED_TARGET_NAME = "common"
|
||||
}
|
||||
}
|
||||
|
||||
private class SourceModuleRoots(
|
||||
val originalPlatformRoots: Map<String, SourceModuleRoot>,
|
||||
val commonizedPlatformRoots: Map<String, SourceModuleRoot>,
|
||||
val commonizedCommonRoot: SourceModuleRoot
|
||||
val originalRoots: Map<InputTarget, SourceModuleRoot>,
|
||||
val commonizedRoots: Map<Target, SourceModuleRoot>,
|
||||
val dependeeRoots: Map<Target, SourceModuleRoot>
|
||||
) {
|
||||
val leafTargets: Set<InputTarget> = originalRoots.keys
|
||||
val sharedTarget: OutputTarget
|
||||
|
||||
init {
|
||||
check(originalPlatformRoots.isNotEmpty())
|
||||
check(COMMON_TARGET_NAME !in originalPlatformRoots)
|
||||
check(originalPlatformRoots.keys == commonizedPlatformRoots.keys)
|
||||
check(commonizedCommonRoot.targetName == COMMON_TARGET_NAME)
|
||||
check(leafTargets.size >= 2)
|
||||
check(leafTargets.none { it.name == SHARED_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 {
|
||||
fun load(dataDir: File): SourceModuleRoots = try {
|
||||
val originalRoots = listRoots(dataDir, ORIGINAL_ROOTS_DIR)
|
||||
val commonizedRoots = listRoots(dataDir, COMMONIZED_ROOTS_DIR)
|
||||
val originalRoots = listRoots(dataDir, ORIGINAL_ROOTS_DIR).mapKeys { InputTarget(it.key) }
|
||||
|
||||
SourceModuleRoots(
|
||||
originalPlatformRoots = originalRoots,
|
||||
commonizedPlatformRoots = commonizedRoots - COMMON_TARGET_NAME,
|
||||
commonizedCommonRoot = commonizedRoots.getValue(COMMON_TARGET_NAME)
|
||||
)
|
||||
val leafTargets = originalRoots.keys
|
||||
val sharedTarget = OutputTarget(leafTargets)
|
||||
|
||||
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) {
|
||||
fail("Source module misconfiguration in $dataDir", cause = e)
|
||||
}
|
||||
|
||||
private const val ORIGINAL_ROOTS_DIR = "original"
|
||||
private const val COMMONIZED_ROOTS_DIR = "commonized"
|
||||
private const val DEPENDEE_ROOTS_DIR = "dependee"
|
||||
|
||||
private fun listRoots(dataDir: File, rootsDirName: String): Map<String, SourceModuleRoot> =
|
||||
dataDir.resolve(rootsDirName).listFiles()?.toSet().orEmpty().map(SourceModuleRoot::load).associateBy { it.targetName }
|
||||
}
|
||||
}
|
||||
|
||||
private class AnalyzedModule<T : Target>(
|
||||
val target: T,
|
||||
val module: ModuleDescriptor
|
||||
private class AnalyzedModuleDependencies(
|
||||
val regularDependencies: Map<Target, List<ModuleDescriptor>>,
|
||||
val expectByDependencies: List<ModuleDescriptor>
|
||||
) {
|
||||
companion object {
|
||||
fun <T : Target> create(
|
||||
target: T,
|
||||
sourceModuleRoot: SourceModuleRoot,
|
||||
commonSourceModuleRoot: SourceModuleRoot? = null,
|
||||
parentDisposable: Disposable
|
||||
): AnalyzedModule<T> {
|
||||
val moduleName: String = sourceModuleRoot.root.parentFile.parentFile.name
|
||||
check(Name.isValidIdentifier(moduleName))
|
||||
fun withExpectByDependency(dependency: ModuleDescriptor) =
|
||||
AnalyzedModuleDependencies(
|
||||
regularDependencies = regularDependencies,
|
||||
expectByDependencies = expectByDependencies + dependency
|
||||
)
|
||||
|
||||
return AnalyzedModule(
|
||||
target = target,
|
||||
module = analyze(
|
||||
moduleName = moduleName,
|
||||
moduleRoot = sourceModuleRoot.root,
|
||||
commonModuleRoot = commonSourceModuleRoot?.root,
|
||||
parentDisposable = parentDisposable
|
||||
companion object {
|
||||
val EMPTY = AnalyzedModuleDependencies(emptyMap(), emptyList())
|
||||
|
||||
fun create(regularDependencies: Map<Target, ModuleDescriptor>, expectByDependencies: List<ModuleDescriptor>) =
|
||||
AnalyzedModuleDependencies(regularDependencies.mapValues { listOf(it.value) }, expectByDependencies)
|
||||
}
|
||||
}
|
||||
|
||||
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(
|
||||
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
|
||||
parameters.dependeeModulesProvider = dependeeModules[sharedTarget]?.let(::MockModulesProvider)
|
||||
|
||||
val module: ModuleDescriptor = analyzeModule(
|
||||
moduleName = moduleName,
|
||||
moduleRoot = moduleRoot,
|
||||
dependencyContainer = commonModule?.let(::CommonizedCommonDependenciesContainer), // platform module has dependencies to common module
|
||||
parentDisposable = parentDisposable
|
||||
return parameters
|
||||
}
|
||||
|
||||
companion object {
|
||||
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) {
|
||||
check(commonModule in module.expectedByModules)
|
||||
check(commonModule in module.allDependencyModules)
|
||||
// then, build "original" and "commonized" modules
|
||||
val originalModules = createModules(sharedTarget, originalRoots, dependencies, parentDisposable)
|
||||
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(
|
||||
moduleName: String,
|
||||
moduleRoot: File,
|
||||
dependencyContainer: CommonDependenciesContainer?,
|
||||
parentDisposable: Disposable
|
||||
private fun createModule(
|
||||
sharedTarget: OutputTarget,
|
||||
currentTarget: Target,
|
||||
moduleRoot: SourceModuleRoot,
|
||||
dependencies: AnalyzedModuleDependencies,
|
||||
parentDisposable: Disposable,
|
||||
isDependeeModule: Boolean
|
||||
): ModuleDescriptor {
|
||||
val moduleName: String = moduleRoot.location.parentFile.parentFile.name.let {
|
||||
if (isDependeeModule) "dependee-$it" else it
|
||||
}
|
||||
check(Name.isValidIdentifier(moduleName))
|
||||
|
||||
val configuration: CompilerConfiguration = newConfiguration()
|
||||
configuration.put(CommonConfigurationKeys.MODULE_NAME, moduleName)
|
||||
|
||||
@@ -220,7 +297,7 @@ private class AnalyzedModule<T : Target>(
|
||||
|
||||
val psiFactory = KtPsiFactory(environment.project)
|
||||
|
||||
val psiFiles: List<KtFile> = moduleRoot.walkTopDown()
|
||||
val psiFiles: List<KtFile> = moduleRoot.location.walkTopDown()
|
||||
.filter { it.isFile }
|
||||
.map { psiFactory.createFile(it.name, doLoadFile(it)) }
|
||||
.toList()
|
||||
@@ -231,105 +308,68 @@ private class AnalyzedModule<T : Target>(
|
||||
dependOnBuiltIns = true,
|
||||
languageVersionSettings = environment.configuration.languageVersionSettings,
|
||||
targetPlatform = CommonPlatforms.defaultCommonPlatform,
|
||||
dependenciesContainer = dependencyContainer
|
||||
dependenciesContainer = DependenciesContainerImpl(sharedTarget, currentTarget, dependencies)
|
||||
) { content ->
|
||||
environment.createPackagePartProvider(content.moduleContentScope)
|
||||
}.moduleDescriptor
|
||||
|
||||
module.accept(PatchingTestDescriptorVisitor, Unit)
|
||||
if (!isDependeeModule)
|
||||
module.accept(PatchingTestDescriptorVisitor, Unit)
|
||||
|
||||
return module
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class AnalyzedModules(
|
||||
val originalPlatformModules: Map<InputTarget, AnalyzedModule<InputTarget>>,
|
||||
val commonizedPlatformModules: Map<InputTarget, AnalyzedModule<InputTarget>>,
|
||||
val commonizedCommonModule: AnalyzedModule<OutputTarget>
|
||||
) {
|
||||
private class DependenciesContainerImpl(
|
||||
sharedTarget: OutputTarget,
|
||||
currentTarget: Target,
|
||||
dependencies: AnalyzedModuleDependencies
|
||||
) : CommonDependenciesContainer {
|
||||
private val moduleInfoToModule = mutableMapOf<ModuleInfo, ModuleDescriptor>()
|
||||
private val expectByModuleInfos = mutableListOf<ModuleInfo>()
|
||||
private val regularModuleInfos = mutableListOf<ModuleInfo>()
|
||||
|
||||
init {
|
||||
check(originalPlatformModules.isNotEmpty())
|
||||
check(originalPlatformModules.keys == commonizedPlatformModules.keys)
|
||||
}
|
||||
|
||||
fun toCommonizationParameters(): Parameters {
|
||||
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
|
||||
)
|
||||
if (currentTarget != sharedTarget) {
|
||||
dependencies.expectByDependencies.forEach { expectByDependency ->
|
||||
val moduleInfo = ModuleInfoImpl(expectByDependency, emptyList())
|
||||
moduleInfoToModule[moduleInfo] = expectByDependency
|
||||
expectByModuleInfos += moduleInfo
|
||||
}
|
||||
}
|
||||
|
||||
private fun createInputTargetModules(
|
||||
sourceModuleRoots: Map<String, SourceModuleRoot>,
|
||||
commonSourceModuleRoot: SourceModuleRoot? = null,
|
||||
parentDisposable: Disposable
|
||||
): Map<InputTarget, AnalyzedModule<InputTarget>> = sourceModuleRoots.map { (targetName, sourceModuleRoot) ->
|
||||
AnalyzedModule.create(
|
||||
target = InputTarget(targetName),
|
||||
sourceModuleRoot = sourceModuleRoot,
|
||||
commonSourceModuleRoot = commonSourceModuleRoot,
|
||||
parentDisposable = parentDisposable
|
||||
)
|
||||
}.associateBy { it.target }
|
||||
}
|
||||
}
|
||||
dependencies.regularDependencies[currentTarget]?.forEach { regularDependency ->
|
||||
val moduleInfo = ModuleInfoImpl(regularDependency, expectByModuleInfos)
|
||||
moduleInfoToModule[moduleInfo] = regularDependency
|
||||
regularModuleInfos += moduleInfo
|
||||
}
|
||||
|
||||
private class CommonizedCommonDependenciesContainer(
|
||||
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
|
||||
regularModuleInfos += expectByModuleInfos
|
||||
}
|
||||
|
||||
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 {
|
||||
if (moduleInfo !== commonModuleInfo)
|
||||
error("Unknown module info $moduleInfo")
|
||||
override fun dependencies() = listOf(this) + regularDependencies
|
||||
override fun dependencyOnBuiltIns() = ModuleInfo.DependencyOnBuiltIns.LAST
|
||||
|
||||
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 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>() {
|
||||
@@ -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),
|
||||
builtInsClass = DefaultBuiltIns::class.java,
|
||||
builtInsProvider = BuiltInsProvider.defaultBuiltInsProvider,
|
||||
modulesProvider = MockModulesProvider(moduleNames)
|
||||
modulesProvider = MockModulesProvider(moduleNames),
|
||||
dependeeModulesProvider = null
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -46,8 +46,7 @@ internal fun mockClassType(
|
||||
storageManager = LockBasedStorageManager.NO_LOCKS,
|
||||
target = InputTarget("Arbitrary target"),
|
||||
builtIns = DefaultBuiltIns.Instance,
|
||||
lazyModulesLookupTable = LockBasedStorageManager.NO_LOCKS.createLazyValue { mutableMapOf() },
|
||||
isCommon = false,
|
||||
lazyClassifierLookupTable = LockBasedStorageManager.NO_LOCKS.createLazyValue { LazyClassifierLookupTable(emptyMap()) },
|
||||
index = 0,
|
||||
cache = DeclarationsBuilderCache(1)
|
||||
)
|
||||
@@ -173,7 +172,7 @@ internal class MockModulesProvider : ModulesProvider {
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user