Skip to content

Commit

Permalink
Fixing external constructors / order of execution for once and for al…
Browse files Browse the repository at this point in the history
…l ... knock on wood.
  • Loading branch information
jashkenas committed May 10, 2011
1 parent f4b8e19 commit 6d6e076
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 21 deletions.
19 changes: 11 additions & 8 deletions lib/nodes.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 9 additions & 8 deletions src/nodes.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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')])
Expand All @@ -847,21 +847,22 @@ 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
# configured.
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
Expand All @@ -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
Expand Down
9 changes: 4 additions & 5 deletions test/classes.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -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", ->
Expand Down Expand Up @@ -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", ->
Expand Down

0 comments on commit 6d6e076

Please sign in to comment.