mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
added automatic safety closure wrapper for functions declared within for loops.
This commit is contained in:
parent
5f94186b40
commit
c3ce2ea9b1
2 changed files with 31 additions and 8 deletions
|
@ -749,6 +749,14 @@ module CoffeeScript
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# A faux-node used to wrap an expressions body in a closure.
|
||||||
|
class ClosureNode
|
||||||
|
def self.wrap(expressions)
|
||||||
|
Expressions.wrap(CallNode.new(ParentheticalNode.new(
|
||||||
|
ValueNode.new(CodeNode.new([], Expressions.wrap(expressions))))))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# A while loop, the only sort of low-level loop exposed by CoffeeScript. From
|
# A while loop, the only sort of low-level loop exposed by CoffeeScript. From
|
||||||
# it, all other loops can be manufactured.
|
# it, all other loops can be manufactured.
|
||||||
class WhileNode < Node
|
class WhileNode < Node
|
||||||
|
@ -808,25 +816,23 @@ module CoffeeScript
|
||||||
rvar = scope.free_variable unless top_level
|
rvar = scope.free_variable unless top_level
|
||||||
svar = scope.free_variable
|
svar = scope.free_variable
|
||||||
ivar = range ? name : @index ? @index : scope.free_variable
|
ivar = range ? name : @index ? @index : scope.free_variable
|
||||||
|
var_part = ''
|
||||||
|
body = Expressions.wrap(@body)
|
||||||
if range
|
if range
|
||||||
index_var = scope.free_variable
|
index_var = scope.free_variable
|
||||||
source_part = source.compile_variables(o)
|
source_part = source.compile_variables(o)
|
||||||
for_part = "#{index_var}=0, #{source.compile(o.merge(:index => ivar, :step => @step))}, #{index_var}++"
|
for_part = "#{index_var}=0, #{source.compile(o.merge(:index => ivar, :step => @step))}, #{index_var}++"
|
||||||
var_part = ''
|
|
||||||
else
|
else
|
||||||
index_var = nil
|
index_var = nil
|
||||||
source_part = "#{svar} = #{source.compile(o)};\n#{idt}"
|
source_part = "#{svar} = #{source.compile(o)};\n#{idt}"
|
||||||
for_part = @object ? "#{ivar} in #{svar}" : "#{ivar} = 0; #{ivar} < #{svar}.length; #{ivar}++"
|
for_part = @object ? "#{ivar} in #{svar}" : "#{ivar} = 0; #{ivar} < #{svar}.length; #{ivar}++"
|
||||||
var_part = @name ? "#{body_dent}#{@name} = #{svar}[#{ivar}];\n" : ''
|
var_part = "#{body_dent}#{@name} = #{svar}[#{ivar}];\n" if @name
|
||||||
|
# body.unshift(AssignNode.new(@name, ValueNode.new(svar, [IndexNode.new(ivar)]))) if @name
|
||||||
end
|
end
|
||||||
body = @body
|
|
||||||
set_result = rvar ? "#{idt}#{rvar} = []; " : idt
|
set_result = rvar ? "#{idt}#{rvar} = []; " : idt
|
||||||
return_result = rvar || ''
|
return_result = rvar || ''
|
||||||
if top_level
|
body = ClosureNode.wrap(body) if top_level && contains? {|n| n.is_a? CodeNode }
|
||||||
body = Expressions.wrap(body)
|
body = PushNode.wrap(rvar, body) unless top_level
|
||||||
else
|
|
||||||
body = PushNode.wrap(rvar, body)
|
|
||||||
end
|
|
||||||
if o[:return]
|
if o[:return]
|
||||||
return_result = "return #{return_result}" if o[:return]
|
return_result = "return #{return_result}" if o[:return]
|
||||||
o.delete(:return)
|
o.delete(:return)
|
||||||
|
|
|
@ -19,7 +19,24 @@ evens: for num in [1, 2, 3, 4, 5, 6] when num % 2 is 0
|
||||||
|
|
||||||
print(evens.join(', ') is '4, 6, 8')
|
print(evens.join(', ') is '4, 6, 8')
|
||||||
|
|
||||||
|
|
||||||
# Make sure that the "in" operator still works.
|
# Make sure that the "in" operator still works.
|
||||||
|
|
||||||
print(2 in evens)
|
print(2 in evens)
|
||||||
|
|
||||||
|
|
||||||
|
# When functions are being defined within the body of a comprehension, make
|
||||||
|
# sure that their safely wrapped in a closure to preserve local variables.
|
||||||
|
|
||||||
|
obj: {}
|
||||||
|
|
||||||
|
methods: ['one', 'two', 'three']
|
||||||
|
|
||||||
|
for method in methods
|
||||||
|
name: method
|
||||||
|
obj[name]: =>
|
||||||
|
"I'm " + name
|
||||||
|
|
||||||
|
print(obj.one() is "I'm one")
|
||||||
|
print(obj.two() is "I'm two")
|
||||||
|
print(obj.three() is "I'm three")
|
||||||
|
|
Loading…
Reference in a new issue