[JS IR] Update IC depends graph after intrinsics loading
- Remove unused params from compilerWithIC wrapper. - Move JsIrBackendContext creation logic into separate function - Introduce and use compiler interface for IC infrastructure On dirty rebuild we may reload IR from stdlib, such reloading may affect files with intrinsics and builtins. As soon as we load only exported symbols, we must track dependencies for files with intrinsics or builtins as for others. This patch implements the logic which updates dependencies for the stdlib files after loading of intrinsics and builtins. ^KT-54323 Fixed
This commit is contained in:
committed by
Space Team
parent
31ba1f1534
commit
7b2c125754
@@ -289,7 +289,7 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
compilerConfiguration = configurationJs,
|
||||
irFactory = { IrFactoryImplForJsIC(WholeWorldStageController()) },
|
||||
mainArguments = mainCallArguments,
|
||||
executor = ::buildCacheForModuleFiles
|
||||
compilerInterfaceFactory = { mainModule, cfg -> JsIrCompilerWithIC(mainModule, cfg) }
|
||||
)
|
||||
|
||||
var tp = System.currentTimeMillis()
|
||||
|
||||
@@ -7,88 +7,65 @@ package org.jetbrains.kotlin.ir.backend.js
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||
import org.jetbrains.kotlin.backend.common.phaser.PhaserState
|
||||
import org.jetbrains.kotlin.backend.common.serialization.linkerissues.checkNoUnboundSymbols
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.backend.js.ic.JsIrCompilerICInterface
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.collectNativeImplementations
|
||||
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.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
||||
import org.jetbrains.kotlin.js.config.RuntimeDiagnostic
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors
|
||||
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
fun compileWithIC(
|
||||
mainModule: IrModuleFragment,
|
||||
class JsIrCompilerWithIC(
|
||||
private val mainModule: IrModuleFragment,
|
||||
configuration: CompilerConfiguration,
|
||||
irLinker: JsIrLinker,
|
||||
allModules: Collection<IrModuleFragment>,
|
||||
filesToLower: Collection<IrFile>,
|
||||
mainArguments: List<String>? = null,
|
||||
exportedDeclarations: Set<FqName> = emptySet(),
|
||||
keep: Set<String> = emptySet(),
|
||||
generateFullJs: Boolean = true,
|
||||
generateDceJs: Boolean = false,
|
||||
dceDriven: Boolean = false,
|
||||
dceRuntimeDiagnostic: RuntimeDiagnostic? = null,
|
||||
es6mode: Boolean = false,
|
||||
multiModule: Boolean = false,
|
||||
verifySignatures: Boolean = true,
|
||||
baseClassIntoMetadata: Boolean = false,
|
||||
lowerPerModule: Boolean = false,
|
||||
safeExternalBoolean: Boolean = false,
|
||||
safeExternalBooleanDiagnostic: RuntimeDiagnostic? = null,
|
||||
): List<JsIrFragmentAndBinaryAst> {
|
||||
val irBuiltIns = mainModule.irBuiltins
|
||||
val symbolTable = (irBuiltIns as IrBuiltInsOverDescriptors).symbolTable
|
||||
es6mode: Boolean = false
|
||||
) : JsIrCompilerICInterface {
|
||||
private val context: JsIrBackendContext
|
||||
|
||||
val context = JsIrBackendContext(
|
||||
mainModule.descriptor,
|
||||
irBuiltIns,
|
||||
symbolTable,
|
||||
mainModule,
|
||||
exportedDeclarations,
|
||||
keep,
|
||||
configuration,
|
||||
es6mode = es6mode,
|
||||
dceRuntimeDiagnostic = dceRuntimeDiagnostic,
|
||||
baseClassIntoMetadata = baseClassIntoMetadata,
|
||||
safeExternalBoolean = safeExternalBoolean,
|
||||
safeExternalBooleanDiagnostic = safeExternalBooleanDiagnostic,
|
||||
icCompatibleIr2Js = IcCompatibleIr2Js.IC_MODE,
|
||||
)
|
||||
init {
|
||||
val irBuiltIns = mainModule.irBuiltins
|
||||
val symbolTable = (irBuiltIns as IrBuiltInsOverDescriptors).symbolTable
|
||||
|
||||
// Load declarations referenced during `context` initialization
|
||||
val irProviders = listOf(irLinker)
|
||||
ExternalDependenciesGenerator(symbolTable, irProviders).generateUnboundSymbolsAsDependencies()
|
||||
|
||||
irLinker.postProcess()
|
||||
irLinker.checkNoUnboundSymbols(symbolTable, "at the end of IR linkage process")
|
||||
|
||||
allModules.forEach {
|
||||
collectNativeImplementations(context, it)
|
||||
moveBodilessDeclarationsToSeparatePlace(context, it)
|
||||
context = JsIrBackendContext(
|
||||
mainModule.descriptor,
|
||||
irBuiltIns,
|
||||
symbolTable,
|
||||
mainModule,
|
||||
exportedDeclarations,
|
||||
keep = emptySet(),
|
||||
configuration = configuration,
|
||||
es6mode = es6mode,
|
||||
icCompatibleIr2Js = IcCompatibleIr2Js.IC_MODE,
|
||||
)
|
||||
}
|
||||
|
||||
generateJsTests(context, mainModule)
|
||||
override fun compile(
|
||||
allModules: Collection<IrModuleFragment>,
|
||||
dirtyFiles: Collection<IrFile>,
|
||||
mainArguments: List<String>?
|
||||
): List<JsIrFragmentAndBinaryAst> {
|
||||
allModules.forEach {
|
||||
collectNativeImplementations(context, it)
|
||||
moveBodilessDeclarationsToSeparatePlace(context, it)
|
||||
}
|
||||
|
||||
lowerPreservingTags(allModules, context, PhaseConfig(jsPhases), symbolTable.irFactory.stageController as WholeWorldStageController)
|
||||
generateJsTests(context, mainModule)
|
||||
|
||||
val transformer = IrModuleToJsTransformerTmp(context, mainArguments)
|
||||
return transformer.generateBinaryAst(filesToLower, allModules)
|
||||
lowerPreservingTags(allModules, context, PhaseConfig(jsPhases), context.irFactory.stageController as WholeWorldStageController)
|
||||
|
||||
val transformer = IrModuleToJsTransformerTmp(context, mainArguments)
|
||||
return transformer.generateBinaryAst(dirtyFiles, allModules)
|
||||
}
|
||||
}
|
||||
|
||||
fun lowerPreservingTags(
|
||||
modules: Iterable<IrModuleFragment>,
|
||||
context: JsIrBackendContext,
|
||||
phaseConfig: PhaseConfig,
|
||||
controller: WholeWorldStageController
|
||||
modules: Iterable<IrModuleFragment>, context: JsIrBackendContext, phaseConfig: PhaseConfig, controller: WholeWorldStageController
|
||||
) {
|
||||
// Lower all the things
|
||||
controller.currentStage = 0
|
||||
|
||||
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.ir.backend.js.*
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker
|
||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsIrFragmentAndBinaryAst
|
||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.safeModuleName
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
@@ -22,19 +21,21 @@ import org.jetbrains.kotlin.name.FqName
|
||||
import java.io.File
|
||||
import java.util.EnumSet
|
||||
|
||||
|
||||
fun interface CacheExecutor {
|
||||
fun execute(
|
||||
mainModule: IrModuleFragment,
|
||||
fun interface JsIrCompilerICInterface {
|
||||
fun compile(
|
||||
allModules: Collection<IrModuleFragment>,
|
||||
irLinker: JsIrLinker,
|
||||
configuration: CompilerConfiguration,
|
||||
dirtyFiles: Collection<IrFile>,
|
||||
exportedDeclarations: Set<FqName>,
|
||||
mainArguments: List<String>?
|
||||
): List<JsIrFragmentAndBinaryAst>
|
||||
}
|
||||
|
||||
fun interface JsIrCompilerICInterfaceFactory {
|
||||
fun createCompilerForIC(
|
||||
mainModule: IrModuleFragment,
|
||||
configuration: CompilerConfiguration
|
||||
): JsIrCompilerICInterface
|
||||
}
|
||||
|
||||
enum class DirtyFileState(val str: String) {
|
||||
ADDED_FILE("added file"),
|
||||
MODIFIED_CONFIG("modified config"),
|
||||
@@ -53,7 +54,7 @@ class CacheUpdater(
|
||||
private val compilerConfiguration: CompilerConfiguration,
|
||||
private val irFactory: () -> IrFactory,
|
||||
private val mainArguments: List<String>?,
|
||||
private val executor: CacheExecutor
|
||||
private val compilerInterfaceFactory: JsIrCompilerICInterfaceFactory
|
||||
) {
|
||||
private val signatureHashCalculator = IdSignatureHashCalculator()
|
||||
|
||||
@@ -323,47 +324,84 @@ class CacheUpdater(
|
||||
return allSignatures
|
||||
}
|
||||
|
||||
private fun IdSignatureHashCalculator.addAllSignatureSymbols(idSignatureToFile: Map<IdSignature, SignatureSource>) {
|
||||
for ((signature, signatureSrc) in idSignatureToFile) {
|
||||
addHashForSignatureIfNotExist(signature, signatureSrc.symbol)
|
||||
}
|
||||
}
|
||||
|
||||
private fun KotlinSourceFileMutableMap<DirtyFileMetadata>.getExportedSignaturesAndAddMetadata(
|
||||
jsIrLinker: JsIrLinker,
|
||||
irModule: IrModuleFragment,
|
||||
libFile: KotlinLibraryFile,
|
||||
dirtySrcFiles: Set<KotlinSourceFile>
|
||||
): Map<IdSignature, SignatureSource> {
|
||||
val idSignatureToFile = hashMapOf<IdSignature, SignatureSource>()
|
||||
val moduleDeserializer = jsIrLinker.moduleDeserializer(irModule.descriptor)
|
||||
val incrementalCache = getLibIncrementalCache(libFile)
|
||||
for (fileDeserializer in moduleDeserializer.fileDeserializers()) {
|
||||
val reachableSignatures = fileDeserializer.symbolDeserializer.signatureDeserializer.signatureToIndexMapping()
|
||||
val maybeImportedSignatures = reachableSignatures.keys.toMutableSet()
|
||||
val implementedSymbols = collectImplementedSymbol(fileDeserializer.symbolDeserializer.deserializedSymbols)
|
||||
for ((signature, symbol) in implementedSymbols) {
|
||||
var symbolCanBeExported = maybeImportedSignatures.remove(signature)
|
||||
resolveFakeOverrideFunction(symbol)?.let { resolvedSignature ->
|
||||
if (resolvedSignature !in implementedSymbols) {
|
||||
maybeImportedSignatures.add(resolvedSignature)
|
||||
}
|
||||
symbolCanBeExported = true
|
||||
}
|
||||
if (symbolCanBeExported) {
|
||||
idSignatureToFile[signature] = SignatureSource(libFile, KotlinSourceFile(fileDeserializer.file), symbol)
|
||||
}
|
||||
}
|
||||
|
||||
val libSrcFile = KotlinSourceFile(fileDeserializer.file)
|
||||
if (libSrcFile in dirtySrcFiles) {
|
||||
val metadata = incrementalCache.fetchSourceFileFullMetadata(libSrcFile)
|
||||
this[libFile, libSrcFile] = DirtyFileMetadata(maybeImportedSignatures, metadata.directDependencies)
|
||||
}
|
||||
}
|
||||
return idSignatureToFile
|
||||
}
|
||||
|
||||
private fun DirtyFileMetadata.setAllDependencies(
|
||||
idSignatureToFile: Map<IdSignature, SignatureSource>,
|
||||
updatedMetadata: KotlinSourceFileMap<DirtyFileMetadata>,
|
||||
libFile: KotlinLibraryFile,
|
||||
srcFile: KotlinSourceFile
|
||||
) {
|
||||
val allImportedSignatures = addParentSignatures(maybeImportedSignatures, idSignatureToFile, libFile, srcFile)
|
||||
for (importedSignature in allImportedSignatures) {
|
||||
val (dependencyLib, dependencyFile) = idSignatureToFile[importedSignature] ?: continue
|
||||
signatureHashCalculator[importedSignature]?.also { signatureHash ->
|
||||
addDirectDependency(dependencyLib, dependencyFile, importedSignature, signatureHash)
|
||||
} ?: notFoundIcError("signature $importedSignature hash", dependencyLib, dependencyFile)
|
||||
|
||||
updatedMetadata[dependencyLib, dependencyFile]?.also { dependencyMetadata ->
|
||||
dependencyMetadata.addInverseDependency(libFile, srcFile, importedSignature)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun rebuildDirtySourceMetadata(
|
||||
jsIrLinker: JsIrLinker,
|
||||
loadedFragments: Map<KotlinLibraryFile, IrModuleFragment>,
|
||||
dirtySrcFiles: KotlinSourceFileMap<KotlinSourceFileExports>,
|
||||
): KotlinSourceFileMap<DirtyFileMetadata> {
|
||||
val idSignatureToFile = mutableMapOf<IdSignature, SignatureSource>()
|
||||
val idSignatureToFile = hashMapOf<IdSignature, SignatureSource>()
|
||||
val updatedMetadata = KotlinSourceFileMutableMap<DirtyFileMetadata>()
|
||||
|
||||
for ((lib, irModule) in loadedFragments) {
|
||||
val moduleDeserializer = jsIrLinker.moduleDeserializer(irModule.descriptor)
|
||||
val incrementalCache = getLibIncrementalCache(lib)
|
||||
for (fileDeserializer in moduleDeserializer.fileDeserializers()) {
|
||||
val libSrcFile = KotlinSourceFile(fileDeserializer.file)
|
||||
|
||||
val reachableSignatures = fileDeserializer.symbolDeserializer.signatureDeserializer.signatureToIndexMapping()
|
||||
val maybeImportedSignatures = reachableSignatures.keys.toMutableSet()
|
||||
val implementedSymbols = collectImplementedSymbol(fileDeserializer.symbolDeserializer.deserializedSymbols)
|
||||
for ((signature, symbol) in implementedSymbols) {
|
||||
var symbolCanBeExported = maybeImportedSignatures.remove(signature)
|
||||
resolveFakeOverrideFunction(symbol)?.let { resolvedSignature ->
|
||||
if (resolvedSignature !in implementedSymbols) {
|
||||
maybeImportedSignatures.add(resolvedSignature)
|
||||
}
|
||||
symbolCanBeExported = true
|
||||
}
|
||||
if (symbolCanBeExported) {
|
||||
signatureHashCalculator.addHashForSignatureIfNotExist(signature, symbol)
|
||||
idSignatureToFile[signature] = SignatureSource(lib, libSrcFile, symbol)
|
||||
}
|
||||
}
|
||||
|
||||
if (dirtySrcFiles[lib, libSrcFile] != null) {
|
||||
val metadata = incrementalCache.fetchSourceFileFullMetadata(libSrcFile)
|
||||
updatedMetadata[lib, libSrcFile] = DirtyFileMetadata(maybeImportedSignatures, metadata.directDependencies)
|
||||
}
|
||||
}
|
||||
val libDirtySrcFiles = dirtySrcFiles[lib]?.keys ?: emptySet()
|
||||
idSignatureToFile += updatedMetadata.getExportedSignaturesAndAddMetadata(jsIrLinker, irModule, lib, libDirtySrcFiles)
|
||||
}
|
||||
|
||||
signatureHashCalculator.addAllSignatureSymbols(idSignatureToFile)
|
||||
|
||||
for ((libFile, srcFiles) in updatedMetadata) {
|
||||
val libDirtySrcFiles = dirtySrcFiles[libFile] ?: continue
|
||||
for ((srcFile, internalHeader) in srcFiles) {
|
||||
for ((srcFile, updatedHeader) in srcFiles) {
|
||||
val dirtySrcFile = libDirtySrcFiles[srcFile] ?: continue
|
||||
dirtySrcFile.inverseDependencies.forEachFile { dependentLibFile, dependentSrcFile, signatures ->
|
||||
signatures.forEach { signature ->
|
||||
@@ -376,17 +414,7 @@ class CacheUpdater(
|
||||
}
|
||||
}
|
||||
|
||||
val allImportedSignatures = addParentSignatures(internalHeader.maybeImportedSignatures, idSignatureToFile, libFile, srcFile)
|
||||
for (importedSignature in allImportedSignatures) {
|
||||
val (dependencyLib, dependencyFile) = idSignatureToFile[importedSignature] ?: continue
|
||||
signatureHashCalculator[importedSignature]?.also { signatureHash ->
|
||||
internalHeader.addDirectDependency(dependencyLib, dependencyFile, importedSignature, signatureHash)
|
||||
} ?: notFoundIcError("signature $importedSignature hash", dependencyLib, dependencyFile)
|
||||
|
||||
updatedMetadata[dependencyLib, dependencyFile]?.also { dependencyMetadata ->
|
||||
dependencyMetadata.addInverseDependency(libFile, srcFile, importedSignature)
|
||||
}
|
||||
}
|
||||
updatedHeader.setAllDependencies(idSignatureToFile, updatedMetadata, libFile, srcFile)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -561,6 +589,95 @@ class CacheUpdater(
|
||||
return artifacts
|
||||
}
|
||||
|
||||
private fun updateStdlibIntrinsicDependencies(
|
||||
linker: JsIrLinker,
|
||||
mainModule: IrModuleFragment,
|
||||
loadedFragments: Map<KotlinLibraryFile, IrModuleFragment>,
|
||||
dirtyFileExports: KotlinSourceFileMap<*>
|
||||
) {
|
||||
val stdlibDescriptor = mainModule.descriptor.builtIns.builtInsModule
|
||||
val (stdlibFile, stdlibIr) = loadedFragments.entries.find {
|
||||
it.value.descriptor === stdlibDescriptor
|
||||
} ?: notFoundIcError("stdlib loaded fragment")
|
||||
|
||||
val stdlibDirtyFiles = dirtyFileExports[stdlibFile]?.keys ?: return
|
||||
|
||||
signatureHashCalculator.updateInlineFunctionTransitiveHashes(listOf(stdlibIr))
|
||||
|
||||
val updatedMetadata = KotlinSourceFileMutableMap<DirtyFileMetadata>()
|
||||
val idSignatureToFile = updatedMetadata.getExportedSignaturesAndAddMetadata(linker, stdlibIr, stdlibFile, stdlibDirtyFiles)
|
||||
|
||||
signatureHashCalculator.addAllSignatureSymbols(idSignatureToFile)
|
||||
|
||||
updatedMetadata.forEachFile { libFile, srcFile, updatedHeader ->
|
||||
updatedHeader.setAllDependencies(idSignatureToFile, updatedMetadata, libFile, srcFile)
|
||||
}
|
||||
|
||||
val incrementalCache = getLibIncrementalCache(stdlibFile)
|
||||
updatedMetadata.forEachFile { libFile, srcFile, updatedHeader ->
|
||||
if (libFile != stdlibFile) {
|
||||
icError("unexpected lib while parsing stdlib dependencies", libFile, srcFile)
|
||||
}
|
||||
|
||||
val cachedHeader = incrementalCache.fetchSourceFileFullMetadata(srcFile)
|
||||
|
||||
val needUpdate = when {
|
||||
!updatedHeader.directDependencies.allFiles { lib, file, dependencies ->
|
||||
cachedHeader.directDependencies[lib, file]?.keys?.containsAll(dependencies.keys) ?: dependencies.isEmpty()
|
||||
} -> true
|
||||
|
||||
!updatedHeader.inverseDependencies.allFiles { lib, file, invDependencies ->
|
||||
cachedHeader.inverseDependencies[lib, file]?.containsAll(invDependencies) ?: invDependencies.isEmpty()
|
||||
} -> true
|
||||
|
||||
else -> false
|
||||
}
|
||||
if (needUpdate) {
|
||||
cachedHeader.directDependencies.forEachFile { lib, file, dependencies ->
|
||||
val updatedDependencies = updatedHeader.directDependencies[lib, file]
|
||||
if (updatedDependencies != null) {
|
||||
updatedDependencies += dependencies
|
||||
} else {
|
||||
updatedHeader.directDependencies[lib, file] = HashMap(dependencies)
|
||||
}
|
||||
}
|
||||
cachedHeader.inverseDependencies.forEachFile { lib, file, dependencies ->
|
||||
val updatedDependencies = updatedHeader.inverseDependencies[lib, file]
|
||||
if (updatedDependencies != null) {
|
||||
updatedDependencies += dependencies
|
||||
} else {
|
||||
updatedHeader.inverseDependencies[lib, file] = HashSet(dependencies)
|
||||
}
|
||||
}
|
||||
incrementalCache.updateSourceFileMetadata(srcFile, updatedHeader)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun compileDirtyFiles(
|
||||
linker: JsIrLinker,
|
||||
loadedFragments: Map<KotlinLibraryFile, IrModuleFragment>,
|
||||
dirtyFileExports: KotlinSourceFileMap<*>
|
||||
): List<JsIrFragmentAndBinaryAst> {
|
||||
val mainModule = loadedFragments[mainLibraryFile] ?: notFoundIcError("main lib loaded fragment", mainLibraryFile)
|
||||
val compilerForIC = compilerInterfaceFactory.createCompilerForIC(mainModule, compilerConfiguration)
|
||||
|
||||
// Load declarations referenced during `context` initialization
|
||||
linker.loadUnboundSymbols(true)
|
||||
|
||||
updateStdlibIntrinsicDependencies(linker, mainModule, loadedFragments, dirtyFileExports)
|
||||
|
||||
return compilerForIC.compile(
|
||||
allModules = loadedFragments.values,
|
||||
dirtyFiles = loadedFragments.flatMap { (libFile, libFragment) ->
|
||||
dirtyFileExports[libFile]?.let { libDirtyFiles ->
|
||||
libFragment.files.filter { file -> KotlinSourceFile(file) in libDirtyFiles }
|
||||
} ?: emptyList()
|
||||
},
|
||||
mainArguments = mainArguments
|
||||
)
|
||||
}
|
||||
|
||||
fun actualizeCaches(eventCallback: (String) -> Unit = {}): List<ModuleArtifact> {
|
||||
dirtyFileStats.clear()
|
||||
|
||||
@@ -601,19 +718,7 @@ class CacheUpdater(
|
||||
eventCallback("final loading of updated files")
|
||||
}
|
||||
|
||||
val rebuiltFragments = executor.execute(
|
||||
mainModule = loadedIr.loadedFragments[mainLibraryFile] ?: notFoundIcError("main lib loaded fragment", mainLibraryFile),
|
||||
allModules = loadedIr.loadedFragments.values,
|
||||
irLinker = loadedIr.linker,
|
||||
configuration = compilerConfiguration,
|
||||
dirtyFiles = loadedIr.loadedFragments.flatMap { (libFile, libFragment) ->
|
||||
dirtyFileExports[libFile]?.let { libDirtyFiles ->
|
||||
libFragment.files.filter { file -> KotlinSourceFile(file) in libDirtyFiles }
|
||||
} ?: emptyList()
|
||||
},
|
||||
exportedDeclarations = emptySet(),
|
||||
mainArguments = mainArguments
|
||||
)
|
||||
val rebuiltFragments = compileDirtyFiles(loadedIr.linker, loadedIr.loadedFragments, dirtyFileExports)
|
||||
eventCallback("updated files processing (lowering)")
|
||||
|
||||
val artifacts = buildModuleArtifactsAndCommitCache(loadedIr.linker, loadedIr.loadedFragments, rebuiltFragments)
|
||||
@@ -650,33 +755,14 @@ fun rebuildCacheForDirtyFiles(
|
||||
currentIrModule.files.filter { irFile -> irFile.fileEntry.name in files }
|
||||
} ?: currentIrModule.files
|
||||
|
||||
return currentIrModule to buildCacheForModuleFiles(
|
||||
mainModule = currentIrModule,
|
||||
val compilerWithIC = JsIrCompilerWithIC(currentIrModule, configuration, exportedDeclarations)
|
||||
|
||||
// Load declarations referenced during `context` initialization
|
||||
jsIrLinker.loadUnboundSymbols(true)
|
||||
|
||||
return currentIrModule to compilerWithIC.compile(
|
||||
allModules = irModules.values,
|
||||
irLinker = jsIrLinker,
|
||||
configuration = configuration,
|
||||
dirtyFiles = dirtyIrFiles,
|
||||
exportedDeclarations = exportedDeclarations,
|
||||
mainArguments = mainArguments
|
||||
)
|
||||
}
|
||||
|
||||
fun buildCacheForModuleFiles(
|
||||
mainModule: IrModuleFragment,
|
||||
allModules: Collection<IrModuleFragment>,
|
||||
irLinker: JsIrLinker,
|
||||
configuration: CompilerConfiguration,
|
||||
dirtyFiles: Collection<IrFile>,
|
||||
exportedDeclarations: Set<FqName>,
|
||||
mainArguments: List<String>?
|
||||
): List<JsIrFragmentAndBinaryAst> {
|
||||
return compileWithIC(
|
||||
mainModule = mainModule,
|
||||
allModules = allModules,
|
||||
filesToLower = dirtyFiles,
|
||||
configuration = configuration,
|
||||
irLinker = irLinker,
|
||||
mainArguments = mainArguments,
|
||||
exportedDeclarations = exportedDeclarations,
|
||||
)
|
||||
}
|
||||
|
||||
+9
-2
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.ir.backend.js.ic
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.serialization.DeserializationStrategy
|
||||
import org.jetbrains.kotlin.backend.common.serialization.linkerissues.checkNoUnboundSymbols
|
||||
import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
@@ -27,6 +28,13 @@ import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors
|
||||
import org.jetbrains.kotlin.psi2ir.generators.TypeTranslatorImpl
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
|
||||
internal fun JsIrLinker.loadUnboundSymbols(checkNoUnbound: Boolean) {
|
||||
ExternalDependenciesGenerator(symbolTable, listOf(this)).generateUnboundSymbolsAsDependencies()
|
||||
postProcess()
|
||||
if (checkNoUnbound) {
|
||||
checkNoUnboundSymbols(symbolTable, "at the end of IR linkage process")
|
||||
}
|
||||
}
|
||||
|
||||
internal class JsIrLinkerLoader(
|
||||
private val compilerConfiguration: CompilerConfiguration,
|
||||
@@ -109,8 +117,7 @@ internal class JsIrLinkerLoader(
|
||||
}
|
||||
}
|
||||
|
||||
ExternalDependenciesGenerator(jsIrLinker.symbolTable, listOf(jsIrLinker)).generateUnboundSymbolsAsDependencies()
|
||||
jsIrLinker.postProcess()
|
||||
jsIrLinker.loadUnboundSymbols(false)
|
||||
return LoadedJsIr(jsIrLinker, irModules)
|
||||
}
|
||||
}
|
||||
|
||||
+3
@@ -46,6 +46,9 @@ open class KotlinSourceFileMap<out T>(files: Map<KotlinLibraryFile, Map<KotlinSo
|
||||
inline fun forEachFile(f: (KotlinLibraryFile, KotlinSourceFile, T) -> Unit) =
|
||||
forEach { (lib, files) -> files.forEach { (file, data) -> f(lib, file, data) } }
|
||||
|
||||
inline fun allFiles(p: (KotlinLibraryFile, KotlinSourceFile, T) -> Boolean) =
|
||||
entries.all { (lib, files) -> files.entries.all { (file, data) -> p(lib, file, data) } }
|
||||
|
||||
operator fun get(libFile: KotlinLibraryFile, sourceFile: KotlinSourceFile): T? = get(libFile)?.get(sourceFile)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user