Fixing closures-generated-within-comprehensions to preserve block local scope for range comprehensions

This commit is contained in:
Jeremy Ashkenas 2010-08-08 10:52:59 -04:00
parent a749d43897
commit d286b33601
3 changed files with 17 additions and 6 deletions

View File

@ -1529,7 +1529,7 @@
scope = o.scope;
name = (this.name && this.name.compile(o)) || scope.freeVariable();
index = this.index && this.index.compile(o);
if (name && !this.pattern && !codeInBody) {
if (name && !this.pattern && (range || !codeInBody)) {
scope.find(name);
}
if (index) {
@ -1539,10 +1539,10 @@
rvar = scope.freeVariable();
}
ivar = (function() {
if (range) {
return name;
} else if (codeInBody) {
if (codeInBody) {
return scope.freeVariable();
} else if (range) {
return name;
} else {
return index || scope.freeVariable();
}
@ -1583,6 +1583,9 @@
}
this.guard ? (body = Expressions.wrap([new IfNode(this.guard, body)])) : null;
if (codeInBody) {
if (range) {
body.unshift(literal(("var " + (name) + " = " + (ivar))));
}
if (namePart) {
body.unshift(literal(("var " + (namePart))));
}

View File

@ -1305,10 +1305,10 @@ exports.ForNode = class ForNode extends BaseNode
scope = o.scope
name = (@name and @name.compile(o)) or scope.freeVariable()
index = @index and @index.compile o
scope.find name if name and not @pattern and not codeInBody
scope.find name if name and not @pattern and (range or not codeInBody)
scope.find index if index
rvar = scope.freeVariable() unless topLevel
ivar = if range then name else if codeInBody then scope.freeVariable() else index or scope.freeVariable()
ivar = if codeInBody then scope.freeVariable() else if range then name else index or scope.freeVariable()
varPart = ''
guardPart = ''
body = Expressions.wrap([@body])
@ -1334,6 +1334,7 @@ exports.ForNode = class ForNode extends BaseNode
if @guard
body = Expressions.wrap([new IfNode(@guard, body)])
if codeInBody
body.unshift literal "var #{name} = #{ivar}" if range
body.unshift literal "var #{namePart}" if namePart
body.unshift literal "var #{index} = #{ivar}" if index
body = ClosureNode.wrap(body, true)

View File

@ -71,6 +71,13 @@ ok obj.two() is "I'm two"
ok obj.three() is "I'm three"
# Ensure that local variables are closed over for range comprehensions.
funcs = for i in [1..3]
-> -i
ok (func() for func in funcs).join(' ') is '-1 -2 -3'
# Even when referenced in the filter.
list = ['one', 'two', 'three']