Skip to content

Commit 981db17

Browse files
committed
Adopting coco-style efficient bound functions for the common case ... but not for class/prototypes.
1 parent 52dd348 commit 981db17

File tree

3 files changed

+48
-21
lines changed

3 files changed

+48
-21
lines changed

lib/coffee-script/nodes.js

Lines changed: 24 additions & 18 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/nodes.coffee

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,8 @@ exports.Literal = class Literal extends Base
310310
compileNode: (o) ->
311311
code = if @isUndefined
312312
if o.level >= LEVEL_ACCESS then '(void 0)' else 'void 0'
313+
else if @value is 'this'
314+
if o.scope.method?.bound then o.scope.method.context else @value
313315
else if @value.reserved and "#{@value}" not in ['eval', 'arguments']
314316
"\"#{@value}\""
315317
else
@@ -1080,7 +1082,7 @@ exports.Code = class Code extends Base
10801082
@params = params or []
10811083
@body = body or new Block
10821084
@bound = tag is 'boundfunc'
1083-
@context = 'this' if @bound
1085+
@context = '_this' if @bound
10841086

10851087
children: ['params', 'body']
10861088

@@ -1095,7 +1097,7 @@ exports.Code = class Code extends Base
10951097
# a closure.
10961098
compileNode: (o) ->
10971099
o.scope = new Scope o.scope, @body, this
1098-
o.scope.shared = del o, 'sharedScope'
1100+
o.scope.shared = del(o, 'sharedScope')
10991101
o.indent += TAB
11001102
delete o.bare
11011103
vars = []
@@ -1122,14 +1124,18 @@ exports.Code = class Code extends Base
11221124
@body.expressions.unshift exprs... if exprs.length
11231125
o.scope.parameter vars[i] = v.compile o for v, i in vars unless splats
11241126
@body.makeReturn() unless wasEmpty or @noReturn
1127+
if @bound
1128+
if o.scope.parent.method?.bound
1129+
@bound = o.scope.parent.method.context
1130+
else
1131+
o.scope.parent.assign '_this', 'this'
11251132
idt = o.indent
11261133
code = 'function'
11271134
code += ' ' + @name if @ctor
11281135
code += '(' + vars.join(', ') + ') {'
11291136
code += "\n#{ @body.compileWithDeclarations o }\n#{@tab}" unless @body.isEmpty()
11301137
code += '}'
11311138
return @tab + code if @ctor
1132-
return utility('bind') + "(#{code}, #{@context})" if @bound
11331139
if @front or (o.level >= LEVEL_ACCESS) then "(#{code})" else code
11341140

11351141
# Short-circuit `traverseChildren` method to prevent it from crossing scope boundaries

test/functions.coffee

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,21 @@ ok obj isnt obj.unbound()
6464
eq obj, obj.nested()
6565

6666

67+
test "even more fancy bound functions", ->
68+
obj =
69+
one: ->
70+
do =>
71+
return this.two()
72+
two: ->
73+
do =>
74+
do =>
75+
do =>
76+
return this.three
77+
three: 3
78+
79+
eq obj.one(), 3
80+
81+
6782
test "self-referencing functions", ->
6883
changeMe = ->
6984
changeMe = 2

0 commit comments

Comments
 (0)