mirror of
https://github.com/jashkenas/coffeescript.git
synced 2026-05-03 03:00:14 -04:00
Fixing external constructors / order of execution for once and for all ... knock on wood.
This commit is contained in:
19
lib/nodes.js
19
lib/nodes.js
@@ -1032,12 +1032,12 @@
|
||||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||||
bvar = _ref2[_i];
|
||||
bname = bvar.compile(o);
|
||||
_results.push(this.ctor.body.unshift(new Literal("this." + bname + " = " + (utility('bind')) + "(this." + bname + ", this);")));
|
||||
_results.push(this.ctor.body.unshift(new Literal("this." + bname + " = " + (utility('bind')) + "(this." + bname + ", this)")));
|
||||
}
|
||||
return _results;
|
||||
}
|
||||
};
|
||||
Class.prototype.addProperties = function(node, name) {
|
||||
Class.prototype.addProperties = function(node, name, o) {
|
||||
var assign, base, exprs, func, props;
|
||||
props = node.base.properties.slice(0);
|
||||
exprs = (function() {
|
||||
@@ -1058,8 +1058,8 @@
|
||||
if (func instanceof Code) {
|
||||
assign = this.ctor = func;
|
||||
} else {
|
||||
assign = null;
|
||||
this.ctor = new Assign(new Value(new Literal(name)), func);
|
||||
this.externalCtor = o.scope.freeVariable('class');
|
||||
assign = new Assign(new Literal(this.externalCtor), func);
|
||||
}
|
||||
} else {
|
||||
if (!assign.variable["this"]) {
|
||||
@@ -1077,7 +1077,7 @@
|
||||
}).call(this);
|
||||
return compact(exprs);
|
||||
};
|
||||
Class.prototype.walkBody = function(name) {
|
||||
Class.prototype.walkBody = function(name, o) {
|
||||
return this.traverseChildren(false, __bind(function(child) {
|
||||
var exps, i, node, _len, _ref2;
|
||||
if (child instanceof Class) {
|
||||
@@ -1088,7 +1088,7 @@
|
||||
for (i = 0, _len = _ref2.length; i < _len; i++) {
|
||||
node = _ref2[i];
|
||||
if (node instanceof Value && node.isObject(true)) {
|
||||
exps[i] = this.addProperties(node, name);
|
||||
exps[i] = this.addProperties(node, name, o);
|
||||
}
|
||||
}
|
||||
return child.expressions = exps = flatten(exps);
|
||||
@@ -1099,7 +1099,10 @@
|
||||
if (!this.ctor) {
|
||||
this.ctor = new Code;
|
||||
if (this.parent) {
|
||||
this.ctor.body.push(new Call('super', [new Splat(new Literal('arguments'))]));
|
||||
this.ctor.body.push(new Literal("" + name + ".__super__.constructor.apply(this, arguments)"));
|
||||
}
|
||||
if (this.externalCtor) {
|
||||
this.ctor.body.push(new Literal("return " + this.externalCtor + ".apply(this, arguments)"));
|
||||
}
|
||||
this.body.expressions.unshift(this.ctor);
|
||||
}
|
||||
@@ -1113,7 +1116,7 @@
|
||||
name = decl || this.name || '_Class';
|
||||
lname = new Literal(name);
|
||||
this.setContext(name);
|
||||
this.walkBody(name);
|
||||
this.walkBody(name, o);
|
||||
this.ensureConstructor(name);
|
||||
if (this.parent) {
|
||||
this.body.expressions.unshift(new Extends(lname, this.parent));
|
||||
|
||||
@@ -816,11 +816,11 @@ exports.Class = class Class extends Base
|
||||
if @boundFuncs.length
|
||||
for bvar in @boundFuncs
|
||||
bname = bvar.compile o
|
||||
@ctor.body.unshift new Literal "this.#{bname} = #{utility 'bind'}(this.#{bname}, this);"
|
||||
@ctor.body.unshift new Literal "this.#{bname} = #{utility 'bind'}(this.#{bname}, this)"
|
||||
|
||||
# Merge the properties from a top-level object as prototypal properties
|
||||
# on the class.
|
||||
addProperties: (node, name) ->
|
||||
addProperties: (node, name, o) ->
|
||||
props = node.base.properties.slice 0
|
||||
exprs = while assign = props.shift()
|
||||
if assign instanceof Assign
|
||||
@@ -835,8 +835,8 @@ exports.Class = class Class extends Base
|
||||
if func instanceof Code
|
||||
assign = @ctor = func
|
||||
else
|
||||
assign = null
|
||||
@ctor = new Assign new Value(new Literal name), func
|
||||
@externalCtor = o.scope.freeVariable 'class'
|
||||
assign = new Assign new Literal(@externalCtor), func
|
||||
else
|
||||
unless assign.variable.this
|
||||
assign.variable = new Value(new Literal(name), [new Access(base, 'proto')])
|
||||
@@ -847,13 +847,13 @@ exports.Class = class Class extends Base
|
||||
compact exprs
|
||||
|
||||
# Walk the body of the class, looking for prototype properties to be converted.
|
||||
walkBody: (name) ->
|
||||
walkBody: (name, o) ->
|
||||
@traverseChildren false, (child) =>
|
||||
return false if child instanceof Class
|
||||
if child instanceof Block
|
||||
for node, i in exps = child.expressions
|
||||
if node instanceof Value and node.isObject(true)
|
||||
exps[i] = @addProperties node, name
|
||||
exps[i] = @addProperties node, name, o
|
||||
child.expressions = exps = flatten exps
|
||||
|
||||
# Make sure that a constructor is defined for the class, and properly
|
||||
@@ -861,7 +861,8 @@ exports.Class = class Class extends Base
|
||||
ensureConstructor: (name) ->
|
||||
if not @ctor
|
||||
@ctor = new Code
|
||||
@ctor.body.push new Call 'super', [new Splat new Literal 'arguments'] if @parent
|
||||
@ctor.body.push new Literal "#{name}.__super__.constructor.apply(this, arguments)" if @parent
|
||||
@ctor.body.push new Literal "return #{@externalCtor}.apply(this, arguments)" if @externalCtor
|
||||
@body.expressions.unshift @ctor
|
||||
@ctor.ctor = @ctor.name = name
|
||||
@ctor.klass = null
|
||||
@@ -876,7 +877,7 @@ exports.Class = class Class extends Base
|
||||
lname = new Literal name
|
||||
|
||||
@setContext name
|
||||
@walkBody name
|
||||
@walkBody name, o
|
||||
@ensureConstructor name
|
||||
@body.expressions.unshift new Extends lname, @parent if @parent
|
||||
@body.expressions.unshift @ctor unless @ctor instanceof Code
|
||||
|
||||
@@ -288,10 +288,10 @@ test "classes with value'd constructors", ->
|
||||
class Two
|
||||
constructor: classMaker()
|
||||
|
||||
ok (new One).value is 1
|
||||
ok (new Two).value is 2
|
||||
ok (new One).value is 1
|
||||
ok (new Two).value is 2
|
||||
eq (new One).value, 1
|
||||
eq (new Two).value, 2
|
||||
eq (new One).value, 1
|
||||
eq (new Two).value, 2
|
||||
|
||||
|
||||
test "exectuable class bodies", ->
|
||||
@@ -451,7 +451,6 @@ test "#1182: external constructors continued", ->
|
||||
class B extends A
|
||||
method: ->
|
||||
constructor: ctor
|
||||
eq ctor, B
|
||||
ok B::method
|
||||
|
||||
test "#1313: misplaced __extends", ->
|
||||
|
||||
Reference in New Issue
Block a user