Split some functions of js compiler to be able to use them in tests

This commit is contained in:
Ivan Kylchik
2021-09-21 16:48:50 +03:00
parent 4eec381d1b
commit 701a10d643
2 changed files with 298 additions and 167 deletions
@@ -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<IrModuleFragment>,
irBuiltIns: IrBuiltIns,
symbolTable: SymbolTable,
deserializer: JsIrLinker,
phaseConfig: PhaseConfig,
exportedDeclarations: Set<FqName>,
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)
@@ -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<KtFile>,
configuration: CompilerConfiguration,
analysisResult: AnalysisResult,
sortedDependencies: Collection<KotlinLibrary>,
icData: MutableList<KotlinFileSerializedData>,
expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>,
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<KotlinFileSerializedData>
val serializedIrFiles: List<SerializedIrFile>?
val serializedIrFiles = mutableListOf<SerializedIrFile>()
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<DeclarationDescriptor, IrSymbol>()
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<KotlinFileSerializedData>()
val expectDescriptorToSymbol = mutableMapOf<DeclarationDescriptor, IrSymbol>()
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<IrModuleFragment> = emptySet(),
)
private fun sortDependencies(resolvedDependencies: List<KotlinResolvedLibrary>, mapping: Map<KotlinLibrary, ModuleDescriptor>): Collection<KotlinLibrary> {
fun sortDependencies(mapping: Map<KotlinLibrary, ModuleDescriptor>): Collection<KotlinLibrary> {
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<KotlinLibrary>,
irLinker: JsIrLinker,
mainModuleLib: KotlinLibrary?,
filesToLoad: Set<String>?,
mapping: (KotlinLibrary) -> ModuleDescriptor
): Map<IrModuleFragment, KotlinLibrary> {
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<IrModuleFragment, KotlinLibrary>.getUniqueNameForEachFragment(): Map<IrModuleFragment, String> {
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<IrModuleFragment, String>()
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<ModuleDescriptor, SerializedIcData>()
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<IrModuleFragment, String>()
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<KotlinLibrary>,
friendModules: Map<String, List<String>>,
filesToLoad: Set<String>?,
configuration: CompilerConfiguration,
symbolTable: SymbolTable,
messageLogger: IrMessageLogger,
loadFunctionInterfacesIntoStdlib: Boolean,
loweredIcData: Map<ModuleDescriptor, SerializedIcData>,
filterModulesWithCache: (Iterable<IrModuleFragment>) -> Set<IrModuleFragment>,
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<KtFile>,
allSortedDependencies: Collection<KotlinLibrary>,
friendModules: Map<String, List<String>>,
loweredIcData: Map<ModuleDescriptor, SerializedIcData>,
symbolTable: SymbolTable,
messageLogger: IrMessageLogger,
loadFunctionInterfacesIntoStdlib: Boolean,
verifySignatures: Boolean,
filterModulesWithCache: (Iterable<IrModuleFragment>) -> Set<IrModuleFragment>,
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<KtFile>,
@@ -448,7 +536,7 @@ private fun preparePsi2Ir(
depsDescriptors: ModulesStructure,
errorIgnorancePolicy: ErrorTolerancePolicy,
symbolTable: SymbolTable,
): Pair<GeneratorContext, Boolean> {
): 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(