mirror of
https://github.com/aphrody-labs/oxc.git
synced 2026-10-14 22:29:17 +00:00
fix(parser): handle escaped let in for loops (#26583)
Escaped `let` is an identifier in non-strict code, but `for` headers treated it as the declaration keyword or applied the restriction on expressions beginning with unescaped `let` in `for…of`. Check for escapes in both paths so valid loops such as `for (l\u0065t[0];;);` and `for (l\u0065t of []);` parse successfully. Adds coverage for classic, `for…in`, `for…of`, and `for await…of` loops, while retaining rejection of escaped declaration keywords.
This commit is contained in:
1 parent
2d1fad2c9f
commit
1c42008540
11 files changed
+48
-15
No files matched your search
@@ -403,7 +403,7 @@ impl<'a, C: Config> ParserImpl<'a, C> {
|
||||
r#await,
|
||||
);
|
||||
}
|
||||
Kind::Let => {
|
||||
Kind::Let if !self.cur_token().escaped() => {
|
||||
// `for (let`
|
||||
let decl_start = self.cur_start();
|
||||
// disallow `for (let in ...`
|
||||
@@ -460,7 +460,7 @@ impl<'a, C: Config> ParserImpl<'a, C> {
|
||||
return self.parse_for_loop(for_start, parenthesis_opening_span, None, r#await);
|
||||
}
|
||||
|
||||
let is_let = self.at(Kind::Let);
|
||||
let is_let = self.at(Kind::Let) && !self.cur_token().escaped();
|
||||
// `async` is allowed as `for (async of ...)` if `async` is escaped
|
||||
let is_async = self.at(Kind::Async) && !self.cur_token().escaped();
|
||||
let expr_start = self.cur_start();
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
for (l\u0065t x = 0;;);
|
||||
@@ -0,0 +1 @@
|
||||
for (l\u0065t x in {});
|
||||
@@ -0,0 +1 @@
|
||||
for (l\u0065t x of []);
|
||||
@@ -0,0 +1,9 @@
|
||||
for (l\u0065t[0];;);
|
||||
for (l\u0065t[0] in {});
|
||||
for (l\u0065t of []);
|
||||
for (l\u0065t[0] of []);
|
||||
for (l\u0065t.x of []);
|
||||
async function f() {
|
||||
for await (l\u0065t of []);
|
||||
for await (l\u0065t[0] of []);
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
codegen_misc Summary:
|
||||
AST Parsed : 107/107 (100.00%)
|
||||
Positive Passed: 107/107 (100.00%)
|
||||
AST Parsed : 108/108 (100.00%)
|
||||
Positive Passed: 108/108 (100.00%)
|
||||
@@ -1,3 +1,3 @@
|
||||
formatter_misc Summary:
|
||||
AST Parsed : 107/107 (100.00%)
|
||||
Positive Passed: 107/107 (100.00%)
|
||||
AST Parsed : 108/108 (100.00%)
|
||||
Positive Passed: 108/108 (100.00%)
|
||||
@@ -1,3 +1,3 @@
|
||||
lexer_misc Summary:
|
||||
AST Parsed : 322/322 (100.00%)
|
||||
Positive Passed: 322/322 (100.00%)
|
||||
AST Parsed : 326/326 (100.00%)
|
||||
Positive Passed: 326/326 (100.00%)
|
||||
@@ -1,7 +1,7 @@
|
||||
parser_misc Summary:
|
||||
AST Parsed : 107/107 (100.00%)
|
||||
Positive Passed: 107/107 (100.00%)
|
||||
Negative Passed: 215/215 (100.00%)
|
||||
AST Parsed : 108/108 (100.00%)
|
||||
Positive Passed: 108/108 (100.00%)
|
||||
Negative Passed: 218/218 (100.00%)
|
||||
|
||||
× Cannot assign to 'arguments' in strict mode
|
||||
╭─[misc/fail/arguments-eval-ambient.ts:2:13]
|
||||
@@ -705,6 +705,27 @@ Negative Passed: 215/215 (100.00%)
|
||||
3 │ }
|
||||
╰────
|
||||
|
||||
× Expected `;` but found `Identifier`
|
||||
╭─[misc/fail/for-escaped-let-declaration.cjs:1:15]
|
||||
1 │ for (l\u0065t x = 0;;);
|
||||
· ┬
|
||||
· ╰── `;` expected
|
||||
╰────
|
||||
|
||||
× Expected `;` but found `Identifier`
|
||||
╭─[misc/fail/for-in-escaped-let-declaration.cjs:1:15]
|
||||
1 │ for (l\u0065t x in {});
|
||||
· ┬
|
||||
· ╰── `;` expected
|
||||
╰────
|
||||
|
||||
× Expected `;` but found `Identifier`
|
||||
╭─[misc/fail/for-of-escaped-let-declaration.cjs:1:15]
|
||||
1 │ for (l\u0065t x of []);
|
||||
· ┬
|
||||
· ╰── `;` expected
|
||||
╰────
|
||||
|
||||
× The left-hand side of a for...in statement cannot be an using declaration.
|
||||
╭─[misc/fail/for-using-in-initializer.js:1:6]
|
||||
1 │ for (using x = a in b;;);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
semantic_misc Summary:
|
||||
AST Parsed : 107/107 (100.00%)
|
||||
Positive Passed: 103/107 (96.26%)
|
||||
AST Parsed : 108/108 (100.00%)
|
||||
Positive Passed: 104/108 (96.30%)
|
||||
semantic Error: tasks/coverage/misc/pass/declare-let-private.ts
|
||||
Bindings mismatch:
|
||||
after transform: ScopeId(0): ["private"]
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
transformer_misc Summary:
|
||||
AST Parsed : 107/107 (100.00%)
|
||||
Positive Passed: 107/107 (100.00%)
|
||||
AST Parsed : 108/108 (100.00%)
|
||||
Positive Passed: 108/108 (100.00%)
|
||||
Reference in new issue
Block a user