[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
This commit is contained in:
Dmitriy Novozhilov
2023-10-06 14:47:16 +03:00
committed by Space Team
parent 3556533d95
commit c8b7dbd352
8 changed files with 32 additions and 2 deletions
@@ -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.declarations.lazy.lazyVar
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol 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.IrSimpleType
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
@@ -154,6 +155,7 @@ class Fir2IrLazyClass(
.also(converter::bindFakeOverridesOrPostpone) .also(converter::bindFakeOverridesOrPostpone)
} }
@IrSymbolInternals
override val declarations: MutableList<IrDeclaration> by lazyVar(lock) { override val declarations: MutableList<IrDeclaration> by lazyVar(lock) {
val result = mutableListOf<IrDeclaration>() val result = mutableListOf<IrDeclaration>()
// NB: it's necessary to take all callables from scope, // NB: it's necessary to take all callables from scope,
@@ -8,6 +8,7 @@
package org.jetbrains.kotlin.ir.declarations package org.jetbrains.kotlin.ir.declarations
import org.jetbrains.kotlin.ir.symbols.IrSymbolInternals
/** /**
* A non-leaf IR tree element. * 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] * Generated from: [org.jetbrains.kotlin.ir.generator.IrTree.declarationContainer]
*/ */
interface IrDeclarationContainer : IrDeclarationParent { 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<IrDeclaration> val declarations: MutableList<IrDeclaration>
} }
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol 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.IrSimpleType
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -47,6 +48,7 @@ open class IrClassImpl(
override var thisReceiver: IrValueParameter? = null override var thisReceiver: IrValueParameter? = null
@IrSymbolInternals
override val declarations: MutableList<IrDeclaration> = ArrayList() override val declarations: MutableList<IrDeclaration> = ArrayList()
override var typeParameters: List<IrTypeParameter> = emptyList() override var typeParameters: List<IrTypeParameter> = emptyList()
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrExternalPackageFragment import org.jetbrains.kotlin.ir.declarations.IrExternalPackageFragment
import org.jetbrains.kotlin.ir.symbols.IrExternalPackageFragmentSymbol 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.ir.symbols.impl.IrExternalPackageFragmentSymbolImpl
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
@@ -51,6 +52,7 @@ class IrExternalPackageFragmentImpl(
override val moduleDescriptor: ModuleDescriptor override val moduleDescriptor: ModuleDescriptor
get() = packageFragmentDescriptor.containingDeclaration get() = packageFragmentDescriptor.containingDeclaration
@IrSymbolInternals
override val declarations: MutableList<IrDeclaration> = ArrayList() override val declarations: MutableList<IrDeclaration> = ArrayList()
@OptIn(ObsoleteDescriptorBasedAPI::class) @OptIn(ObsoleteDescriptorBasedAPI::class)
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.declarations.MetadataSource import org.jetbrains.kotlin.ir.declarations.MetadataSource
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.symbols.IrFileSymbol 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.ir.symbols.impl.IrFileSymbolImpl
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
@@ -79,6 +80,7 @@ class IrFileImpl(
packageFragmentDescriptor.containingDeclaration packageFragmentDescriptor.containingDeclaration
} }
@IrSymbolInternals
override val declarations: MutableList<IrDeclaration> = ArrayList() override val declarations: MutableList<IrDeclaration> = ArrayList()
override var annotations: List<IrConstructorCall> = emptyList() override var annotations: List<IrConstructorCall> = emptyList()
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol 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.IrSimpleType
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
@@ -55,7 +56,7 @@ class IrLazyClass(
} }
} }
@IrSymbolInternals
override val declarations: MutableList<IrDeclaration> by lazyVar(stubGenerator.lock) { override val declarations: MutableList<IrDeclaration> by lazyVar(stubGenerator.lock) {
ArrayList<IrDeclaration>().also { ArrayList<IrDeclaration>().also {
typeTranslator.buildWithScope(this) { typeTranslator.buildWithScope(this) {
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.symbols.IrFileSymbol 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.ir.symbols.impl.IrClassSymbolImpl
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -31,6 +32,8 @@ object IrErrorClassImpl : IrClassImpl(
override var annotations: List<IrConstructorCall> override var annotations: List<IrConstructorCall>
get() = shouldNotBeCalled() get() = shouldNotBeCalled()
set(_) {} set(_) {}
@IrSymbolInternals
override val declarations: MutableList<IrDeclaration> override val declarations: MutableList<IrDeclaration>
get() = shouldNotBeCalled() get() = shouldNotBeCalled()
override val symbol: IrFileSymbol override val symbol: IrFileSymbol
@@ -343,7 +343,17 @@ object IrTree : AbstractTreeBuilder() {
parent(declarationParent) 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) { val typeParametersContainer: ElementConfig by element(Declaration) {
ownsChildren = false ownsChildren = false