KT-16438 Strange dispatch receiver for descriptors of delegated members
Provide proper dispatch receiver parameter for delegated members. Use dispatch receiver parameter for delegated members in IR generation for delegated member body (and check that the receiver has corresponding type).
This commit is contained in:
@@ -70,7 +70,14 @@ class DelegationResolver<T : CallableMemberDescriptor> private constructor(
|
||||
getDelegatableMembers(delegatedInterfaceType).map { memberDescriptor ->
|
||||
val newModality = if (memberDescriptor.modality == Modality.ABSTRACT) Modality.OPEN else memberDescriptor.modality
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
(memberDescriptor.copy(ownerDescriptor, newModality, Visibilities.INHERITED, DELEGATION, false) as T)
|
||||
memberDescriptor.newCopyBuilder()
|
||||
.setOwner(ownerDescriptor)
|
||||
.setDispatchReceiverParameter(ownerDescriptor.thisAsReceiverParameter)
|
||||
.setModality(newModality)
|
||||
.setVisibility(Visibilities.INHERITED)
|
||||
.setKind(DELEGATION)
|
||||
.setCopyOverrides(false)
|
||||
.build() as T
|
||||
}
|
||||
|
||||
private fun checkClashWithOtherDelegatedMember(candidate: T, delegatedMembers: Collection<T>): Boolean {
|
||||
|
||||
@@ -168,13 +168,14 @@ class ClassGenerator(val declarationGenerator: DeclarationGenerator) : Generator
|
||||
private fun generateDelegateFunctionBody(irDelegate: IrFieldImpl, delegated: FunctionDescriptor, overridden: FunctionDescriptor): IrBlockBodyImpl {
|
||||
val startOffset = irDelegate.startOffset
|
||||
val endOffset = irDelegate.endOffset
|
||||
val classOwner = delegated.containingDeclaration.assertedCast<ClassDescriptor> { "Class member expected: $delegated" }
|
||||
val dispatchReceiver = delegated.dispatchReceiverParameter ?:
|
||||
throw AssertionError("Delegated member should have a dispatch receiver: $delegated")
|
||||
|
||||
val irBlockBody = IrBlockBodyImpl(startOffset, endOffset)
|
||||
val returnType = overridden.returnType!!
|
||||
val irCall = IrCallImpl(startOffset, endOffset, returnType, overridden, null)
|
||||
irCall.dispatchReceiver = IrGetFieldImpl(startOffset, endOffset, irDelegate.descriptor,
|
||||
IrGetValueImpl(startOffset, endOffset, classOwner.thisAsReceiverParameter)
|
||||
IrGetValueImpl(startOffset, endOffset, dispatchReceiver)
|
||||
)
|
||||
irCall.extensionReceiver = delegated.extensionReceiverParameter?.let { extensionReceiver ->
|
||||
IrGetValueImpl(startOffset, endOffset, extensionReceiver)
|
||||
|
||||
Reference in New Issue
Block a user