[Serializer] UniqId clashes handling

This commit is contained in:
Igor Chevdar
2019-06-24 16:32:18 +03:00
parent b62e9487d1
commit dff0ac8866
2 changed files with 24 additions and 5 deletions
@@ -243,7 +243,7 @@ abstract class KotlinIrLinker(
fileProto.declarationIdList.forEach { fileProto.declarationIdList.forEach {
val uniqIdKey = it.uniqIdKey(moduleDescriptor) val uniqIdKey = it.uniqIdKey(moduleDescriptor)
reversedFileIndex.put(uniqIdKey, file) reversedFileIndex.getOrPut(uniqIdKey) { mutableListOf() }.add(file)
} }
when (deserializationStrategy) { when (deserializationStrategy) {
@@ -299,16 +299,16 @@ abstract class KotlinIrLinker(
return codedInputStream return codedInputStream
} }
private val reversedFileIndex = mutableMapOf<UniqIdKey, IrFile>() private val reversedFileIndex = mutableMapOf<UniqIdKey, MutableList<IrFile>>()
private val UniqIdKey.moduleOfOrigin private val UniqIdKey.moduleOfOrigin
get() = get() =
this.moduleDescriptor ?: reversedFileIndex[this]?.packageFragmentDescriptor?.containingDeclaration this.moduleDescriptor ?: reversedFileIndex[this]?.handleClashes(this)?.packageFragmentDescriptor?.containingDeclaration
private fun deserializeTopLevelDeclaration(uniqIdKey: UniqIdKey): IrDeclaration { private fun deserializeTopLevelDeclaration(uniqIdKey: UniqIdKey): IrDeclaration {
val proto = loadTopLevelDeclarationProto(uniqIdKey) val proto = loadTopLevelDeclarationProto(uniqIdKey)
return deserializersForModules[uniqIdKey.moduleOfOrigin]!! return deserializersForModules[uniqIdKey.moduleOfOrigin]!!
.deserializeDeclaration(proto, reversedFileIndex[uniqIdKey]!!) .deserializeDeclaration(proto, reversedFileIndex[uniqIdKey]!!.handleClashes(uniqIdKey))
} }
protected abstract fun reader(moduleDescriptor: ModuleDescriptor, uniqId: UniqId): ByteArray protected abstract fun reader(moduleDescriptor: ModuleDescriptor, uniqId: UniqId): ByteArray
@@ -316,6 +316,14 @@ abstract class KotlinIrLinker(
protected abstract fun readType(moduleDescriptor: ModuleDescriptor, typeIndex: Int): ByteArray protected abstract fun readType(moduleDescriptor: ModuleDescriptor, typeIndex: Int): ByteArray
protected abstract fun readString(moduleDescriptor: ModuleDescriptor, stringIndex: Int): ByteArray protected abstract fun readString(moduleDescriptor: ModuleDescriptor, stringIndex: Int): ByteArray
protected open fun List<IrFile>.handleClashes(uniqIdKey: UniqIdKey): IrFile {
if (size == 1)
return this[0]
assert(size != 0)
error("UniqId clash: ${uniqIdKey.uniqId.index}. Found in the " +
"[${this.joinToString { it.packageFragmentDescriptor.containingDeclaration.name.asString() }}]")
}
private fun loadTopLevelDeclarationProto(uniqIdKey: UniqIdKey): KotlinIr.IrDeclaration { private fun loadTopLevelDeclarationProto(uniqIdKey: UniqIdKey): KotlinIr.IrDeclaration {
val stream = reader(uniqIdKey.moduleOfOrigin!!, uniqIdKey.uniqId).codedInputStream val stream = reader(uniqIdKey.moduleOfOrigin!!, uniqIdKey.uniqId).codedInputStream
return KotlinIr.IrDeclaration.parseFrom(stream, newInstance()) return KotlinIr.IrDeclaration.parseFrom(stream, newInstance())
@@ -358,7 +366,7 @@ abstract class KotlinIrLinker(
} }
val reachable = deserializeTopLevelDeclaration(key) val reachable = deserializeTopLevelDeclaration(key)
val file = reversedFileIndex[key]!! val file = reversedFileIndex[key]!!.handleClashes(key)
file.declarations.add(reachable) file.declarations.add(reachable)
deserializeFileAnnotationsIfFirstUse(moduleOfOrigin, file) deserializeFileAnnotationsIfFirstUse(moduleOfOrigin, file)
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.common.LoggingContext
import org.jetbrains.kotlin.backend.common.serialization.* import org.jetbrains.kotlin.backend.common.serialization.*
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.ir.backend.js.kotlinLibrary import org.jetbrains.kotlin.ir.backend.js.kotlinLibrary
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.ir.util.SymbolTable
@@ -45,6 +46,16 @@ class JsIrLinker(
override fun readString(moduleDescriptor: ModuleDescriptor, stringIndex: Int) = override fun readString(moduleDescriptor: ModuleDescriptor, stringIndex: Int) =
moduleDescriptor.kotlinLibrary.string(stringIndex) moduleDescriptor.kotlinLibrary.string(stringIndex)
override fun List<IrFile>.handleClashes(uniqIdKey: UniqIdKey): IrFile {
if (size == 1)
return this[0]
assert(size != 0)
error("UniqId clash: ${uniqIdKey.uniqId.index}. Found in the " +
"[${this.joinToString { it.packageFragmentDescriptor.containingDeclaration.userName }}]")
}
private val ModuleDescriptor.userName get() = kotlinLibrary.libraryFile.absolutePath
override fun declareForwardDeclarations() { override fun declareForwardDeclarations() {
// since for `knownBuiltIns` such as FunctionN it is possible to have unbound symbols after deserialization // since for `knownBuiltIns` such as FunctionN it is possible to have unbound symbols after deserialization
// reference them through out lazy symbol table // reference them through out lazy symbol table