Skip to content

Commit

Permalink
Allow @ values as indices in for expressions
Browse files Browse the repository at this point in the history
This loosens the compilation of `for` expressions to allow the index
variable to be an `@` value, e.g.

    do @visit for @node, @Index in nodes

Within `@visit`, the index of the current node (`@node`) would be
available as `@index`.

Fixes #4411.
  • Loading branch information
Chris Connelly committed Dec 29, 2016
1 parent 0a6aeef commit 1143ac0
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 4 deletions.
4 changes: 2 additions & 2 deletions lib/coffee-script/nodes.js

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

4 changes: 2 additions & 2 deletions src/nodes.coffee
Expand Up @@ -2312,7 +2312,7 @@ exports.For = class For extends While
@index.error 'cannot use index with for-from' if @from and @index
source.ownTag.error "cannot use own with for-#{if @from then 'from' else 'in'}" if @own and not @object
[@name, @index] = [@index, @name] if @object
@index.error 'index cannot be a pattern matching expression' if @index instanceof Value
@index.error 'index cannot be a pattern matching expression' if @index instanceof Value and not @index.isAssignable()
@range = @source instanceof Value and @source.base instanceof Range and not @source.properties.length and not @from
@pattern = @name instanceof Value
@index.error 'indexes do not apply to range loops' if @range and @index
Expand All @@ -2334,7 +2334,7 @@ exports.For = class For extends While
name = @name and (@name.compile o, LEVEL_LIST) if not @pattern
index = @index and (@index.compile o, LEVEL_LIST)
scope.find(name) if name and not @pattern
scope.find(index) if index
scope.find(index) if index and @index not instanceof Value
rvar = scope.freeVariable 'results' if @returns
if @from
ivar = scope.freeVariable 'x', single: true if @pattern
Expand Down
10 changes: 10 additions & 0 deletions test/comprehensions.coffee
Expand Up @@ -515,6 +515,16 @@ test "#2274: Allow @values as loop variables", ->
obj.method()
eq obj.item, 3

test "#4411: Allow @values as loop indices", ->
obj =
index: null
get: -> @index
method: ->
@get() for _, @index in [1, 2, 3]
eq obj.index, null
arrayEq obj.method(), [0, 1, 2]
eq obj.index, 3

test "#2525, #1187, #1208, #1758, looping over an array forwards", ->
list = [0, 1, 2, 3, 4]

Expand Down
7 changes: 7 additions & 0 deletions test/error_messages.coffee
Expand Up @@ -1179,3 +1179,10 @@ test "tagged template literals must be called by an identifier", ->
1"""#{b}"""
^
'''

test "can't use pattern matches for loop indices", ->
assertErrorFormat 'a for b, {c} in d', '''
[stdin]:1:10: error: index cannot be a pattern matching expression
a for b, {c} in d
^^^
'''

0 comments on commit 1143ac0

Please sign in to comment.