[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
This commit is contained in:
Dmitriy Novozhilov
2023-11-03 14:05:08 +02:00
committed by Space Team
parent 3c0f153de4
commit fe66f3a384
4 changed files with 50 additions and 50 deletions
@@ -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
@@ -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)
}
}
}
@@ -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
}
}
@@ -7,9 +7,9 @@ interface J
expect class Foo : I, C, J
<!SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR!>expect class Bar : C<!SUPERTYPE_INITIALIZED_IN_EXPECTED_CLASS!>()<!><!>
<!EXPECT_ACTUAL_INCOMPATIBILITY{JVM}, SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR, SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR!>expect class Bar : C<!SUPERTYPE_INITIALIZED_IN_EXPECTED_CLASS, SUPERTYPE_INITIALIZED_IN_EXPECTED_CLASS!>()<!><!>
expect class WithExplicitPrimaryConstructor() : C<!SUPERTYPE_INITIALIZED_IN_EXPECTED_CLASS!>()<!>
expect class WithExplicitPrimaryConstructor() : C<!SUPERTYPE_INITIALIZED_IN_EXPECTED_CLASS, SUPERTYPE_INITIALIZED_IN_EXPECTED_CLASS!>()<!>
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt