[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.expressions.IrSyntheticBodyKind
import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl 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.symbols.impl.IrSimpleFunctionSymbolImpl
import org.jetbrains.kotlin.ir.util.IdSignature import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.ir.util.classId import org.jetbrains.kotlin.ir.util.classId
@@ -419,7 +420,22 @@ class Fir2IrDeclarationStorage(
isLocal: Boolean = false, isLocal: Boolean = false,
): IrConstructor { ): IrConstructor {
// caching of created constructor is not called here, because `callablesGenerator` calls `cacheIrConstructor` by itself // 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 @LeakedDeclarationCaches
@@ -178,29 +178,16 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi
// ------------------------------------ constructors ------------------------------------ // ------------------------------------ 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( fun createIrConstructor(
constructor: FirConstructor, constructor: FirConstructor,
irParent: IrClass, irParent: IrClass,
symbol: IrConstructorSymbol,
predefinedOrigin: IrDeclarationOrigin? = null, predefinedOrigin: IrDeclarationOrigin? = null,
isLocal: Boolean = false,
): IrConstructor = convertCatching(constructor) { ): IrConstructor = convertCatching(constructor) {
val origin = constructor.computeIrOrigin(predefinedOrigin, irParent.origin) val origin = constructor.computeIrOrigin(predefinedOrigin, irParent.origin)
val isPrimary = constructor.isPrimary val isPrimary = constructor.isPrimary
// we need to compose signature even if `linkViaSignatures` set to false, because otherwise we will never if (irParent is Fir2IrLazyClass) {
// create lazy constructor (it requires not nullable signature) val lazyConstructor = lazyDeclarationsGenerator.createIrLazyConstructor(constructor, symbol, origin, irParent) as Fir2IrLazyConstructor
val signature = runUnless(isLocal) {
signatureComposer.composeSignature(constructor)
}
if (irParent is Fir2IrLazyClass && signature != null) {
val lazyConstructor = lazyDeclarationsGenerator.createIrLazyConstructor(constructor, signature, origin, irParent) as Fir2IrLazyConstructor
// Add to cache before generating parameters to prevent an infinite loop when an annotation value parameter is annotated // Add to cache before generating parameters to prevent an infinite loop when an annotation value parameter is annotated
// with the annotation itself. // with the annotation itself.
@OptIn(LeakedDeclarationCaches::class) @OptIn(LeakedDeclarationCaches::class)
@@ -210,32 +197,30 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi
} }
val visibility = if (irParent.isAnonymousObject) Visibilities.Public else constructor.visibility val visibility = if (irParent.isAnonymousObject) Visibilities.Public else constructor.visibility
return constructor.convertWithOffsets { startOffset, endOffset -> return constructor.convertWithOffsets { startOffset, endOffset ->
declareIrConstructor(signature.takeIf { components.configuration.linkViaSignatures }) { symbol -> classifierStorage.preCacheTypeParameters(constructor, symbol)
classifierStorage.preCacheTypeParameters(constructor, symbol) irFactory.createConstructor(
irFactory.createConstructor( startOffset = startOffset,
startOffset = startOffset, endOffset = endOffset,
endOffset = endOffset, origin = origin,
origin = origin, name = SpecialNames.INIT,
name = SpecialNames.INIT, visibility = components.visibilityConverter.convertToDescriptorVisibility(visibility),
visibility = components.visibilityConverter.convertToDescriptorVisibility(visibility), isInline = false,
isInline = false, isExpect = constructor.isExpect,
isExpect = constructor.isExpect, returnType = constructor.returnTypeRef.toIrType(),
returnType = constructor.returnTypeRef.toIrType(), symbol = symbol,
symbol = symbol, isPrimary = isPrimary,
isPrimary = isPrimary, isExternal = false,
isExternal = false, ).apply {
).apply { metadata = FirMetadataSource.Function(constructor)
metadata = FirMetadataSource.Function(constructor) annotationGenerator.generate(this, constructor)
annotationGenerator.generate(this, constructor) // Add to cache before generating parameters to prevent an infinite loop when an annotation value parameter is annotated
// Add to cache before generating parameters to prevent an infinite loop when an annotation value parameter is annotated // with the annotation itself.
// with the annotation itself. @OptIn(LeakedDeclarationCaches::class)
@OptIn(LeakedDeclarationCaches::class) declarationStorage.cacheIrConstructor(constructor, this)
declarationStorage.cacheIrConstructor(constructor, this) declarationStorage.withScope(symbol) {
declarationStorage.withScope(symbol) { setParent(irParent)
setParent(irParent) addDeclarationToParent(this, irParent)
addDeclarationToParent(this, irParent) declareParameters(constructor, irParent, dispatchReceiverType = null, isStatic = false, forSetter = false)
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.lazy.*
import org.jetbrains.kotlin.fir.resolve.providers.firProvider import org.jetbrains.kotlin.fir.resolve.providers.firProvider
import org.jetbrains.kotlin.ir.declarations.* 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.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorPublicSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorPublicSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldPublicSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrFieldPublicSymbolImpl
@@ -86,14 +87,12 @@ class Fir2IrLazyDeclarationsGenerator(val components: Fir2IrComponents) : Fir2Ir
fun createIrLazyConstructor( fun createIrLazyConstructor(
fir: FirConstructor, fir: FirConstructor,
signature: IdSignature, symbol: IrConstructorSymbol,
declarationOrigin: IrDeclarationOrigin, declarationOrigin: IrDeclarationOrigin,
lazyParent: IrDeclarationParent, lazyParent: IrDeclarationParent,
): IrConstructor = fir.convertWithOffsets { startOffset, endOffset -> ): IrConstructor = fir.convertWithOffsets { startOffset, endOffset ->
symbolTable.declareConstructor(signature, { IrConstructorPublicSymbolImpl(signature) }) { symbol -> Fir2IrLazyConstructor(components, startOffset, endOffset, declarationOrigin, fir, symbol).apply {
Fir2IrLazyConstructor(components, startOffset, endOffset, declarationOrigin, fir, symbol).apply { parent = lazyParent
parent = lazyParent
}
} }
} }
@@ -7,9 +7,9 @@ interface J
expect class Foo : I, C, 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) // MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt // FILE: jvm.kt