@@ -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_; |
|