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:
+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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user