JS backend: fix native spread call
This commit is contained in:
@@ -37,6 +37,7 @@ public final class Namer {
|
|||||||
public static final String OUTER_CLASS_NAME = "$outer";
|
public static final String OUTER_CLASS_NAME = "$outer";
|
||||||
|
|
||||||
private static final String CALL_FUNCTION = "call";
|
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 CLASS_OBJECT_NAME = "createClass";
|
||||||
private static final String TRAIT_OBJECT_NAME = "createTrait";
|
private static final String TRAIT_OBJECT_NAME = "createTrait";
|
||||||
private static final String OBJECT_OBJECT_NAME = "createObject";
|
private static final String OBJECT_OBJECT_NAME = "createObject";
|
||||||
@@ -139,6 +140,10 @@ public final class Namer {
|
|||||||
public static JsNameRef getFunctionCallRef(@NotNull JsExpression functionExpression) {
|
public static JsNameRef getFunctionCallRef(@NotNull JsExpression functionExpression) {
|
||||||
return new JsNameRef(CALL_FUNCTION, functionExpression);
|
return new JsNameRef(CALL_FUNCTION, functionExpression);
|
||||||
}
|
}
|
||||||
|
@NotNull
|
||||||
|
public static JsNameRef getFunctionApplyRef(@NotNull JsExpression functionExpression) {
|
||||||
|
return new JsNameRef(APPLY_FUNCTION, functionExpression);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static Namer newInstance(@NotNull JsScope rootScope) {
|
public static Namer newInstance(@NotNull JsScope rootScope) {
|
||||||
|
|||||||
@@ -505,7 +505,7 @@ public final class StaticContext {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//TODO: hack!
|
//TODO: hack! it seems like needed, only for Inheritance from native class
|
||||||
Rule<Boolean> nativeObjectsHaveNoQualifiers = new Rule<Boolean>() {
|
Rule<Boolean> nativeObjectsHaveNoQualifiers = new Rule<Boolean>() {
|
||||||
@Override
|
@Override
|
||||||
public Boolean apply(@NotNull DeclarationDescriptor descriptor) {
|
public Boolean apply(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import org.jetbrains.k2js.translate.utils.TranslationUtils
|
|||||||
import org.jetbrains.k2js.translate.general.Translation
|
import org.jetbrains.k2js.translate.general.Translation
|
||||||
import org.jetbrains.k2js.translate.utils.PsiUtils
|
import org.jetbrains.k2js.translate.utils.PsiUtils
|
||||||
import com.google.dart.compiler.backend.js.ast.JsLiteral
|
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<JsExpression>) : List<JsExpression> {
|
public fun addReceiverToArgs(receiver: JsExpression, arguments: List<JsExpression>) : List<JsExpression> {
|
||||||
if (arguments.isEmpty())
|
if (arguments.isEmpty())
|
||||||
@@ -53,35 +54,41 @@ class DefaultCallCase(callInfo: FunctionCallInfo): FunctionCallCase(callInfo) {
|
|||||||
return JsInvocation(functionRef, addReceiverToArgs(receiverObject!!, argumentsInfo.getTranslateArguments()))
|
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 {
|
override fun FunctionCallInfo.thisObject(): JsExpression {
|
||||||
if (isNative() && hasSpreadOperator()) {
|
if (isNative() && hasSpreadOperator()) {
|
||||||
val cachedReceiver = argumentsInfo.getCachedReceiver()!!
|
return nativeSpreadFunWithThisObjectOrReceiver(argumentsInfo, functionName)
|
||||||
val functionCallRef = Namer.getFunctionCallRef(JsNameRef(functionName, cachedReceiver.assignmentExpression()))
|
|
||||||
return JsInvocation(functionCallRef, argumentsInfo.getTranslateArguments())
|
|
||||||
}
|
}
|
||||||
val functionRef = JsNameRef(functionName, thisObject!!)
|
val functionRef = JsNameRef(functionName, thisObject!!)
|
||||||
return JsInvocation(functionRef, argumentsInfo.getTranslateArguments())
|
return JsInvocation(functionRef, argumentsInfo.getTranslateArguments())
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: refactor after fix ArgumentsInfo - duplicate code
|
|
||||||
override fun FunctionCallInfo.receiverArgument(): JsExpression {
|
override fun FunctionCallInfo.receiverArgument(): JsExpression {
|
||||||
val qualifierForFunction = context.getQualifierForDescriptor(callableDescriptor)
|
|
||||||
if (isNative() && hasSpreadOperator()) {
|
if (isNative() && hasSpreadOperator()) {
|
||||||
val functionCallRef = Namer.getFunctionCallRef(JsNameRef(functionName, qualifierForFunction))
|
return nativeSpreadFunWithThisObjectOrReceiver(argumentsInfo, functionName)
|
||||||
return JsInvocation(functionCallRef, argumentsInfo.getTranslateArguments())
|
|
||||||
}
|
}
|
||||||
if (isNative()) {
|
if (isNative()) {
|
||||||
return JsInvocation(JsNameRef(functionName, receiverObject), argumentsInfo.getTranslateArguments())
|
return JsInvocation(JsNameRef(functionName, receiverObject), argumentsInfo.getTranslateArguments())
|
||||||
}
|
}
|
||||||
|
val qualifierForFunction = context.getQualifierForDescriptor(callableDescriptor)
|
||||||
val functionCall = JsNameRef(functionName, qualifierForFunction) // TODO: remake to call
|
val functionCall = JsNameRef(functionName, qualifierForFunction) // TODO: remake to call
|
||||||
return JsInvocation(functionCall, addReceiverToArgs(receiverObject!!, argumentsInfo.getTranslateArguments()))
|
return JsInvocation(functionCall, addReceiverToArgs(receiverObject!!, argumentsInfo.getTranslateArguments()))
|
||||||
}
|
}
|
||||||
override fun FunctionCallInfo.noReceivers(): JsExpression {
|
override fun FunctionCallInfo.noReceivers(): JsExpression {
|
||||||
val qualifierForFunction = context.getQualifierForDescriptor(callableDescriptor)
|
|
||||||
if (isNative() && hasSpreadOperator()) {
|
if (isNative() && hasSpreadOperator()) {
|
||||||
val functionCallRef = Namer.getFunctionCallRef(JsNameRef(functionName, qualifierForFunction))
|
val functionCallRef = Namer.getFunctionApplyRef(JsNameRef(functionName))
|
||||||
return JsInvocation(functionCallRef, argumentsInfo.getTranslateArguments())
|
return JsInvocation(functionCallRef, argumentsInfo.getTranslateArguments())
|
||||||
}
|
}
|
||||||
|
if (isNative()) {
|
||||||
|
return JsInvocation(JsNameRef(functionName), argumentsInfo.getTranslateArguments())
|
||||||
|
}
|
||||||
|
val qualifierForFunction = context.getQualifierForDescriptor(callableDescriptor)
|
||||||
val functionCall = JsNameRef(functionName, qualifierForFunction)
|
val functionCall = JsNameRef(functionName, qualifierForFunction)
|
||||||
return JsInvocation(functionCall, argumentsInfo.getTranslateArguments())
|
return JsInvocation(functionCall, argumentsInfo.getTranslateArguments())
|
||||||
}
|
}
|
||||||
@@ -121,6 +128,9 @@ class InvokeIntrinsic(callInfo: FunctionCallInfo) : FunctionCallCase(callInfo) {
|
|||||||
|
|
||||||
class ConstructorCallCase(callInfo: FunctionCallInfo) : FunctionCallCase(callInfo) {
|
class ConstructorCallCase(callInfo: FunctionCallInfo) : FunctionCallCase(callInfo) {
|
||||||
override fun FunctionCallInfo.noReceivers(): JsExpression {
|
override fun FunctionCallInfo.noReceivers(): JsExpression {
|
||||||
|
if (isNative()) {
|
||||||
|
return JsNew(JsNameRef(functionName), argumentsInfo.getTranslateArguments())
|
||||||
|
}
|
||||||
return JsNew(context.getQualifiedReference(callableDescriptor), argumentsInfo.getTranslateArguments())
|
return JsNew(context.getQualifiedReference(callableDescriptor), argumentsInfo.getTranslateArguments())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,12 @@ fun count(vararg a : Int) = paramCount(*a)
|
|||||||
// test spread operator
|
// test spread operator
|
||||||
fun anotherCount(vararg a : Int) = anotherParamCount(*a)
|
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
|
native
|
||||||
class Bar(val size: Int, order: Int = 0) {
|
class Bar(val size: Int, order: Int = 0) {
|
||||||
fun test(order: Int, dummy: Int, vararg args: Int): Boolean = js.noImpl
|
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 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
|
native
|
||||||
fun testNativeVarargWithFunLit(vararg args: Int, f: (a: IntArray) -> Boolean): Boolean = js.noImpl
|
fun testNativeVarargWithFunLit(vararg args: Int, f: (a: IntArray) -> Boolean): Boolean = js.noImpl
|
||||||
|
|
||||||
@@ -79,6 +89,12 @@ fun box(): String {
|
|||||||
if (!(spreadInObjectMethodCall(2, 1, 2)))
|
if (!(spreadInObjectMethodCall(2, 1, 2)))
|
||||||
return "failed when call method of object using spread operator"
|
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 }))
|
if (!(testNativeVarargWithFunLit(1, 2, 3) { args -> args.size == 3 }))
|
||||||
return "failed when call native function with vararg and fun literal"
|
return "failed when call native function with vararg and fun literal"
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,11 @@ Bar.prototype.test = function (order, dummy /*, args */) {
|
|||||||
Bar.checkOrder(order);
|
Bar.checkOrder(order);
|
||||||
return dummy === 1 && (arguments.length - 2) === this.size;
|
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 = {
|
var obj = {
|
||||||
test : function (size /*, args */) {
|
test : function (size /*, args */) {
|
||||||
|
|||||||
Reference in New Issue
Block a user