KT-29340 Provide effective modality for enum class in IR
* if enum class has abstract members, then it is ABSTRACT * otherwise, if enum class has entries with members, then it is OPEN * otherwise, it is FINAL.
This commit is contained in:
+1
-1
@@ -291,7 +291,7 @@ private fun MemberDescriptor.calcModalityFlag(): Int {
|
||||
private val MemberDescriptor.effectiveModality: Modality
|
||||
get() {
|
||||
if (this is ClassDescriptor && kind == ClassKind.ENUM_CLASS) {
|
||||
if (JvmCodegenUtil.hasAbstractMembers(this)) {
|
||||
if (DescriptorUtils.hasAbstractMembers(this)) {
|
||||
return Modality.ABSTRACT
|
||||
}
|
||||
}
|
||||
|
||||
+35
-15
@@ -58,7 +58,8 @@ class ClassGenerator(
|
||||
val endOffset = ktClassOrObject.pureEndOffset
|
||||
|
||||
return context.symbolTable.declareClass(
|
||||
startOffset, endOffset, IrDeclarationOrigin.DEFINED, classDescriptor
|
||||
startOffset, endOffset, IrDeclarationOrigin.DEFINED, classDescriptor,
|
||||
getEffectiveModality(ktClassOrObject, classDescriptor)
|
||||
).buildWithScope { irClass ->
|
||||
declarationGenerator.generateGlobalTypeParametersDeclarations(irClass, classDescriptor.declaredTypeParameters)
|
||||
|
||||
@@ -99,6 +100,25 @@ class ClassGenerator(
|
||||
}
|
||||
}
|
||||
|
||||
private fun getEffectiveModality(ktClassOrObject: KtPureClassOrObject, classDescriptor: ClassDescriptor): Modality =
|
||||
when {
|
||||
!DescriptorUtils.isEnumClass(classDescriptor) ->
|
||||
classDescriptor.modality
|
||||
DescriptorUtils.hasAbstractMembers(classDescriptor) ->
|
||||
Modality.ABSTRACT
|
||||
ktClassOrObject.hasEnumEntriesWithClassMembers() ->
|
||||
Modality.OPEN
|
||||
else ->
|
||||
Modality.FINAL
|
||||
}
|
||||
|
||||
private fun KtPureClassOrObject.hasEnumEntriesWithClassMembers(): Boolean {
|
||||
val body = this.body ?: return false
|
||||
return body.enumEntries.any { it.hasMemberDeclarations() }
|
||||
}
|
||||
|
||||
private fun KtEnumEntry.hasMemberDeclarations() = declarations.isNotEmpty()
|
||||
|
||||
private fun generateFakeOverrideMemberDeclarations(irClass: IrClass, ktClassOrObject: KtPureClassOrObject) {
|
||||
irClass.descriptor.unsubstitutedMemberScope.getContributedDescriptors()
|
||||
.mapNotNull {
|
||||
@@ -252,20 +272,20 @@ class ClassGenerator(
|
||||
val dispatchReceiverParameter = irDelegatedFunction.dispatchReceiverParameter!!
|
||||
val dispatchReceiverType = dispatchReceiverParameter.type
|
||||
irCall.dispatchReceiver =
|
||||
IrGetFieldImpl(
|
||||
IrGetFieldImpl(
|
||||
startOffset, endOffset,
|
||||
irDelegate.symbol,
|
||||
irDelegate.type,
|
||||
IrGetValueImpl(
|
||||
startOffset, endOffset,
|
||||
irDelegate.symbol,
|
||||
irDelegate.type,
|
||||
IrGetValueImpl(
|
||||
startOffset, endOffset,
|
||||
dispatchReceiverType,
|
||||
dispatchReceiverParameter.symbol
|
||||
)
|
||||
dispatchReceiverType,
|
||||
dispatchReceiverParameter.symbol
|
||||
)
|
||||
)
|
||||
irCall.extensionReceiver =
|
||||
irDelegatedFunction.extensionReceiverParameter?.let { extensionReceiver ->
|
||||
IrGetValueImpl(startOffset, endOffset, extensionReceiver.type, extensionReceiver.symbol)
|
||||
}
|
||||
irDelegatedFunction.extensionReceiverParameter?.let { extensionReceiver ->
|
||||
IrGetValueImpl(startOffset, endOffset, extensionReceiver.type, extensionReceiver.symbol)
|
||||
}
|
||||
irCall.mapValueParameters { overriddenValueParameter ->
|
||||
val delegatedValueParameter = delegated.valueParameters[overriddenValueParameter.index]
|
||||
val irDelegatedValueParameter = irDelegatedFunction.getIrValueParameter(delegatedValueParameter)
|
||||
@@ -400,11 +420,11 @@ class ClassGenerator(
|
||||
|
||||
if (!enumEntryDescriptor.isExpect) {
|
||||
irEnumEntry.initializerExpression =
|
||||
createBodyGenerator(irEnumEntry.symbol)
|
||||
.generateEnumEntryInitializer(ktEnumEntry, enumEntryDescriptor)
|
||||
createBodyGenerator(irEnumEntry.symbol)
|
||||
.generateEnumEntryInitializer(ktEnumEntry, enumEntryDescriptor)
|
||||
}
|
||||
|
||||
if (ktEnumEntry.declarations.isNotEmpty()) {
|
||||
if (ktEnumEntry.hasMemberDeclarations()) {
|
||||
irEnumEntry.correspondingClass = generateClass(ktEnumEntry)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,12 +53,14 @@ class IrClassImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
symbol: IrClassSymbol
|
||||
symbol: IrClassSymbol,
|
||||
modality: Modality = symbol.descriptor.modality
|
||||
) :
|
||||
this(
|
||||
startOffset, endOffset, origin, symbol,
|
||||
symbol.descriptor.name, symbol.descriptor.kind,
|
||||
symbol.descriptor.visibility, symbol.descriptor.modality,
|
||||
symbol.descriptor.visibility,
|
||||
modality = modality,
|
||||
isCompanion = symbol.descriptor.isCompanionObject,
|
||||
isInner = symbol.descriptor.isInner,
|
||||
isData = symbol.descriptor.isData,
|
||||
@@ -70,17 +72,19 @@ class IrClassImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
descriptor: ClassDescriptor
|
||||
descriptor: ClassDescriptor,
|
||||
modality: Modality = descriptor.modality
|
||||
) :
|
||||
this(startOffset, endOffset, origin, IrClassSymbolImpl(descriptor))
|
||||
this(startOffset, endOffset, origin, IrClassSymbolImpl(descriptor), modality)
|
||||
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
descriptor: ClassDescriptor,
|
||||
members: List<IrDeclaration>
|
||||
) : this(startOffset, endOffset, origin, descriptor) {
|
||||
modality: Modality = descriptor.modality,
|
||||
members: List<IrDeclaration> = emptyList()
|
||||
) : this(startOffset, endOffset, origin, descriptor, modality) {
|
||||
addAll(members)
|
||||
}
|
||||
|
||||
|
||||
@@ -92,6 +92,7 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
|
||||
declaration.startOffset, declaration.endOffset,
|
||||
mapDeclarationOrigin(declaration.origin),
|
||||
mapClassDeclaration(declaration.descriptor),
|
||||
declaration.modality,
|
||||
declaration.declarations.map { it.transform() }
|
||||
).apply {
|
||||
transformAnnotations(declaration)
|
||||
|
||||
@@ -232,7 +232,8 @@ open class SymbolTable : ReferenceSymbolTable {
|
||||
|
||||
fun declareClass(
|
||||
startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor,
|
||||
classFactory: (IrClassSymbol) -> IrClass = { IrClassImpl(startOffset, endOffset, origin, it) }
|
||||
modality: Modality = descriptor.modality,
|
||||
classFactory: (IrClassSymbol) -> IrClass = { IrClassImpl(startOffset, endOffset, origin, it, modality) }
|
||||
): IrClass {
|
||||
return classSymbolTable.declare(
|
||||
descriptor,
|
||||
|
||||
Reference in New Issue
Block a user