[JS IR] Fix file name clashes during JS BE invalidation
This commit is contained in:
committed by
Space Team
parent
73bf7fa506
commit
ec71fe20e2
@@ -273,11 +273,11 @@ class CacheUpdater(
|
|||||||
symbolCanBeExported = true
|
symbolCanBeExported = true
|
||||||
}
|
}
|
||||||
if (symbolCanBeExported) {
|
if (symbolCanBeExported) {
|
||||||
idSignatureToFile[signature] = IdSignatureSource(libFile, fileSymbolProvider.irFile, symbol)
|
idSignatureToFile[signature] = IdSignatureSource(libFile, fileSymbolProvider, symbol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val libSrcFile = KotlinSourceFile(fileSymbolProvider.irFile)
|
val libSrcFile = fileSymbolProvider.srcFile
|
||||||
if (libSrcFile in dirtySrcFiles) {
|
if (libSrcFile in dirtySrcFiles) {
|
||||||
val metadata = incrementalCache.fetchSourceFileFullMetadata(libSrcFile)
|
val metadata = incrementalCache.fetchSourceFileFullMetadata(libSrcFile)
|
||||||
this[libFile, libSrcFile] = DirtyFileMetadata(maybeImportedSignatures, metadata.directDependencies)
|
this[libFile, libSrcFile] = DirtyFileMetadata(maybeImportedSignatures, metadata.directDependencies)
|
||||||
@@ -296,10 +296,10 @@ class CacheUpdater(
|
|||||||
for (importedSignature in allImportedSignatures) {
|
for (importedSignature in allImportedSignatures) {
|
||||||
val dependency = idSignatureToFile[importedSignature] ?: continue
|
val dependency = idSignatureToFile[importedSignature] ?: continue
|
||||||
signatureHashCalculator[importedSignature]?.also { signatureHash ->
|
signatureHashCalculator[importedSignature]?.also { signatureHash ->
|
||||||
addDirectDependency(dependency.lib, dependency.src, importedSignature, signatureHash)
|
addDirectDependency(dependency.lib, dependency.srcFile, importedSignature, signatureHash)
|
||||||
} ?: notFoundIcError("signature $importedSignature hash", dependency.lib, dependency.src)
|
} ?: notFoundIcError("signature $importedSignature hash", dependency.lib, dependency.srcFile)
|
||||||
|
|
||||||
updatedMetadata[dependency.lib, dependency.src]?.also { dependencyMetadata ->
|
updatedMetadata[dependency.lib, dependency.srcFile]?.also { dependencyMetadata ->
|
||||||
dependencyMetadata.addInverseDependency(libFile, srcFile, importedSignature)
|
dependencyMetadata.addInverseDependency(libFile, srcFile, importedSignature)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -328,7 +328,7 @@ class CacheUpdater(
|
|||||||
signatures.forEach { signature ->
|
signatures.forEach { signature ->
|
||||||
val signatureSrc = idSignatureToFile[signature]
|
val signatureSrc = idSignatureToFile[signature]
|
||||||
val dependencyLib = signatureSrc?.lib ?: libFile
|
val dependencyLib = signatureSrc?.lib ?: libFile
|
||||||
val dependencyFile = signatureSrc?.src ?: srcFile
|
val dependencyFile = signatureSrc?.srcFile ?: srcFile
|
||||||
updatedMetadata[dependencyLib, dependencyFile]?.also { dependencyMetadata ->
|
updatedMetadata[dependencyLib, dependencyFile]?.also { dependencyMetadata ->
|
||||||
dependencyMetadata.addInverseDependency(dependentLibFile, dependentSrcFile, signature)
|
dependencyMetadata.addInverseDependency(dependentLibFile, dependentSrcFile, signature)
|
||||||
}
|
}
|
||||||
@@ -590,14 +590,16 @@ class CacheUpdater(
|
|||||||
val libFile = KotlinLibraryFile(library)
|
val libFile = KotlinLibraryFile(library)
|
||||||
val incrementalCache = getLibIncrementalCache(libFile)
|
val incrementalCache = getLibIncrementalCache(libFile)
|
||||||
val providers = loadedIr.getSignatureProvidersForLib(libFile)
|
val providers = loadedIr.getSignatureProvidersForLib(libFile)
|
||||||
val signatureToIndexMapping = providers.associate { KotlinSourceFile(it.irFile) to it.getSignatureToIndexMapping() }
|
val signatureToIndexMapping = providers.associate { it.srcFile to it.getSignatureToIndexMapping() }
|
||||||
|
|
||||||
val cacheArtifact = incrementalCache.buildAndCommitCacheArtifact(signatureToIndexMapping, stubbedSignatures)
|
val cacheArtifact = incrementalCache.buildAndCommitCacheArtifact(signatureToIndexMapping, stubbedSignatures)
|
||||||
|
|
||||||
val libFragment = loadedIr.loadedFragments[libFile] ?: notFoundIcError("loaded fragment", libFile)
|
val libFragment = loadedIr.loadedFragments[libFile] ?: notFoundIcError("loaded fragment", libFile)
|
||||||
|
val sourceNames = loadedIr.getIrFileNames(libFragment)
|
||||||
val sourceFilesFromCache = cacheArtifact.getSourceFiles()
|
val sourceFilesFromCache = cacheArtifact.getSourceFiles()
|
||||||
for (irFile in libFragment.files) {
|
for (irFile in libFragment.files) {
|
||||||
if (KotlinSourceFile(irFile) !in sourceFilesFromCache) {
|
val srcName = sourceNames[irFile] ?: notFoundIcError("source file name", libFile, irFile)
|
||||||
|
if (srcName !in sourceFilesFromCache) {
|
||||||
// IC doesn't support cases when extra IrFiles (which don't exist in klib) are added into IrModuleFragment
|
// IC doesn't support cases when extra IrFiles (which don't exist in klib) are added into IrModuleFragment
|
||||||
icError("file ${irFile.fileEntry.name} is absent in incremental cache and klib", libFile)
|
icError("file ${irFile.fileEntry.name} is absent in incremental cache and klib", libFile)
|
||||||
}
|
}
|
||||||
@@ -623,16 +625,17 @@ class CacheUpdater(
|
|||||||
|
|
||||||
private fun compileDirtyFiles(
|
private fun compileDirtyFiles(
|
||||||
compilerForIC: JsIrCompilerICInterface,
|
compilerForIC: JsIrCompilerICInterface,
|
||||||
loadedFragments: Map<KotlinLibraryFile, IrModuleFragment>,
|
loadedIr: LoadedJsIr,
|
||||||
dirtyFiles: Map<KotlinLibraryFile, Set<KotlinSourceFile>>
|
dirtyFiles: Map<KotlinLibraryFile, Set<KotlinSourceFile>>
|
||||||
): MutableList<Triple<KotlinLibraryFile, KotlinSourceFile, () -> JsIrProgramFragments>> =
|
): MutableList<Triple<KotlinLibraryFile, KotlinSourceFile, () -> JsIrProgramFragments>> =
|
||||||
stopwatch.measure("Processing IR - lowering") {
|
stopwatch.measure("Processing IR - lowering") {
|
||||||
val dirtyFilesForCompiling = mutableListOf<IrFile>()
|
val dirtyFilesForCompiling = mutableListOf<IrFile>()
|
||||||
val dirtyFilesForRestoring = mutableListOf<Pair<KotlinLibraryFile, KotlinSourceFile>>()
|
val dirtyFilesForRestoring = mutableListOf<Pair<KotlinLibraryFile, KotlinSourceFile>>()
|
||||||
for ((libFile, libFragment) in loadedFragments) {
|
for ((libFile, libFragment) in loadedIr.loadedFragments) {
|
||||||
val dirtySrcFiles = dirtyFiles[libFile] ?: continue
|
val dirtySrcFiles = dirtyFiles[libFile] ?: continue
|
||||||
|
val sourceNames = loadedIr.getIrFileNames(libFragment)
|
||||||
for (irFile in libFragment.files) {
|
for (irFile in libFragment.files) {
|
||||||
val srcFile = KotlinSourceFile(irFile)
|
val srcFile = sourceNames[irFile] ?: notFoundIcError("source file name", libFile, irFile)
|
||||||
if (srcFile in dirtySrcFiles) {
|
if (srcFile in dirtySrcFiles) {
|
||||||
dirtyFilesForCompiling += irFile
|
dirtyFilesForCompiling += irFile
|
||||||
dirtyFilesForRestoring += libFile to srcFile
|
dirtyFilesForRestoring += libFile to srcFile
|
||||||
@@ -640,7 +643,7 @@ class CacheUpdater(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val fragmentGenerators = compilerForIC.compile(loadedFragments.values, dirtyFilesForCompiling)
|
val fragmentGenerators = compilerForIC.compile(loadedIr.loadedFragments.values, dirtyFilesForCompiling)
|
||||||
|
|
||||||
dirtyFilesForRestoring.mapIndexedTo(ArrayList(dirtyFilesForRestoring.size)) { i, libFileAndSrcFile ->
|
dirtyFilesForRestoring.mapIndexedTo(ArrayList(dirtyFilesForRestoring.size)) { i, libFileAndSrcFile ->
|
||||||
Triple(libFileAndSrcFile.first, libFileAndSrcFile.second, fragmentGenerators[i])
|
Triple(libFileAndSrcFile.first, libFileAndSrcFile.second, fragmentGenerators[i])
|
||||||
@@ -649,7 +652,7 @@ class CacheUpdater(
|
|||||||
|
|
||||||
private data class IrForDirtyFilesAndCompiler(
|
private data class IrForDirtyFilesAndCompiler(
|
||||||
val incrementalCacheArtifacts: Map<KotlinLibraryFile, IncrementalCacheArtifact>,
|
val incrementalCacheArtifacts: Map<KotlinLibraryFile, IncrementalCacheArtifact>,
|
||||||
val loadedFragments: Map<KotlinLibraryFile, IrModuleFragment>,
|
val loadedIr: LoadedJsIr,
|
||||||
val dirtyFiles: Map<KotlinLibraryFile, Set<KotlinSourceFile>>,
|
val dirtyFiles: Map<KotlinLibraryFile, Set<KotlinSourceFile>>,
|
||||||
val irCompiler: JsIrCompilerICInterface
|
val irCompiler: JsIrCompilerICInterface
|
||||||
)
|
)
|
||||||
@@ -726,7 +729,7 @@ class CacheUpdater(
|
|||||||
val incrementalCachesArtifacts = updater.buildAndCommitCacheArtifacts(loadedIr)
|
val incrementalCachesArtifacts = updater.buildAndCommitCacheArtifacts(loadedIr)
|
||||||
|
|
||||||
stopwatch.stop()
|
stopwatch.stop()
|
||||||
return IrForDirtyFilesAndCompiler(incrementalCachesArtifacts, loadedIr.loadedFragments, dirtyFiles, compilerForIC)
|
return IrForDirtyFilesAndCompiler(incrementalCachesArtifacts, loadedIr, dirtyFiles, compilerForIC)
|
||||||
}
|
}
|
||||||
|
|
||||||
private data class FragmentGenerators(
|
private data class FragmentGenerators(
|
||||||
@@ -736,11 +739,11 @@ class CacheUpdater(
|
|||||||
)
|
)
|
||||||
|
|
||||||
private fun loadIrAndMakeIrFragmentGenerators(): FragmentGenerators {
|
private fun loadIrAndMakeIrFragmentGenerators(): FragmentGenerators {
|
||||||
val (incrementalCachesArtifacts, irFragments, dirtyFiles, irCompiler) = loadIrForDirtyFilesAndInitCompiler()
|
val (incrementalCachesArtifacts, loadedIr, dirtyFiles, irCompiler) = loadIrForDirtyFilesAndInitCompiler()
|
||||||
|
|
||||||
val moduleNames = irFragments.entries.associate { it.key to it.value.name.asString() }
|
val moduleNames = loadedIr.loadedFragments.entries.associate { it.key to it.value.name.asString() }
|
||||||
|
|
||||||
val rebuiltFragmentGenerators = compileDirtyFiles(irCompiler, irFragments, dirtyFiles)
|
val rebuiltFragmentGenerators = compileDirtyFiles(irCompiler, loadedIr, dirtyFiles)
|
||||||
|
|
||||||
return FragmentGenerators(incrementalCachesArtifacts, moduleNames, rebuiltFragmentGenerators)
|
return FragmentGenerators(incrementalCachesArtifacts, moduleNames, rebuiltFragmentGenerators)
|
||||||
}
|
}
|
||||||
@@ -784,7 +787,9 @@ fun rebuildCacheForDirtyFiles(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val libFile = KotlinLibraryFile(library)
|
val libFile = KotlinLibraryFile(library)
|
||||||
val dirtySrcFiles = dirtyFiles?.memoryOptimizedMap { KotlinSourceFile(it) } ?: KotlinLoadedLibraryHeader(library, internationService).sourceFileFingerprints.keys
|
val dirtySrcFiles = dirtyFiles?.let {
|
||||||
|
KotlinSourceFile.fromSources(it.toList())
|
||||||
|
} ?: KotlinLoadedLibraryHeader(library, internationService).sourceFileFingerprints.keys
|
||||||
|
|
||||||
val modifiedFiles = mapOf(libFile to dirtySrcFiles.associateWith { emptyMetadata })
|
val modifiedFiles = mapOf(libFile to dirtySrcFiles.associateWith { emptyMetadata })
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.backend.js.ic
|
package org.jetbrains.kotlin.ir.backend.js.ic
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
import org.jetbrains.kotlin.protobuf.CodedInputStream
|
import org.jetbrains.kotlin.protobuf.CodedInputStream
|
||||||
import org.jetbrains.kotlin.protobuf.CodedOutputStream
|
import org.jetbrains.kotlin.protobuf.CodedOutputStream
|
||||||
@@ -43,8 +44,8 @@ internal inline fun <T> CodedInputStream.ifTrue(then: () -> T): T? {
|
|||||||
return if (readBool()) then() else null
|
return if (readBool()) then() else null
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun icError(what: String, libFile: KotlinLibraryFile? = null, srcFile: KotlinSourceFile? = null): Nothing {
|
internal fun icError(what: String, libFile: KotlinLibraryFile? = null, srcFile: KotlinSourceFile? = null, irFile: IrFile? = null): Nothing {
|
||||||
val filePath = listOfNotNull(libFile?.path, srcFile?.path).joinToString(":") { File(it).name }
|
val filePath = listOfNotNull(libFile?.path, (srcFile?.path ?: irFile?.fileEntry?.name)).joinToString(":") { File(it).name }
|
||||||
val msg = if (filePath.isEmpty()) what else "$what for $filePath"
|
val msg = if (filePath.isEmpty()) what else "$what for $filePath"
|
||||||
error("IC internal error: $msg")
|
error("IC internal error: $msg")
|
||||||
}
|
}
|
||||||
@@ -53,6 +54,10 @@ internal fun notFoundIcError(what: String, libFile: KotlinLibraryFile? = null, s
|
|||||||
icError("can not find $what", libFile, srcFile)
|
icError("can not find $what", libFile, srcFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun notFoundIcError(what: String, libFile: KotlinLibraryFile, irFile: IrFile): Nothing {
|
||||||
|
icError("can not find $what", libFile, irFile = irFile)
|
||||||
|
}
|
||||||
|
|
||||||
internal inline fun <E> buildSetUntil(to: Int, builderAction: MutableSet<E>.(Int) -> Unit): Set<E> {
|
internal inline fun <E> buildSetUntil(to: Int, builderAction: MutableSet<E>.(Int) -> Unit): Set<E> {
|
||||||
return newHashSetWithExpectedSize<E>(to).apply { repeat(to) { builderAction(it) } }
|
return newHashSetWithExpectedSize<E>(to).apply { repeat(to) { builderAction(it) } }
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -88,7 +88,7 @@ internal class IdSignatureHashCalculator(private val icHasher: ICHasher) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun IrSymbol.calculateSymbolHash(): ICHash {
|
private fun IrSymbol.calculateSymbolHash(): ICHash {
|
||||||
var srcIrFile = signature?.let { sig -> idSignatureSources[sig]?.srcIrFile }
|
var srcIrFile = signature?.let { sig -> idSignatureSources[sig]?.irFile }
|
||||||
if (srcIrFile == null) {
|
if (srcIrFile == null) {
|
||||||
var parentDeclaration = (owner as? IrDeclaration)?.parent
|
var parentDeclaration = (owner as? IrDeclaration)?.parent
|
||||||
while (parentDeclaration is IrDeclaration) {
|
while (parentDeclaration is IrDeclaration) {
|
||||||
|
|||||||
+10
-7
@@ -14,11 +14,14 @@ import org.jetbrains.kotlin.ir.util.resolveFakeOverride
|
|||||||
|
|
||||||
internal class IdSignatureSource(
|
internal class IdSignatureSource(
|
||||||
val lib: KotlinLibraryFile,
|
val lib: KotlinLibraryFile,
|
||||||
val srcIrFile: IrFile,
|
private val fileSignatureProvider: FileSignatureProvider,
|
||||||
val symbol: IrSymbol
|
val symbol: IrSymbol
|
||||||
) {
|
) {
|
||||||
val src: KotlinSourceFile
|
val irFile: IrFile
|
||||||
get() = KotlinSourceFile(srcIrFile)
|
get() = fileSignatureProvider.irFile
|
||||||
|
|
||||||
|
val srcFile: KotlinSourceFile
|
||||||
|
get() = fileSignatureProvider.srcFile
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun addParentSignatures(
|
internal fun addParentSignatures(
|
||||||
@@ -31,7 +34,7 @@ internal fun addParentSignatures(
|
|||||||
|
|
||||||
fun addAllParents(sig: IdSignature) {
|
fun addAllParents(sig: IdSignature) {
|
||||||
val signatureSrc = idSignatureToFile[sig] ?: return
|
val signatureSrc = idSignatureToFile[sig] ?: return
|
||||||
if (signatureSrc.lib == importerLibFile && signatureSrc.src == importerSrcFile) {
|
if (signatureSrc.lib == importerLibFile && signatureSrc.srcFile == importerSrcFile) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (allSignatures.add(sig)) {
|
if (allSignatures.add(sig)) {
|
||||||
@@ -100,12 +103,12 @@ private fun collectImplementedSymbol(deserializedSymbols: Map<IdSignature, IrSym
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal sealed class FileSignatureProvider(val irFile: IrFile) {
|
internal sealed class FileSignatureProvider(val irFile: IrFile, val srcFile: KotlinSourceFile) {
|
||||||
abstract fun getSignatureToIndexMapping(): Map<IdSignature, Int>
|
abstract fun getSignatureToIndexMapping(): Map<IdSignature, Int>
|
||||||
abstract fun getReachableSignatures(): Set<IdSignature>
|
abstract fun getReachableSignatures(): Set<IdSignature>
|
||||||
abstract fun getImplementedSymbols(): Map<IdSignature, IrSymbol>
|
abstract fun getImplementedSymbols(): Map<IdSignature, IrSymbol>
|
||||||
|
|
||||||
class DeserializedFromKlib(private val fileDeserializer: IrFileDeserializer) : FileSignatureProvider(fileDeserializer.file) {
|
class DeserializedFromKlib(private val fileDeserializer: IrFileDeserializer, srcFile: KotlinSourceFile) : FileSignatureProvider(fileDeserializer.file, srcFile) {
|
||||||
override fun getSignatureToIndexMapping(): Map<IdSignature, Int> {
|
override fun getSignatureToIndexMapping(): Map<IdSignature, Int> {
|
||||||
return fileDeserializer.symbolDeserializer.signatureDeserializer.signatureToIndexMapping()
|
return fileDeserializer.symbolDeserializer.signatureDeserializer.signatureToIndexMapping()
|
||||||
}
|
}
|
||||||
@@ -127,7 +130,7 @@ internal sealed class FileSignatureProvider(val irFile: IrFile) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class GeneratedFunctionTypeInterface(file: IrFile) : FileSignatureProvider(file) {
|
class GeneratedFunctionTypeInterface(file: IrFile, srcFile: KotlinSourceFile) : FileSignatureProvider(file, srcFile) {
|
||||||
private val allSignatures = run {
|
private val allSignatures = run {
|
||||||
val topLevelSymbols = buildMap {
|
val topLevelSymbols = buildMap {
|
||||||
for (declaration in irFile.declarations) {
|
for (declaration in irFile.declarations) {
|
||||||
|
|||||||
+1
-1
@@ -86,7 +86,7 @@ internal class IncrementalCache(private val library: KotlinLibraryHeader, val ca
|
|||||||
|
|
||||||
private fun KotlinSourceFile.getCacheFile(suffix: String): File {
|
private fun KotlinSourceFile.getCacheFile(suffix: String): File {
|
||||||
val pathHash = path.cityHash64String()
|
val pathHash = path.cityHash64String()
|
||||||
return File(cacheDir, "${File(path).name}.$pathHash.$suffix")
|
return File(cacheDir, "${File(path).name}.$id.$pathHash.$suffix")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun buildAndCommitCacheArtifact(
|
fun buildAndCommitCacheArtifact(
|
||||||
|
|||||||
+25
-9
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.backend.js.JsFactories
|
|||||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker
|
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerDesc
|
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerDesc
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFactory
|
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.IrModuleFragment
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrDescriptorBasedFunctionFactory
|
import org.jetbrains.kotlin.ir.descriptors.IrDescriptorBasedFunctionFactory
|
||||||
import org.jetbrains.kotlin.ir.linkage.partial.partialLinkageConfig
|
import org.jetbrains.kotlin.ir.linkage.partial.partialLinkageConfig
|
||||||
@@ -42,21 +43,25 @@ import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
|||||||
internal data class LoadedJsIr(
|
internal data class LoadedJsIr(
|
||||||
val loadedFragments: Map<KotlinLibraryFile, IrModuleFragment>,
|
val loadedFragments: Map<KotlinLibraryFile, IrModuleFragment>,
|
||||||
private val linker: JsIrLinker,
|
private val linker: JsIrLinker,
|
||||||
private val functionTypeInterfacePackages: FunctionTypeInterfacePackages
|
private val functionTypeInterfacePackages: FunctionTypeInterfacePackages,
|
||||||
) {
|
) {
|
||||||
private val signatureProvidersImpl = hashMapOf<KotlinLibraryFile, List<FileSignatureProvider>>()
|
private val signatureProvidersImpl = hashMapOf<KotlinLibraryFile, List<FileSignatureProvider>>()
|
||||||
|
|
||||||
private fun collectSignatureProviders(irModule: IrModuleFragment): List<FileSignatureProvider> {
|
private val irFileSourceNames = hashMapOf<IrModuleFragment, Map<IrFile, KotlinSourceFile>>()
|
||||||
|
|
||||||
|
private fun collectSignatureProviders(lib: KotlinLibraryFile, irModule: IrModuleFragment): List<FileSignatureProvider> {
|
||||||
val moduleDeserializer = linker.moduleDeserializer(irModule.descriptor)
|
val moduleDeserializer = linker.moduleDeserializer(irModule.descriptor)
|
||||||
val deserializers = moduleDeserializer.fileDeserializers()
|
val deserializers = moduleDeserializer.fileDeserializers()
|
||||||
val providers = ArrayList<FileSignatureProvider>(deserializers.size)
|
val providers = ArrayList<FileSignatureProvider>(deserializers.size)
|
||||||
|
val sourceFiles = getIrFileNames(irModule)
|
||||||
|
|
||||||
for (fileDeserializer in deserializers) {
|
for (fileDeserializer in deserializers) {
|
||||||
val irFile = fileDeserializer.file
|
val irFile = fileDeserializer.file
|
||||||
|
val sourceFile = sourceFiles[irFile] ?: notFoundIcError("source file name", lib, irFile)
|
||||||
if (functionTypeInterfacePackages.isFunctionTypeInterfacePackageFile(irFile)) {
|
if (functionTypeInterfacePackages.isFunctionTypeInterfacePackageFile(irFile)) {
|
||||||
providers += FileSignatureProvider.GeneratedFunctionTypeInterface(irFile)
|
providers += FileSignatureProvider.GeneratedFunctionTypeInterface(irFile, sourceFile)
|
||||||
} else {
|
} else {
|
||||||
providers += FileSignatureProvider.DeserializedFromKlib(fileDeserializer)
|
providers += FileSignatureProvider.DeserializedFromKlib(fileDeserializer, sourceFile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,7 +71,7 @@ internal data class LoadedJsIr(
|
|||||||
fun getSignatureProvidersForLib(lib: KotlinLibraryFile): List<FileSignatureProvider> {
|
fun getSignatureProvidersForLib(lib: KotlinLibraryFile): List<FileSignatureProvider> {
|
||||||
return signatureProvidersImpl.getOrPut(lib) {
|
return signatureProvidersImpl.getOrPut(lib) {
|
||||||
val irFragment = loadedFragments[lib] ?: notFoundIcError("loaded fragment", lib)
|
val irFragment = loadedFragments[lib] ?: notFoundIcError("loaded fragment", lib)
|
||||||
collectSignatureProviders(irFragment)
|
collectSignatureProviders(lib, irFragment)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,6 +86,17 @@ internal data class LoadedJsIr(
|
|||||||
fun collectSymbolsReplacedWithStubs(): Set<IrSymbol> {
|
fun collectSymbolsReplacedWithStubs(): Set<IrSymbol> {
|
||||||
return linker.partialLinkageSupport.collectAllStubbedSymbols()
|
return linker.partialLinkageSupport.collectAllStubbedSymbols()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getIrFileNames(fragment: IrModuleFragment): Map<IrFile, KotlinSourceFile> {
|
||||||
|
return irFileSourceNames.getOrPut(fragment) {
|
||||||
|
val files = linker.getDeserializedFilesInKlibOrder(fragment)
|
||||||
|
val names = files.map { it.fileEntry.name }
|
||||||
|
val sourceFiles = KotlinSourceFile.fromSources(names)
|
||||||
|
files.indices.associate {
|
||||||
|
files[it] to sourceFiles[it]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class JsIrLinkerLoader(
|
internal class JsIrLinkerLoader(
|
||||||
@@ -88,7 +104,7 @@ internal class JsIrLinkerLoader(
|
|||||||
private val dependencyGraph: Map<KotlinLibrary, List<KotlinLibrary>>,
|
private val dependencyGraph: Map<KotlinLibrary, List<KotlinLibrary>>,
|
||||||
private val mainModuleFriends: Collection<KotlinLibrary>,
|
private val mainModuleFriends: Collection<KotlinLibrary>,
|
||||||
private val irFactory: IrFactory,
|
private val irFactory: IrFactory,
|
||||||
private val stubbedSignatures: Set<IdSignature>
|
private val stubbedSignatures: Set<IdSignature>,
|
||||||
) {
|
) {
|
||||||
private val mainLibrary = dependencyGraph.keys.lastOrNull() ?: notFoundIcError("main library")
|
private val mainLibrary = dependencyGraph.keys.lastOrNull() ?: notFoundIcError("main library")
|
||||||
|
|
||||||
@@ -97,7 +113,7 @@ internal class JsIrLinkerLoader(
|
|||||||
val symbolTable: SymbolTable,
|
val symbolTable: SymbolTable,
|
||||||
val typeTranslator: TypeTranslatorImpl,
|
val typeTranslator: TypeTranslatorImpl,
|
||||||
val irBuiltIns: IrBuiltInsOverDescriptors,
|
val irBuiltIns: IrBuiltInsOverDescriptors,
|
||||||
val linker: JsIrLinker
|
val linker: JsIrLinker,
|
||||||
) {
|
) {
|
||||||
val functionTypeInterfacePackages = FunctionTypeInterfacePackages()
|
val functionTypeInterfacePackages = FunctionTypeInterfacePackages()
|
||||||
|
|
||||||
@@ -183,9 +199,9 @@ internal class JsIrLinkerLoader(
|
|||||||
module == mainLibrary -> DeserializationStrategy.ALL
|
module == mainLibrary -> DeserializationStrategy.ALL
|
||||||
else -> DeserializationStrategy.EXPLICITLY_EXPORTED
|
else -> DeserializationStrategy.EXPLICITLY_EXPORTED
|
||||||
}
|
}
|
||||||
val modified = modifiedFiles[libraryFile] ?: emptyMap()
|
val modified = modifiedFiles[libraryFile]?.keys?.mapTo(hashSetOf()) { it.path } ?: emptySet()
|
||||||
libraryFile to linkerContext.linker.deserializeIrModuleHeader(descriptor, module, {
|
libraryFile to linkerContext.linker.deserializeIrModuleHeader(descriptor, module, {
|
||||||
when (KotlinSourceFile(it)) {
|
when (it) {
|
||||||
in modified -> modifiedStrategy
|
in modified -> modifiedStrategy
|
||||||
else -> DeserializationStrategy.WITH_INLINE_BODIES
|
else -> DeserializationStrategy.WITH_INLINE_BODIES
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -66,10 +66,11 @@ internal class KotlinLoadedLibraryHeader(
|
|||||||
|
|
||||||
private val sourceFiles by lazy(LazyThreadSafetyMode.NONE) {
|
private val sourceFiles by lazy(LazyThreadSafetyMode.NONE) {
|
||||||
val extReg = ExtensionRegistryLite.newInstance()
|
val extReg = ExtensionRegistryLite.newInstance()
|
||||||
Array(library.fileCount()) {
|
val sources = (0 until library.fileCount()).map {
|
||||||
val fileProto = IrFile.parseFrom(library.file(it).codedInputStream, extReg)
|
val fileProto = IrFile.parseFrom(library.file(it).codedInputStream, extReg)
|
||||||
KotlinSourceFile(fileProto.fileEntry.name)
|
fileProto.fileEntry.name
|
||||||
}
|
}
|
||||||
|
KotlinSourceFile.fromSources(sources)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+37
-10
@@ -26,18 +26,45 @@ value class KotlinLibraryFile(val path: String) {
|
|||||||
override fun toString(): String = File(path).name
|
override fun toString(): String = File(path).name
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmInline
|
class KotlinSourceFile private constructor(val path: String, val id: Int) {
|
||||||
value class KotlinSourceFile(val path: String) {
|
fun toProtoStream(out: CodedOutputStream) {
|
||||||
constructor(irFile: IrFile) : this(irFile.fileEntry.name)
|
out.writeStringNoTag(path)
|
||||||
|
out.writeInt32NoTag(id)
|
||||||
|
}
|
||||||
|
|
||||||
fun toProtoStream(out: CodedOutputStream) = out.writeStringNoTag(path)
|
override fun hashCode(): Int {
|
||||||
|
return path.hashCode() xor id
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
override fun equals(other: Any?): Boolean {
|
||||||
fun fromProtoStream(input: CodedInputStream) = KotlinSourceFile(input.readString())
|
return other is KotlinSourceFile && other.path == path && other.id == id
|
||||||
}
|
}
|
||||||
|
|
||||||
// for debugging purposes only
|
// for debugging purposes only
|
||||||
override fun toString(): String = File(path).name
|
override fun toString(): String = "${File(path).name}${if (id != 0) ".$id" else ""}"
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun fromProtoStream(input: CodedInputStream): KotlinSourceFile {
|
||||||
|
val path = input.readString()
|
||||||
|
val fileIndex = input.readInt32()
|
||||||
|
return KotlinSourceFile(path, fileIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Source file paths in one module may clash;
|
||||||
|
* for example, common and platform parts of the module could have files with the same root paths.
|
||||||
|
* @param sources is a list of the module sources and must be in the same order as they appear in the klib.
|
||||||
|
* @return a list of [KotlinSourceFile] containing the file path and the unique id in case of a clash
|
||||||
|
*/
|
||||||
|
fun fromSources(sources: List<String>): List<KotlinSourceFile> {
|
||||||
|
val counters = hashMapOf<String, Int>()
|
||||||
|
return sources.map { fileName ->
|
||||||
|
val id = counters[fileName] ?: 0
|
||||||
|
counters[fileName] = id + 1
|
||||||
|
KotlinSourceFile(fileName, id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open class KotlinSourceFileMap<out T>(files: Map<KotlinLibraryFile, Map<KotlinSourceFile, T>>) :
|
open class KotlinSourceFileMap<out T>(files: Map<KotlinLibraryFile, Map<KotlinSourceFile, T>>) :
|
||||||
@@ -54,7 +81,7 @@ open class KotlinSourceFileMap<out T>(files: Map<KotlinLibraryFile, Map<KotlinSo
|
|||||||
|
|
||||||
@Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE") // K2 warning suppression, TODO: KT-62472
|
@Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE") // K2 warning suppression, TODO: KT-62472
|
||||||
class KotlinSourceFileMutableMap<T>(
|
class KotlinSourceFileMutableMap<T>(
|
||||||
private val files: MutableMap<KotlinLibraryFile, MutableMap<KotlinSourceFile, T>> = hashMapOf()
|
private val files: MutableMap<KotlinLibraryFile, MutableMap<KotlinSourceFile, T>> = hashMapOf(),
|
||||||
) : KotlinSourceFileMap<T>(files) {
|
) : KotlinSourceFileMap<T>(files) {
|
||||||
|
|
||||||
operator fun set(libFile: KotlinLibraryFile, sourceFile: KotlinSourceFile, data: T) = getOrPutFiles(libFile).put(sourceFile, data)
|
operator fun set(libFile: KotlinLibraryFile, sourceFile: KotlinSourceFile, data: T) = getOrPutFiles(libFile).put(sourceFile, data)
|
||||||
@@ -126,7 +153,7 @@ internal class DirtyFileExports : KotlinSourceFileExports() {
|
|||||||
|
|
||||||
internal class DirtyFileMetadata(
|
internal class DirtyFileMetadata(
|
||||||
val maybeImportedSignatures: Collection<IdSignature>,
|
val maybeImportedSignatures: Collection<IdSignature>,
|
||||||
val oldDirectDependencies: KotlinSourceFileMap<*>
|
val oldDirectDependencies: KotlinSourceFileMap<*>,
|
||||||
) : KotlinSourceFileMetadata() {
|
) : KotlinSourceFileMetadata() {
|
||||||
override val inverseDependencies: KotlinSourceFileMutableMap<MutableSet<IdSignature>> = KotlinSourceFileMutableMap()
|
override val inverseDependencies: KotlinSourceFileMutableMap<MutableSet<IdSignature>> = KotlinSourceFileMutableMap()
|
||||||
override val directDependencies: KotlinSourceFileMutableMap<MutableMap<IdSignature, ICHash>> = KotlinSourceFileMutableMap()
|
override val directDependencies: KotlinSourceFileMutableMap<MutableMap<IdSignature, ICHash>> = KotlinSourceFileMutableMap()
|
||||||
@@ -161,7 +188,7 @@ internal class UpdatedDependenciesMetadata(oldMetadata: KotlinSourceFileMetadata
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun KotlinSourceFileMutableMap<UpdatedDependenciesMetadata>.addNewMetadata(
|
internal fun KotlinSourceFileMutableMap<UpdatedDependenciesMetadata>.addNewMetadata(
|
||||||
libFile: KotlinLibraryFile, srcFile: KotlinSourceFile, oldMetadata: KotlinSourceFileMetadata
|
libFile: KotlinLibraryFile, srcFile: KotlinSourceFile, oldMetadata: KotlinSourceFileMetadata,
|
||||||
) = this[libFile, srcFile] ?: UpdatedDependenciesMetadata(oldMetadata).also {
|
) = this[libFile, srcFile] ?: UpdatedDependenciesMetadata(oldMetadata).also {
|
||||||
this[libFile, srcFile] = it
|
this[libFile, srcFile] = it
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-1
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.backend.common.serialization.*
|
|||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.ir.IrBuiltIns
|
import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||||
import org.jetbrains.kotlin.ir.builders.TranslationPluginContext
|
import org.jetbrains.kotlin.ir.builders.TranslationPluginContext
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
import org.jetbrains.kotlin.ir.types.IrTypeSystemContextImpl
|
import org.jetbrains.kotlin.ir.types.IrTypeSystemContextImpl
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
@@ -18,6 +19,7 @@ import org.jetbrains.kotlin.library.IrLibrary
|
|||||||
import org.jetbrains.kotlin.library.KotlinAbiVersion
|
import org.jetbrains.kotlin.library.KotlinAbiVersion
|
||||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
import org.jetbrains.kotlin.library.containsErrorCode
|
import org.jetbrains.kotlin.library.containsErrorCode
|
||||||
|
import org.jetbrains.kotlin.utils.memoryOptimizedMap
|
||||||
|
|
||||||
class JsIrLinker(
|
class JsIrLinker(
|
||||||
private val currentModule: ModuleDescriptor?, messageLogger: IrMessageLogger, builtIns: IrBuiltIns, symbolTable: SymbolTable,
|
private val currentModule: ModuleDescriptor?, messageLogger: IrMessageLogger, builtIns: IrBuiltIns, symbolTable: SymbolTable,
|
||||||
@@ -67,8 +69,16 @@ class JsIrLinker(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val deserializedFilesInKlibOrder = mutableMapOf<IrModuleFragment, List<IrFile>>()
|
||||||
|
|
||||||
private inner class JsModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary, strategyResolver: (String) -> DeserializationStrategy, libraryAbiVersion: KotlinAbiVersion, allowErrorCode: Boolean) :
|
private inner class JsModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary, strategyResolver: (String) -> DeserializationStrategy, libraryAbiVersion: KotlinAbiVersion, allowErrorCode: Boolean) :
|
||||||
BasicIrModuleDeserializer(this, moduleDescriptor, klib, strategyResolver, libraryAbiVersion, allowErrorCode, false)
|
BasicIrModuleDeserializer(this, moduleDescriptor, klib, strategyResolver, libraryAbiVersion, allowErrorCode, true) {
|
||||||
|
|
||||||
|
override fun init(delegate: IrModuleDeserializer) {
|
||||||
|
super.init(delegate)
|
||||||
|
deserializedFilesInKlibOrder[moduleFragment] = fileDeserializationStates.memoryOptimizedMap { it.file }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun createCurrentModuleDeserializer(moduleFragment: IrModuleFragment, dependencies: Collection<IrModuleDeserializer>): IrModuleDeserializer {
|
override fun createCurrentModuleDeserializer(moduleFragment: IrModuleFragment, dependencies: Collection<IrModuleDeserializer>): IrModuleDeserializer {
|
||||||
val currentModuleDeserializer = super.createCurrentModuleDeserializer(moduleFragment, dependencies)
|
val currentModuleDeserializer = super.createCurrentModuleDeserializer(moduleFragment, dependencies)
|
||||||
@@ -91,6 +101,10 @@ class JsIrLinker(
|
|||||||
return deserializersForModules[moduleDescriptor.name.asString()] ?: error("Deserializer for $moduleDescriptor not found")
|
return deserializersForModules[moduleDescriptor.name.asString()] ?: error("Deserializer for $moduleDescriptor not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getDeserializedFilesInKlibOrder(fragment: IrModuleFragment): List<IrFile> {
|
||||||
|
return deserializedFilesInKlibOrder[fragment] ?: emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
class JsFePluginContext(
|
class JsFePluginContext(
|
||||||
override val moduleDescriptor: ModuleDescriptor,
|
override val moduleDescriptor: ModuleDescriptor,
|
||||||
override val symbolTable: ReferenceSymbolTable,
|
override val symbolTable: ReferenceSymbolTable,
|
||||||
|
|||||||
@@ -242,7 +242,7 @@ abstract class AbstractInvalidationTest(
|
|||||||
for ((srcFile, dirtyStats) in updateStatus) {
|
for ((srcFile, dirtyStats) in updateStatus) {
|
||||||
for (dirtyStat in dirtyStats) {
|
for (dirtyStat in dirtyStats) {
|
||||||
if (dirtyStat != DirtyFileState.NON_MODIFIED_IR) {
|
if (dirtyStat != DirtyFileState.NON_MODIFIED_IR) {
|
||||||
got.getOrPut(dirtyStat.str) { mutableSetOf() }.add(File(srcFile.path).name)
|
got.getOrPut(dirtyStat.str) { mutableSetOf() }.add(srcFile.toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user