wip
diff --git a/compiler/testData/codegen/box/callableReference/bound/emptyLHS.kt b/compiler/testData/codegen/box/callableReference/bound/emptyLHS.kt index b32270c..fb4fd3c 100644 --- a/compiler/testData/codegen/box/callableReference/bound/emptyLHS.kt +++ b/compiler/testData/codegen/box/callableReference/bound/emptyLHS.kt
@@ -6,32 +6,34 @@ val memberProperty: Int get() = 42.also { result += "A.mp," } val aMemberProperty: Int get() = 42.also { result += "A.amp," } - fun test(): String { - (::memberFunction)() - (::aExtensionFunction)() - - (::memberProperty)() - (::aExtensionProperty)() - - return result - } +// fun test(): String { +// (::memberFunction)() +// (::aExtensionFunction)() +// +// (::memberProperty)() +// (::aExtensionProperty)() +// +// return result +// } inner class B { fun memberFunction() { result += "B.mf," } val memberProperty: Int get() = 42.also { result += "B.mp," } fun test(): String { + aMemberFunction() + (::aMemberFunction)() - (::aExtensionFunction)() - - (::aMemberProperty)() - (::aExtensionProperty)() - - (::memberFunction)() - (::memberProperty)() - - (::bExtensionFunction)() - (::bExtensionProperty)() +// (::aExtensionFunction)() +// +// (::aMemberProperty)() +// (::aExtensionProperty)() +// +// (::memberFunction)() +// (::memberProperty)() +// +// (::bExtensionFunction)() +// (::bExtensionProperty)() return result } @@ -44,8 +46,9 @@ val A.B.bExtensionProperty: Int get() = 42.also { result += "B.ep," } fun box(): String { - val a = A().test() - if (a != "A.mf,A.ef,A.mp,A.ep,") return "Fail $a" +// (A()::aExtensionFunction)() +// val a = A().test() +// if (a != "A.mf,A.ef,A.mp,A.ep,") return "Fail $a" result = "" val b = A().B().test()
diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallableReferenceTranslator.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallableReferenceTranslator.kt index 258a6d0..b877a11 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallableReferenceTranslator.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallableReferenceTranslator.kt
@@ -38,7 +38,10 @@ import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument +import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind import org.jetbrains.kotlin.resolve.calls.util.CallMaker +import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension +import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue import org.jetbrains.kotlin.types.expressions.DoubleColonLHS object CallableReferenceTranslator { @@ -46,23 +49,30 @@ fun translate(expression: KtCallableReferenceExpression, context: TranslationContext): JsExpression { val descriptor = BindingUtils.getDescriptorForReferenceExpression(context.bindingContext(), expression.callableReference) - val receiver = expression.receiverExpression?.let { r -> - if (context.bindingContext().get(BindingContext.DOUBLE_COLON_LHS, r) is DoubleColonLHS.Expression && - descriptor is CallableMemberDescriptor && - descriptor.dispatchReceiverParameter ?: descriptor.extensionReceiverParameter != null - ) { - val block = JsBlock() - val e = Translation.translateAsExpression(r, context, block) - if (!block.isEmpty) { - context.addStatementsToCurrentBlockFrom(block) + val receiverExpression = expression.receiverExpression + val receiver = when { + receiverExpression != null -> { + if (context.bindingContext().get(BindingContext.DOUBLE_COLON_LHS, receiverExpression) is DoubleColonLHS.Expression && + descriptor is CallableMemberDescriptor && + descriptor.dispatchReceiverParameter ?: descriptor.extensionReceiverParameter != null + ) { + val block = JsBlock() + val e = Translation.translateAsExpression(receiverExpression, context, block) + if (!block.isEmpty) { + context.addStatementsToCurrentBlockFrom(block) + } + e } - e + else { + null + } } - else { - null + descriptor is PropertyImportedFromObject -> { + ReferenceTranslator.translateAsValueReference(descriptor.containingObject, context) } - } ?: (descriptor as? PropertyImportedFromObject)?.let { - ReferenceTranslator.translateAsValueReference(it.containingObject, context) + else -> { // Assume receiver is `this` + JsThisRef() + } } return when (descriptor) { @@ -94,11 +104,20 @@ override fun getValueArgumentsByIndex(): List<ResolvedValueArgument> = valueArgumentList override fun getValueArguments(): Map<ValueParameterDescriptor, ResolvedValueArgument> = valueArgumentMap + + override fun getExplicitReceiverKind(): ExplicitReceiverKind { + if (receiver != null) { + return if (descriptor.isExtension) ExplicitReceiverKind.EXTENSION_RECEIVER else ExplicitReceiverKind.DISPATCH_RECEIVER + } + else { + return ExplicitReceiverKind.NO_EXPLICIT_RECEIVER + } + } } val function = JsFunction(context.scope(), JsBlock(), "") function.source = expression - val receiverParam = if (descriptor.dispatchReceiverParameter != null || descriptor.extensionReceiverParameter != null) { + val receiverParam = if (descriptor.dispatchReceiverParameter != null || descriptor.extensionReceiverParameter != null || receiver != null) { val paramName = JsScope.declareTemporaryName(Namer.getReceiverParameterName()) function.parameters += JsParameter(paramName) paramName.makeRef() @@ -127,7 +146,18 @@ expression: KtCallableReferenceExpression, receiver: JsExpression? ): JsExpression { - val call = expression.callableReference.getPropertyResolvedCallWithAssert(context.bindingContext()) + val realCall = expression.callableReference.getPropertyResolvedCallWithAssert(context.bindingContext()) + + val call = object : DelegatingResolvedCall<PropertyDescriptor>(realCall) { + override fun getExplicitReceiverKind(): ExplicitReceiverKind { + if (receiver != null) { + return if (descriptor.isExtension) ExplicitReceiverKind.EXTENSION_RECEIVER else ExplicitReceiverKind.DISPATCH_RECEIVER + } + else { + return ExplicitReceiverKind.NO_EXPLICIT_RECEIVER + } + } + } val getter = translateForPropertyAccessor(call, expression, descriptor, context, receiver, false) { context, call, _, receiverParam -> CallTranslator.translateGet(context, call, receiverParam)