diff --git a/lib/nodes.js b/lib/nodes.js index d3491856..33fed78f 100644 --- a/lib/nodes.js +++ b/lib/nodes.js @@ -482,7 +482,12 @@ obj = temp; meth = ("(" + temp + " = " + (this.variable.source) + ")" + (this.variable.last)); } - return "" + (this.prefix()) + (meth) + ".apply(" + obj + ", " + (this.compileSplatArguments(o)) + ")"; + if (this.isNew) { + utility('extends'); + return "(function() {\n" + (this.idt(1)) + "var ctor = function(){ };\n" + (this.idt(1)) + "__extends(ctor, " + meth + ");\n" + (this.idt(1)) + "return " + (meth) + ".apply(new ctor, " + (this.compileSplatArguments(o)) + ");\n" + this.tab + "}).call(this)"; + } else { + return "" + (this.prefix()) + (meth) + ".apply(" + obj + ", " + (this.compileSplatArguments(o)) + ")"; + } }; return CallNode; })(); diff --git a/src/nodes.coffee b/src/nodes.coffee index 275d9b35..c779f702 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -440,6 +440,8 @@ exports.CallNode: class CallNode extends BaseNode # If you call a function with a splat, it's converted into a JavaScript # `.apply()` call to allow an array of arguments to be passed. + # If it's a constructor, then things get real tricky. We have to inject an + # inner constructor in order to be able to pass the varargs. compileSplat: (o) -> meth: if @variable then @variable.compile(o) else @superReference(o) obj: @variable and @variable.source or 'this' @@ -447,7 +449,17 @@ exports.CallNode: class CallNode extends BaseNode temp: o.scope.freeVariable() obj: temp meth: "($temp = ${ @variable.source })${ @variable.last }" - "${@prefix()}${meth}.apply($obj, ${ @compileSplatArguments(o) })" + if @isNew + utility 'extends' + """ + (function() { + ${@idt(1)}var ctor = function(){ }; + ${@idt(1)}__extends(ctor, $meth); + ${@idt(1)}return ${meth}.apply(new ctor, ${ @compileSplatArguments(o) }); + $@tab}).call(this) + """ + else + "${@prefix()}${meth}.apply($obj, ${ @compileSplatArguments(o) })" #### ExtendsNode diff --git a/test/test_classes.coffee b/test/test_classes.coffee index 0930d231..9867e21e 100644 --- a/test/test_classes.coffee +++ b/test/test_classes.coffee @@ -156,3 +156,16 @@ class Mini m: new Mini ok (func() for func in m.generate()).join(' ') is '10 10 10' + + +# Testing a contructor called with varargs. +class Connection + constructor: (one, two, three) -> + [@one, @two, @three]: [one, two, three] + + out: -> + "$@one-$@two-$@three" + +list: [3, 2, 1] +conn: new Connection list... +ok conn.out() is '3-2-1'