diff --git a/lib/nodes.js b/lib/nodes.js index 2b098e6c..8b0c961e 100644 --- a/lib/nodes.js +++ b/lib/nodes.js @@ -507,6 +507,13 @@ return ''; } }; + // Grab the reference to the superclass' implementation of the current method. + CallNode.prototype.super_reference = function super_reference(o) { + var meth, methname; + methname = o.scope.method.name; + meth = o.scope.method.proto ? ("" + (o.scope.method.proto) + ".__superClass__." + methname) : ("" + (methname) + ".__superClass__.constructor"); + return meth; + }; // Compile a vanilla function call. CallNode.prototype.compile_node = function compile_node(o) { var _a, _b, _c, _d, _e, _f, _g, arg, args; @@ -533,17 +540,14 @@ // `super()` is converted into a call against the superclass's implementation // of the current function. CallNode.prototype.compile_super = function compile_super(args, o) { - var meth, methname; - methname = o.scope.method.name; - meth = o.scope.method.proto ? ("" + (o.scope.method.proto) + ".__superClass__." + methname) : ("" + (methname) + ".__superClass__.constructor"); - return "" + (meth) + ".call(this" + (args.length ? ', ' : '') + args + ")"; + return "" + (this.super_reference(o)) + ".call(this" + (args.length ? ', ' : '') + args + ")"; }; // 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. CallNode.prototype.compile_splat = function compile_splat(o) { var meth, obj, temp; - meth = this.variable.compile(o); - obj = this.variable.source || 'this'; + meth = this.variable ? this.variable.compile(o) : this.super_reference(o); + obj = this.variable && this.variable.source || 'this'; if (obj.match(/\(/)) { temp = o.scope.free_variable(); obj = temp; diff --git a/src/nodes.coffee b/src/nodes.coffee index ffa25272..739f4a21 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -369,6 +369,14 @@ exports.CallNode: class CallNode extends BaseNode prefix: -> if @is_new then 'new ' else '' + # Grab the reference to the superclass' implementation of the current method. + super_reference: (o) -> + methname: o.scope.method.name + meth: if o.scope.method.proto + "${o.scope.method.proto}.__superClass__.$methname" + else + "${methname}.__superClass__.constructor" + # Compile a vanilla function call. compile_node: (o) -> for arg in @args @@ -380,18 +388,13 @@ exports.CallNode: class CallNode extends BaseNode # `super()` is converted into a call against the superclass's implementation # of the current function. compile_super: (args, o) -> - methname: o.scope.method.name - meth: if o.scope.method.proto - "${o.scope.method.proto}.__superClass__.$methname" - else - "${methname}.__superClass__.constructor" - "${meth}.call(this${ if args.length then ', ' else '' }$args)" + "${@super_reference(o)}.call(this${ if args.length then ', ' else '' }$args)" # 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. compile_splat: (o) -> - meth: @variable.compile o - obj: @variable.source or 'this' + meth: if @variable then @variable.compile(o) else @super_reference(o) + obj: @variable and @variable.source or 'this' if obj.match(/\(/) temp: o.scope.free_variable() obj: temp diff --git a/test/test_splats.coffee b/test/test_splats.coffee index 97e60dfc..00dec887 100644 --- a/test/test_splats.coffee +++ b/test/test_splats.coffee @@ -75,4 +75,18 @@ ok crowd[0] is contenders[0] ok crowd[10] is "Mighty Mouse" ok bests[1] is contenders[0] -ok bests[4] is contenders[3] \ No newline at end of file +ok bests[4] is contenders[3] + + +# Finally, splats with super() within classes. + +class Parent + meth: (args...) -> + args + +class Child extends Parent + meth: -> + nums: [3, 2, 1] + super nums... + +ok (new Child()).meth().join(' ') is '3 2 1' \ No newline at end of file