diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt index beaec1e0f73..bc6321dc501 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt @@ -8,11 +8,13 @@ package org.jetbrains.kotlin.ir.backend.js import org.jetbrains.kotlin.backend.common.lower import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel +import org.jetbrains.kotlin.config.CompilerConfiguration +import org.jetbrains.kotlin.ir.IrBuiltIns import org.jetbrains.kotlin.ir.backend.js.codegen.JsGenerationGranularity -import org.jetbrains.kotlin.ir.backend.js.ic.ModuleCache import org.jetbrains.kotlin.ir.backend.js.ic.icCompile import org.jetbrains.kotlin.ir.backend.js.lower.generateJsTests import org.jetbrains.kotlin.ir.backend.js.lower.moveBodilessDeclarationsToSeparatePlace +import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrModuleToJsTransformer import org.jetbrains.kotlin.ir.backend.js.utils.NameTables import org.jetbrains.kotlin.ir.declarations.IrFactory @@ -20,6 +22,7 @@ import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.declarations.StageController import org.jetbrains.kotlin.ir.declarations.persistent.PersistentIrFactory import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator +import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.ir.util.noUnboundLeft import org.jetbrains.kotlin.js.backend.ast.JsProgram import org.jetbrains.kotlin.js.config.RuntimeDiagnostic @@ -78,10 +81,50 @@ fun compile( val (moduleFragment: IrModuleFragment, dependencyModules, irBuiltIns, symbolTable, deserializer, _) = loadIr(depsDescriptors, irFactory, verifySignatures, filesToLower, loadFunctionInterfacesIntoStdlib = true) - val mainModule = depsDescriptors.mainModule - val configuration = depsDescriptors.compilerConfiguration + return compileIr( + moduleFragment, + depsDescriptors.mainModule, + depsDescriptors.compilerConfiguration, + dependencyModules, + irBuiltIns, + symbolTable, + deserializer, + phaseConfig, + exportedDeclarations, + dceDriven, + dceRuntimeDiagnostic, + es6mode, + propertyLazyInitialization, + baseClassIntoMetadata, + lowerPerModule, + safeExternalBoolean, + safeExternalBooleanDiagnostic, + granularity + ) +} +fun compileIr( + moduleFragment: IrModuleFragment, + mainModule: MainModule, + configuration: CompilerConfiguration, + dependencyModules: List, + irBuiltIns: IrBuiltIns, + symbolTable: SymbolTable, + deserializer: JsIrLinker, + phaseConfig: PhaseConfig, + exportedDeclarations: Set, + dceDriven: Boolean, + dceRuntimeDiagnostic: RuntimeDiagnostic?, + es6mode: Boolean, + propertyLazyInitialization: Boolean, + baseClassIntoMetadata: Boolean, + lowerPerModule: Boolean, + safeExternalBoolean: Boolean, + safeExternalBooleanDiagnostic: RuntimeDiagnostic?, + granularity: JsGenerationGranularity, +): LoweredIr { val moduleDescriptor = moduleFragment.descriptor + val irFactory = symbolTable.irFactory val allModules = when (mainModule) { is MainModule.SourceFiles -> dependencyModules + listOf(moduleFragment) diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt index 53996327f7d..cab39f04e98 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt @@ -38,6 +38,7 @@ import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrModuleSeria import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerDesc import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerIr import org.jetbrains.kotlin.ir.declarations.IrFactory +import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl import org.jetbrains.kotlin.ir.descriptors.IrBuiltInsOverDescriptors @@ -120,25 +121,23 @@ fun IrMessageLogger?.toResolverLogger(): Logger { } } -fun generateKLib( - depsDescriptors: ModulesStructure, +fun generateIrForKlibSerialization( + project: Project, + files: List, + configuration: CompilerConfiguration, + analysisResult: AnalysisResult, + sortedDependencies: Collection, + icData: MutableList, + expectDescriptorToSymbol: MutableMap, irFactory: IrFactory, - outputKlibPath: String, - nopack: Boolean, verifySignatures: Boolean = true, - abiVersion: KotlinAbiVersion = KotlinAbiVersion.CURRENT, - jsOutputName: String? -) { - val project = depsDescriptors.project - val files = (depsDescriptors.mainModule as MainModule.SourceFiles).files - val configuration = depsDescriptors.compilerConfiguration - val allDependencies = depsDescriptors.allDependencies + getDescriptorByLibrary: (KotlinLibrary) -> ModuleDescriptor, +): IrModuleFragment { val incrementalDataProvider = configuration.get(JSConfigurationKeys.INCREMENTAL_DATA_PROVIDER) val errorPolicy = configuration.get(JSConfigurationKeys.ERROR_TOLERANCE_POLICY) ?: ErrorTolerancePolicy.DEFAULT val messageLogger = configuration.get(IrMessageLogger.IR_MESSAGE_LOGGER) ?: IrMessageLogger.None - val icData: List - val serializedIrFiles: List? + val serializedIrFiles = mutableListOf() if (incrementalDataProvider != null) { val nonCompiledSources = files.map { VfsUtilCore.virtualToIoFile(it.virtualFile) to it }.toMap() @@ -160,17 +159,15 @@ fun generateKLib( storage.add(KotlinFileSerializedData(metaFile.metadata, irFile)) } - icData = storage - serializedIrFiles = storage.map { it.irData } - } else { - icData = emptyList() - serializedIrFiles = null + icData.addAll(storage) + serializedIrFiles.addAll(storage.map { it.irData }) } - val (psi2IrContext, hasErrors) = preparePsi2Ir(depsDescriptors, errorPolicy, SymbolTable(IdSignatureDescriptor(JsManglerDesc), irFactory)) + val symbolTable = SymbolTable(IdSignatureDescriptor(JsManglerDesc), irFactory) + val psi2Ir = Psi2IrTranslator(configuration.languageVersionSettings, Psi2IrConfiguration(errorPolicy.allowErrors)) + val psi2IrContext = psi2Ir.createGeneratorContext(analysisResult.moduleDescriptor, analysisResult.bindingContext, symbolTable) val irBuiltIns = psi2IrContext.irBuiltIns - val expectDescriptorToSymbol = mutableMapOf() val feContext = psi2IrContext.run { JsIrLinker.JsFePluginContext(moduleDescriptor, symbolTable, typeTranslator, irBuiltIns) } @@ -180,12 +177,10 @@ fun generateKLib( psi2IrContext.irBuiltIns, psi2IrContext.symbolTable, feContext, - serializedIrFiles?.let { ICData(it, errorPolicy.allowErrors) } + serializedIrFiles.let { ICData(it, errorPolicy.allowErrors) } ) - sortDependencies(allDependencies, depsDescriptors.descriptors).map { - irLinker.deserializeOnlyHeaderModule(depsDescriptors.getModuleDescriptor(it), it) - } + sortedDependencies.map { irLinker.deserializeOnlyHeaderModule(getDescriptorByLibrary(it), it) } val moduleFragment = psi2IrContext.generateModuleFragmentWithPlugins(project, files, irLinker, messageLogger, expectDescriptorToSymbol) @@ -197,27 +192,60 @@ fun generateKLib( irLinker.modules.forEach { fakeOverrideChecker.check(it) } } - val moduleName = configuration[CommonConfigurationKeys.MODULE_NAME]!! - if (!configuration.expectActualLinker) { moduleFragment.acceptVoid(ExpectDeclarationRemover(psi2IrContext.symbolTable, false)) } + return moduleFragment +} + +fun generateKLib( + depsDescriptors: ModulesStructure, + irFactory: IrFactory, + outputKlibPath: String, + nopack: Boolean, + verifySignatures: Boolean = true, + abiVersion: KotlinAbiVersion = KotlinAbiVersion.CURRENT, + jsOutputName: String? +) { + val project = depsDescriptors.project + val files = (depsDescriptors.mainModule as MainModule.SourceFiles).files + val configuration = depsDescriptors.compilerConfiguration + val allDependencies = depsDescriptors.allDependencies.map { it.library } + val messageLogger = configuration.get(IrMessageLogger.IR_MESSAGE_LOGGER) ?: IrMessageLogger.None + + val icData = mutableListOf() + val expectDescriptorToSymbol = mutableMapOf() + + val moduleFragment = generateIrForKlibSerialization( + project, + files, + configuration, + depsDescriptors.jsFrontEndResult.jsAnalysisResult, + sortDependencies(depsDescriptors.descriptors), + icData, + expectDescriptorToSymbol, + irFactory, + verifySignatures + ) { + depsDescriptors.getModuleDescriptor(it) + } + serializeModuleIntoKlib( - moduleName, + configuration[CommonConfigurationKeys.MODULE_NAME]!!, project, configuration, messageLogger, - psi2IrContext.bindingContext, + depsDescriptors.jsFrontEndResult.bindingContext, files, outputKlibPath, - allDependencies.map { it.library }, + allDependencies, moduleFragment, expectDescriptorToSymbol, icData, nopack, perFile = false, - hasErrors, + depsDescriptors.jsFrontEndResult.hasErrors, abiVersion, jsOutputName ) @@ -233,11 +261,10 @@ data class IrModuleInfo( val loweredIrLoaded: Set = emptySet(), ) -private fun sortDependencies(resolvedDependencies: List, mapping: Map): Collection { +fun sortDependencies(mapping: Map): Collection { val m2l = mapping.map { it.value to it.key }.toMap() - val dependencies = resolvedDependencies.map { it.library } - return DFS.topologicalOrder(dependencies) { 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() @@ -251,6 +278,41 @@ object EmptyLoweringsCacheProvider : LoweringsCacheProvider { override fun cacheByPath(path: String): SerializedIcData? = null } +fun deserializeDependencies( + sortedDependencies: Collection, + irLinker: JsIrLinker, + mainModuleLib: KotlinLibrary?, + filesToLoad: Set?, + mapping: (KotlinLibrary) -> ModuleDescriptor +): Map { + return sortedDependencies.associateBy { klib -> + val descriptor = mapping(klib) + when { + mainModuleLib == null -> irLinker.deserializeIrModuleHeader(descriptor, klib, { DeserializationStrategy.EXPLICITLY_EXPORTED }) + filesToLoad != null && klib == mainModuleLib -> irLinker.deserializeDirtyFiles(descriptor, klib, filesToLoad) + filesToLoad != null && klib != mainModuleLib -> irLinker.deserializeHeadersWithInlineBodies(descriptor, klib) + klib == mainModuleLib -> irLinker.deserializeIrModuleHeader(descriptor, klib, { DeserializationStrategy.ALL }) + else -> irLinker.deserializeIrModuleHeader(descriptor, klib, { DeserializationStrategy.EXPLICITLY_EXPORTED }) + } + } +} + +fun Map.getUniqueNameForEachFragment(): Map { + return this.entries.mapNotNull { (moduleFragment, klib) -> + klib.manifestProperties.getProperty(KLIB_PROPERTY_JS_OUTPUT_NAME)?.let { + moduleFragment to it + } + }.toMap() +} + +fun getFunctionFactoryCallback(stdlibModule: IrModuleFragment) = { packageFragmentDescriptor: PackageFragmentDescriptor -> + IrFileImpl( + NaiveSourceBasedFileEntryImpl("${packageFragmentDescriptor.fqName}-[K][Suspend]Functions"), + packageFragmentDescriptor, + stdlibModule + ).also { stdlibModule.files += it } +} + @OptIn(ObsoleteDescriptorBasedAPI::class) fun loadIr( depsDescriptors: ModulesStructure, @@ -262,99 +324,38 @@ fun loadIr( val project = depsDescriptors.project val mainModule = depsDescriptors.mainModule val configuration = depsDescriptors.compilerConfiguration - val allDependencies = depsDescriptors.allDependencies + val allDependencies = depsDescriptors.allDependencies.map { it.library } val errorPolicy = configuration.get(JSConfigurationKeys.ERROR_TOLERANCE_POLICY) ?: ErrorTolerancePolicy.DEFAULT val messageLogger = configuration.get(IrMessageLogger.IR_MESSAGE_LOGGER) ?: IrMessageLogger.None val signaturer = IdSignatureDescriptor(JsManglerDesc) val symbolTable = SymbolTable(signaturer, irFactory) - lateinit var stdlibModule: IrModuleFragment - - val createFunctionFactoryCallback = - if (loadFunctionInterfacesIntoStdlib) { - { packageFragmentDescriptor: PackageFragmentDescriptor -> - IrFileImpl( - NaiveSourceBasedFileEntryImpl("${packageFragmentDescriptor.fqName}-[K][Suspend]Functions"), - packageFragmentDescriptor, - stdlibModule - ).also { stdlibModule.files += it } - } - } else { - null - } - when (mainModule) { is MainModule.SourceFiles -> { assert(filesToLoad == null) - val (psi2IrContext, _) = preparePsi2Ir(depsDescriptors, errorPolicy, symbolTable) - val irBuiltIns = psi2IrContext.irBuiltIns - (irBuiltIns as IrBuiltInsOverDescriptors).functionFactory = - IrDescriptorBasedFunctionFactory(irBuiltIns, symbolTable, createFunctionFactoryCallback, true) - - val feContext = psi2IrContext.run { - JsIrLinker.JsFePluginContext(moduleDescriptor, symbolTable, typeTranslator, irBuiltIns) - } - val moduleFragmentToUniqueName = mutableMapOf() + val psi2IrContext = preparePsi2Ir(depsDescriptors, errorPolicy, symbolTable) val friendModules = mapOf(psi2IrContext.moduleDescriptor.name.asString() to depsDescriptors.friendDependencies.map { it.library.uniqueName }) - val irLinker = - JsIrLinker( - psi2IrContext.moduleDescriptor, - messageLogger, - irBuiltIns, - symbolTable, - feContext, - null, - depsDescriptors.loweredIcData, - friendModules - ) - val deserializedModuleFragments = sortDependencies(allDependencies, depsDescriptors.descriptors).map { klib -> - irLinker.deserializeIrModuleHeader( - depsDescriptors.getModuleDescriptor(klib), - klib, - deserializationStrategy = { DeserializationStrategy.EXPLICITLY_EXPORTED } - ).also { moduleFragment -> - klib.manifestProperties.getProperty(KLIB_PROPERTY_JS_OUTPUT_NAME)?.let { - moduleFragmentToUniqueName[moduleFragment] = it - } - } - } - stdlibModule = deserializedModuleFragments.first() - val moduleFragment = psi2IrContext.generateModuleFragmentWithPlugins(project, mainModule.files, irLinker, messageLogger) - symbolTable.noUnboundLeft("Unbound symbols left after linker") - - // TODO: not sure whether this check should be enabled by default. Add configuration key for it. - val mangleChecker = ManglerChecker(JsManglerIr, Ir2DescriptorManglerAdapter(JsManglerDesc)) - if (verifySignatures) { - moduleFragment.acceptVoid(mangleChecker) - } - - if (configuration.getBoolean(JSConfigurationKeys.FAKE_OVERRIDE_VALIDATOR)) { - val fakeOverrideChecker = FakeOverrideChecker(JsManglerIr, JsManglerDesc) - irLinker.modules.forEach { fakeOverrideChecker.check(it) } - } - - if (verifySignatures) { - irBuiltIns.knownBuiltins.forEach { it.acceptVoid(mangleChecker) } - } - - return IrModuleInfo(moduleFragment, deserializedModuleFragments, irBuiltIns, symbolTable, irLinker, moduleFragmentToUniqueName, - depsDescriptors.modulesWithCaches(deserializedModuleFragments)) + return getIrModuleInfoForSourceFiles( + psi2IrContext, + project, + configuration, + mainModule.files, + sortDependencies(depsDescriptors.descriptors), + friendModules, + depsDescriptors.loweredIcData, + symbolTable, + messageLogger, + loadFunctionInterfacesIntoStdlib, + verifySignatures, + { depsDescriptors.modulesWithCaches(it) }, + { depsDescriptors.getModuleDescriptor(it) }, + ) } is MainModule.Klib -> { - val mainPath = File(mainModule.libPath).canonicalPath - val mainModuleLib = - depsDescriptors.allDependencies.find { it.library.libraryFile.canonicalPath == mainPath }?.library - ?: error("No module with ${mainModule.libPath} found") - val moduleDescriptor = depsDescriptors.getModuleDescriptor(mainModuleLib) - val typeTranslator = - TypeTranslatorImpl(symbolTable, depsDescriptors.compilerConfiguration.languageVersionSettings, moduleDescriptor) - val irBuiltIns = IrBuiltInsOverDescriptors(moduleDescriptor.builtIns, typeTranslator, symbolTable) - irBuiltIns.functionFactory = IrDescriptorBasedFunctionFactory(irBuiltIns, symbolTable, createFunctionFactoryCallback, true) - - val loweredIcData = if (!depsDescriptors.icUseStdlibCache && !depsDescriptors.icUseStdlibCache) emptyMap() else { + val loweredIcData = if (!depsDescriptors.icUseGlobalSignatures && !depsDescriptors.icUseStdlibCache) emptyMap() else { val result = mutableMapOf() for (lib in depsDescriptors.moduleDependencies.keys) { @@ -369,62 +370,149 @@ fun loadIr( result } + val mainPath = File(mainModule.libPath).canonicalPath + val mainModuleLib = allDependencies.find { it.libraryFile.canonicalPath == mainPath } + ?: error("No module with ${mainModule.libPath} found") + val moduleDescriptor = depsDescriptors.getModuleDescriptor(mainModuleLib) + val sortedDependencies = sortDependencies(depsDescriptors.descriptors) val friendModules = mapOf(mainModuleLib.uniqueName to depsDescriptors.friendDependencies.map { it.library.uniqueName }) - val irLinker = - JsIrLinker( - null, - messageLogger, - irBuiltIns, - symbolTable, - null, - null, - loweredIcData, - friendModules - ) - - val moduleFragmentToUniqueName = mutableMapOf() - - val reachableDependencies = depsDescriptors.allResolvedDependencies.filterRoots { - it.library.libraryFile.canonicalPath == mainPath - } - - val deserializedModuleFragments = - sortDependencies(reachableDependencies.getFullResolvedList(), depsDescriptors.descriptors).map { klib -> - val descriptor = depsDescriptors.getModuleDescriptor(klib) - if (filesToLoad != null) { - if (klib == mainModuleLib) { - irLinker.deserializeDirtyFiles(descriptor, klib, filesToLoad) - } else { - irLinker.deserializeHeadersWithInlineBodies(descriptor, klib) - } - } else { - val strategy = if (klib == mainModuleLib) - DeserializationStrategy.ALL - else - DeserializationStrategy.EXPLICITLY_EXPORTED - - irLinker.deserializeIrModuleHeader(descriptor, klib, { strategy }) - }.also { moduleFragment -> - klib.manifestProperties.getProperty(KLIB_PROPERTY_JS_OUTPUT_NAME)?.let { - moduleFragmentToUniqueName[moduleFragment] = it - } - } - } - stdlibModule = deserializedModuleFragments.first() - - val moduleFragment = deserializedModuleFragments.last() - - irLinker.init(null, emptyList()) - ExternalDependenciesGenerator(symbolTable, listOf(irLinker)).generateUnboundSymbolsAsDependencies() - irLinker.postProcess() - - return IrModuleInfo(moduleFragment, deserializedModuleFragments, irBuiltIns, symbolTable, irLinker, moduleFragmentToUniqueName, - depsDescriptors.modulesWithCaches(deserializedModuleFragments)) + return getIrModuleInfoForKlib( + moduleDescriptor, + sortedDependencies, + friendModules, + filesToLoad, + configuration, + symbolTable, + messageLogger, + loadFunctionInterfacesIntoStdlib, + loweredIcData, + { depsDescriptors.modulesWithCaches(it) }, + { depsDescriptors.getModuleDescriptor(it) }, + ) } } } +@OptIn(ObsoleteDescriptorBasedAPI::class) +fun getIrModuleInfoForKlib( + moduleDescriptor: ModuleDescriptor, + sortedDependencies: Collection, + friendModules: Map>, + filesToLoad: Set?, + configuration: CompilerConfiguration, + symbolTable: SymbolTable, + messageLogger: IrMessageLogger, + loadFunctionInterfacesIntoStdlib: Boolean, + loweredIcData: Map, + filterModulesWithCache: (Iterable) -> Set, + mapping: (KotlinLibrary) -> ModuleDescriptor, +): IrModuleInfo { + val mainModuleLib = sortedDependencies.last() + val typeTranslator = TypeTranslatorImpl(symbolTable, configuration.languageVersionSettings, moduleDescriptor) + val irBuiltIns = IrBuiltInsOverDescriptors(moduleDescriptor.builtIns, typeTranslator, symbolTable) + + val irLinker = + JsIrLinker( + null, + messageLogger, + irBuiltIns, + symbolTable, + null, + null, + loweredIcData, + friendModules + ) + + val deserializedModuleFragmentsToLib = deserializeDependencies(sortedDependencies, irLinker, mainModuleLib, filesToLoad, mapping) + val deserializedModuleFragments = deserializedModuleFragmentsToLib.keys.toList() + irBuiltIns.functionFactory = IrDescriptorBasedFunctionFactory( + irBuiltIns, + symbolTable, + if (loadFunctionInterfacesIntoStdlib) getFunctionFactoryCallback(deserializedModuleFragments.first()) else null, + true + ) + + val moduleFragment = deserializedModuleFragments.last() + + irLinker.init(null, emptyList()) + ExternalDependenciesGenerator(symbolTable, listOf(irLinker)).generateUnboundSymbolsAsDependencies() + irLinker.postProcess() + + return IrModuleInfo( + moduleFragment, deserializedModuleFragments, irBuiltIns, symbolTable, irLinker, + deserializedModuleFragmentsToLib.getUniqueNameForEachFragment(), + filterModulesWithCache(deserializedModuleFragments) + ) +} + +@OptIn(ObsoleteDescriptorBasedAPI::class) +fun getIrModuleInfoForSourceFiles( + psi2IrContext: GeneratorContext, + project: Project, + configuration: CompilerConfiguration, + files: List, + allSortedDependencies: Collection, + friendModules: Map>, + loweredIcData: Map, + symbolTable: SymbolTable, + messageLogger: IrMessageLogger, + loadFunctionInterfacesIntoStdlib: Boolean, + verifySignatures: Boolean, + filterModulesWithCache: (Iterable) -> Set, + mapping: (KotlinLibrary) -> ModuleDescriptor +): IrModuleInfo { + val irBuiltIns = psi2IrContext.irBuiltIns + val feContext = psi2IrContext.run { + JsIrLinker.JsFePluginContext(moduleDescriptor, symbolTable, typeTranslator, irBuiltIns) + } + val irLinker = + JsIrLinker( + psi2IrContext.moduleDescriptor, + messageLogger, + irBuiltIns, + symbolTable, + feContext, + null, + loweredIcData, + friendModules + ) + val deserializedModuleFragmentsToLib = deserializeDependencies(allSortedDependencies, irLinker, null,null, mapping) + val deserializedModuleFragments = deserializedModuleFragmentsToLib.keys.toList() + (irBuiltIns as IrBuiltInsOverDescriptors).functionFactory = + IrDescriptorBasedFunctionFactory( + irBuiltIns, + symbolTable, + if (loadFunctionInterfacesIntoStdlib) getFunctionFactoryCallback(deserializedModuleFragments.first()) else null, + true + ) + + val moduleFragment = psi2IrContext.generateModuleFragmentWithPlugins(project, files, irLinker, messageLogger) + symbolTable.noUnboundLeft("Unbound symbols left after linker") + + + // TODO: not sure whether this check should be enabled by default. Add configuration key for it. + val mangleChecker = ManglerChecker(JsManglerIr, Ir2DescriptorManglerAdapter(JsManglerDesc)) + if (verifySignatures) { + moduleFragment.acceptVoid(mangleChecker) + } + + if (configuration.getBoolean(JSConfigurationKeys.FAKE_OVERRIDE_VALIDATOR)) { + val fakeOverrideChecker = FakeOverrideChecker(JsManglerIr, JsManglerDesc) + irLinker.modules.forEach { fakeOverrideChecker.check(it) } + } + + if (verifySignatures) { + irBuiltIns.knownBuiltins.forEach { it.acceptVoid(mangleChecker) } + } + + return IrModuleInfo( + moduleFragment, deserializedModuleFragments, irBuiltIns, symbolTable, irLinker, + deserializedModuleFragmentsToLib.getUniqueNameForEachFragment(), + filterModulesWithCache(deserializedModuleFragments) + ) +} + fun prepareAnalyzedSourceModule( project: Project, files: List, @@ -448,7 +536,7 @@ private fun preparePsi2Ir( depsDescriptors: ModulesStructure, errorIgnorancePolicy: ErrorTolerancePolicy, symbolTable: SymbolTable, -): Pair { +): GeneratorContext { val analysisResult = depsDescriptors.jsFrontEndResult val psi2Ir = Psi2IrTranslator( depsDescriptors.compilerConfiguration.languageVersionSettings, @@ -458,7 +546,7 @@ private fun preparePsi2Ir( analysisResult.moduleDescriptor, analysisResult.bindingContext, symbolTable - ) to analysisResult.hasErrors + ) } fun GeneratorContext.generateModuleFragmentWithPlugins(