[JS IR] Module descriptors depends on each other

This commit is contained in:
Ilya Goncharov
2023-01-06 18:41:42 +01:00
committed by Space Team
parent b42492cd4d
commit 7ae85ed68e
9 changed files with 52 additions and 24 deletions
@@ -449,7 +449,7 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
moduleSourceFiles, moduleSourceFiles,
environmentForJS.configuration, environmentForJS.configuration,
sourceModule.jsFrontEndResult.jsAnalysisResult, sourceModule.jsFrontEndResult.jsAnalysisResult,
sortDependencies(sourceModule.descriptors), sortDependencies(sourceModule.moduleDependencies),
icData, icData,
expectDescriptorToSymbol, expectDescriptorToSymbol,
IrFactoryImpl, IrFactoryImpl,
@@ -68,7 +68,11 @@ internal class JsIrLinkerLoader(
var runtimeModule: ModuleDescriptorImpl? = null var runtimeModule: ModuleDescriptorImpl? = null
// TODO: deduplicate this code using part from klib.kt // TODO: deduplicate this code using part from klib.kt
fun getModuleDescriptor(current: KotlinLibrary): ModuleDescriptorImpl = descriptors.getOrPut(current) { fun getModuleDescriptor(current: KotlinLibrary): ModuleDescriptorImpl {
if (current in descriptors) {
return descriptors.getValue(current)
}
val isBuiltIns = current.unresolvedDependencies.isEmpty() val isBuiltIns = current.unresolvedDependencies.isEmpty()
val lookupTracker = LookupTracker.DO_NOTHING val lookupTracker = LookupTracker.DO_NOTHING
@@ -82,12 +86,15 @@ internal class JsIrLinkerLoader(
) )
if (isBuiltIns) runtimeModule = md if (isBuiltIns) runtimeModule = md
val dependencies = dependencyGraph[current]!!.map { getModuleDescriptor(it) } descriptors[current] = md
md.setDependencies(listOf(md) + dependencies) return md
md
} }
return dependencyGraph.keys.associateBy { klib -> getModuleDescriptor(klib) } val moduleDescriptorToKotlinLibrary = dependencyGraph.keys.associateBy { klib -> getModuleDescriptor(klib) }
return moduleDescriptorToKotlinLibrary
.onEach { (key, _) -> key.setDependencies(moduleDescriptorToKotlinLibrary.keys.toList()) }
.map<ModuleDescriptorImpl, KotlinLibrary, Pair<ModuleDescriptor, KotlinLibrary>> { it.key to it.value }
.toMap()
} }
data class LoadedJsIr(val linker: JsIrLinker, val loadedFragments: Map<KotlinLibraryFile, IrModuleFragment>) data class LoadedJsIr(val linker: JsIrLinker, val loadedFragments: Map<KotlinLibraryFile, IrModuleFragment>)
@@ -159,12 +159,9 @@ data class IrModuleInfo(
val moduleFragmentToUniqueName: Map<IrModuleFragment, String>, val moduleFragmentToUniqueName: Map<IrModuleFragment, String>,
) )
fun sortDependencies(mapping: Map<KotlinLibrary, ModuleDescriptor>): Collection<KotlinLibrary> { fun sortDependencies(moduleDependencies: Map<KotlinLibrary, List<KotlinLibrary>>): Collection<KotlinLibrary> {
val m2l = mapping.map { it.value to it.key }.toMap() return DFS.topologicalOrder(moduleDependencies.keys) { m ->
moduleDependencies.getValue(m)
return DFS.topologicalOrder(mapping.keys) { m ->
val descriptor = mapping[m] ?: error("No descriptor found for library ${m.libraryName}")
descriptor.allDependencyModules.filter { it != descriptor }.map { m2l[it] }
}.reversed() }.reversed()
} }
@@ -225,7 +222,7 @@ fun loadIr(
project, project,
configuration, configuration,
mainModule.files, mainModule.files,
sortDependencies(depsDescriptors.descriptors), sortDependencies(depsDescriptors.moduleDependencies),
friendModules, friendModules,
symbolTable, symbolTable,
messageLogger, messageLogger,
@@ -238,7 +235,7 @@ fun loadIr(
val mainModuleLib = allDependencies.find { it.libraryFile.canonicalPath == mainPath } val mainModuleLib = allDependencies.find { it.libraryFile.canonicalPath == mainPath }
?: error("No module with ${mainModule.libPath} found") ?: error("No module with ${mainModule.libPath} found")
val moduleDescriptor = depsDescriptors.getModuleDescriptor(mainModuleLib) val moduleDescriptor = depsDescriptors.getModuleDescriptor(mainModuleLib)
val sortedDependencies = sortDependencies(depsDescriptors.descriptors) val sortedDependencies = sortDependencies(depsDescriptors.moduleDependencies)
val friendModules = mapOf(mainModuleLib.uniqueName to depsDescriptors.friendDependencies.map { it.library.uniqueName }) val friendModules = mapOf(mainModuleLib.uniqueName to depsDescriptors.friendDependencies.map { it.library.uniqueName })
return getIrModuleInfoForKlib( return getIrModuleInfoForKlib(
@@ -520,7 +517,7 @@ class ModulesStructure(
files, files,
project, project,
compilerConfiguration, compilerConfiguration,
allDependencies.map { getModuleDescriptor(it.library) }, allModuleDescriptors,
friendDependencies.map { getModuleDescriptor(it.library) }, friendDependencies.map { getModuleDescriptor(it.library) },
analyzer.targetEnvironment, analyzer.targetEnvironment,
thisIsBuiltInsModule = builtInModuleDescriptor == null, thisIsBuiltInsModule = builtInModuleDescriptor == null,
@@ -556,7 +553,21 @@ class ModulesStructure(
// TODO: these are roughly equivalent to KlibResolvedModuleDescriptorsFactoryImpl. Refactor me. // TODO: these are roughly equivalent to KlibResolvedModuleDescriptorsFactoryImpl. Refactor me.
val descriptors = mutableMapOf<KotlinLibrary, ModuleDescriptorImpl>() val descriptors = mutableMapOf<KotlinLibrary, ModuleDescriptorImpl>()
fun getModuleDescriptor(current: KotlinLibrary): ModuleDescriptorImpl = descriptors.getOrPut(current) { val allModuleDescriptors = run {
val descriptors = allDependencies.map { getModuleDescriptor(it.library) }
descriptors.forEach { descriptor ->
descriptor.setDependencies(descriptors)
}
descriptors
}
fun getModuleDescriptor(current: KotlinLibrary): ModuleDescriptorImpl {
if (current in descriptors) {
return descriptors.getValue(current)
}
val isBuiltIns = current.unresolvedDependencies.isEmpty() val isBuiltIns = current.unresolvedDependencies.isEmpty()
val lookupTracker = compilerConfiguration[CommonConfigurationKeys.LOOKUP_TRACKER] ?: LookupTracker.DO_NOTHING val lookupTracker = compilerConfiguration[CommonConfigurationKeys.LOOKUP_TRACKER] ?: LookupTracker.DO_NOTHING
@@ -570,10 +581,9 @@ class ModulesStructure(
) )
if (isBuiltIns) runtimeModule = md if (isBuiltIns) runtimeModule = md
val dependencies = moduleDependencies.getValue(current).map { getModuleDescriptor(it) } descriptors[current] = md
md.setDependencies(listOf(md) + dependencies)
md return md
} }
val builtInModuleDescriptor = val builtInModuleDescriptor =
@@ -84,12 +84,13 @@ class ClassicFrontend2IrConverter(
val sourceFiles = psiFiles.values.toList() val sourceFiles = psiFiles.values.toList()
val icData = configuration.incrementalDataProvider?.getSerializedData(sourceFiles) ?: emptyList() val icData = configuration.incrementalDataProvider?.getSerializedData(sourceFiles) ?: emptyList()
val expectDescriptorToSymbol = mutableMapOf<DeclarationDescriptor, IrSymbol>() val expectDescriptorToSymbol = mutableMapOf<DeclarationDescriptor, IrSymbol>()
val (moduleFragment, pluginContext) = generateIrForKlibSerialization( val (moduleFragment, pluginContext) = generateIrForKlibSerialization(
project, project,
sourceFiles, sourceFiles,
configuration, configuration,
analysisResult, analysisResult,
sortDependencies(JsEnvironmentConfigurator.getAllRecursiveLibrariesFor(module, testServices)), sortDependencies(JsEnvironmentConfigurator.getAllDependenciesMappingFor(module, testServices)),
icData, icData,
expectDescriptorToSymbol, expectDescriptorToSymbol,
IrFactoryImpl, IrFactoryImpl,
@@ -213,6 +213,16 @@ class JsEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigu
return dependencies.associateBy { testServices.jsLibraryProvider.getCompiledLibraryByDescriptor(it) } return dependencies.associateBy { testServices.jsLibraryProvider.getCompiledLibraryByDescriptor(it) }
} }
fun getAllDependenciesMappingFor(module: TestModule, testServices: TestServices): Map<KotlinLibrary, List<KotlinLibrary>> {
val allRecursiveLibraries: Map<KotlinLibrary, ModuleDescriptor> = getAllRecursiveLibrariesFor(module, testServices)
val m2l = allRecursiveLibraries.map { it.value to it.key }.toMap()
return allRecursiveLibraries.keys.associateWith { m ->
val descriptor = allRecursiveLibraries[m] ?: error("No descriptor found for library ${m.libraryName}")
descriptor.allDependencyModules.filter { it != descriptor }.map { m2l.getValue(it) }
}
}
fun TestModule.hasFilesToRecompile(): Boolean { fun TestModule.hasFilesToRecompile(): Boolean {
return files.any { JsEnvironmentConfigurationDirectives.RECOMPILE in it.directives } return files.any { JsEnvironmentConfigurationDirectives.RECOMPILE in it.directives }
} }
@@ -67,7 +67,7 @@ class FilePathsInKlibTest : CodegenTestCase() {
sourceFiles, sourceFiles,
module.compilerConfiguration, module.compilerConfiguration,
module.jsFrontEndResult.jsAnalysisResult, module.jsFrontEndResult.jsAnalysisResult,
sortDependencies(module.descriptors), sortDependencies(module.moduleDependencies),
icData, icData,
expectDescriptorToSymbol, expectDescriptorToSymbol,
IrFactoryImpl, IrFactoryImpl,
@@ -387,7 +387,7 @@ abstract class AbstractInvalidationTest(
moduleSourceFiles, moduleSourceFiles,
configuration, configuration,
sourceModule.jsFrontEndResult.jsAnalysisResult, sourceModule.jsFrontEndResult.jsAnalysisResult,
sortDependencies(sourceModule.descriptors), sortDependencies(sourceModule.moduleDependencies),
icData, icData,
expectDescriptorToSymbol, expectDescriptorToSymbol,
IrFactoryImpl, IrFactoryImpl,
@@ -208,7 +208,7 @@ class JsIrBackendFacade(
return getIrModuleInfoForKlib( return getIrModuleInfoForKlib(
moduleDescriptor, moduleDescriptor,
sortDependencies(JsEnvironmentConfigurator.getAllRecursiveLibrariesFor(module, testServices)) + mainModuleLib, sortDependencies(JsEnvironmentConfigurator.getAllDependenciesMappingFor(module, testServices)) + mainModuleLib,
friendModules, friendModules,
filesToLoad, filesToLoad,
configuration, configuration,
@@ -130,7 +130,7 @@ abstract class AbstractJsKLibABITestCase : KtUsefulTestCase() {
moduleSourceFiles, moduleSourceFiles,
config, config,
sourceModule.jsFrontEndResult.jsAnalysisResult, sourceModule.jsFrontEndResult.jsAnalysisResult,
sortDependencies(sourceModule.descriptors), sortDependencies(sourceModule.moduleDependencies),
icData, icData,
expectDescriptorToSymbol, expectDescriptorToSymbol,
IrFactoryImpl, IrFactoryImpl,