Skip to content

Commit

Permalink
Bug 1685482 - Part 2: Disallow identifiers named "async" in for-of lo…
Browse files Browse the repository at this point in the history
…ops. r=yulia

`for-of` loops mustn't start with the token sequence `async of`, because that
leads to a shift-reduce conflict when parsing `for (async of => {};;)` or
`for (async of [])`. This restriction doesn't apply to `for-await-of` loops,
because `async` in `for await (async of ...)` is always parsed as an identifier.

Parsing `for (async of ...)` already results in a SyntaxError, but that happens
because `assignExpr()` always tries to parse the sequence `async [no LineTerminator] of`
as the start of an async arrow function. That means `forHeadStart()` still needs
to handle the case when `async` and `of` are separated by a line terminator.

Part 3 will update the parser to allow `for await (async of ...)`.

Spec change: tc39/ecma262#2256

Depends on D100994

Differential Revision: https://phabricator.services.mozilla.com/D100995

UltraBlame original commit: c260009506931dfe9e8c75906cd200e3ff687b79
  • Loading branch information
marco-c committed Jan 25, 2021
1 parent 95b6687 commit 6b73d97
Show file tree
Hide file tree
Showing 4 changed files with 1,219 additions and 4 deletions.
8 changes: 5 additions & 3 deletions js/public/friend/ErrorNumbers.msg
Original file line number Diff line number Diff line change
Expand Up @@ -3089,8 +3089,8 @@ binding
)
MSG_DEF
(
JSMSG_LET_STARTING_FOROF_LHS
0
JSMSG_BAD_STARTING_FOROF_LHS
1
JSEXN_SYNTAXERR
"
an
Expand All @@ -3110,7 +3110,9 @@ not
start
with
'
let
{
0
}
'
"
)
Expand Down
204 changes: 203 additions & 1 deletion js/src/frontend/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36058,6 +36058,8 @@ forHeadStart
(
YieldHandling
yieldHandling
IteratorKind
iterKind
ParseNodeKind
*
forHeadKind
Expand Down Expand Up @@ -36352,6 +36354,65 @@ a
declaration
.
)
/
/
/
/
For
-
of
loops
can
'
t
start
with
the
token
sequence
"
async
of
"
because
that
/
/
leads
to
a
shift
-
reduce
conflict
when
parsing
|
for
(
async
of
=
>
{
}
;
;
)
|
or
/
/
|
for
(
async
of
[
]
)
|
.
bool
parsingLexicalDeclaration
=
Expand All @@ -36362,6 +36423,11 @@ letIsIdentifier
=
false
;
bool
startsWithForOf
=
false
;
if
(
tt
Expand Down Expand Up @@ -36508,6 +36574,83 @@ true
;
}
}
else
if
(
tt
=
=
TokenKind
:
:
Async
&
&
iterKind
=
=
IteratorKind
:
:
Sync
)
{
tokenStream
.
consumeKnownToken
(
TokenKind
:
:
Async
TokenStream
:
:
SlashIsRegExp
)
;
TokenKind
next
;
if
(
!
tokenStream
.
peekToken
(
&
next
)
)
{
return
false
;
}
if
(
next
=
=
TokenKind
:
:
Of
)
{
startsWithForOf
=
true
;
}
anyChars
.
ungetToken
(
)
;
}
if
(
parsingLexicalDeclaration
Expand Down Expand Up @@ -36933,7 +37076,65 @@ letIsIdentifier
errorAt
(
exprOffset
JSMSG_LET_STARTING_FOROF_LHS
JSMSG_BAD_STARTING_FOROF_LHS
"
let
"
)
;
return
false
;
}
/
/
In
a
for
-
of
loop
the
LeftHandSideExpression
isn
'
t
allowed
to
be
an
/
/
identifier
named
"
async
"
per
the
[
lookahead
async
of
]
restriction
.
if
(
isForOf
&
&
startsWithForOf
)
{
errorAt
(
exprOffset
JSMSG_BAD_STARTING_FOROF_LHS
"
async
of
"
)
;
return
Expand Down Expand Up @@ -37804,6 +38005,7 @@ if
forHeadStart
(
yieldHandling
iterKind
&
headKind
&
Expand Down
11 changes: 11 additions & 0 deletions js/src/frontend/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -1599,6 +1599,15 @@ include
"
frontend
/
IteratorKind
.
h
"
#
include
"
frontend
/
NameAnalysisTypes
.
h
Expand Down Expand Up @@ -6608,6 +6617,8 @@ forHeadStart
(
YieldHandling
yieldHandling
IteratorKind
iterKind
ParseNodeKind
*
forHeadKind
Expand Down
Loading

0 comments on commit 6b73d97

Please sign in to comment.