Fixing splats-with-super()-in-classes, an oversight.

This commit is contained in:
Jeremy Ashkenas 2010-04-24 15:57:15 -04:00
parent 49824ce1a6
commit 1438cecfad
3 changed files with 36 additions and 15 deletions

View File

@ -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;

View File

@ -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

View File

@ -76,3 +76,17 @@ ok crowd[10] is "Mighty Mouse"
ok bests[1] is contenders[0]
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'