@@ -1178,15 +1178,16 @@ class ParserBase {
1178
1178
scope ()->scope_type () == REPL_MODE_SCOPE) &&
1179
1179
!scope ()->is_nonlinear ());
1180
1180
}
1181
- bool IsNextUsingKeyword (Token::Value token_after_using, bool is_await_using) {
1181
+ bool IsNextUsingKeyword (bool is_await_using) {
1182
1182
// using and await using declarations in for-of statements must be followed
1183
- // by a non-pattern ForBinding. In the case of synchronous `using`, `of` is
1184
- // disallowed as well with a negative lookahead.
1183
+ // by a non-pattern ForBinding.
1185
1184
//
1186
1185
// `of`: for ( [lookahead ≠ using of] ForDeclaration[?Yield, ?Await, +Using]
1187
1186
// of AssignmentExpression[+In, ?Yield, ?Await] )
1188
1187
//
1189
1188
// If `using` is not considered a keyword, it is parsed as an identifier.
1189
+ Token::Value token_after_using =
1190
+ is_await_using ? PeekAheadAhead () : PeekAhead ();
1190
1191
if (v8_flags.js_explicit_resource_management ) {
1191
1192
switch (token_after_using) {
1192
1193
case Token::kIdentifier :
@@ -1201,7 +1202,16 @@ class ParserBase {
1201
1202
case Token::kAsync :
1202
1203
return true ;
1203
1204
case Token::kOf :
1204
- return is_await_using;
1205
+ if (is_await_using) {
1206
+ return true ;
1207
+ } else {
1208
+ // In the case of synchronous `using`, `of` is disallowed as well
1209
+ // with a negative lookahead for for-of loops. But, cursedly,
1210
+ // `using of` is allowed as the initializer of C-style for loops,
1211
+ // e.g. `for (using of = null;;)` parses.
1212
+ Token::Value token_after_of = PeekAheadAhead ();
1213
+ return token_after_of == Token::kAssign ;
1214
+ }
1205
1215
case Token::kFutureStrictReservedWord :
1206
1216
case Token::kEscapedStrictReservedWord :
1207
1217
return is_sloppy (language_mode ());
@@ -1220,12 +1230,12 @@ class ParserBase {
1220
1230
// LineTerminator here] ForBinding[?Yield, +Await, ~Pattern]
1221
1231
return ((peek () == Token::kUsing &&
1222
1232
!scanner ()->HasLineTerminatorAfterNext () &&
1223
- IsNextUsingKeyword (PeekAhead (), /* is_await_using */ false )) ||
1233
+ IsNextUsingKeyword (/* is_await_using */ false )) ||
1224
1234
(is_await_allowed () && peek () == Token::kAwait &&
1225
1235
!scanner ()->HasLineTerminatorAfterNext () &&
1226
1236
PeekAhead () == Token::kUsing &&
1227
1237
!scanner ()->HasLineTerminatorAfterNextNext () &&
1228
- IsNextUsingKeyword (PeekAheadAhead (), /* is_await_using */ true )));
1238
+ IsNextUsingKeyword (/* is_await_using */ true )));
1229
1239
}
1230
1240
const PendingCompilationErrorHandler* pending_error_handler () const {
1231
1241
return pending_error_handler_;
0 commit comments