From fe66f3a384f0e4157d48cf41bfa01d11bed8295e Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Fri, 3 Nov 2023 14:05:08 +0200 Subject: [PATCH] [FIR2IR] Manage constructor symbols in declaration storage instead of declaration generator This is needed to be able to implement creation of unbound symbols for references of corresponding declarations (KT-62856) There was an exception from FIR2IR that was fixed with this change, so fir2ir test SuperClass started to pass along with IrActualizer, which reported some new errors --- .../fir/backend/Fir2IrDeclarationStorage.kt | 18 ++++- .../Fir2IrCallableDeclarationsGenerator.kt | 69 ++++++++----------- .../Fir2IrLazyDeclarationsGenerator.kt | 9 ++- .../headerClass/superClass.fir.kt | 4 +- 4 files changed, 50 insertions(+), 50 deletions(-) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt index db82cb9647e..6c21a639852 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt @@ -38,6 +38,7 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl import org.jetbrains.kotlin.ir.expressions.IrSyntheticBodyKind import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl +import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl import org.jetbrains.kotlin.ir.util.IdSignature import org.jetbrains.kotlin.ir.util.classId @@ -419,7 +420,22 @@ class Fir2IrDeclarationStorage( isLocal: Boolean = false, ): IrConstructor { // caching of created constructor is not called here, because `callablesGenerator` calls `cacheIrConstructor` by itself - return callablesGenerator.createIrConstructor(constructor, irParent(), predefinedOrigin, isLocal) + val signature = runIf(!isLocal && configuration.linkViaSignatures) { + signatureComposer.composeSignature(constructor) + } + return callablesGenerator.createIrConstructor( + constructor, + irParent(), + createConstructorSymbol(signature), + predefinedOrigin + ) + } + + private fun createConstructorSymbol(signature: IdSignature?): IrConstructorSymbol { + return when { + signature != null -> symbolTable.referenceConstructor(signature) + else -> IrConstructorSymbolImpl() + } } @LeakedDeclarationCaches diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrCallableDeclarationsGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrCallableDeclarationsGenerator.kt index 883decc274d..ff11c81d3a5 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrCallableDeclarationsGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrCallableDeclarationsGenerator.kt @@ -178,29 +178,16 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi // ------------------------------------ constructors ------------------------------------ - private fun declareIrConstructor(signature: IdSignature?, factory: (IrConstructorSymbol) -> IrConstructor): IrConstructor { - return if (signature == null) - factory(IrConstructorSymbolImpl()) - else - symbolTable.declareConstructor(signature, { IrConstructorPublicSymbolImpl(signature) }, factory) - } - fun createIrConstructor( constructor: FirConstructor, irParent: IrClass, + symbol: IrConstructorSymbol, predefinedOrigin: IrDeclarationOrigin? = null, - isLocal: Boolean = false, ): IrConstructor = convertCatching(constructor) { val origin = constructor.computeIrOrigin(predefinedOrigin, irParent.origin) val isPrimary = constructor.isPrimary - // we need to compose signature even if `linkViaSignatures` set to false, because otherwise we will never - // create lazy constructor (it requires not nullable signature) - val signature = runUnless(isLocal) { - signatureComposer.composeSignature(constructor) - } - - if (irParent is Fir2IrLazyClass && signature != null) { - val lazyConstructor = lazyDeclarationsGenerator.createIrLazyConstructor(constructor, signature, origin, irParent) as Fir2IrLazyConstructor + if (irParent is Fir2IrLazyClass) { + val lazyConstructor = lazyDeclarationsGenerator.createIrLazyConstructor(constructor, symbol, origin, irParent) as Fir2IrLazyConstructor // Add to cache before generating parameters to prevent an infinite loop when an annotation value parameter is annotated // with the annotation itself. @OptIn(LeakedDeclarationCaches::class) @@ -210,32 +197,30 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi } val visibility = if (irParent.isAnonymousObject) Visibilities.Public else constructor.visibility return constructor.convertWithOffsets { startOffset, endOffset -> - declareIrConstructor(signature.takeIf { components.configuration.linkViaSignatures }) { symbol -> - classifierStorage.preCacheTypeParameters(constructor, symbol) - irFactory.createConstructor( - startOffset = startOffset, - endOffset = endOffset, - origin = origin, - name = SpecialNames.INIT, - visibility = components.visibilityConverter.convertToDescriptorVisibility(visibility), - isInline = false, - isExpect = constructor.isExpect, - returnType = constructor.returnTypeRef.toIrType(), - symbol = symbol, - isPrimary = isPrimary, - isExternal = false, - ).apply { - metadata = FirMetadataSource.Function(constructor) - annotationGenerator.generate(this, constructor) - // Add to cache before generating parameters to prevent an infinite loop when an annotation value parameter is annotated - // with the annotation itself. - @OptIn(LeakedDeclarationCaches::class) - declarationStorage.cacheIrConstructor(constructor, this) - declarationStorage.withScope(symbol) { - setParent(irParent) - addDeclarationToParent(this, irParent) - declareParameters(constructor, irParent, dispatchReceiverType = null, isStatic = false, forSetter = false) - } + classifierStorage.preCacheTypeParameters(constructor, symbol) + irFactory.createConstructor( + startOffset = startOffset, + endOffset = endOffset, + origin = origin, + name = SpecialNames.INIT, + visibility = components.visibilityConverter.convertToDescriptorVisibility(visibility), + isInline = false, + isExpect = constructor.isExpect, + returnType = constructor.returnTypeRef.toIrType(), + symbol = symbol, + isPrimary = isPrimary, + isExternal = false, + ).apply { + metadata = FirMetadataSource.Function(constructor) + annotationGenerator.generate(this, constructor) + // Add to cache before generating parameters to prevent an infinite loop when an annotation value parameter is annotated + // with the annotation itself. + @OptIn(LeakedDeclarationCaches::class) + declarationStorage.cacheIrConstructor(constructor, this) + declarationStorage.withScope(symbol) { + setParent(irParent) + addDeclarationToParent(this, irParent) + declareParameters(constructor, irParent, dispatchReceiverType = null, isStatic = false, forSetter = false) } } } diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrLazyDeclarationsGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrLazyDeclarationsGenerator.kt index eacd4b2f939..2752662f777 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrLazyDeclarationsGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrLazyDeclarationsGenerator.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.lazy.* import org.jetbrains.kotlin.fir.resolve.providers.firProvider import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorPublicSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrFieldPublicSymbolImpl @@ -86,14 +87,12 @@ class Fir2IrLazyDeclarationsGenerator(val components: Fir2IrComponents) : Fir2Ir fun createIrLazyConstructor( fir: FirConstructor, - signature: IdSignature, + symbol: IrConstructorSymbol, declarationOrigin: IrDeclarationOrigin, lazyParent: IrDeclarationParent, ): IrConstructor = fir.convertWithOffsets { startOffset, endOffset -> - symbolTable.declareConstructor(signature, { IrConstructorPublicSymbolImpl(signature) }) { symbol -> - Fir2IrLazyConstructor(components, startOffset, endOffset, declarationOrigin, fir, symbol).apply { - parent = lazyParent - } + Fir2IrLazyConstructor(components, startOffset, endOffset, declarationOrigin, fir, symbol).apply { + parent = lazyParent } } diff --git a/compiler/testData/diagnostics/tests/multiplatform/headerClass/superClass.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/headerClass/superClass.fir.kt index 0e66fb047af..f3a2c6ac9f0 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/headerClass/superClass.fir.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/headerClass/superClass.fir.kt @@ -7,9 +7,9 @@ interface J expect class Foo : I, C, J -expect class Bar : C() +expect class Bar : C() -expect class WithExplicitPrimaryConstructor() : C() +expect class WithExplicitPrimaryConstructor() : C() // MODULE: m2-jvm()()(m1-common) // FILE: jvm.kt