diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/FunctionTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/FunctionTest.java index 71b519b8cb3..c829649bbc4 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/FunctionTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/FunctionTest.java @@ -87,6 +87,9 @@ public class FunctionTest extends AbstractExpressionTest { fooBoxTest(); } + public void testExpressionAsExtFunction() throws Exception { + checkFooBoxIsOk(); + } public void testVararg() throws Exception { checkFooBoxIsOk(); diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/callTranslator/FunctionCallCases.kt b/js/js.translator/src/org/jetbrains/k2js/translate/callTranslator/FunctionCallCases.kt index 842aa6ec02d..d1461c19d82 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/callTranslator/FunctionCallCases.kt +++ b/js/js.translator/src/org/jetbrains/k2js/translate/callTranslator/FunctionCallCases.kt @@ -22,22 +22,18 @@ import com.google.dart.compiler.backend.js.ast.JsInvocation import java.util.Collections import java.util.ArrayList import org.jetbrains.k2js.translate.context.Namer -import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor import org.jetbrains.jet.lang.descriptors.CallableDescriptor -import org.jetbrains.jet.lang.resolve.calls.tasks.ExplicitReceiverKind import com.google.dart.compiler.backend.js.ast.JsNew import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns import org.jetbrains.jet.lang.resolve.calls.util.ExpressionAsFunctionDescriptor -import org.jetbrains.k2js.translate.utils.TranslationUtils import org.jetbrains.k2js.translate.general.Translation -import org.jetbrains.k2js.translate.utils.PsiUtils import com.google.dart.compiler.backend.js.ast.JsLiteral import com.google.dart.compiler.backend.js.ast.JsName import org.jetbrains.k2js.translate.context.TranslationContext import org.jetbrains.k2js.translate.reference.CallArgumentTranslator -public fun addReceiverToArgs(receiver: JsExpression, arguments: List) : List { +public fun addReceiverToArgs(receiver: JsExpression, arguments: List): List { if (arguments.isEmpty()) return Collections.singletonList(receiver) @@ -58,10 +54,10 @@ object DefaultFunctionCallCase : FunctionCallCase { } fun buildDefaultCallWithThisObject(argumentsInfo: CallArgumentTranslator.ArgumentsInfo, - thisObject: JsExpression, - functionName: JsName, - isNative: Boolean, - hasSpreadOperator: Boolean): JsExpression { + thisObject: JsExpression, + functionName: JsName, + isNative: Boolean, + hasSpreadOperator: Boolean): JsExpression { if (isNative && hasSpreadOperator) { return nativeSpreadFunWithThisObjectOrReceiver(argumentsInfo, functionName) } @@ -113,7 +109,8 @@ object DefaultFunctionCallCase : FunctionCallCase { return JsInvocation(functionRef, addReceiverToArgs(receiverObject!!, argumentsInfo.getTranslateArguments())) } - override fun FunctionCallInfo.bothReceivers(): JsExpression { // TODO: think about crazy case: spreadOperator + native + override fun FunctionCallInfo.bothReceivers(): JsExpression { + // TODO: think about crazy case: spreadOperator + native val functionRef = JsNameRef(functionName, thisObject!!) return JsInvocation(functionRef, addReceiverToArgs(receiverObject!!, argumentsInfo.getTranslateArguments())) } @@ -178,6 +175,15 @@ object ExpressionAsFunctionDescriptorIntrinsic : FunctionCallCase { val funRef = Translation.translateAsExpression((callableDescriptor as ExpressionAsFunctionDescriptor).getExpression()!!, context) return JsInvocation(funRef, argumentsInfo.getTranslateArguments()) } + + override fun FunctionCallInfo.receiverArgument(): JsExpression { + if (callableDescriptor !is ExpressionAsFunctionDescriptor) { + throw IllegalStateException("callableDescriptor must be ExpressionAsFunctionDescriptor $this") + } + + val funRef = Translation.translateAsExpression((callableDescriptor as ExpressionAsFunctionDescriptor).getExpression()!!, context) + return JsInvocation(funRef, addReceiverToArgs(receiverObject!!, argumentsInfo.getTranslateArguments())) + } } object SuperCallCase : FunctionCallCase { @@ -185,9 +191,10 @@ object SuperCallCase : FunctionCallCase { return callInfo.isSuperInvocation() } - override fun FunctionCallInfo.thisObject(): JsExpression { // TODO: spread operator + override fun FunctionCallInfo.thisObject(): JsExpression { + // TODO: spread operator val prototypeClass = JsNameRef(Namer.getPrototypeName(), thisObject!!) - val functionRef = Namer.getFunctionCallRef(JsNameRef(functionName, prototypeClass)) + val functionRef = Namer.getFunctionCallRef(JsNameRef(functionName, prototypeClass)) return JsInvocation(functionRef, addReceiverToArgs(JsLiteral.THIS, argumentsInfo.getTranslateArguments())) } } diff --git a/js/js.translator/testData/expression/function/cases/expressionAsExtFunction.kt b/js/js.translator/testData/expression/function/cases/expressionAsExtFunction.kt new file mode 100644 index 00000000000..66c80d30e75 --- /dev/null +++ b/js/js.translator/testData/expression/function/cases/expressionAsExtFunction.kt @@ -0,0 +1,8 @@ +package foo + +fun box(): String { + val a = 23.{ Int.(a: Int) -> a * a + this }(3) + if (a != 32) return "a != 32, a = $a"; + + return "OK"; +}