[IR SERIALIZATION] Fix forward Declarations in deserializaer

This commit is contained in:
Roman Artemev
2019-08-15 17:17:26 +03:00
committed by romanart
parent 2bd3d90fe0
commit 0c7454c918
2 changed files with 24 additions and 14 deletions
@@ -32,7 +32,6 @@ import org.jetbrains.kotlin.ir.util.IrDeserializer
import org.jetbrains.kotlin.ir.util.NaiveSourceBasedFileEntryImpl import org.jetbrains.kotlin.ir.util.NaiveSourceBasedFileEntryImpl
import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite.newInstance import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite.newInstance
import org.jetbrains.kotlin.resolve.descriptorUtil.isPublishedApi
import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
@@ -107,7 +106,7 @@ abstract class KotlinIrLinker(
} }
} }
private val globalDeserializationState = DeserializationState.SimpleDeserializationState() protected val globalDeserializationState = DeserializationState.SimpleDeserializationState()
private val modulesWithReachableTopLevels = mutableSetOf<IrModuleDeserializer>() private val modulesWithReachableTopLevels = mutableSetOf<IrModuleDeserializer>()
//TODO: This is Native specific. Eliminate me. //TODO: This is Native specific. Eliminate me.
@@ -281,16 +280,15 @@ abstract class KotlinIrLinker(
descriptorReferenceDeserializer.checkIfSpecialDescriptorId(uniqId.index) descriptorReferenceDeserializer.checkIfSpecialDescriptorId(uniqId.index)
} }
private fun getModuleForTopLevelId(key: UniqId): IrModuleDeserializer { private fun getModuleForTopLevelId(key: UniqId): IrModuleDeserializer? {
if (key in moduleReversedFileIndex) return this@IrModuleDeserializer if (key in moduleReversedFileIndex) return this@IrModuleDeserializer
return moduleDependencies.firstOrNull { key in it.moduleReversedFileIndex } ?: return moduleDependencies.firstOrNull { key in it.moduleReversedFileIndex }
error("Deserializer for declaration $key is not found")
} }
private fun getStateForID(key: UniqId): DeserializationState { private fun getStateForID(key: UniqId): DeserializationState {
if (key.isLocal) return fileLocalDeserializationState if (key.isLocal) return fileLocalDeserializationState
if (isGlobalUniqID(key)) return globalDeserializationState if (isGlobalUniqID(key)) return globalDeserializationState
return getModuleForTopLevelId(key).moduleDeserializationState return getModuleForTopLevelId(key)?.moduleDeserializationState ?: handleNoModuleDeserializerFound(key)
} }
private fun deserializeIrSymbolData(proto: ProtoSymbolData): IrSymbol { private fun deserializeIrSymbolData(proto: ProtoSymbolData): IrSymbol {
@@ -316,9 +314,8 @@ abstract class KotlinIrLinker(
} }
resolvedForwardDeclarations[key]?.let { resolvedForwardDeclarations[key]?.let {
with (getForwardDeclararationModuleDeserializer().moduleDeserializationState) { val fdState = getStateForID(it)
if (it !in this) addUniqID(it) fdState.addUniqID(it)
}
} }
referenceDeserializedSymbol(proto, descriptor) referenceDeserializedSymbol(proto, descriptor)
@@ -513,6 +510,11 @@ abstract class KotlinIrLinker(
protected abstract fun readFile(moduleDescriptor: ModuleDescriptor, fileIndex: Int): ByteArray protected abstract fun readFile(moduleDescriptor: ModuleDescriptor, fileIndex: Int): ByteArray
protected abstract fun readFileCount(moduleDescriptor: ModuleDescriptor): Int protected abstract fun readFileCount(moduleDescriptor: ModuleDescriptor): Int
protected abstract fun checkAccessibility(declarationDescriptor: DeclarationDescriptor): Boolean
protected open fun handleNoModuleDeserializerFound(key: UniqId): DeserializationState {
error("Deserializer for declaration $key is not found")
}
private fun deserializeAllReachableTopLevels() { private fun deserializeAllReachableTopLevels() {
do { do {
val moduleDeserializer = modulesWithReachableTopLevels.first() val moduleDeserializer = modulesWithReachableTopLevels.first()
@@ -525,12 +527,13 @@ abstract class KotlinIrLinker(
private fun findDeserializedDeclarationForDescriptor(descriptor: DeclarationDescriptor): DeclarationDescriptor? { private fun findDeserializedDeclarationForDescriptor(descriptor: DeclarationDescriptor): DeclarationDescriptor? {
val topLevelDescriptor = descriptor.findTopLevelDescriptor() as DeclarationDescriptorWithVisibility val topLevelDescriptor = descriptor.findTopLevelDescriptor() as DeclarationDescriptorWithVisibility
require(topLevelDescriptor.isPublishedApi() || topLevelDescriptor.visibility.let { it.isPublicAPI || it == Visibilities.INTERNAL }) { // This is Native specific. Try to eliminate.
if (topLevelDescriptor.module.isForwardDeclarationModule) return null
require(checkAccessibility(topLevelDescriptor)) {
"Locally accessible declarations should not be accessed here $topLevelDescriptor" "Locally accessible declarations should not be accessed here $topLevelDescriptor"
} }
// This is Native specific. Try to eliminate.
if (topLevelDescriptor.module.isForwardDeclarationModule) return null
if (topLevelDescriptor !is DeserializedClassDescriptor && topLevelDescriptor !is DeserializedCallableMemberDescriptor) { if (topLevelDescriptor !is DeserializedClassDescriptor && topLevelDescriptor !is DeserializedCallableMemberDescriptor) {
return null return null
@@ -7,12 +7,14 @@ package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
import org.jetbrains.kotlin.backend.common.LoggingContext 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.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.Visibilities
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.util.SymbolTable import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.resolve.descriptorUtil.isPublishedApi
class JsIrLinker( class JsIrLinker(
currentModule: ModuleDescriptor, currentModule: ModuleDescriptor,
@@ -47,5 +49,10 @@ class JsIrLinker(
override fun readFileCount(moduleDescriptor: ModuleDescriptor) = override fun readFileCount(moduleDescriptor: ModuleDescriptor) =
moduleDescriptor.kotlinLibrary.fileCount() moduleDescriptor.kotlinLibrary.fileCount()
override fun checkAccessibility(declarationDescriptor: DeclarationDescriptor): Boolean {
require(declarationDescriptor is DeclarationDescriptorWithVisibility)
return declarationDescriptor.isPublishedApi() || declarationDescriptor.visibility.let { it.isPublicAPI || it == Visibilities.INTERNAL }
}
private val ModuleDescriptor.userName get() = kotlinLibrary.libraryFile.absolutePath private val ModuleDescriptor.userName get() = kotlinLibrary.libraryFile.absolutePath
} }