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:
Dmitry Petrov
2017-03-01 15:47:29 +03:00
parent c92f118e5e
commit dc1d92855d
2 changed files with 11 additions and 3 deletions
@@ -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)