diff --git a/crates/oxc_parser/src/js/statement.rs b/crates/oxc_parser/src/js/statement.rs index cf67e11503005..f58855a7d4ba1 100644 --- a/crates/oxc_parser/src/js/statement.rs +++ b/crates/oxc_parser/src/js/statement.rs @@ -411,11 +411,23 @@ impl<'a> ParserImpl<'a> { } // [+Using] using [no LineTerminator here] ForBinding[?Yield, ?Await, ~Pattern] - if self.at(Kind::Using) && { - let token = self.lexer.peek_token(); - let kind = token.kind(); - !token.is_on_new_line() && kind != Kind::Of && kind.is_binding_identifier() - } { + if self.at(Kind::Using) + && self.lookahead(|p| { + p.bump_any(); // bump `using` + let token = p.cur_token(); + if token.is_on_new_line() { + return false; + } + let kind = token.kind(); + // `for (using of` is only a using declaration if followed by `=`, `;`, or `:` + // to distinguish from `for (using of collection)` which is a for-of loop + if kind == Kind::Of { + p.bump_any(); // bump `of` + return matches!(p.cur_kind(), Kind::Eq | Kind::Semicolon | Kind::Colon); + } + kind.is_binding_identifier() + }) + { return self.parse_using_declaration_for_statement( span, parenthesis_opening_span, diff --git a/tasks/coverage/snapshots/parser_babel.snap b/tasks/coverage/snapshots/parser_babel.snap index 8e6fae640d9f8..4cd24ab013b66 100644 --- a/tasks/coverage/snapshots/parser_babel.snap +++ b/tasks/coverage/snapshots/parser_babel.snap @@ -1,11 +1,13 @@ commit: fc58af40 parser_babel Summary: -AST Parsed : 2222/2234 (99.46%) -Positive Passed: 2205/2234 (98.70%) -Negative Passed: 1649/1697 (97.17%) +AST Parsed : 2224/2234 (99.55%) +Positive Passed: 2207/2234 (98.79%) +Negative Passed: 1648/1697 (97.11%) Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/private-in/invalid-private-followed-by-in-2/input.js +Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2026/explicit-resource-management/invalid-for-using-of-no-initializer/input.js + Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/estree/class-private-property/typescript-invalid-abstract/input.ts Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/typescript/arrow-function/arrow-like-in-conditional-2/input.ts @@ -294,16 +296,6 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2026 · ╰── Opened here ╰──── -Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2026/explicit-resource-management/valid-for-using-declaration-binding-of/input.js - - × Unexpected token - ╭─[babel/packages/babel-parser/test/fixtures/es2026/explicit-resource-management/valid-for-using-declaration-binding-of/input.js:2:17] - 1 │ { - 2 │ for (using of = reader();;); - · ─ - 3 │ } - ╰──── - Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2026/explicit-resource-management/valid-module-block-top-level-using-binding/input.js × Expected a semicolon or an implicit semicolon after a statement, but found none @@ -522,16 +514,6 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc 6 │ } ╰──── -Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typescript/explicit-resource-management/valid-for-using-declaration-binding-of/input.js - - × Unexpected token - ╭─[babel/packages/babel-parser/test/fixtures/typescript/explicit-resource-management/valid-for-using-declaration-binding-of/input.js:2:16] - 1 │ { - 2 │ for (using of: Reader = reader();;); - · ─ - 3 │ } - ╰──── - Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typescript/function/declare-pattern-parameters/input.ts × TS(1016): A required parameter cannot follow an optional parameter. @@ -9278,12 +9260,6 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc · ── ╰──── - × Unexpected token - ╭─[babel/packages/babel-parser/test/fixtures/es2026/explicit-resource-management/invalid-for-using-of-no-initializer/input.js:1:14] - 1 │ for (using of;of.isValid;); - · ─ - ╰──── - × Lexical declaration cannot appear in a single-statement context ╭─[babel/packages/babel-parser/test/fixtures/es2026/explicit-resource-management/invalid-in-single-statement-context/input.js:2:13] 1 │ { diff --git a/tasks/coverage/snapshots/parser_test262.snap b/tasks/coverage/snapshots/parser_test262.snap index 850b789e0b232..e4a58be8f186d 100644 --- a/tasks/coverage/snapshots/parser_test262.snap +++ b/tasks/coverage/snapshots/parser_test262.snap @@ -1,8 +1,8 @@ commit: 6f55d0c2 parser_test262 Summary: -AST Parsed : 46555/46563 (99.98%) -Positive Passed: 46555/46563 (99.98%) +AST Parsed : 46556/46563 (99.98%) +Positive Passed: 46556/46563 (99.98%) Negative Passed: 4581/4581 (100.00%) Expect to Parse: tasks/coverage/test262/test/annexB/language/expressions/assignmenttargettype/callexpression-as-for-in-lhs.js @@ -74,15 +74,6 @@ Expect to Parse: tasks/coverage/test262/test/annexB/language/expressions/assignm 21 │ }); ╰──── -Expect to Parse: tasks/coverage/test262/test/language/statements/using/syntax/using-for-statement.js - - × Unexpected token - ╭─[test262/test/language/statements/using/syntax/using-for-statement.js:14:15] - 13 │ // handled similar to `for (let of = null;;)`: - 14 │ for (using of = null;;) break; - · ─ - ╰──── - × '0'-prefixed octal literals and octal escape sequences are deprecated ╭─[test262/test/annexB/language/expressions/template-literal/legacy-octal-escape-sequence-strict.js:19:4] diff --git a/tasks/coverage/snapshots/parser_typescript.snap b/tasks/coverage/snapshots/parser_typescript.snap index 3be5c8420afc8..32ba7cd62bb10 100644 --- a/tasks/coverage/snapshots/parser_typescript.snap +++ b/tasks/coverage/snapshots/parser_typescript.snap @@ -3,7 +3,7 @@ commit: f5ccf434 parser_typescript Summary: AST Parsed : 9844/9845 (99.99%) Positive Passed: 9836/9845 (99.91%) -Negative Passed: 1496/2549 (58.69%) +Negative Passed: 1495/2549 (58.65%) Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/FunctionDeclaration3.ts Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/FunctionDeclaration4.ts @@ -1960,6 +1960,8 @@ Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/statement Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/awaitUsingDeclarationsInForOf.4.ts +Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/usingDeclarationsInForOf.4.ts + Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/statements/for-inStatements/for-inStatementsArrayErrors.ts Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/statements/for-inStatements/for-inStatementsDestructuring.ts @@ -24820,13 +24822,6 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/statements/Va 2 │ } ╰──── - × Unexpected token - ╭─[typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/usingDeclarationsInForOf.4.ts:1:15] - 1 │ for (using of = null;;) break; - · ─ - 2 │ for (using of: null = null;;) break; - ╰──── - × Illegal break statement ╭─[typescript/tests/cases/conformance/statements/breakStatements/invalidDoWhileBreakStatements.ts:4:1] 3 │ // naked break not allowed diff --git a/tasks/coverage/snapshots/semantic_babel.snap b/tasks/coverage/snapshots/semantic_babel.snap index 4675177aadd9c..83b8ba0a181da 100644 --- a/tasks/coverage/snapshots/semantic_babel.snap +++ b/tasks/coverage/snapshots/semantic_babel.snap @@ -2,7 +2,7 @@ commit: fc58af40 semantic_babel Summary: AST Parsed : 2234/2234 (100.00%) -Positive Passed: 1938/2234 (86.75%) +Positive Passed: 1939/2234 (86.79%) semantic Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/annex-b/enabled/valid-assignment-target-type/input.js Cannot assign to this expression @@ -206,9 +206,6 @@ semantic Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2026/ Keywords cannot contain escape characters Expected `)` but found `of` -semantic Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2026/explicit-resource-management/valid-for-using-declaration-binding-of/input.js -Unexpected token - semantic Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2026/explicit-resource-management/valid-module-block-top-level-using-binding/input.js Expected a semicolon or an implicit semicolon after a statement, but found none @@ -706,7 +703,9 @@ after transform: SymbolId(0): SymbolFlags(RegularEnum) rebuilt : SymbolId(0): SymbolFlags(FunctionScopedVariable) semantic Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/typescript/explicit-resource-management/valid-for-using-declaration-binding-of/input.js -Unexpected token +Unresolved references mismatch: +after transform: ["Reader", "reader"] +rebuilt : ["reader"] semantic Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/typescript/export/declare/input.ts Bindings mismatch: diff --git a/tasks/coverage/snapshots/semantic_test262.snap b/tasks/coverage/snapshots/semantic_test262.snap index a2ca653979365..5e4db1631db7d 100644 --- a/tasks/coverage/snapshots/semantic_test262.snap +++ b/tasks/coverage/snapshots/semantic_test262.snap @@ -2,7 +2,7 @@ commit: 6f55d0c2 semantic_test262 Summary: AST Parsed : 46563/46563 (100.00%) -Positive Passed: 44919/46563 (96.47%) +Positive Passed: 44920/46563 (96.47%) semantic Error: tasks/coverage/test262/test/annexB/language/expressions/assignmenttargettype/callexpression-as-for-in-lhs.js Cannot assign to this expression @@ -14655,9 +14655,6 @@ Reference symbol mismatch for "x": after transform: SymbolId(1) "x" rebuilt : SymbolId(1) "x" -semantic Error: tasks/coverage/test262/test/language/statements/using/syntax/using-for-statement.js -Unexpected token - semantic Error: tasks/coverage/test262/test/language/statements/using/throws-if-initializer-not-object.js Bindings mismatch: after transform: ScopeId(1): ["_usingCtx", "x"]