[IR] Supported extension receivers in SAM conversions

This commit is contained in:
Igor Chevdar
2020-06-17 00:02:40 +05:00
parent 8c2baf0704
commit 2bf73ccfe5
@@ -147,13 +147,14 @@ abstract class SingleAbstractMethodLowering(val context: CommonBackendContext) :
val inlinePrefix = if (wrapperVisibility == Visibilities.PUBLIC) "\$i" else "" val inlinePrefix = if (wrapperVisibility == Visibilities.PUBLIC) "\$i" else ""
val wrapperName = Name.identifier("sam$inlinePrefix\$$superFqName$SAM_WRAPPER_SUFFIX") val wrapperName = Name.identifier("sam$inlinePrefix\$$superFqName$SAM_WRAPPER_SUFFIX")
val superMethod = superClass.functions.single { it.modality == Modality.ABSTRACT } val superMethod = superClass.functions.single { it.modality == Modality.ABSTRACT }
val extensionReceiversCount = if (superMethod.extensionReceiverParameter == null) 0 else 1
// TODO: have psi2ir cast the argument to the correct function type. Also see the TODO // TODO: have psi2ir cast the argument to the correct function type. Also see the TODO
// about type parameters in `visitTypeOperator`. // about type parameters in `visitTypeOperator`.
val wrappedFunctionClass = val wrappedFunctionClass =
if (superMethod.isSuspend) if (superMethod.isSuspend)
context.ir.symbols.suspendFunctionN(superMethod.valueParameters.size).owner context.ir.symbols.suspendFunctionN(superMethod.valueParameters.size + extensionReceiversCount).owner
else else
context.ir.symbols.functionN(superMethod.valueParameters.size).owner context.ir.symbols.functionN(superMethod.valueParameters.size + extensionReceiversCount).owner
val wrappedFunctionType = wrappedFunctionClass.defaultType val wrappedFunctionType = wrappedFunctionClass.defaultType
val subclass = buildClass { val subclass = buildClass {
@@ -204,11 +205,13 @@ abstract class SingleAbstractMethodLowering(val context: CommonBackendContext) :
}.apply { }.apply {
overriddenSymbols = listOf(superMethod.symbol) overriddenSymbols = listOf(superMethod.symbol)
dispatchReceiverParameter = subclass.thisReceiver!!.copyTo(this) dispatchReceiverParameter = subclass.thisReceiver!!.copyTo(this)
extensionReceiverParameter = superMethod.extensionReceiverParameter?.copyTo(this)
valueParameters = superMethod.valueParameters.map { it.copyTo(this) } valueParameters = superMethod.valueParameters.map { it.copyTo(this) }
body = context.createIrBuilder(symbol).irBlockBody { body = context.createIrBuilder(symbol).irBlockBody {
+irReturn(irCall(wrappedFunctionClass.functions.single { it.name == OperatorNameConventions.INVOKE }).apply { +irReturn(irCall(wrappedFunctionClass.functions.single { it.name == OperatorNameConventions.INVOKE }).apply {
dispatchReceiver = irGetField(irGet(dispatchReceiverParameter!!), field) dispatchReceiver = irGetField(irGet(dispatchReceiverParameter!!), field)
valueParameters.forEachIndexed { i, parameter -> putValueArgument(i, irGet(parameter)) } extensionReceiverParameter?.let { putValueArgument(0, irGet(it)) }
valueParameters.forEachIndexed { i, parameter -> putValueArgument(extensionReceiversCount + i, irGet(parameter)) }
}) })
} }
} }