[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.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<IrDeclaration> by lazyVar(lock) {
val result = mutableListOf<IrDeclaration>()
// NB: it's necessary to take all callables from scope,
@@ -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<IrDeclaration>
}
@@ -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<IrDeclaration> = ArrayList()
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.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<IrDeclaration> = ArrayList()
@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.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<IrDeclaration> = ArrayList()
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.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<IrDeclaration> by lazyVar(stubGenerator.lock) {
ArrayList<IrDeclaration>().also {
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.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<IrConstructorCall>
get() = shouldNotBeCalled()
set(_) {}
@IrSymbolInternals
override val declarations: MutableList<IrDeclaration>
get() = shouldNotBeCalled()
override val symbol: IrFileSymbol
@@ -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