FIR2IR: don't create synthetic class for enum entry w/o members
This commit is contained in:
committed by
Mikhail Glukhikh
parent
2ea3579281
commit
1a861b2df9
+1
-1
@@ -135,7 +135,7 @@ class FirElementSerializer private constructor(
|
||||
?: klass.declarations.filterIsInstance<FirCallableMemberDeclaration<*>>()
|
||||
|
||||
for (declaration in callableMembers) {
|
||||
if (declaration.isStatic) continue // ??? Miss values() & valueOf()
|
||||
if (declaration !is FirEnumEntry && declaration.isStatic) continue // ??? Miss values() & valueOf()
|
||||
when (declaration) {
|
||||
is FirProperty -> propertyProto(declaration)?.let { builder.addProperty(it) }
|
||||
is FirSimpleFunction -> functionProto(declaration)?.let { builder.addFunction(it) }
|
||||
|
||||
@@ -396,11 +396,14 @@ class Fir2IrClassifierStorage(
|
||||
this.parent = irParent
|
||||
}
|
||||
val initializer = enumEntry.initializer
|
||||
if (initializer != null) {
|
||||
initializer as FirAnonymousObject
|
||||
val klass = getIrAnonymousObjectForEnumEntry(initializer, enumEntry.name, irParent)
|
||||
|
||||
this.correspondingClass = klass
|
||||
if (initializer is FirAnonymousObject) {
|
||||
// An enum entry with its own members
|
||||
if (initializer.declarations.any { it !is FirConstructor }) {
|
||||
val klass = getIrAnonymousObjectForEnumEntry(initializer, enumEntry.name, irParent)
|
||||
this.correspondingClass = klass
|
||||
}
|
||||
// Otherwise, this is a default-ish enum entry whose initializer would be a delegating constructor call,
|
||||
// which will be translated via visitor later.
|
||||
} else if (irParent != null && origin == IrDeclarationOrigin.DEFINED) {
|
||||
val constructor = irParent.constructors.first()
|
||||
this.initializerExpression = IrExpressionBodyImpl(
|
||||
|
||||
@@ -106,26 +106,40 @@ class Fir2IrVisitor(
|
||||
|
||||
override fun visitEnumEntry(enumEntry: FirEnumEntry, data: Any?): IrElement {
|
||||
val irEnumEntry = classifierStorage.getCachedIrEnumEntry(enumEntry)!!
|
||||
val correspondingClass = irEnumEntry.correspondingClass ?: return irEnumEntry
|
||||
declarationStorage.enterScope(irEnumEntry)
|
||||
classifierStorage.putEnumEntryClassInScope(enumEntry, correspondingClass)
|
||||
val anonymousObject = enumEntry.initializer as FirAnonymousObject
|
||||
converter.processAnonymousObjectMembers(anonymousObject, correspondingClass)
|
||||
conversionScope.withParent(correspondingClass) {
|
||||
conversionScope.withContainingFirClass(anonymousObject) {
|
||||
memberGenerator.convertClassContent(correspondingClass, anonymousObject)
|
||||
}
|
||||
val constructor = correspondingClass.constructors.first()
|
||||
irEnumEntry.initializerExpression = IrExpressionBodyImpl(
|
||||
IrEnumConstructorCallImpl(
|
||||
startOffset, endOffset, enumEntry.returnTypeRef.toIrType(),
|
||||
constructor.symbol,
|
||||
typeArgumentsCount = constructor.typeParameters.size,
|
||||
valueArgumentsCount = constructor.valueParameters.size
|
||||
val correspondingClass = irEnumEntry.correspondingClass
|
||||
val initializer = enumEntry.initializer
|
||||
// If then enum entry has its own members, we need to introduce a synthetic class.
|
||||
if (correspondingClass != null) {
|
||||
declarationStorage.enterScope(irEnumEntry)
|
||||
classifierStorage.putEnumEntryClassInScope(enumEntry, correspondingClass)
|
||||
val anonymousObject = enumEntry.initializer as FirAnonymousObject
|
||||
converter.processAnonymousObjectMembers(anonymousObject, correspondingClass)
|
||||
conversionScope.withParent(correspondingClass) {
|
||||
conversionScope.withContainingFirClass(anonymousObject) {
|
||||
memberGenerator.convertClassContent(correspondingClass, anonymousObject)
|
||||
}
|
||||
val constructor = correspondingClass.constructors.first()
|
||||
irEnumEntry.initializerExpression = IrExpressionBodyImpl(
|
||||
IrEnumConstructorCallImpl(
|
||||
startOffset, endOffset, enumEntry.returnTypeRef.toIrType(),
|
||||
constructor.symbol,
|
||||
typeArgumentsCount = constructor.typeParameters.size,
|
||||
valueArgumentsCount = constructor.valueParameters.size
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
declarationStorage.leaveScope(irEnumEntry)
|
||||
} else if (initializer is FirAnonymousObject) {
|
||||
// Otherwise, this is a default-ish enum entry, which doesn't need its own synthetic class.
|
||||
// During raw FIR building, we put the delegated constructor call inside an anonymous object.
|
||||
val primaryConstructor = initializer.getPrimaryConstructorIfAny()
|
||||
val delegatedConstructor = primaryConstructor?.delegatedConstructor
|
||||
if (delegatedConstructor != null) {
|
||||
with(memberGenerator) {
|
||||
irEnumEntry.initializerExpression = IrExpressionBodyImpl(delegatedConstructor.toIrDelegatingConstructorCall())
|
||||
}
|
||||
}
|
||||
}
|
||||
declarationStorage.leaveScope(irEnumEntry)
|
||||
return irEnumEntry
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -272,7 +272,7 @@ internal class ClassMemberGenerator(
|
||||
return this
|
||||
}
|
||||
|
||||
private fun FirDelegatedConstructorCall.toIrDelegatingConstructorCall(): IrExpression {
|
||||
internal fun FirDelegatedConstructorCall.toIrDelegatingConstructorCall(): IrExpression {
|
||||
val constructedIrType = constructedTypeRef.toIrType()
|
||||
val referencedSymbol = (this.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirConstructorSymbol
|
||||
?: return convertWithOffsets { startOffset, endOffset ->
|
||||
|
||||
Reference in New Issue
Block a user