diff --git a/lib/nodes.js b/lib/nodes.js index 3e90df15..d3a6d041 100644 --- a/lib/nodes.js +++ b/lib/nodes.js @@ -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)))); } diff --git a/src/nodes.coffee b/src/nodes.coffee index f66f45b9..f9b5c198 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -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) diff --git a/test/test_comprehensions.coffee b/test/test_comprehensions.coffee index 48b123be..c292e71c 100644 --- a/test/test_comprehensions.coffee +++ b/test/test_comprehensions.coffee @@ -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']