diff --git a/lib/nodes.js b/lib/nodes.js index e86215fb..9ea09953 100644 --- a/lib/nodes.js +++ b/lib/nodes.js @@ -819,7 +819,7 @@ __extends(Class, Base); Class.prototype.children = ['variable', 'parent', 'body']; Class.prototype.compileNode = function(o) { - var assign, assigns, ctor, decl, exps, i, klass, lname, name, node, tail, _i, _len, _len2, _ref, _ref2, _ref3, _results; + var assign, assigns, base, bname, boundFuncs, bvar, ctor, decl, exps, func, i, klass, lname, name, node, tail, _i, _j, _len, _len2, _len3, _ref, _ref2, _ref3, _results; if (this.variable) { decl = (tail = last(this.variable.properties)) ? tail instanceof Accessor && tail.name.value : this.variable.base.value; decl && (decl = IDENTIFIER.test(decl) && decl); @@ -836,6 +836,7 @@ } } }); + boundFuncs = []; _ref = exps = this.body.expressions; for (i = 0, _len = _ref.length; i < _len; i++) { node = _ref[i]; @@ -846,8 +847,14 @@ for (_i = 0, _len2 = _ref2.length; _i < _len2; _i++) { assign = _ref2[_i]; if (assign instanceof Assign) { - assign.variable = new Value(lname, [new Accessor(assign.variable.base, 'proto')]); + base = assign.variable.base; + assign.variable = new Value(lname, [new Accessor(base, 'proto')]); delete assign.context; + func = assign.value; + if (func instanceof Code && func.bound) { + boundFuncs.push(base); + func.bound = false; + } } _results.push(assign); } @@ -880,6 +887,13 @@ exps.splice(1, 0, new Extends(lname, this.parent)); } exps.push(lname); + if (boundFuncs.length) { + for (_j = 0, _len3 = boundFuncs.length; _j < _len3; _j++) { + bvar = boundFuncs[_j]; + bname = bvar.compile(o); + ctor.body.unshift(new Literal("this." + bname + " = " + (utility('bind')) + "(this." + bname + ", this);")); + } + } klass = new Parens(new Call(new Code([], this.body)), true); if (decl && ((_ref3 = this.variable) != null ? _ref3.isComplex() : void 0)) { klass = new Assign(new Value(lname), klass); diff --git a/src/nodes.coffee b/src/nodes.coffee index 6417af58..2219c2ed 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -680,12 +680,18 @@ exports.Class = class Class extends Base node.klass = name node.context = name if node.bound + boundFuncs = [] for node, i in exps = @body.expressions if node instanceof Value and node.isObject() assigns = for assign in node.base.properties if assign instanceof Assign - assign.variable = new Value(lname, [new Accessor(assign.variable.base, 'proto')]) + base = assign.variable.base + assign.variable = new Value(lname, [new Accessor(base, 'proto')]) delete assign.context + func = assign.value + if func instanceof Code and func.bound + boundFuncs.push base + func.bound = no assign exps[i] = assigns else if node instanceof Code @@ -707,6 +713,12 @@ exports.Class = class Class extends Base ctor.noReturn = yes exps.splice 1, 0, new Extends lname, @parent if @parent exps.push lname + + if boundFuncs.length + for bvar in boundFuncs + bname = bvar.compile o + ctor.body.unshift new Literal "this.#{bname} = #{utility 'bind'}(this.#{bname}, this);" + klass = new Parens new Call(new Code [], @body), true klass = new Assign new Value(lname), klass if decl and @variable?.isComplex() klass = new Assign @variable, klass if @variable diff --git a/test/test_classes.coffee b/test/test_classes.coffee index da5e2c18..00200a42 100644 --- a/test/test_classes.coffee +++ b/test/test_classes.coffee @@ -18,7 +18,7 @@ thirdCtor = -> @array = [1, 2, 3] class ThirdChild extends SecondChild - constructor: thirdCtor + -> thirdCtor.call this # Gratuitous comment for testing. func: (string) -> @@ -40,15 +40,15 @@ ok (new ThirdChild).array.join(' ') is '1 2 3' class TopClass - constructor: (arg) -> + (arg) -> @prop = 'top-' + arg class SuperClass extends TopClass - constructor: (arg) -> + (arg) -> super 'super-' + arg class SubClass extends SuperClass - constructor: -> + -> super 'sub' ok (new SubClass).prop is 'top-super-sub' @@ -57,7 +57,7 @@ ok (new SubClass).prop is 'top-super-sub' class OneClass @new = 'new' function: 'function' - constructor: (name) -> @name = name + (name) -> @name = name class TwoClass extends OneClass @@ -121,7 +121,7 @@ ok (new SubClass).prop is 'top-super-sub' # '@' referring to the current instance, and not being coerced into a call. class ClassName - amI = -> + amI: -> @ instanceof ClassName obj = new ClassName