Description
(discovered in https://bugzilla.mozilla.org/show_bug.cgi?id=1934205 )
In the proposal, ForInOfStatement
definition is modified and the using
handling is added into ForDeclaration
with [Using]
parameter, where the parameter is set only after a negative lookahead for for of
using of
:
https://arai-a.github.io/ecma262-compare/?pr=3000&id=sec-for-in-and-for-of-statements&secAll=true
ForInOfStatement[Yield, Await, Return] :
for ( [lookahead ≠ let [] LeftHandSideExpression[?Yield, ?Await] in Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return]
for ( var ForBinding[?Yield, ?Await, +Pattern] in Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return]
for ( ForDeclaration[?Yield, ?Await, ~Using] in Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return]
for ( [lookahead ∉ { let, async of }] LeftHandSideExpression[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return]
for ( var ForBinding[?Yield, ?Await, +Pattern] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return]
for ( [lookahead ≠ using of] ForDeclaration[?Yield, ?Await, +Using] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return]
[+Await] for await ( [lookahead ≠ let] LeftHandSideExpression[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return]
[+Await] for await ( var ForBinding[?Yield, ?Await, +Pattern] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return]
[+Await] for await ( [lookahead ≠ using of] ForDeclaration[?Yield, ?Await, +Using] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return]
ForDeclaration[Yield, Await, Using] :
LetOrConst ForBinding[?Yield, ?Await, +Pattern]
[+Using] using [no LineTerminator here] ForBinding[?Yield, ?Await, ~Pattern]
[+Using, +Await] await [no LineTerminator here] using [no LineTerminator here] ForBinding[?Yield, +Await, ~Pattern]
So, for (using of
cannot become a prefix of the for-in/for-of with using declaration, but it can be a prefix of for-of with the using
being an identifier in LeftHandSideExpression
.
On the other hand, the proposal doesn't touch the ForStatement
definition, and the using
handling is added into LexicalDeclaration
unconditionally.
https://arai-a.github.io/ecma262-compare/?pr=3000&id=sec-for-statement&secAll=true
ForStatement[Yield, Await, Return] :
...
for ( LexicalDeclaration[~In, ?Yield, ?Await] Expression[+In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ) Statement[?Yield, ?Await, ?Return]
LexicalDeclaration[In, Yield, Await] :
LetOrConst BindingList[?In, ?Yield, ?Await, +Pattern] ;
UsingDeclaration[?In, ?Yield, ?Await]
[+Await] AwaitUsingDeclaration[?In, ?Yield]
UsingDeclaration[In, Yield, Await] :
using [no LineTerminator here] BindingList[?In, ?Yield, ?Await, ~Pattern] ;
AwaitUsingDeclaration[In, Yield] :
CoverAwaitExpressionAndAwaitUsingDeclarationHead[?Yield] [no LineTerminator here] BindingList[?In, ?Yield, +Await, ~Pattern] ;
This means ForStatement
matches for (using of = obj;;);
.
Is this expected?
TypeScript doesn't recognize the syntax, and
Babel, esbuild, Chromium, and SpiderMonkey throw syntax error.
Apparently the negative lookahead is applied also to ForStatement in all of them.
If for (using of = obj;;);
should throw SyntaxError, the ForStatement
syntax should be modified to have a negative lookahead, with propagating the existence of using
to LexicalDeclaration
, or maybe replacing that part with something similar to ForDeclaration
.
Activity