From c8b7dbd3520f114e53b64f4a9a18d21b43958e73 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Fri, 6 Oct 2023 14:47:16 +0300 Subject: [PATCH] [IR] Add optIn to IrDeclarationContainer.declarations Accessing list of declaration may trigger lazy declaration list computation for lazy class, which requires computation of fake-overrides for this class. So it's unsafe to access it before IR for all sources is built (because fake-overrides of lazy classes may depend on declaration of source classes, e.g. for java source classes) So this OptIn is needed to carefully handle all cases of .declarations access in FIR2IR --- .../org/jetbrains/kotlin/fir/lazy/Fir2IrLazyClass.kt | 2 ++ .../kotlin/ir/declarations/IrDeclarationContainer.kt | 8 ++++++++ .../kotlin/ir/declarations/impl/IrClassImpl.kt | 2 ++ .../impl/IrExternalPackageFragmentImpl.kt | 2 ++ .../kotlin/ir/declarations/impl/IrFileImpl.kt | 2 ++ .../kotlin/ir/declarations/lazy/IrLazyClass.kt | 3 ++- .../kotlin/ir/types/impl/IrErrorClassImpl.kt | 3 +++ .../src/org/jetbrains/kotlin/ir/generator/IrTree.kt | 12 +++++++++++- 8 files changed, 32 insertions(+), 2 deletions(-) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyClass.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyClass.kt index ee8dfb4f50f..53f8a2697b1 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyClass.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyClass.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.ir.declarations.lazy.IrMaybeDeserializedClass import org.jetbrains.kotlin.ir.declarations.lazy.lazyVar import org.jetbrains.kotlin.ir.expressions.IrConstructorCall import org.jetbrains.kotlin.ir.symbols.IrClassSymbol +import org.jetbrains.kotlin.ir.symbols.IrSymbolInternals import org.jetbrains.kotlin.ir.types.IrSimpleType import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl @@ -154,6 +155,7 @@ class Fir2IrLazyClass( .also(converter::bindFakeOverridesOrPostpone) } + @IrSymbolInternals override val declarations: MutableList by lazyVar(lock) { val result = mutableListOf() // NB: it's necessary to take all callables from scope, diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrDeclarationContainer.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrDeclarationContainer.kt index acc533b3b44..4af7d164be1 100644 --- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrDeclarationContainer.kt +++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrDeclarationContainer.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.ir.declarations +import org.jetbrains.kotlin.ir.symbols.IrSymbolInternals /** * A non-leaf IR tree element. @@ -15,5 +16,12 @@ package org.jetbrains.kotlin.ir.declarations * Generated from: [org.jetbrains.kotlin.ir.generator.IrTree.declarationContainer] */ interface IrDeclarationContainer : IrDeclarationParent { + /** + * Accessing list of declaration may trigger lazy declaration list computation for lazy class, + * which requires computation of fake-overrides for this class. So it's unsafe to access it + * before IR for all sources is built (because fake-overrides of lazy classes may depend on + * declaration of source classes, e.g. for java source classes) + */ + @IrSymbolInternals val declarations: MutableList } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrClassImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrClassImpl.kt index d142e1b3cd7..4e68a138dfc 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrClassImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrClassImpl.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.IrConstructorCall import org.jetbrains.kotlin.ir.symbols.IrClassSymbol +import org.jetbrains.kotlin.ir.symbols.IrSymbolInternals import org.jetbrains.kotlin.ir.types.IrSimpleType import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.name.Name @@ -47,6 +48,7 @@ open class IrClassImpl( override var thisReceiver: IrValueParameter? = null + @IrSymbolInternals override val declarations: MutableList = ArrayList() override var typeParameters: List = emptyList() diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrExternalPackageFragmentImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrExternalPackageFragmentImpl.kt index a41392766fc..57a906672ea 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrExternalPackageFragmentImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrExternalPackageFragmentImpl.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrExternalPackageFragment import org.jetbrains.kotlin.ir.symbols.IrExternalPackageFragmentSymbol +import org.jetbrains.kotlin.ir.symbols.IrSymbolInternals import org.jetbrains.kotlin.ir.symbols.impl.IrExternalPackageFragmentSymbolImpl import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource @@ -51,6 +52,7 @@ class IrExternalPackageFragmentImpl( override val moduleDescriptor: ModuleDescriptor get() = packageFragmentDescriptor.containingDeclaration + @IrSymbolInternals override val declarations: MutableList = ArrayList() @OptIn(ObsoleteDescriptorBasedAPI::class) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrFileImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrFileImpl.kt index 93efec29c50..88aa5d8032d 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrFileImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrFileImpl.kt @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.declarations.MetadataSource import org.jetbrains.kotlin.ir.expressions.IrConstructorCall import org.jetbrains.kotlin.ir.symbols.IrFileSymbol +import org.jetbrains.kotlin.ir.symbols.IrSymbolInternals import org.jetbrains.kotlin.ir.symbols.impl.IrFileSymbolImpl import org.jetbrains.kotlin.name.FqName @@ -79,6 +80,7 @@ class IrFileImpl( packageFragmentDescriptor.containingDeclaration } + @IrSymbolInternals override val declarations: MutableList = ArrayList() override var annotations: List = emptyList() diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/lazy/IrLazyClass.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/lazy/IrLazyClass.kt index 9f35d63930a..4bd2a83e64b 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/lazy/IrLazyClass.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/lazy/IrLazyClass.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.IrConstructorCall import org.jetbrains.kotlin.ir.symbols.IrClassSymbol +import org.jetbrains.kotlin.ir.symbols.IrSymbolInternals import org.jetbrains.kotlin.ir.types.IrSimpleType import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.util.* @@ -55,7 +56,7 @@ class IrLazyClass( } } - + @IrSymbolInternals override val declarations: MutableList by lazyVar(stubGenerator.lock) { ArrayList().also { typeTranslator.buildWithScope(this) { diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrErrorClassImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrErrorClassImpl.kt index badc006c5dc..33942d717cc 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrErrorClassImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrErrorClassImpl.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl import org.jetbrains.kotlin.ir.expressions.IrConstructorCall import org.jetbrains.kotlin.ir.symbols.IrFileSymbol +import org.jetbrains.kotlin.ir.symbols.IrSymbolInternals import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name @@ -31,6 +32,8 @@ object IrErrorClassImpl : IrClassImpl( override var annotations: List get() = shouldNotBeCalled() set(_) {} + + @IrSymbolInternals override val declarations: MutableList get() = shouldNotBeCalled() override val symbol: IrFileSymbol diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/IrTree.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/IrTree.kt index f2b4fe5034b..1bd17e76fde 100644 --- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/IrTree.kt +++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/IrTree.kt @@ -343,7 +343,17 @@ object IrTree : AbstractTreeBuilder() { parent(declarationParent) - +listField("declarations", declaration, mutability = List, isChild = true) + +listField("declarations", declaration, mutability = List, isChild = true) { + kDoc = """ + Accessing list of declaration may trigger lazy declaration list computation for lazy class, + which requires computation of fake-overrides for this class. So it's unsafe to access it + before IR for all sources is built (because fake-overrides of lazy classes may depend on + declaration of source classes, e.g. for java source classes) + """.trimIndent() + generationCallback = { + addAnnotation(ClassName("org.jetbrains.kotlin.ir.symbols", "IrSymbolInternals")) + } + } } val typeParametersContainer: ElementConfig by element(Declaration) { ownsChildren = false