Skip to content

Commit 6da43e8

Browse files
committed
fix(parser): reject using / await using in a switch case / default clause
1 parent abfe820 commit 6da43e8

File tree

9 files changed

+192
-22
lines changed

9 files changed

+192
-22
lines changed

crates/oxc_linter/src/snapshots/eslint_no_case_declarations.snap

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,16 @@ source: crates/oxc_linter/src/tester.rs
4949
· ─────
5050
╰────
5151

52-
eslint(no-case-declarations): Unexpected lexical declaration in case block.
52+
× Using declaration cannot appear in the bare case statement.
5353
╭─[no_case_declarations.tsx:1:23]
5454
1switch (a) { default: using x = {}; break; }
55-
· ─────
55+
· ─────────────
5656
╰────
57+
help: Wrap this declaration in a block statement
5758

58-
eslint(no-case-declarations): Unexpected lexical declaration in case block.
59+
× Using declaration cannot appear in the bare case statement.
5960
╭─[no_case_declarations.tsx:1:23]
6061
1switch (a) { default: await using x = {}; break; }
61-
· ───────────
62+
· ───────────────────
6263
╰────
64+
help: Wrap this declaration in a block statement

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/estree_typescript.snap

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ commit: 8ea03f88
22

33
estree_typescript Summary:
44
AST Parsed : 8767/8767 (100.00%)
5-
Positive Passed: 8762/8767 (99.94%)
5+
Positive Passed: 8761/8767 (99.93%)
66
Mismatch: tasks/coverage/typescript/tests/cases/conformance/importDefer/importDeferComments.ts
77

88
Mismatch: tasks/coverage/typescript/tests/cases/conformance/importDefer/importDeferDeclaration.ts
@@ -13,3 +13,5 @@ Mismatch: tasks/coverage/typescript/tests/cases/conformance/jsx/tsxReactEmitEnti
1313

1414
Mismatch: tasks/coverage/typescript/tests/cases/conformance/jsx/tsxReactEmitNesting.tsx
1515

16+
Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/usingDeclarations.1.ts
17+
Using declaration cannot appear in the bare case statement.

tasks/coverage/snapshots/formatter_typescript.snap

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ commit: 8ea03f88
22

33
formatter_typescript Summary:
44
AST Parsed : 8827/8827 (100.00%)
5-
Positive Passed: 8818/8827 (99.90%)
5+
Positive Passed: 8817/8827 (99.89%)
66
Mismatch: tasks/coverage/typescript/tests/cases/compiler/amdLikeInputDeclarationEmit.ts
77

88
Expect to Parse: tasks/coverage/typescript/tests/cases/compiler/arrayFromAsync.ts
@@ -19,5 +19,7 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/expressions/e
1919
Unexpected token
2020
Mismatch: tasks/coverage/typescript/tests/cases/conformance/generators/yieldStatementNoAsiAfterTransform.ts
2121

22+
Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/usingDeclarations.1.ts
23+
Using declaration cannot appear in the bare case statement.Using declaration cannot appear in the bare case statement.Using declaration cannot appear in the bare case statement.
2224
Mismatch: tasks/coverage/typescript/tests/cases/conformance/statements/returnStatements/returnStatementNoAsiAfterTransform.ts
2325

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() {

tasks/coverage/snapshots/semantic_typescript.snap

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ commit: 8ea03f88
22

33
semantic_typescript Summary:
44
AST Parsed : 6175/6175 (100.00%)
5-
Positive Passed: 2664/6175 (43.14%)
5+
Positive Passed: 2663/6175 (43.13%)
66
semantic Error: tasks/coverage/typescript/tests/cases/compiler/2dArrays.ts
77
Symbol reference IDs mismatch for "Cell":
88
after transform: SymbolId(0): [ReferenceId(1)]
@@ -28758,6 +28758,11 @@ Scope children mismatch:
2875828758
after transform: ScopeId(0): [ScopeId(1), ScopeId(3)]
2875928759
rebuilt : ScopeId(0): [ScopeId(1)]
2876028760

28761+
semantic Error: tasks/coverage/typescript/tests/cases/compiler/tripleSlashReferenceAbsoluteWindowsPath.ts
28762+
Unresolved references mismatch:
28763+
after transform: ["x"]
28764+
rebuilt : []
28765+
2876128766
semantic Error: tasks/coverage/typescript/tests/cases/compiler/trivialSubtypeReductionNoStructuralCheck2.ts
2876228767
Bindings mismatch:
2876328768
after transform: ScopeId(0): ["Wizard", "_objectSpread", "props"]
@@ -46161,6 +46166,9 @@ after transform: ScopeId(2): [ScopeId(4)]
4616146166
rebuilt : ScopeId(9): []
4616246167

4616346168
semantic Error: tasks/coverage/typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/usingDeclarations.1.ts
46169+
Using declaration cannot appear in the bare case statement.
46170+
Using declaration cannot appear in the bare case statement.
46171+
Using declaration cannot appear in the bare case statement.
4616446172
Bindings mismatch:
4616546173
after transform: ScopeId(0): ["C1", "C2", "C3", "N", "_af", "_ag", "_asyncToGenerator", "_awaitAsyncGenerator", "_defineProperty", "_usingCtx2", "_usingCtx20", "_usingCtx23", "_usingCtx24", "_usingCtx25", "_usingCtx26", "_usingCtx27", "_usingCtx28", "_usingCtx29", "_usingCtx30", "_usingCtx6", "_wrapAsyncGenerator", "a", "af", "ag", "d1", "f", "g"]
4616646174
rebuilt : ScopeId(0): ["C1", "C2", "C3", "N", "_af", "_ag", "_asyncToGenerator", "_awaitAsyncGenerator", "_defineProperty", "_usingCtx2", "_usingCtx20", "_usingCtx21", "_usingCtx22", "_usingCtx23", "_usingCtx24", "_usingCtx25", "_usingCtx26", "_usingCtx27", "_usingCtx28", "_usingCtx29", "_usingCtx30", "_usingCtx6", "_wrapAsyncGenerator", "a", "af", "ag", "d1", "f", "g"]

tasks/transform_conformance/snapshots/babel.snap.md

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
commit: 4cc3d888
22

3-
Passed: 712/1217
3+
Passed: 711/1217
44

55
# All Passed:
66
* babel-plugin-transform-logical-assignment-operators
@@ -268,7 +268,7 @@ x Output mismatch
268268
x Output mismatch
269269

270270

271-
# babel-plugin-transform-explicit-resource-management (21/29)
271+
# babel-plugin-transform-explicit-resource-management (20/29)
272272
* integration/commonjs-transform/input.js
273273
x Output mismatch
274274

@@ -286,6 +286,28 @@ Symbol scope ID mismatch for "x":
286286
after transform: SymbolId(1): ScopeId(1)
287287
rebuilt : SymbolId(2): ScopeId(2)
288288

289+
* transform-sync/invalid-switch-bare-case/input.js
290+
291+
x Using declaration cannot appear in the bare case statement.
292+
,-[tasks\coverage\babel\packages\babel-plugin-transform-explicit-resource-management\test/fixtures\transform-sync\invalid-switch-bare-case\input.js:4:7]
293+
3 | case 0:
294+
4 | using x = 0;
295+
: ^^^^^^^^^^^^
296+
5 | break;
297+
`----
298+
help: Wrap this declaration in a block statement
299+
300+
301+
x Using declaration cannot appear in the bare case statement.
302+
,-[tasks\coverage\babel\packages\babel-plugin-transform-explicit-resource-management\test/fixtures\transform-sync\invalid-switch-bare-case\input.js:7:7]
303+
6 | default:
304+
7 | using y = 1;
305+
: ^^^^^^^^^^^^
306+
8 | break;
307+
`----
308+
help: Wrap this declaration in a block statement
309+
310+
289311
* transform-sync/multiple-nested/input.js
290312
Bindings mismatch:
291313
after transform: ScopeId(3): ["_usingCtx3", "z"]

0 commit comments

Comments
 (0)