From 42437eb755dbf0e7a65051e5aeb6ac5c910de967 Mon Sep 17 00:00:00 2001 From: Erokhin Stanislav Date: Tue, 28 Jan 2014 21:52:58 +0400 Subject: [PATCH] JS backend: fix native spread call --- .../k2js/translate/context/Namer.java | 5 ++++ .../k2js/translate/context/StaticContext.java | 2 +- .../translate/reference/FunctionCallCases.kt | 28 +++++++++++++------ .../testFiles/native/cases/vararg.kt | 16 +++++++++++ .../testFiles/native/native/vararg.js | 5 ++++ 5 files changed, 46 insertions(+), 10 deletions(-) diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/context/Namer.java b/js/js.translator/src/org/jetbrains/k2js/translate/context/Namer.java index 63a30476a6c..18b1da16738 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/context/Namer.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/context/Namer.java @@ -37,6 +37,7 @@ public final class Namer { public static final String OUTER_CLASS_NAME = "$outer"; private static final String CALL_FUNCTION = "call"; + private static final String APPLY_FUNCTION = "apply"; private static final String CLASS_OBJECT_NAME = "createClass"; private static final String TRAIT_OBJECT_NAME = "createTrait"; private static final String OBJECT_OBJECT_NAME = "createObject"; @@ -139,6 +140,10 @@ public final class Namer { public static JsNameRef getFunctionCallRef(@NotNull JsExpression functionExpression) { return new JsNameRef(CALL_FUNCTION, functionExpression); } + @NotNull + public static JsNameRef getFunctionApplyRef(@NotNull JsExpression functionExpression) { + return new JsNameRef(APPLY_FUNCTION, functionExpression); + } @NotNull public static Namer newInstance(@NotNull JsScope rootScope) { diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/context/StaticContext.java b/js/js.translator/src/org/jetbrains/k2js/translate/context/StaticContext.java index 0667d9604cf..f6ffddee6e7 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/context/StaticContext.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/context/StaticContext.java @@ -505,7 +505,7 @@ public final class StaticContext { return null; } }; - //TODO: hack! + //TODO: hack! it seems like needed, only for Inheritance from native class Rule nativeObjectsHaveNoQualifiers = new Rule() { @Override public Boolean apply(@NotNull DeclarationDescriptor descriptor) { diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/reference/FunctionCallCases.kt b/js/js.translator/src/org/jetbrains/k2js/translate/reference/FunctionCallCases.kt index 207656963f8..8027b2fa8a8 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/reference/FunctionCallCases.kt +++ b/js/js.translator/src/org/jetbrains/k2js/translate/reference/FunctionCallCases.kt @@ -33,6 +33,7 @@ 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 public fun addReceiverToArgs(receiver: JsExpression, arguments: List) : List { if (arguments.isEmpty()) @@ -53,35 +54,41 @@ class DefaultCallCase(callInfo: FunctionCallInfo): FunctionCallCase(callInfo) { return JsInvocation(functionRef, addReceiverToArgs(receiverObject!!, argumentsInfo.getTranslateArguments())) } + // TODO: refactor after fix ArgumentsInfo - duplicate code + private fun nativeSpreadFunWithThisObjectOrReceiver(argumentsInfo: CallArgumentTranslator.ArgumentsInfo, functionName: JsName): JsExpression { + val cachedReceiver = argumentsInfo.getCachedReceiver()!! + val functionCallRef = Namer.getFunctionApplyRef(JsNameRef(functionName, cachedReceiver.assignmentExpression())) + return JsInvocation(functionCallRef, argumentsInfo.getTranslateArguments()) + } + override fun FunctionCallInfo.thisObject(): JsExpression { if (isNative() && hasSpreadOperator()) { - val cachedReceiver = argumentsInfo.getCachedReceiver()!! - val functionCallRef = Namer.getFunctionCallRef(JsNameRef(functionName, cachedReceiver.assignmentExpression())) - return JsInvocation(functionCallRef, argumentsInfo.getTranslateArguments()) + return nativeSpreadFunWithThisObjectOrReceiver(argumentsInfo, functionName) } val functionRef = JsNameRef(functionName, thisObject!!) return JsInvocation(functionRef, argumentsInfo.getTranslateArguments()) } - // TODO: refactor after fix ArgumentsInfo - duplicate code override fun FunctionCallInfo.receiverArgument(): JsExpression { - val qualifierForFunction = context.getQualifierForDescriptor(callableDescriptor) if (isNative() && hasSpreadOperator()) { - val functionCallRef = Namer.getFunctionCallRef(JsNameRef(functionName, qualifierForFunction)) - return JsInvocation(functionCallRef, argumentsInfo.getTranslateArguments()) + return nativeSpreadFunWithThisObjectOrReceiver(argumentsInfo, functionName) } if (isNative()) { return JsInvocation(JsNameRef(functionName, receiverObject), argumentsInfo.getTranslateArguments()) } + val qualifierForFunction = context.getQualifierForDescriptor(callableDescriptor) val functionCall = JsNameRef(functionName, qualifierForFunction) // TODO: remake to call return JsInvocation(functionCall, addReceiverToArgs(receiverObject!!, argumentsInfo.getTranslateArguments())) } override fun FunctionCallInfo.noReceivers(): JsExpression { - val qualifierForFunction = context.getQualifierForDescriptor(callableDescriptor) if (isNative() && hasSpreadOperator()) { - val functionCallRef = Namer.getFunctionCallRef(JsNameRef(functionName, qualifierForFunction)) + val functionCallRef = Namer.getFunctionApplyRef(JsNameRef(functionName)) return JsInvocation(functionCallRef, argumentsInfo.getTranslateArguments()) } + if (isNative()) { + return JsInvocation(JsNameRef(functionName), argumentsInfo.getTranslateArguments()) + } + val qualifierForFunction = context.getQualifierForDescriptor(callableDescriptor) val functionCall = JsNameRef(functionName, qualifierForFunction) return JsInvocation(functionCall, argumentsInfo.getTranslateArguments()) } @@ -121,6 +128,9 @@ class InvokeIntrinsic(callInfo: FunctionCallInfo) : FunctionCallCase(callInfo) { class ConstructorCallCase(callInfo: FunctionCallInfo) : FunctionCallCase(callInfo) { override fun FunctionCallInfo.noReceivers(): JsExpression { + if (isNative()) { + return JsNew(JsNameRef(functionName), argumentsInfo.getTranslateArguments()) + } return JsNew(context.getQualifiedReference(callableDescriptor), argumentsInfo.getTranslateArguments()) } } diff --git a/js/js.translator/testFiles/native/cases/vararg.kt b/js/js.translator/testFiles/native/cases/vararg.kt index efeedf0b1e5..15f62c4ed47 100644 --- a/js/js.translator/testFiles/native/cases/vararg.kt +++ b/js/js.translator/testFiles/native/cases/vararg.kt @@ -14,6 +14,12 @@ fun count(vararg a : Int) = paramCount(*a) // test spread operator fun anotherCount(vararg a : Int) = anotherParamCount(*a) +native +fun test3(bar:Bar, dummy: Int, vararg args: Int): Boolean = js.noImpl + +native +fun Bar.test2(order: Int, dummy: Int, vararg args: Int): Boolean = js.noImpl + native class Bar(val size: Int, order: Int = 0) { fun test(order: Int, dummy: Int, vararg args: Int): Boolean = js.noImpl @@ -32,6 +38,10 @@ fun spreadInMethodCall(size: Int, vararg args: Int) = Bar(size).test(0, 1, *args fun spreadInObjectMethodCall(size: Int, vararg args: Int) = obj.test(size, *args) +fun spreadInMethodCallWithReceiver(size: Int, vararg args: Int) = Bar(size).test2(0, 1, *args) + +fun spreadInPackageMethodCall(size: Int, vararg args: Int) = test3(Bar(size), 1, *args) + native fun testNativeVarargWithFunLit(vararg args: Int, f: (a: IntArray) -> Boolean): Boolean = js.noImpl @@ -79,6 +89,12 @@ fun box(): String { if (!(spreadInObjectMethodCall(2, 1, 2))) return "failed when call method of object using spread operator" + if (!spreadInMethodCallWithReceiver(2, 1, 2)) + return "failed when call method using spread operator with receiver" + + if (!spreadInPackageMethodCall(2, 1, 2)) + return "failed when call package method using spread operator" + if (!(testNativeVarargWithFunLit(1, 2, 3) { args -> args.size == 3 })) return "failed when call native function with vararg and fun literal" diff --git a/js/js.translator/testFiles/native/native/vararg.js b/js/js.translator/testFiles/native/native/vararg.js index 1222cb5d625..cbc084f5902 100644 --- a/js/js.translator/testFiles/native/native/vararg.js +++ b/js/js.translator/testFiles/native/native/vararg.js @@ -41,6 +41,11 @@ Bar.prototype.test = function (order, dummy /*, args */) { Bar.checkOrder(order); return dummy === 1 && (arguments.length - 2) === this.size; }; +Bar.prototype.test2 = Bar.prototype.test; + +function test3(bar, dummy /*, args */) { + return dummy === 1 && (arguments.length - 2) === bar.size; +} var obj = { test : function (size /*, args */) {