Skip to content

Commit 6340a33

Browse files
committed
fix(parser): reject using / await using in a switch case / default clause
1 parent b1a60ed commit 6340a33

File tree

4 files changed

+147
-13
lines changed

4 files changed

+147
-13
lines changed

crates/oxc_parser/src/diagnostics.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,13 @@ pub fn using_declarations_must_be_initialized(span: Span) -> OxcDiagnostic {
521521
.with_help("Add an initializer (e.g. ` = undefined`) here")
522522
}
523523

524+
#[cold]
525+
pub fn using_declaration_not_allowed_in_switch_bare_case(span: Span) -> OxcDiagnostic {
526+
OxcDiagnostic::error("Using declaration cannot appear in the bare case statement.")
527+
.with_label(span)
528+
.with_help("Wrap this declaration in a block statement")
529+
}
530+
524531
#[cold]
525532
pub fn jsx_element_no_match(span: Span, span1: Span, name: &str) -> OxcDiagnostic {
526533
OxcDiagnostic::error(format!("Expected corresponding JSX closing tag for '{name}'."))

crates/oxc_parser/src/js/statement.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,15 @@ impl<'a> ParserImpl<'a> {
628628
break;
629629
}
630630
let stmt = self.parse_statement_list_item(StatementContext::StatementList);
631+
if let Statement::VariableDeclaration(var_decl) = &stmt
632+
&& var_decl.kind.is_using()
633+
{
634+
// It is a Syntax Error if UsingDeclaration is contained directly within the StatementList of either a CaseClause or DefaultClause.
635+
// It is a Syntax Error if AwaitUsingDeclaration is contained directly within the StatementList of either a CaseClause or DefaultClause.
636+
self.error(diagnostics::using_declaration_not_allowed_in_switch_bare_case(
637+
stmt.span(),
638+
));
639+
}
631640
consequent.push(stmt);
632641
}
633642
self.ast.switch_case(self.end_span(span), test, consequent)

tasks/coverage/snapshots/parser_babel.snap

Lines changed: 73 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,11 @@ commit: 4cc3d888
33
parser_babel Summary:
44
AST Parsed : 2422/2440 (99.26%)
55
Positive Passed: 2395/2440 (98.16%)
6-
Negative Passed: 1685/1752 (96.18%)
6+
Negative Passed: 1689/1752 (96.40%)
77
Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/private-in/invalid-private-followed-by-in-2/input.js
88

9-
Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2026/async-explicit-resource-management/invalid-module-bare-case-await-using-binding/input.js
10-
11-
Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2026/async-explicit-resource-management/invalid-script-bare-case-await-using-binding/input.js
12-
139
Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2026/async-explicit-resource-management/invalid-script-top-level-using-binding/input.js
1410

15-
Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2026/explicit-resource-management/invalid-module-bare-case-using-binding/input.js
16-
17-
Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2026/explicit-resource-management/invalid-script-bare-case-using-binding/input.js
18-
1911
Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2026/explicit-resource-management/invalid-script-top-level-using-binding/input.js
2012

2113
Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/estree/class-private-property/typescript-invalid-abstract/input.ts
@@ -9199,6 +9191,42 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc
91999191
╰────
92009192
help: Wrap this declaration in a block statement
92019193

9194+
× Using declaration cannot appear in the bare case statement.
9195+
╭─[babel/packages/babel-parser/test/fixtures/es2026/async-explicit-resource-management/invalid-module-bare-case-await-using-binding/input.js:5:7]
9196+
4 │ {}
9197+
5 │ await using x = bar();
9198+
· ──────────────────────
9199+
6 │ default:
9200+
╰────
9201+
help: Wrap this declaration in a block statement
9202+
9203+
× Using declaration cannot appear in the bare case statement.
9204+
╭─[babel/packages/babel-parser/test/fixtures/es2026/async-explicit-resource-management/invalid-module-bare-case-await-using-binding/input.js:8:7]
9205+
7 │ {}
9206+
8 │ await using y = bar();
9207+
· ──────────────────────
9208+
9 │ }
9209+
╰────
9210+
help: Wrap this declaration in a block statement
9211+
9212+
× Using declaration cannot appear in the bare case statement.
9213+
╭─[babel/packages/babel-parser/test/fixtures/es2026/async-explicit-resource-management/invalid-script-bare-case-await-using-binding/input.js:5:7]
9214+
4 │ {}
9215+
5 │ await using x = bar();
9216+
· ──────────────────────
9217+
6 │ default:
9218+
╰────
9219+
help: Wrap this declaration in a block statement
9220+
9221+
× Using declaration cannot appear in the bare case statement.
9222+
╭─[babel/packages/babel-parser/test/fixtures/es2026/async-explicit-resource-management/invalid-script-bare-case-await-using-binding/input.js:8:7]
9223+
7 │ {}
9224+
8 │ await using y = bar();
9225+
· ──────────────────────
9226+
9 │ }
9227+
╰────
9228+
help: Wrap this declaration in a block statement
9229+
92029230
× Lexical declaration cannot appear in a single-statement context
92039231
╭─[babel/packages/babel-parser/test/fixtures/es2026/async-explicit-resource-management/invalid-script-top-level-labeled-using-binding/input.js:1:8]
92049232
1 │ label: await using x = bar();
@@ -9504,6 +9532,42 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc
95049532
╰────
95059533
help: Wrap this declaration in a block statement
95069534

9535+
× Using declaration cannot appear in the bare case statement.
9536+
╭─[babel/packages/babel-parser/test/fixtures/es2026/explicit-resource-management/invalid-module-bare-case-using-binding/input.js:5:7]
9537+
4 │ {}
9538+
5 │ using x = bar();
9539+
· ────────────────
9540+
6 │ default:
9541+
╰────
9542+
help: Wrap this declaration in a block statement
9543+
9544+
× Using declaration cannot appear in the bare case statement.
9545+
╭─[babel/packages/babel-parser/test/fixtures/es2026/explicit-resource-management/invalid-module-bare-case-using-binding/input.js:8:7]
9546+
7 │ {}
9547+
8 │ using y = bar();
9548+
· ────────────────
9549+
9 │ }
9550+
╰────
9551+
help: Wrap this declaration in a block statement
9552+
9553+
× Using declaration cannot appear in the bare case statement.
9554+
╭─[babel/packages/babel-parser/test/fixtures/es2026/explicit-resource-management/invalid-script-bare-case-using-binding/input.js:5:7]
9555+
4 │ {}
9556+
5 │ using x = bar();
9557+
· ────────────────
9558+
6 │ default:
9559+
╰────
9560+
help: Wrap this declaration in a block statement
9561+
9562+
× Using declaration cannot appear in the bare case statement.
9563+
╭─[babel/packages/babel-parser/test/fixtures/es2026/explicit-resource-management/invalid-script-bare-case-using-binding/input.js:8:7]
9564+
7 │ {}
9565+
8 │ using y = bar();
9566+
· ────────────────
9567+
9 │ }
9568+
╰────
9569+
help: Wrap this declaration in a block statement
9570+
95079571
× Lexical declaration cannot appear in a single-statement context
95089572
╭─[babel/packages/babel-parser/test/fixtures/es2026/explicit-resource-management/invalid-script-top-level-labeled-using-binding/input.js:1:8]
95099573
1 │ label: using x = bar();

tasks/coverage/snapshots/parser_typescript.snap

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ commit: 8ea03f88
22

33
parser_typescript Summary:
44
AST Parsed : 8825/8827 (99.98%)
5-
Positive Passed: 8814/8827 (99.85%)
6-
Negative Passed: 1453/3530 (41.16%)
5+
Positive Passed: 8813/8827 (99.84%)
6+
Negative Passed: 1454/3530 (41.19%)
77
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/ExportAssignment7.ts
88

99
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/ExportAssignment8.ts
@@ -3794,8 +3794,6 @@ Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/scanner/e
37943794

37953795
Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/statements/VariableStatements/everyTypeWithAnnotationAndInvalidInitializer.ts
37963796

3797-
Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/awaitUsingDeclarations.1.ts
3798-
37993797
Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/awaitUsingDeclarations.12.ts
38003798

38013799
Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/awaitUsingDeclarations.13.ts
@@ -4435,6 +4433,35 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/parser/ecmasc
44354433
3 │ }
44364434
╰────
44374435

4436+
Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/usingDeclarations.1.ts
4437+
4438+
× Using declaration cannot appear in the bare case statement.
4439+
╭─[typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/usingDeclarations.1.ts:95:9]
4440+
94 │ case 0:
4441+
95 │ using d20 = { [Symbol.dispose]() {} };
4442+
· ──────────────────────────────────────
4443+
96 │ break;
4444+
╰────
4445+
help: Wrap this declaration in a block statement
4446+
4447+
× Using declaration cannot appear in the bare case statement.
4448+
╭─[typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/usingDeclarations.1.ts:99:9]
4449+
98 │ case 1:
4450+
99 │ using d21 = { [Symbol.dispose]() {} };
4451+
· ──────────────────────────────────────
4452+
100 │ break;
4453+
╰────
4454+
help: Wrap this declaration in a block statement
4455+
4456+
× Using declaration cannot appear in the bare case statement.
4457+
╭─[typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/usingDeclarations.1.ts:106:13]
4458+
105 │ case 0:
4459+
106 │ using d22 = { [Symbol.dispose]() {} };
4460+
· ──────────────────────────────────────
4461+
107 │ break;
4462+
╰────
4463+
help: Wrap this declaration in a block statement
4464+
44384465

44394466
× TS(1090): 'public' modifier cannot appear on a parameter.
44404467
╭─[typescript/tests/cases/compiler/ArrowFunctionExpression1.ts:1:10]
@@ -25566,6 +25593,33 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/parser/ecmasc
2556625593
7 │ function *gen() {
2556725594
╰────
2556825595

25596+
× Using declaration cannot appear in the bare case statement.
25597+
╭─[typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/awaitUsingDeclarations.1.ts:41:9]
25598+
40 │ case 0:
25599+
41 │ await using d20 = { async [Symbol.asyncDispose]() {} };
25600+
· ───────────────────────────────────────────────────────
25601+
42 │ break;
25602+
╰────
25603+
help: Wrap this declaration in a block statement
25604+
25605+
× Using declaration cannot appear in the bare case statement.
25606+
╭─[typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/awaitUsingDeclarations.1.ts:45:9]
25607+
44 │ case 1:
25608+
45 │ await using d21 = { async [Symbol.asyncDispose]() {} };
25609+
· ───────────────────────────────────────────────────────
25610+
46 │ break;
25611+
╰────
25612+
help: Wrap this declaration in a block statement
25613+
25614+
× Using declaration cannot appear in the bare case statement.
25615+
╭─[typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/awaitUsingDeclarations.1.ts:52:13]
25616+
51 │ case 0:
25617+
52 │ await using d22 = { async [Symbol.asyncDispose]() {} };
25618+
· ───────────────────────────────────────────────────────
25619+
53 │ break;
25620+
╰────
25621+
help: Wrap this declaration in a block statement
25622+
2556925623
× Lexical declaration cannot appear in a single-statement context
2557025624
╭─[typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/awaitUsingDeclarations.10.ts:5:12]
2557125625
4 │ async function f() {

0 commit comments

Comments
 (0)