mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
Allow @
values as indices in for
expressions
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.
This commit is contained in:
parent
0a6aeef0c9
commit
1143ac0268
4 changed files with 21 additions and 4 deletions
|
@ -3415,7 +3415,7 @@
|
|||
if (this.object) {
|
||||
ref3 = [this.index, this.name], this.name = ref3[0], this.index = ref3[1];
|
||||
}
|
||||
if (this.index instanceof Value) {
|
||||
if (this.index instanceof Value && !this.index.isAssignable()) {
|
||||
this.index.error('index cannot be a pattern matching expression');
|
||||
}
|
||||
this.range = this.source instanceof Value && this.source.base instanceof Range && !this.source.properties.length && !this.from;
|
||||
|
@ -3447,7 +3447,7 @@
|
|||
if (name && !this.pattern) {
|
||||
scope.find(name);
|
||||
}
|
||||
if (index) {
|
||||
if (index && !(this.index instanceof Value)) {
|
||||
scope.find(index);
|
||||
}
|
||||
if (this.returns) {
|
||||
|
|
|
@ -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
|
||||
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
||||
|
|
|
@ -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
|
||||
^^^
|
||||
'''
|
||||
|
|
Loading…
Add table
Reference in a new issue