diff --git a/lib/coffee-script/nodes.js b/lib/coffee-script/nodes.js index c274724d..60eda4ef 100644 --- a/lib/coffee-script/nodes.js +++ b/lib/coffee-script/nodes.js @@ -1,6 +1,6 @@ // Generated by CoffeeScript 1.6.1 (function() { - var Access, Arr, Assign, Base, Block, Call, Class, Closure, Code, CodeFragment, Comment, Existence, Extends, For, IDENTIFIER, IDENTIFIER_STR, IS_STRING, If, In, Index, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, METHOD_DEF, NEGATE, NO, Obj, Op, Param, Parens, RESERVED, Range, Return, SIMPLENUM, STRICT_PROSCRIBED, Scope, Slice, Splat, Switch, TAB, THIS, Throw, Try, UTILITIES, Value, While, YES, addLocationDataFn, compact, del, ends, extend, flatten, fragmentsToText, last, locationDataToString, merge, multident, some, starts, unfoldSoak, utility, _ref, _ref1, + var Access, Arr, Assign, Base, Block, Call, Class, Closure, Code, CodeFragment, Comment, Existence, Extends, For, IDENTIFIER, IDENTIFIER_STR, IS_STRING, If, In, Index, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, METHOD_DEF, NEGATE, NO, Obj, Op, Param, Parens, RESERVED, Range, Return, SIMPLENUM, STRICT_PROSCRIBED, Scope, Slice, Splat, Switch, TAB, THIS, Throw, Try, UTILITIES, Value, While, YES, addLocationDataFn, compact, del, ends, extend, flatten, fragmentsToText, last, locationDataToString, merge, multident, some, starts, unfoldSoak, utility, _ref, _ref1, _ref2, _ref3, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, @@ -554,7 +554,8 @@ __extends(Undefined, _super); function Undefined() { - return Undefined.__super__.constructor.apply(this, arguments); + _ref2 = Undefined.__super__.constructor.apply(this, arguments); + return _ref2; } Undefined.prototype.isAssignable = NO; @@ -574,7 +575,8 @@ __extends(Null, _super); function Null() { - return Null.__super__.constructor.apply(this, arguments); + _ref3 = Null.__super__.constructor.apply(this, arguments); + return _ref3; } Null.prototype.isAssignable = NO; @@ -628,8 +630,8 @@ Return.prototype.jumps = THIS; Return.prototype.compileToFragments = function(o, level) { - var expr, _ref2; - expr = (_ref2 = this.expression) != null ? _ref2.makeReturn() : void 0; + var expr, _ref4; + expr = (_ref4 = this.expression) != null ? _ref4.makeReturn() : void 0; if (expr && !(expr instanceof Return)) { return expr.compileToFragments(o, level); } else { @@ -700,10 +702,10 @@ }; Value.prototype.isAtomic = function() { - var node, _i, _len, _ref2; - _ref2 = this.properties.concat(this.base); - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - node = _ref2[_i]; + var node, _i, _len, _ref4; + _ref4 = this.properties.concat(this.base); + for (_i = 0, _len = _ref4.length; _i < _len; _i++) { + node = _ref4[_i]; if (node.soak || node instanceof Call) { return false; } @@ -780,17 +782,17 @@ }; Value.prototype.unfoldSoak = function(o) { - var _ref2, + var _ref4, _this = this; - return (_ref2 = this.unfoldedSoak) != null ? _ref2 : this.unfoldedSoak = (function() { - var fst, i, ifn, prop, ref, snd, _i, _len, _ref3, _ref4; + return (_ref4 = this.unfoldedSoak) != null ? _ref4 : this.unfoldedSoak = (function() { + var fst, i, ifn, prop, ref, snd, _i, _len, _ref5, _ref6; if (ifn = _this.base.unfoldSoak(o)) { - (_ref3 = ifn.body.properties).push.apply(_ref3, _this.properties); + (_ref5 = ifn.body.properties).push.apply(_ref5, _this.properties); return ifn; } - _ref4 = _this.properties; - for (i = _i = 0, _len = _ref4.length; _i < _len; i = ++_i) { - prop = _ref4[i]; + _ref6 = _this.properties; + for (i = _i = 0, _len = _ref6.length; _i < _len; i = ++_i) { + prop = _ref6[i]; if (!prop.soak) { continue; } @@ -854,8 +856,8 @@ Call.prototype.children = ['variable', 'args']; Call.prototype.newInstance = function() { - var base, _ref2; - base = ((_ref2 = this.variable) != null ? _ref2.base : void 0) || this.variable; + var base, _ref4; + base = ((_ref4 = this.variable) != null ? _ref4.base : void 0) || this.variable; if (base instanceof Call && !base.isNew) { base.newInstance(); } else { @@ -888,13 +890,13 @@ }; Call.prototype.unfoldSoak = function(o) { - var call, ifn, left, list, rite, _i, _len, _ref2, _ref3; + var call, ifn, left, list, rite, _i, _len, _ref4, _ref5; if (this.soak) { if (this.variable) { if (ifn = unfoldSoak(o, this, 'variable')) { return ifn; } - _ref2 = new Value(this.variable).cacheReference(o), left = _ref2[0], rite = _ref2[1]; + _ref4 = new Value(this.variable).cacheReference(o), left = _ref4[0], rite = _ref4[1]; } else { left = new Literal(this.superReference(o)); rite = new Value(left); @@ -922,9 +924,9 @@ break; } } - _ref3 = list.reverse(); - for (_i = 0, _len = _ref3.length; _i < _len; _i++) { - call = _ref3[_i]; + _ref5 = list.reverse(); + for (_i = 0, _len = _ref5.length; _i < _len; _i++) { + call = _ref5[_i]; if (ifn) { if (call.variable instanceof Call) { call.variable = ifn; @@ -938,18 +940,18 @@ }; Call.prototype.compileNode = function(o) { - var arg, argIndex, compiledArgs, compiledArray, fragments, preface, _i, _len, _ref2, _ref3; - if ((_ref2 = this.variable) != null) { - _ref2.front = this.front; + var arg, argIndex, compiledArgs, compiledArray, fragments, preface, _i, _len, _ref4, _ref5; + if ((_ref4 = this.variable) != null) { + _ref4.front = this.front; } compiledArray = Splat.compileSplattedArray(o, this.args, true); if (compiledArray.length) { return this.compileSplat(o, compiledArray); } compiledArgs = []; - _ref3 = this.args; - for (argIndex = _i = 0, _len = _ref3.length; _i < _len; argIndex = ++_i) { - arg = _ref3[argIndex]; + _ref5 = this.args; + for (argIndex = _i = 0, _len = _ref5.length; _i < _len; argIndex = ++_i) { + arg = _ref5[argIndex]; if (argIndex) { compiledArgs.push(this.makeCode(", ")); } @@ -1093,23 +1095,23 @@ } Range.prototype.compileVariables = function(o) { - var step, _ref2, _ref3, _ref4, _ref5; + var step, _ref4, _ref5, _ref6, _ref7; o = merge(o, { top: true }); - _ref2 = this.cacheToCodeFragments(this.from.cache(o, LEVEL_LIST)), this.fromC = _ref2[0], this.fromVar = _ref2[1]; - _ref3 = this.cacheToCodeFragments(this.to.cache(o, LEVEL_LIST)), this.toC = _ref3[0], this.toVar = _ref3[1]; + _ref4 = this.cacheToCodeFragments(this.from.cache(o, LEVEL_LIST)), this.fromC = _ref4[0], this.fromVar = _ref4[1]; + _ref5 = this.cacheToCodeFragments(this.to.cache(o, LEVEL_LIST)), this.toC = _ref5[0], this.toVar = _ref5[1]; if (step = del(o, 'step')) { - _ref4 = this.cacheToCodeFragments(step.cache(o, LEVEL_LIST)), this.step = _ref4[0], this.stepVar = _ref4[1]; + _ref6 = this.cacheToCodeFragments(step.cache(o, LEVEL_LIST)), this.step = _ref6[0], this.stepVar = _ref6[1]; } - _ref5 = [this.fromVar.match(SIMPLENUM), this.toVar.match(SIMPLENUM)], this.fromNum = _ref5[0], this.toNum = _ref5[1]; + _ref7 = [this.fromVar.match(SIMPLENUM), this.toVar.match(SIMPLENUM)], this.fromNum = _ref7[0], this.toNum = _ref7[1]; if (this.stepVar) { return this.stepNum = this.stepVar.match(SIMPLENUM); } }; Range.prototype.compileNode = function(o) { - var cond, condPart, from, gt, idx, idxName, known, lt, namedIndex, stepPart, to, varPart, _ref2, _ref3; + var cond, condPart, from, gt, idx, idxName, known, lt, namedIndex, stepPart, to, varPart, _ref4, _ref5; if (!this.fromVar) { this.compileVariables(o); } @@ -1127,8 +1129,8 @@ if (this.step !== this.stepVar) { varPart += ", " + this.step; } - _ref2 = ["" + idx + " <" + this.equals, "" + idx + " >" + this.equals], lt = _ref2[0], gt = _ref2[1]; - condPart = this.stepNum ? +this.stepNum > 0 ? "" + lt + " " + this.toVar : "" + gt + " " + this.toVar : known ? ((_ref3 = [+this.fromNum, +this.toNum], from = _ref3[0], to = _ref3[1], _ref3), from <= to ? "" + lt + " " + to : "" + gt + " " + to) : (cond = this.stepVar ? "" + this.stepVar + " > 0" : "" + this.fromVar + " <= " + this.toVar, "" + cond + " ? " + lt + " " + this.toVar + " : " + gt + " " + this.toVar); + _ref4 = ["" + idx + " <" + this.equals, "" + idx + " >" + this.equals], lt = _ref4[0], gt = _ref4[1]; + condPart = this.stepNum ? +this.stepNum > 0 ? "" + lt + " " + this.toVar : "" + gt + " " + this.toVar : known ? ((_ref5 = [+this.fromNum, +this.toNum], from = _ref5[0], to = _ref5[1], _ref5), from <= to ? "" + lt + " " + to : "" + gt + " " + to) : (cond = this.stepVar ? "" + this.stepVar + " > 0" : "" + this.fromVar + " <= " + this.toVar, "" + cond + " ? " + lt + " " + this.toVar + " : " + gt + " " + this.toVar); stepPart = this.stepVar ? "" + idx + " += " + this.stepVar : known ? namedIndex ? from <= to ? "++" + idx : "--" + idx : from <= to ? "" + idx + "++" : "" + idx + "--" : namedIndex ? "" + cond + " ? ++" + idx + " : --" + idx : "" + cond + " ? " + idx + "++ : " + idx + "--"; if (namedIndex) { varPart = "" + idxName + " = " + varPart; @@ -1140,11 +1142,11 @@ }; Range.prototype.compileArray = function(o) { - var args, body, cond, hasArgs, i, idt, post, pre, range, result, vars, _i, _ref2, _ref3, _results; + var args, body, cond, hasArgs, i, idt, post, pre, range, result, vars, _i, _ref4, _ref5, _results; if (this.fromNum && this.toNum && Math.abs(this.fromNum - this.toNum) <= 20) { range = (function() { _results = []; - for (var _i = _ref2 = +this.fromNum, _ref3 = +this.toNum; _ref2 <= _ref3 ? _i <= _ref3 : _i >= _ref3; _ref2 <= _ref3 ? _i++ : _i--){ _results.push(_i); } + for (var _i = _ref4 = +this.fromNum, _ref5 = +this.toNum; _ref4 <= _ref5 ? _i <= _ref5 : _i >= _ref5; _ref4 <= _ref5 ? _i++ : _i--){ _results.push(_i); } return _results; }).apply(this); if (this.exclusive) { @@ -1192,8 +1194,8 @@ } Slice.prototype.compileNode = function(o) { - var compiled, compiledText, from, fromCompiled, to, toStr, _ref2; - _ref2 = this.range, to = _ref2.to, from = _ref2.from; + var compiled, compiledText, from, fromCompiled, to, toStr, _ref4; + _ref4 = this.range, to = _ref4.to, from = _ref4.from; fromCompiled = from && from.compileToFragments(o, LEVEL_PAREN) || [this.makeCode('0')]; if (to) { compiled = to.compileToFragments(o, LEVEL_PAREN); @@ -1268,10 +1270,10 @@ }; Obj.prototype.assigns = function(name) { - var prop, _i, _len, _ref2; - _ref2 = this.properties; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - prop = _ref2[_i]; + var prop, _i, _len, _ref4; + _ref4 = this.properties; + for (_i = 0, _len = _ref4.length; _i < _len; _i++) { + prop = _ref4[_i]; if (prop.assigns(name)) { return true; } @@ -1305,11 +1307,11 @@ } answer = []; compiledObjs = (function() { - var _i, _len, _ref2, _results; - _ref2 = this.objects; + var _i, _len, _ref4, _results; + _ref4 = this.objects; _results = []; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - obj = _ref2[_i]; + for (_i = 0, _len = _ref4.length; _i < _len; _i++) { + obj = _ref4[_i]; _results.push(obj.compileToFragments(o, LEVEL_LIST)); } return _results; @@ -1332,10 +1334,10 @@ }; Arr.prototype.assigns = function(name) { - var obj, _i, _len, _ref2; - _ref2 = this.objects; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - obj = _ref2[_i]; + var obj, _i, _len, _ref4; + _ref4 = this.objects; + for (_i = 0, _len = _ref4.length; _i < _len; _i++) { + obj = _ref4[_i]; if (obj.assigns(name)) { return true; } @@ -1390,17 +1392,17 @@ }; Class.prototype.addBoundFunctions = function(o) { - var body, bound, func, lhs, name, rhs, _i, _len, _ref2, _ref3; + var body, bound, func, lhs, name, rhs, _i, _len, _ref4, _ref5; if (this.boundFuncs.length) { o.scope.assign('_this', 'this'); - _ref2 = this.boundFuncs; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - _ref3 = _ref2[_i], name = _ref3[0], func = _ref3[1]; + _ref4 = this.boundFuncs; + for (_i = 0, _len = _ref4.length; _i < _len; _i++) { + _ref5 = _ref4[_i], name = _ref5[0], func = _ref5[1]; lhs = new Value(new Literal("this"), [new Access(name)]); body = new Block([new Return(new Literal("" + this.ctor.name + ".prototype." + name.value + ".apply(_this, arguments)"))]); rhs = new Code(func.params, body, 'boundfunc'); bound = new Assign(lhs, rhs); - this.ctor.body.unshift(bound); + this.ctor.body.push(bound); } } }; @@ -1454,15 +1456,15 @@ Class.prototype.walkBody = function(name, o) { var _this = this; return this.traverseChildren(false, function(child) { - var cont, exps, i, node, _i, _len, _ref2; + var cont, exps, i, node, _i, _len, _ref4; cont = true; if (child instanceof Class) { return false; } if (child instanceof Block) { - _ref2 = exps = child.expressions; - for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) { - node = _ref2[i]; + _ref4 = exps = child.expressions; + for (i = _i = 0, _len = _ref4.length; _i < _len; i = ++_i) { + node = _ref4[i]; if (node instanceof Value && node.isObject(true)) { cont = false; exps[i] = _this.addProperties(node, name, o); @@ -1484,25 +1486,37 @@ return this.directives = expressions.splice(0, index); }; - Class.prototype.ensureConstructor = function(name) { - if (!this.ctor) { - this.ctor = new Code; - if (this.parent) { - this.ctor.body.push(new Literal("" + name + ".__super__.constructor.apply(this, arguments)")); - } - if (this.externalCtor) { - this.ctor.body.push(new Literal("" + this.externalCtor + ".apply(this, arguments)")); - } - this.ctor.body.makeReturn(); - this.body.expressions.unshift(this.ctor); - } + Class.prototype.ensureConstructor = function(name, o) { + var missing, ref, superCall; + missing = !this.ctor; + this.ctor || (this.ctor = new Code); this.ctor.ctor = this.ctor.name = name; this.ctor.klass = null; - return this.ctor.noReturn = true; + this.ctor.noReturn = true; + if (missing) { + if (this.parent) { + superCall = new Literal("" + name + ".__super__.constructor.apply(this, arguments)"); + } + if (this.externalCtor) { + superCall = new Literal("" + this.externalCtor + ".apply(this, arguments)"); + } + if (superCall) { + ref = new Literal(o.scope.freeVariable('ref')); + this.ctor.body.unshift(new Assign(ref, superCall)); + } + this.addBoundFunctions(o); + if (superCall) { + this.ctor.body.push(ref); + this.ctor.body.makeReturn(); + } + return this.body.expressions.unshift(this.ctor); + } else { + return this.addBoundFunctions(o); + } }; Class.prototype.compileNode = function(o) { - var call, decl, klass, lname, name, params, _ref2; + var call, decl, klass, lname, name, params, _ref4; decl = this.determineName(); name = decl || '_Class'; if (name.reserved) { @@ -1512,14 +1526,13 @@ this.hoistDirectivePrologue(); this.setContext(name); this.walkBody(name, o); - this.ensureConstructor(name); + this.ensureConstructor(name, o); this.body.spaced = true; if (!(this.ctor instanceof Code)) { this.body.expressions.unshift(this.ctor); } this.body.expressions.push(lname); - (_ref2 = this.body.expressions).unshift.apply(_ref2, this.directives); - this.addBoundFunctions(o); + (_ref4 = this.body.expressions).unshift.apply(_ref4, this.directives); call = Closure.wrap(this.body); if (this.parent) { this.superClass = new Literal(o.scope.freeVariable('super', false)); @@ -1544,13 +1557,13 @@ __extends(Assign, _super); function Assign(variable, value, context, options) { - var forbidden, name, _ref2; + var forbidden, name, _ref4; this.variable = variable; this.value = value; this.context = context; this.param = options && options.param; this.subpattern = options && options.subpattern; - forbidden = (_ref2 = (name = this.variable.unwrapAll().value), __indexOf.call(STRICT_PROSCRIBED, _ref2) >= 0); + forbidden = (_ref4 = (name = this.variable.unwrapAll().value), __indexOf.call(STRICT_PROSCRIBED, _ref4) >= 0); if (forbidden && this.context !== 'object') { throw SyntaxError("variable name may not be \"" + name + "\""); } @@ -1571,7 +1584,7 @@ }; Assign.prototype.compileNode = function(o) { - var answer, compiledName, isValue, match, name, val, varBase, _ref2, _ref3, _ref4, _ref5; + var answer, compiledName, isValue, match, name, val, varBase, _ref4, _ref5, _ref6, _ref7; if (isValue = this.variable instanceof Value) { if (this.variable.isArray() || this.variable.isObject()) { return this.compilePatternMatch(o); @@ -1579,7 +1592,7 @@ if (this.variable.isSplice()) { return this.compileSplice(o); } - if ((_ref2 = this.context) === '||=' || _ref2 === '&&=' || _ref2 === '?=') { + if ((_ref4 = this.context) === '||=' || _ref4 === '&&=' || _ref4 === '?=') { return this.compileConditional(o); } } @@ -1601,7 +1614,7 @@ if (match[1]) { this.value.klass = match[1]; } - this.value.name = (_ref3 = (_ref4 = (_ref5 = match[2]) != null ? _ref5 : match[3]) != null ? _ref4 : match[4]) != null ? _ref3 : match[5]; + this.value.name = (_ref5 = (_ref6 = (_ref7 = match[2]) != null ? _ref7 : match[3]) != null ? _ref6 : match[4]) != null ? _ref5 : match[5]; } val = this.value.compileToFragments(o, LEVEL_LIST); if (this.context === 'object') { @@ -1616,7 +1629,7 @@ }; Assign.prototype.compilePatternMatch = function(o) { - var acc, assigns, code, fragments, i, idx, isObject, ivar, name, obj, objects, olen, ref, rest, splat, top, val, value, vvar, vvarText, _i, _len, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7; + var acc, assigns, code, fragments, i, idx, isObject, ivar, name, obj, objects, olen, ref, rest, splat, top, val, value, vvar, vvarText, _i, _len, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9; top = o.level === LEVEL_TOP; value = this.value; objects = this.variable.base.objects; @@ -1631,14 +1644,14 @@ isObject = this.variable.isObject(); if (top && olen === 1 && !((obj = objects[0]) instanceof Splat)) { if (obj instanceof Assign) { - _ref2 = obj, (_ref3 = _ref2.variable, idx = _ref3.base), obj = _ref2.value; + _ref4 = obj, (_ref5 = _ref4.variable, idx = _ref5.base), obj = _ref4.value; } else { idx = isObject ? obj["this"] ? obj.properties[0].name : obj : new Literal(0); } acc = IDENTIFIER.test(idx.unwrap().value || 0); value = new Value(value); value.properties.push(new (acc ? Access : Index)(idx)); - if (_ref4 = obj.unwrap().value, __indexOf.call(RESERVED, _ref4) >= 0) { + if (_ref6 = obj.unwrap().value, __indexOf.call(RESERVED, _ref6) >= 0) { throw new SyntaxError("assignment to a reserved word: " + (obj.compile(o)) + " = " + (value.compile(o))); } return new Assign(obj, value, null, { @@ -1659,10 +1672,10 @@ idx = i; if (isObject) { if (obj instanceof Assign) { - _ref5 = obj, (_ref6 = _ref5.variable, idx = _ref6.base), obj = _ref5.value; + _ref7 = obj, (_ref8 = _ref7.variable, idx = _ref8.base), obj = _ref7.value; } else { if (obj.base instanceof Parens) { - _ref7 = new Value(obj.unwrapAll()).cacheReference(o), obj = _ref7[0], idx = _ref7[1]; + _ref9 = new Value(obj.unwrapAll()).cacheReference(o), obj = _ref9[0], idx = _ref9[1]; } else { idx = obj["this"] ? obj.properties[0].name : obj; } @@ -1714,8 +1727,8 @@ }; Assign.prototype.compileConditional = function(o) { - var left, right, _ref2; - _ref2 = this.variable.cacheReference(o), left = _ref2[0], right = _ref2[1]; + var left, right, _ref4; + _ref4 = this.variable.cacheReference(o), left = _ref4[0], right = _ref4[1]; if (!left.properties.length && left.base instanceof Literal && left.base.value !== "this" && !o.scope.check(left.base.value)) { throw new Error("the variable \"" + left.base.value + "\" can't be assigned with " + this.context + " because it has not been defined."); } @@ -1726,11 +1739,11 @@ }; Assign.prototype.compileSplice = function(o) { - var answer, exclusive, from, fromDecl, fromRef, name, to, valDef, valRef, _ref2, _ref3, _ref4; - _ref2 = this.variable.properties.pop().range, from = _ref2.from, to = _ref2.to, exclusive = _ref2.exclusive; + var answer, exclusive, from, fromDecl, fromRef, name, to, valDef, valRef, _ref4, _ref5, _ref6; + _ref4 = this.variable.properties.pop().range, from = _ref4.from, to = _ref4.to, exclusive = _ref4.exclusive; name = this.variable.compile(o); if (from) { - _ref3 = this.cacheToCodeFragments(from.cache(o, LEVEL_OP)), fromDecl = _ref3[0], fromRef = _ref3[1]; + _ref5 = this.cacheToCodeFragments(from.cache(o, LEVEL_OP)), fromDecl = _ref5[0], fromRef = _ref5[1]; } else { fromDecl = fromRef = '0'; } @@ -1749,7 +1762,7 @@ } else { to = "9e9"; } - _ref4 = this.value.cache(o, LEVEL_LIST), valDef = _ref4[0], valRef = _ref4[1]; + _ref6 = this.value.cache(o, LEVEL_LIST), valDef = _ref6[0], valRef = _ref6[1]; answer = [].concat(this.makeCode("[].splice.apply(" + name + ", [" + fromDecl + ", " + to + "].concat("), valDef, this.makeCode(")), "), valRef); if (o.level > LEVEL_TOP) { return this.wrapInBraces(answer); @@ -1784,7 +1797,7 @@ Code.prototype.jumps = NO; Code.prototype.compileNode = function(o) { - var answer, code, exprs, i, idt, lit, name, p, param, params, ref, splats, uniqs, val, wasEmpty, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _len5, _len6, _m, _n, _o, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8; + var answer, code, exprs, i, idt, lit, name, p, param, params, ref, splats, uniqs, val, wasEmpty, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _len5, _len6, _m, _n, _o, _ref10, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9; o.scope = new Scope(o.scope, this.body, this); o.scope.shared = del(o, 'sharedScope'); o.indent += TAB; @@ -1792,22 +1805,22 @@ delete o.isExistentialEquals; params = []; exprs = []; - _ref2 = this.paramNames(); - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - name = _ref2[_i]; + _ref4 = this.paramNames(); + for (_i = 0, _len = _ref4.length; _i < _len; _i++) { + name = _ref4[_i]; if (!o.scope.check(name)) { o.scope.parameter(name); } } - _ref3 = this.params; - for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) { - param = _ref3[_j]; + _ref5 = this.params; + for (_j = 0, _len1 = _ref5.length; _j < _len1; _j++) { + param = _ref5[_j]; if (!param.splat) { continue; } - _ref4 = this.params; - for (_k = 0, _len2 = _ref4.length; _k < _len2; _k++) { - p = _ref4[_k].name; + _ref6 = this.params; + for (_k = 0, _len2 = _ref6.length; _k < _len2; _k++) { + p = _ref6[_k].name; if (p["this"]) { p = p.properties[0].name; } @@ -1816,20 +1829,20 @@ } } splats = new Assign(new Value(new Arr((function() { - var _l, _len3, _ref5, _results; - _ref5 = this.params; + var _l, _len3, _ref7, _results; + _ref7 = this.params; _results = []; - for (_l = 0, _len3 = _ref5.length; _l < _len3; _l++) { - p = _ref5[_l]; + for (_l = 0, _len3 = _ref7.length; _l < _len3; _l++) { + p = _ref7[_l]; _results.push(p.asReference(o)); } return _results; }).call(this))), new Value(new Literal('arguments'))); break; } - _ref5 = this.params; - for (_l = 0, _len3 = _ref5.length; _l < _len3; _l++) { - param = _ref5[_l]; + _ref7 = this.params; + for (_l = 0, _len3 = _ref7.length; _l < _len3; _l++) { + param = _ref7[_l]; if (param.isComplex()) { val = ref = param.asReference(o); if (param.value) { @@ -1855,7 +1868,7 @@ exprs.unshift(splats); } if (exprs.length) { - (_ref6 = this.body.expressions).unshift.apply(_ref6, exprs); + (_ref8 = this.body.expressions).unshift.apply(_ref8, exprs); } for (i = _m = 0, _len4 = params.length; _m < _len4; i = ++_m) { p = params[i]; @@ -1863,9 +1876,9 @@ o.scope.parameter(fragmentsToText(params[i])); } uniqs = []; - _ref7 = this.paramNames(); - for (_n = 0, _len5 = _ref7.length; _n < _len5; _n++) { - name = _ref7[_n]; + _ref9 = this.paramNames(); + for (_n = 0, _len5 = _ref9.length; _n < _len5; _n++) { + name = _ref9[_n]; if (__indexOf.call(uniqs, name) >= 0) { throw SyntaxError("multiple parameters named '" + name + "'"); } @@ -1875,7 +1888,7 @@ this.body.makeReturn(); } if (this.bound) { - if ((_ref8 = o.scope.parent.method) != null ? _ref8.bound : void 0) { + if ((_ref10 = o.scope.parent.method) != null ? _ref10.bound : void 0) { this.bound = this.context = o.scope.parent.method.context; } else if (!this["static"]) { o.scope.parent.assign('_this', 'this'); @@ -1911,11 +1924,11 @@ }; Code.prototype.paramNames = function() { - var names, param, _i, _len, _ref2; + var names, param, _i, _len, _ref4; names = []; - _ref2 = this.params; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - param = _ref2[_i]; + _ref4 = this.params; + for (_i = 0, _len = _ref4.length; _i < _len; _i++) { + param = _ref4[_i]; names.push.apply(names, param.names()); } return names; @@ -1936,11 +1949,11 @@ __extends(Param, _super); function Param(name, value, splat) { - var _ref2; + var _ref4; this.name = name; this.value = value; this.splat = splat; - if (_ref2 = (name = this.name.unwrapAll().value), __indexOf.call(STRICT_PROSCRIBED, _ref2) >= 0) { + if (_ref4 = (name = this.name.unwrapAll().value), __indexOf.call(STRICT_PROSCRIBED, _ref4) >= 0) { throw SyntaxError("parameter name \"" + name + "\" is not allowed"); } } @@ -1977,7 +1990,7 @@ }; Param.prototype.names = function(name) { - var atParam, names, obj, _i, _len, _ref2; + var atParam, names, obj, _i, _len, _ref4; if (name == null) { name = this.name; } @@ -1997,9 +2010,9 @@ return atParam(name); } names = []; - _ref2 = name.objects; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - obj = _ref2[_i]; + _ref4 = name.objects; + for (_i = 0, _len = _ref4.length; _i < _len; _i++) { + obj = _ref4[_i]; if (obj instanceof Assign) { names.push.apply(names, this.names(obj.value.unwrap())); } else if (obj instanceof Splat) { @@ -2076,11 +2089,11 @@ return args[0].concat(node.makeCode(".concat("), concatPart, node.makeCode(")")); } base = (function() { - var _j, _len1, _ref2, _results; - _ref2 = list.slice(0, index); + var _j, _len1, _ref4, _results; + _ref4 = list.slice(0, index); _results = []; - for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { - node = _ref2[_j]; + for (_j = 0, _len1 = _ref4.length; _j < _len1; _j++) { + node = _ref4[_j]; _results.push(node.compileToFragments(o, LEVEL_LIST)); } return _results; @@ -2221,17 +2234,17 @@ }; Op.prototype.isComplex = function() { - var _ref2; - return !(this.isUnary() && ((_ref2 = this.operator) === '+' || _ref2 === '-')) || this.first.isComplex(); + var _ref4; + return !(this.isUnary() && ((_ref4 = this.operator) === '+' || _ref4 === '-')) || this.first.isComplex(); }; Op.prototype.isChainable = function() { - var _ref2; - return (_ref2 = this.operator) === '<' || _ref2 === '>' || _ref2 === '>=' || _ref2 === '<=' || _ref2 === '===' || _ref2 === '!=='; + var _ref4; + return (_ref4 = this.operator) === '<' || _ref4 === '>' || _ref4 === '>=' || _ref4 === '<=' || _ref4 === '===' || _ref4 === '!=='; }; Op.prototype.invert = function() { - var allInvertable, curr, fst, op, _ref2; + var allInvertable, curr, fst, op, _ref4; if (this.isChainable() && this.first.isChainable()) { allInvertable = true; curr = this; @@ -2257,7 +2270,7 @@ return this; } else if (this.second) { return new Parens(this).invert(); - } else if (this.operator === '!' && (fst = this.first.unwrap()) instanceof Op && ((_ref2 = fst.operator) === '!' || _ref2 === 'in' || _ref2 === 'instanceof')) { + } else if (this.operator === '!' && (fst = this.first.unwrap()) instanceof Op && ((_ref4 = fst.operator) === '!' || _ref4 === 'in' || _ref4 === 'instanceof')) { return fst; } else { return new Op('!', this); @@ -2265,17 +2278,17 @@ }; Op.prototype.unfoldSoak = function(o) { - var _ref2; - return ((_ref2 = this.operator) === '++' || _ref2 === '--' || _ref2 === 'delete') && unfoldSoak(o, this, 'first'); + var _ref4; + return ((_ref4 = this.operator) === '++' || _ref4 === '--' || _ref4 === 'delete') && unfoldSoak(o, this, 'first'); }; Op.prototype.generateDo = function(exp) { - var call, func, param, passedParams, ref, _i, _len, _ref2; + var call, func, param, passedParams, ref, _i, _len, _ref4; passedParams = []; func = exp instanceof Assign && (ref = exp.value.unwrap()) instanceof Code ? ref : exp; - _ref2 = func.params || []; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - param = _ref2[_i]; + _ref4 = func.params || []; + for (_i = 0, _len = _ref4.length; _i < _len; _i++) { + param = _ref4[_i]; if (param.value) { passedParams.push(param.value); delete param.value; @@ -2289,7 +2302,7 @@ }; Op.prototype.compileNode = function(o) { - var answer, isChain, _ref2, _ref3; + var answer, isChain, _ref4, _ref5; isChain = this.isChainable() && this.first.isChainable(); if (!isChain) { this.first.front = this.front; @@ -2297,7 +2310,7 @@ if (this.operator === 'delete' && o.scope.check(this.first.unwrapAll().value)) { throw SyntaxError('delete operand may not be argument or var'); } - if (((_ref2 = this.operator) === '--' || _ref2 === '++') && (_ref3 = this.first.unwrapAll().value, __indexOf.call(STRICT_PROSCRIBED, _ref3) >= 0)) { + if (((_ref4 = this.operator) === '--' || _ref4 === '++') && (_ref5 = this.first.unwrapAll().value, __indexOf.call(STRICT_PROSCRIBED, _ref5) >= 0)) { throw SyntaxError('prefix increment/decrement may not have eval or arguments operand'); } if (this.isUnary()) { @@ -2318,8 +2331,8 @@ }; Op.prototype.compileChain = function(o) { - var fragments, fst, shared, _ref2; - _ref2 = this.first.second.cache(o), this.first.second = _ref2[0], shared = _ref2[1]; + var fragments, fst, shared, _ref4; + _ref4 = this.first.second.cache(o), this.first.second = _ref4[0], shared = _ref4[1]; fst = this.first.compileToFragments(o, LEVEL_OP); fragments = fst.concat(this.makeCode(" " + (this.invert ? '&&' : '||') + " "), shared.compileToFragments(o), this.makeCode(" " + this.operator + " "), this.second.compileToFragments(o, LEVEL_OP)); return this.wrapInBraces(fragments); @@ -2387,11 +2400,11 @@ In.prototype.invert = NEGATE; In.prototype.compileNode = function(o) { - var hasSplat, obj, _i, _len, _ref2; + var hasSplat, obj, _i, _len, _ref4; if (this.array instanceof Value && this.array.isArray()) { - _ref2 = this.array.base.objects; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - obj = _ref2[_i]; + _ref4 = this.array.base.objects; + for (_i = 0, _len = _ref4.length; _i < _len; _i++) { + obj = _ref4[_i]; if (!(obj instanceof Splat)) { continue; } @@ -2406,16 +2419,16 @@ }; In.prototype.compileOrTest = function(o) { - var cmp, cnj, i, item, ref, sub, tests, _i, _len, _ref2, _ref3, _ref4; + var cmp, cnj, i, item, ref, sub, tests, _i, _len, _ref4, _ref5, _ref6; if (this.array.base.objects.length === 0) { return [this.makeCode("" + (!!this.negated))]; } - _ref2 = this.object.cache(o, LEVEL_OP), sub = _ref2[0], ref = _ref2[1]; - _ref3 = this.negated ? [' !== ', ' && '] : [' === ', ' || '], cmp = _ref3[0], cnj = _ref3[1]; + _ref4 = this.object.cache(o, LEVEL_OP), sub = _ref4[0], ref = _ref4[1]; + _ref5 = this.negated ? [' !== ', ' && '] : [' === ', ' || '], cmp = _ref5[0], cnj = _ref5[1]; tests = []; - _ref4 = this.array.base.objects; - for (i = _i = 0, _len = _ref4.length; _i < _len; i = ++_i) { - item = _ref4[i]; + _ref6 = this.array.base.objects; + for (i = _i = 0, _len = _ref6.length; _i < _len; i = ++_i) { + item = _ref6[i]; if (i) { tests.push(this.makeCode(cnj)); } @@ -2429,8 +2442,8 @@ }; In.prototype.compileLoopTest = function(o) { - var fragments, ref, sub, _ref2; - _ref2 = this.object.cache(o, LEVEL_LIST), sub = _ref2[0], ref = _ref2[1]; + var fragments, ref, sub, _ref4; + _ref4 = this.object.cache(o, LEVEL_LIST), sub = _ref4[0], ref = _ref4[1]; fragments = [].concat(this.makeCode(utility('indexOf') + ".call("), this.array.compileToFragments(o, LEVEL_LIST), this.makeCode(", "), ref, this.makeCode(") " + (this.negated ? '< 0' : '>= 0'))); if ((fragmentsToText(sub)) === (fragmentsToText(ref))) { return fragments; @@ -2467,8 +2480,8 @@ Try.prototype.isStatement = YES; Try.prototype.jumps = function(o) { - var _ref2; - return this.attempt.jumps(o) || ((_ref2 = this.recovery) != null ? _ref2.jumps(o) : void 0); + var _ref4; + return this.attempt.jumps(o) || ((_ref4 = this.recovery) != null ? _ref4.jumps(o) : void 0); }; Try.prototype.makeReturn = function(res) { @@ -2486,14 +2499,14 @@ o.indent += TAB; tryPart = this.attempt.compileToFragments(o, LEVEL_TOP); catchPart = (function() { - var _base, _ref2; + var _base, _ref4; if (this.recovery) { if (typeof (_base = this.error).isObject === "function" ? _base.isObject() : void 0) { placeholder = new Literal('_error'); this.recovery.unshift(new Assign(this.error, placeholder)); this.error = placeholder; } - if (_ref2 = this.error.value, __indexOf.call(STRICT_PROSCRIBED, _ref2) >= 0) { + if (_ref4 = this.error.value, __indexOf.call(STRICT_PROSCRIBED, _ref4) >= 0) { throw SyntaxError("catch variable may not be \"" + this.error.value + "\""); } if (!o.scope.check(this.error.value)) { @@ -2551,11 +2564,11 @@ Existence.prototype.invert = NEGATE; Existence.prototype.compileNode = function(o) { - var cmp, cnj, code, _ref2; + var cmp, cnj, code, _ref4; this.expression.front = this.front; code = this.expression.compile(o, LEVEL_OP); if (IDENTIFIER.test(code) && !o.scope.check(code)) { - _ref2 = this.negated ? ['===', '||'] : ['!==', '&&'], cmp = _ref2[0], cnj = _ref2[1]; + _ref4 = this.negated ? ['===', '||'] : ['!==', '&&'], cmp = _ref4[0], cnj = _ref4[1]; code = "typeof " + code + " " + cmp + " \"undefined\" " + cnj + " " + code + " " + cmp + " null"; } else { code = "" + code + " " + (this.negated ? '==' : '!=') + " null"; @@ -2610,13 +2623,13 @@ __extends(For, _super); function For(body, source) { - var _ref2; + var _ref4; this.source = source.source, this.guard = source.guard, this.step = source.step, this.name = source.name, this.index = source.index; this.body = Block.wrap([body]); this.own = !!source.own; this.object = !!source.object; if (this.object) { - _ref2 = [this.index, this.name], this.name = _ref2[0], this.index = _ref2[1]; + _ref4 = [this.index, this.name], this.name = _ref4[0], this.index = _ref4[1]; } if (this.index instanceof Value) { throw SyntaxError('index cannot be a pattern matching expression'); @@ -2635,9 +2648,9 @@ For.prototype.children = ['body', 'source', 'guard', 'step']; For.prototype.compileNode = function(o) { - var body, bodyFragments, compare, compareDown, declare, declareDown, defPart, defPartFragments, down, forPartFragments, guardPart, idt1, increment, index, ivar, kvar, kvarAssign, lastJumps, lvar, name, namePart, ref, resultPart, returnResult, rvar, scope, source, step, stepNum, stepVar, svar, varPart, _ref2, _ref3; + var body, bodyFragments, compare, compareDown, declare, declareDown, defPart, defPartFragments, down, forPartFragments, guardPart, idt1, increment, index, ivar, kvar, kvarAssign, lastJumps, lvar, name, namePart, ref, resultPart, returnResult, rvar, scope, source, step, stepNum, stepVar, svar, varPart, _ref4, _ref5; body = Block.wrap([this.body]); - lastJumps = (_ref2 = last(body.expressions)) != null ? _ref2.jumps() : void 0; + lastJumps = (_ref4 = last(body.expressions)) != null ? _ref4.jumps() : void 0; if (lastJumps && lastJumps instanceof Return) { this.returns = false; } @@ -2658,7 +2671,7 @@ kvar = (this.range && name) || index || ivar; kvarAssign = kvar !== ivar ? "" + kvar + " = " : ""; if (this.step && !this.range) { - _ref3 = this.cacheToCodeFragments(this.step.cache(o, LEVEL_LIST)), step = _ref3[0], stepVar = _ref3[1]; + _ref5 = this.cacheToCodeFragments(this.step.cache(o, LEVEL_LIST)), step = _ref5[0], stepVar = _ref5[1]; stepNum = stepVar.match(SIMPLENUM); } if (this.pattern) { @@ -2748,24 +2761,24 @@ }; For.prototype.pluckDirectCall = function(o, body) { - var base, defs, expr, fn, idx, ref, val, _i, _len, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7; + var base, defs, expr, fn, idx, ref, val, _i, _len, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9; defs = []; - _ref2 = body.expressions; - for (idx = _i = 0, _len = _ref2.length; _i < _len; idx = ++_i) { - expr = _ref2[idx]; + _ref4 = body.expressions; + for (idx = _i = 0, _len = _ref4.length; _i < _len; idx = ++_i) { + expr = _ref4[idx]; expr = expr.unwrapAll(); if (!(expr instanceof Call)) { continue; } val = expr.variable.unwrapAll(); - if (!((val instanceof Code) || (val instanceof Value && ((_ref3 = val.base) != null ? _ref3.unwrapAll() : void 0) instanceof Code && val.properties.length === 1 && ((_ref4 = (_ref5 = val.properties[0].name) != null ? _ref5.value : void 0) === 'call' || _ref4 === 'apply')))) { + if (!((val instanceof Code) || (val instanceof Value && ((_ref5 = val.base) != null ? _ref5.unwrapAll() : void 0) instanceof Code && val.properties.length === 1 && ((_ref6 = (_ref7 = val.properties[0].name) != null ? _ref7.value : void 0) === 'call' || _ref6 === 'apply')))) { continue; } - fn = ((_ref6 = val.base) != null ? _ref6.unwrapAll() : void 0) || val; + fn = ((_ref8 = val.base) != null ? _ref8.unwrapAll() : void 0) || val; ref = new Literal(o.scope.freeVariable('fn')); base = new Value(ref); if (val.base) { - _ref7 = [base, val], val.base = _ref7[0], base = _ref7[1]; + _ref9 = [base, val], val.base = _ref9[0], base = _ref9[1]; } body.expressions[idx] = new Call(base, expr.args); defs = defs.concat(this.makeCode(this.tab), new Assign(ref, fn).compileToFragments(o, LEVEL_TOP), this.makeCode(';\n')); @@ -2792,49 +2805,49 @@ Switch.prototype.isStatement = YES; Switch.prototype.jumps = function(o) { - var block, conds, _i, _len, _ref2, _ref3, _ref4; + var block, conds, _i, _len, _ref4, _ref5, _ref6; if (o == null) { o = { block: true }; } - _ref2 = this.cases; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - _ref3 = _ref2[_i], conds = _ref3[0], block = _ref3[1]; + _ref4 = this.cases; + for (_i = 0, _len = _ref4.length; _i < _len; _i++) { + _ref5 = _ref4[_i], conds = _ref5[0], block = _ref5[1]; if (block.jumps(o)) { return block; } } - return (_ref4 = this.otherwise) != null ? _ref4.jumps(o) : void 0; + return (_ref6 = this.otherwise) != null ? _ref6.jumps(o) : void 0; }; Switch.prototype.makeReturn = function(res) { - var pair, _i, _len, _ref2, _ref3; - _ref2 = this.cases; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - pair = _ref2[_i]; + var pair, _i, _len, _ref4, _ref5; + _ref4 = this.cases; + for (_i = 0, _len = _ref4.length; _i < _len; _i++) { + pair = _ref4[_i]; pair[1].makeReturn(res); } if (res) { this.otherwise || (this.otherwise = new Block([new Literal('void 0')])); } - if ((_ref3 = this.otherwise) != null) { - _ref3.makeReturn(res); + if ((_ref5 = this.otherwise) != null) { + _ref5.makeReturn(res); } return this; }; Switch.prototype.compileNode = function(o) { - var block, body, cond, conditions, expr, fragments, i, idt1, idt2, _i, _j, _len, _len1, _ref2, _ref3, _ref4; + var block, body, cond, conditions, expr, fragments, i, idt1, idt2, _i, _j, _len, _len1, _ref4, _ref5, _ref6; idt1 = o.indent + TAB; idt2 = o.indent = idt1 + TAB; fragments = [].concat(this.makeCode(this.tab + "switch ("), (this.subject ? this.subject.compileToFragments(o, LEVEL_PAREN) : this.makeCode("false")), this.makeCode(") {\n")); - _ref2 = this.cases; - for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) { - _ref3 = _ref2[i], conditions = _ref3[0], block = _ref3[1]; - _ref4 = flatten([conditions]); - for (_j = 0, _len1 = _ref4.length; _j < _len1; _j++) { - cond = _ref4[_j]; + _ref4 = this.cases; + for (i = _i = 0, _len = _ref4.length; _i < _len; i = ++_i) { + _ref5 = _ref4[i], conditions = _ref5[0], block = _ref5[1]; + _ref6 = flatten([conditions]); + for (_j = 0, _len1 = _ref6.length; _j < _len1; _j++) { + cond = _ref6[_j]; if (!this.subject) { cond = cond.invert(); } @@ -2881,13 +2894,13 @@ If.prototype.children = ['condition', 'body', 'elseBody']; If.prototype.bodyNode = function() { - var _ref2; - return (_ref2 = this.body) != null ? _ref2.unwrap() : void 0; + var _ref4; + return (_ref4 = this.body) != null ? _ref4.unwrap() : void 0; }; If.prototype.elseBodyNode = function() { - var _ref2; - return (_ref2 = this.elseBody) != null ? _ref2.unwrap() : void 0; + var _ref4; + return (_ref4 = this.elseBody) != null ? _ref4.unwrap() : void 0; }; If.prototype.addElse = function(elseBody) { @@ -2901,13 +2914,13 @@ }; If.prototype.isStatement = function(o) { - var _ref2; - return (o != null ? o.level : void 0) === LEVEL_TOP || this.bodyNode().isStatement(o) || ((_ref2 = this.elseBodyNode()) != null ? _ref2.isStatement(o) : void 0); + var _ref4; + return (o != null ? o.level : void 0) === LEVEL_TOP || this.bodyNode().isStatement(o) || ((_ref4 = this.elseBodyNode()) != null ? _ref4.isStatement(o) : void 0); }; If.prototype.jumps = function(o) { - var _ref2; - return this.body.jumps(o) || ((_ref2 = this.elseBody) != null ? _ref2.jumps(o) : void 0); + var _ref4; + return this.body.jumps(o) || ((_ref4 = this.elseBody) != null ? _ref4.jumps(o) : void 0); }; If.prototype.compileNode = function(o) { diff --git a/src/nodes.coffee b/src/nodes.coffee index c9dd19e8..20962342 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -989,15 +989,7 @@ exports.Class = class Class extends Base body = new Block [new Return new Literal "#{@ctor.name}.prototype.#{name.value}.apply(_this, arguments)"] rhs = new Code func.params, body, 'boundfunc' bound = new Assign lhs, rhs - - @ctor.body.unshift bound - - # {base} = assign.variable - # lhs = (new Value (new Literal "this"), [new Access base]).compile o - # @ctor.body.unshift new Literal """#{lhs} = function() { - # #{o.indent} return #{@ctor.name}.prototype.#{base.value}.apply(_this, arguments); - # #{o.indent}}\n - # """ + @ctor.body.push bound return # Merge the properties from a top-level object as prototypal properties @@ -1057,16 +1049,26 @@ exports.Class = class Class extends Base # Make sure that a constructor is defined for the class, and properly # configured. - ensureConstructor: (name) -> - if not @ctor - @ctor = new Code - @ctor.body.push new Literal "#{name}.__super__.constructor.apply(this, arguments)" if @parent - @ctor.body.push new Literal "#{@externalCtor}.apply(this, arguments)" if @externalCtor - @ctor.body.makeReturn() - @body.expressions.unshift @ctor - @ctor.ctor = @ctor.name = name - @ctor.klass = null + ensureConstructor: (name, o) -> + missing = not @ctor + @ctor or= new Code + @ctor.ctor = @ctor.name = name + @ctor.klass = null @ctor.noReturn = yes + if missing + superCall = new Literal "#{name}.__super__.constructor.apply(this, arguments)" if @parent + superCall = new Literal "#{@externalCtor}.apply(this, arguments)" if @externalCtor + if superCall + ref = new Literal o.scope.freeVariable 'ref' + @ctor.body.unshift new Assign ref, superCall + @addBoundFunctions o + if superCall + @ctor.body.push ref + @ctor.body.makeReturn() + @body.expressions.unshift @ctor + else + @addBoundFunctions o + # Instead of generating the JavaScript string directly, we build up the # equivalent syntax tree and compile that, in pieces. You can see the @@ -1080,12 +1082,11 @@ exports.Class = class Class extends Base @hoistDirectivePrologue() @setContext name @walkBody name, o - @ensureConstructor name + @ensureConstructor name, o @body.spaced = yes @body.expressions.unshift @ctor unless @ctor instanceof Code @body.expressions.push lname @body.expressions.unshift @directives... - @addBoundFunctions o call = Closure.wrap @body diff --git a/test/classes.coffee b/test/classes.coffee index ad3d673f..e2604345 100644 --- a/test/classes.coffee +++ b/test/classes.coffee @@ -740,3 +740,13 @@ test "#2489: removing __bind", -> eq thing.foo.length, 3 eq thing.bar.length, 3 + + +test "#2773: overriding bound functions", -> + class Foo + method: => 'Foo' + + class Bar extends Foo + method: => 'Bar' + + eq (new Bar).method(), 'Bar'