Do not set parent for deserialized IR declarations

This commit is contained in:
Georgy Bronnikov
2021-12-28 22:34:36 +03:00
committed by Alexander Udalov
parent 49bd3c1758
commit 0ef474a8d3
2 changed files with 50 additions and 48 deletions
@@ -239,6 +239,7 @@ class IrDeclarationDeserializer(
private inline fun <T> withDeserializedIrDeclarationBase( private inline fun <T> withDeserializedIrDeclarationBase(
proto: ProtoDeclarationBase, proto: ProtoDeclarationBase,
setParent: Boolean = true,
block: (IrSymbol, IdSignature, Int, Int, IrDeclarationOrigin, Long) -> T block: (IrSymbol, IdSignature, Int, Int, IrDeclarationOrigin, Long) -> T
): T where T : IrDeclaration, T : IrSymbolOwner { ): T where T : IrDeclaration, T : IrSymbolOwner {
val (s, uid) = symbolDeserializer.deserializeIrSymbolToDeclare(proto.symbol) val (s, uid) = symbolDeserializer.deserializeIrSymbolToDeclare(proto.symbol)
@@ -253,14 +254,17 @@ class IrDeclarationDeserializer(
) )
// avoid duplicate annotations for local variables // avoid duplicate annotations for local variables
result.annotations = deserializeAnnotations(proto.annotationList) result.annotations = deserializeAnnotations(proto.annotationList)
result.parent = currentParent if (setParent) {
result.parent = currentParent
}
return result return result
} finally { } finally {
eraseDelegatedSymbol(s) eraseDelegatedSymbol(s)
} }
} }
private fun deserializeIrTypeParameter(proto: ProtoTypeParameter, index: Int, isGlobal: Boolean): IrTypeParameter { private fun deserializeIrTypeParameter(proto: ProtoTypeParameter, index: Int, isGlobal: Boolean, setParent: Boolean = true):
IrTypeParameter {
val name = deserializeName(proto.name) val name = deserializeName(proto.name)
val coordinates = BinaryCoordinates.decode(proto.base.coordinates) val coordinates = BinaryCoordinates.decode(proto.base.coordinates)
val flags = TypeParameterFlags.decode(proto.base.flags) val flags = TypeParameterFlags.decode(proto.base.flags)
@@ -305,12 +309,12 @@ class IrDeclarationDeserializer(
// make sure this symbol is known to linker // make sure this symbol is known to linker
symbolDeserializer.referenceLocalIrSymbol(result.symbol, sig) symbolDeserializer.referenceLocalIrSymbol(result.symbol, sig)
result.annotations = deserializeAnnotations(proto.base.annotationList) result.annotations = deserializeAnnotations(proto.base.annotationList)
result.parent = currentParent if (setParent) result.parent = currentParent
return result return result
} }
private fun deserializeIrValueParameter(proto: ProtoValueParameter, index: Int): IrValueParameter = private fun deserializeIrValueParameter(proto: ProtoValueParameter, index: Int, setParent: Boolean = true): IrValueParameter =
withDeserializedIrDeclarationBase(proto.base) { symbol, _, startOffset, endOffset, origin, fcode -> withDeserializedIrDeclarationBase(proto.base, setParent) { symbol, _, startOffset, endOffset, origin, fcode ->
val flags = ValueParameterFlags.decode(fcode) val flags = ValueParameterFlags.decode(fcode)
val nameAndType = BinaryNameAndType.decode(proto.nameType) val nameAndType = BinaryNameAndType.decode(proto.nameType)
irFactory.createValueParameter( irFactory.createValueParameter(
@@ -331,8 +335,8 @@ class IrDeclarationDeserializer(
} }
} }
private fun deserializeIrClass(proto: ProtoClass): IrClass = private fun deserializeIrClass(proto: ProtoClass, setParent: Boolean = true): IrClass =
withDeserializedIrDeclarationBase(proto.base) { symbol, signature, startOffset, endOffset, origin, fcode -> withDeserializedIrDeclarationBase(proto.base, setParent) { symbol, signature, startOffset, endOffset, origin, fcode ->
checkSymbolType<IrClassSymbol>(symbol) checkSymbolType<IrClassSymbol>(symbol)
val flags = ClassFlags.decode(fcode) val flags = ClassFlags.decode(fcode)
@@ -411,8 +415,8 @@ class IrDeclarationDeserializer(
return InlineClassRepresentation(parameter.name, parameter.type as IrSimpleType) return InlineClassRepresentation(parameter.name, parameter.type as IrSimpleType)
} }
private fun deserializeIrTypeAlias(proto: ProtoTypeAlias): IrTypeAlias = private fun deserializeIrTypeAlias(proto: ProtoTypeAlias, setParent: Boolean = true): IrTypeAlias =
withDeserializedIrDeclarationBase(proto.base) { symbol, uniqId, startOffset, endOffset, origin, fcode -> withDeserializedIrDeclarationBase(proto.base, setParent) { symbol, uniqId, startOffset, endOffset, origin, fcode ->
checkSymbolType<IrTypeAliasSymbol>(symbol) checkSymbolType<IrTypeAliasSymbol>(symbol)
symbolTable.declareTypeAlias(uniqId, { symbol }) { symbolTable.declareTypeAlias(uniqId, { symbol }) {
val flags = TypeAliasFlags.decode(fcode) val flags = TypeAliasFlags.decode(fcode)
@@ -431,11 +435,11 @@ class IrDeclarationDeserializer(
} }
} }
private fun deserializeErrorDeclaration(proto: ProtoErrorDeclaration): IrErrorDeclaration { private fun deserializeErrorDeclaration(proto: ProtoErrorDeclaration, setParent: Boolean = true): IrErrorDeclaration {
checkErrorNodesAllowed<IrErrorDeclaration>(allowErrorNodes) checkErrorNodesAllowed<IrErrorDeclaration>(allowErrorNodes)
val coordinates = BinaryCoordinates.decode(proto.coordinates) val coordinates = BinaryCoordinates.decode(proto.coordinates)
return irFactory.createErrorDeclaration(coordinates.startOffset, coordinates.endOffset).also { return irFactory.createErrorDeclaration(coordinates.startOffset, coordinates.endOffset).also {
it.parent = currentParent if (setParent) it.parent = currentParent
} }
} }
@@ -548,8 +552,9 @@ class IrDeclarationDeserializer(
private inline fun <T : IrFunction> withDeserializedIrFunctionBase( private inline fun <T : IrFunction> withDeserializedIrFunctionBase(
proto: ProtoFunctionBase, proto: ProtoFunctionBase,
setParent: Boolean = true,
block: (IrFunctionSymbol, IdSignature, Int, Int, IrDeclarationOrigin, Long) -> T block: (IrFunctionSymbol, IdSignature, Int, Int, IrDeclarationOrigin, Long) -> T
): T = withDeserializedIrDeclarationBase(proto.base) { symbol, idSig, startOffset, endOffset, origin, fcode -> ): T = withDeserializedIrDeclarationBase(proto.base, setParent) { symbol, idSig, startOffset, endOffset, origin, fcode ->
symbolTable.withScope(symbol) { symbolTable.withScope(symbol) {
block(checkSymbolType(symbol), idSig, startOffset, endOffset, origin, fcode).usingParent { block(checkSymbolType(symbol), idSig, startOffset, endOffset, origin, fcode).usingParent {
typeParameters = deserializeTypeParameters(proto.typeParameterList, false) typeParameters = deserializeTypeParameters(proto.typeParameterList, false)
@@ -574,8 +579,8 @@ class IrDeclarationDeserializer(
} }
} }
internal fun deserializeIrFunction(proto: ProtoFunction): IrSimpleFunction { internal fun deserializeIrFunction(proto: ProtoFunction, setParent: Boolean = true): IrSimpleFunction {
return withDeserializedIrFunctionBase(proto.base) { symbol, idSig, startOffset, endOffset, origin, fcode -> return withDeserializedIrFunctionBase(proto.base, setParent) { symbol, idSig, startOffset, endOffset, origin, fcode ->
checkSymbolType<IrSimpleFunctionSymbol>(symbol) checkSymbolType<IrSimpleFunctionSymbol>(symbol)
val flags = FunctionFlags.decode(fcode) val flags = FunctionFlags.decode(fcode)
@@ -603,8 +608,8 @@ class IrDeclarationDeserializer(
} }
} }
fun deserializeIrVariable(proto: ProtoVariable): IrVariable = fun deserializeIrVariable(proto: ProtoVariable, setParent: Boolean = true): IrVariable =
withDeserializedIrDeclarationBase(proto.base) { symbol, _, startOffset, endOffset, origin, fcode -> withDeserializedIrDeclarationBase(proto.base, setParent) { symbol, _, startOffset, endOffset, origin, fcode ->
checkSymbolType<IrVariableSymbol>(symbol) checkSymbolType<IrVariableSymbol>(symbol)
val flags = LocalVariableFlags.decode(fcode) val flags = LocalVariableFlags.decode(fcode)
@@ -624,8 +629,8 @@ class IrDeclarationDeserializer(
} }
} }
private fun deserializeIrEnumEntry(proto: ProtoEnumEntry): IrEnumEntry = private fun deserializeIrEnumEntry(proto: ProtoEnumEntry, setParent: Boolean = true): IrEnumEntry =
withDeserializedIrDeclarationBase(proto.base) { symbol, uniqId, startOffset, endOffset, origin, _ -> withDeserializedIrDeclarationBase(proto.base, setParent) { symbol, uniqId, startOffset, endOffset, origin, _ ->
symbolTable.declareEnumEntry(uniqId, { checkSymbolType(symbol) }) { symbolTable.declareEnumEntry(uniqId, { checkSymbolType(symbol) }) {
irFactory.createEnumEntry(startOffset, endOffset, origin, it, deserializeName(proto.name)) irFactory.createEnumEntry(startOffset, endOffset, origin, it, deserializeName(proto.name))
}.apply { }.apply {
@@ -636,15 +641,15 @@ class IrDeclarationDeserializer(
} }
} }
private fun deserializeIrAnonymousInit(proto: ProtoAnonymousInit): IrAnonymousInitializer = private fun deserializeIrAnonymousInit(proto: ProtoAnonymousInit, setParent: Boolean = true): IrAnonymousInitializer =
withDeserializedIrDeclarationBase(proto.base) { symbol, _, startOffset, endOffset, origin, _ -> withDeserializedIrDeclarationBase(proto.base, setParent) { symbol, _, startOffset, endOffset, origin, _ ->
irFactory.createAnonymousInitializer(startOffset, endOffset, origin, checkSymbolType(symbol)).apply { irFactory.createAnonymousInitializer(startOffset, endOffset, origin, checkSymbolType(symbol)).apply {
body = deserializeStatementBody(proto.body) as IrBlockBody? ?: irFactory.createBlockBody(startOffset, endOffset) body = deserializeStatementBody(proto.body) as IrBlockBody? ?: irFactory.createBlockBody(startOffset, endOffset)
} }
} }
private fun deserializeIrConstructor(proto: ProtoConstructor): IrConstructor = private fun deserializeIrConstructor(proto: ProtoConstructor, setParent: Boolean = true): IrConstructor =
withDeserializedIrFunctionBase(proto.base) { symbol, idSig, startOffset, endOffset, origin, fcode -> withDeserializedIrFunctionBase(proto.base, setParent) { symbol, idSig, startOffset, endOffset, origin, fcode ->
checkSymbolType<IrConstructorSymbol>(symbol) checkSymbolType<IrConstructorSymbol>(symbol)
val flags = FunctionFlags.decode(fcode) val flags = FunctionFlags.decode(fcode)
val nameType = BinaryNameAndType.decode(proto.base.nameType) val nameType = BinaryNameAndType.decode(proto.base.nameType)
@@ -664,8 +669,8 @@ class IrDeclarationDeserializer(
} }
private fun deserializeIrField(proto: ProtoField, isConst: Boolean): IrField = private fun deserializeIrField(proto: ProtoField, isConst: Boolean, setParent: Boolean = true): IrField =
withDeserializedIrDeclarationBase(proto.base) { symbol, uniqId, startOffset, endOffset, origin, fcode -> withDeserializedIrDeclarationBase(proto.base, setParent) { symbol, uniqId, startOffset, endOffset, origin, fcode ->
checkSymbolType<IrFieldSymbol>(symbol) checkSymbolType<IrFieldSymbol>(symbol)
val nameType = BinaryNameAndType.decode(proto.nameType) val nameType = BinaryNameAndType.decode(proto.nameType)
val type = deserializeIrType(nameType.typeIndex) val type = deserializeIrType(nameType.typeIndex)
@@ -695,8 +700,11 @@ class IrDeclarationDeserializer(
field field
} }
private fun deserializeIrLocalDelegatedProperty(proto: ProtoLocalDelegatedProperty): IrLocalDelegatedProperty = private fun deserializeIrLocalDelegatedProperty(
withDeserializedIrDeclarationBase(proto.base) { symbol, _, startOffset, endOffset, origin, fcode -> proto: ProtoLocalDelegatedProperty,
setParent: Boolean = true
): IrLocalDelegatedProperty =
withDeserializedIrDeclarationBase(proto.base, setParent) { symbol, _, startOffset, endOffset, origin, fcode ->
checkSymbolType<IrLocalDelegatedPropertySymbol>(symbol) checkSymbolType<IrLocalDelegatedPropertySymbol>(symbol)
val flags = LocalVariableFlags.decode(fcode) val flags = LocalVariableFlags.decode(fcode)
@@ -718,8 +726,8 @@ class IrDeclarationDeserializer(
} }
} }
private fun deserializeIrProperty(proto: ProtoProperty): IrProperty = private fun deserializeIrProperty(proto: ProtoProperty, setParent: Boolean = true): IrProperty =
withDeserializedIrDeclarationBase(proto.base) { symbol, uniqId, startOffset, endOffset, origin, fcode -> withDeserializedIrDeclarationBase(proto.base, setParent) { symbol, uniqId, startOffset, endOffset, origin, fcode ->
checkSymbolType<IrPropertySymbol>(symbol) checkSymbolType<IrPropertySymbol>(symbol)
val flags = PropertyFlags.decode(fcode) val flags = PropertyFlags.decode(fcode)
val prop = symbolTable.declareProperty(uniqId, { symbol }) { val prop = symbolTable.declareProperty(uniqId, { symbol }) {
@@ -771,21 +779,21 @@ class IrDeclarationDeserializer(
return declarationOriginIndex[originName] ?: object : IrDeclarationOriginImpl(originName) {} return declarationOriginIndex[originName] ?: object : IrDeclarationOriginImpl(originName) {}
} }
fun deserializeDeclaration(proto: ProtoDeclaration): IrDeclaration { fun deserializeDeclaration(proto: ProtoDeclaration, setParent: Boolean = true): IrDeclaration {
val declaration: IrDeclaration = when (proto.declaratorCase!!) { val declaration: IrDeclaration = when (proto.declaratorCase!!) {
IR_ANONYMOUS_INIT -> deserializeIrAnonymousInit(proto.irAnonymousInit) IR_ANONYMOUS_INIT -> deserializeIrAnonymousInit(proto.irAnonymousInit, setParent)
IR_CONSTRUCTOR -> deserializeIrConstructor(proto.irConstructor) IR_CONSTRUCTOR -> deserializeIrConstructor(proto.irConstructor, setParent)
IR_FIELD -> deserializeIrField(proto.irField, isConst = false) IR_FIELD -> deserializeIrField(proto.irField, isConst = false, setParent)
IR_CLASS -> deserializeIrClass(proto.irClass) IR_CLASS -> deserializeIrClass(proto.irClass, setParent)
IR_FUNCTION -> deserializeIrFunction(proto.irFunction) IR_FUNCTION -> deserializeIrFunction(proto.irFunction, setParent)
IR_PROPERTY -> deserializeIrProperty(proto.irProperty) IR_PROPERTY -> deserializeIrProperty(proto.irProperty, setParent)
IR_TYPE_PARAMETER -> error("") // deserializeIrTypeParameter(proto.irTypeParameter, proto.irTypeParameter.index, proto.irTypeParameter.isGlobal) IR_TYPE_PARAMETER -> error("") // deserializeIrTypeParameter(proto.irTypeParameter, proto.irTypeParameter.index, proto.irTypeParameter.isGlobal)
IR_VARIABLE -> deserializeIrVariable(proto.irVariable) IR_VARIABLE -> deserializeIrVariable(proto.irVariable, setParent)
IR_VALUE_PARAMETER -> error("") // deserializeIrValueParameter(proto.irValueParameter, proto.irValueParameter.index) IR_VALUE_PARAMETER -> error("") // deserializeIrValueParameter(proto.irValueParameter, proto.irValueParameter.index)
IR_ENUM_ENTRY -> deserializeIrEnumEntry(proto.irEnumEntry) IR_ENUM_ENTRY -> deserializeIrEnumEntry(proto.irEnumEntry, setParent)
IR_LOCAL_DELEGATED_PROPERTY -> deserializeIrLocalDelegatedProperty(proto.irLocalDelegatedProperty) IR_LOCAL_DELEGATED_PROPERTY -> deserializeIrLocalDelegatedProperty(proto.irLocalDelegatedProperty, setParent)
IR_TYPE_ALIAS -> deserializeIrTypeAlias(proto.irTypeAlias) IR_TYPE_ALIAS -> deserializeIrTypeAlias(proto.irTypeAlias, setParent)
IR_ERROR_DECLARATION -> deserializeErrorDeclaration(proto.irErrorDeclaration) IR_ERROR_DECLARATION -> deserializeErrorDeclaration(proto.irErrorDeclaration, setParent)
DECLARATOR_NOT_SET -> error("Declaration deserialization not implemented: ${proto.declaratorCase}") DECLARATOR_NOT_SET -> error("Declaration deserialization not implemented: ${proto.declaratorCase}")
} }
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmIrMangler
import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyDeclarationBase
import org.jetbrains.kotlin.ir.declarations.lazy.LazyIrFactory import org.jetbrains.kotlin.ir.declarations.lazy.LazyIrFactory
import org.jetbrains.kotlin.ir.linkage.IrProvider import org.jetbrains.kotlin.ir.linkage.IrProvider
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
@@ -89,18 +88,13 @@ fun deserializeFromByteArray(
compatibilityMode = CompatibilityMode.CURRENT, compatibilityMode = CompatibilityMode.CURRENT,
) )
for (declarationProto in irProto.declarationList) { for (declarationProto in irProto.declarationList) {
val declaration = deserializer.deserializeDeclaration(declarationProto) deserializer.deserializeDeclaration(declarationProto, setParent = false)
// Either declaration is lazy, supplied by LazyIrFactory,
// or, if it is newly created, there must have been no references to it from the current module.
// These newly created declarations will never be used, so it does not matter if we patch their parent or not.
if (declaration is IrLazyDeclarationBase) {
declaration.parent = declaration.lazyParent()
}
} }
symbolTable.signaturer.withFileSignature(dummyFileSignature) { symbolTable.signaturer.withFileSignature(dummyFileSignature) {
ExternalDependenciesGenerator(symbolTable, irProviders).generateUnboundSymbolsAsDependencies() ExternalDependenciesGenerator(symbolTable, irProviders).generateUnboundSymbolsAsDependencies()
} }
toplevelParent.acceptChildrenVoid(PatchDeclarationParentsVisitor(toplevelParent))
buildFakeOverridesForLocalClasses(symbolTable, typeSystemContext, symbolDeserializer, toplevelParent) buildFakeOverridesForLocalClasses(symbolTable, typeSystemContext, symbolDeserializer, toplevelParent)
} }