From 084071e2e57519df8e86363d31b58dbc35542e42 Mon Sep 17 00:00:00 2001 From: Roman Artemev Date: Mon, 17 Sep 2018 16:59:52 +0300 Subject: [PATCH] [JS IR BE] Fix callable reference lowering * more precisely handle implicit receiver arguments --- .../js/lower/CallableReferenceLowering.kt | 41 +++++++++++++++---- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/CallableReferenceLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/CallableReferenceLowering.kt index dbed1f545da..370b1d77c7d 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/CallableReferenceLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/CallableReferenceLowering.kt @@ -410,17 +410,44 @@ class CallableReferenceLowering(val context: JsIrBackendContext) { ): List { val result = mutableListOf() - if (callable.dispatchReceiverParameter != null && reference.dispatchReceiver == null) { - val dispatch = callable.dispatchReceiverParameter!! - result.add(JsIrBuilder.buildValueParameter(dispatch.name, result.size, dispatch.type).also { it.parent = closure }) + /* + * class D { + * fun foo(a, b, c) {} <= callable signature + * } + * + * val d = D() + * val reference = d::foo <= captures dispatch receiver + * + * is translated into + * + * function foo_get(d) { <= getter signature(d) + * return function (a, b, c) { <= result signature (a, b, c) + * return d.foo(a, b, c) + * } + * } + */ + var caprutedParams = getter.valueParameters.size + + callable.dispatchReceiverParameter?.let { dispatch -> + if (reference.dispatchReceiver == null) { + result.add(JsIrBuilder.buildValueParameter(dispatch.name, result.size, dispatch.type).also { it.parent = closure }) + } else { + // do not consider implicit receiver in result signature if it was captured + caprutedParams-- + } } - if (callable.extensionReceiverParameter != null && reference.extensionReceiver == null) { - val ext = callable.extensionReceiverParameter!! - result.add(JsIrBuilder.buildValueParameter(ext.name, result.size, ext.type).also { it.parent = closure }) + callable.extensionReceiverParameter?.let { ext -> + if (reference.extensionReceiver == null) { + result.add(JsIrBuilder.buildValueParameter(ext.name, result.size, ext.type).also { it.parent = closure }) + } else { + // the same as for dispatch + caprutedParams-- + } } - for (i in getter.valueParameters.size until callable.valueParameters.size) { + // pass through value parameters + for (i in caprutedParams until callable.valueParameters.size) { val param = callable.valueParameters[i] val paramName = param.name.run { if (!isSpecial) identifier else "p$i" } result += JsIrBuilder.buildValueParameter(paramName, result.size, param.type).also { it.parent = closure }