diff --git a/crates/oxc_parser/src/diagnostics.rs b/crates/oxc_parser/src/diagnostics.rs index 87f65d51aca24..069d1764b3ba8 100644 --- a/crates/oxc_parser/src/diagnostics.rs +++ b/crates/oxc_parser/src/diagnostics.rs @@ -752,6 +752,17 @@ pub fn using_declaration_not_allowed_in_switch_bare_case(span: Span) -> OxcDiagn .with_help("Wrap this declaration in a block statement") } +#[cold] +pub fn using_declarations_not_allowed_in_ambient_contexts(span: Span) -> OxcDiagnostic { + ts_error("1545", "'using' declarations are not allowed in ambient contexts.").with_label(span) +} + +#[cold] +pub fn await_using_declarations_not_allowed_in_ambient_contexts(span: Span) -> OxcDiagnostic { + ts_error("1546", "'await using' declarations are not allowed in ambient contexts.") + .with_label(span) +} + #[cold] pub fn jsx_element_no_match(span: Span, span1: Span, name: &str) -> OxcDiagnostic { OxcDiagnostic::error(format!("Expected corresponding JSX closing tag for '{name}'.")) diff --git a/crates/oxc_parser/src/js/declaration.rs b/crates/oxc_parser/src/js/declaration.rs index aa8ab4accb398..4304f5931c6fd 100644 --- a/crates/oxc_parser/src/js/declaration.rs +++ b/crates/oxc_parser/src/js/declaration.rs @@ -137,6 +137,7 @@ impl<'a, C: Config> ParserImpl<'a, C> { ); if self.ctx.has_ambient() && let Some(init) = &decl.init + && !decl.kind.is_using() && !(decl.kind.is_const() && decl.type_annotation.is_none()) { self.error(diagnostics::initializers_not_allowed_in_ambient_contexts(init.span())); @@ -184,6 +185,14 @@ impl<'a, C: Config> ParserImpl<'a, C> { }; self.expect(Kind::Using); + if self.ctx.has_ambient() { + let using_span = self.cur_token().span(); + self.error(if kind.is_await() { + diagnostics::await_using_declarations_not_allowed_in_ambient_contexts(using_span) + } else { + diagnostics::using_declarations_not_allowed_in_ambient_contexts(using_span) + }); + } // BindingList[?In, ?Yield, ?Await, ~Pattern] let mut declarations = self.ast.vec(); diff --git a/tasks/coverage/snapshots/parser_babel.snap b/tasks/coverage/snapshots/parser_babel.snap index 1b424f1f09718..d789d2d815fd7 100644 --- a/tasks/coverage/snapshots/parser_babel.snap +++ b/tasks/coverage/snapshots/parser_babel.snap @@ -13271,38 +13271,70 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc ╰──── help: Try inserting a semicolon here - × TS(1039): Initializers are not allowed in ambient contexts. - ╭─[babel/packages/babel-parser/test/fixtures/typescript/declare/invalid-namespace-await-using/input.ts:3:20] + × TS(1546): 'await using' declarations are not allowed in ambient contexts. + ╭─[babel/packages/babel-parser/test/fixtures/typescript/declare/invalid-namespace-await-using/input.ts:2:15] + 1 │ declare namespace invalid_namespace_var { 2 │ await using A; + · ─ 3 │ await using A1 = 0; - · ─ + ╰──── + + × TS(1546): 'await using' declarations are not allowed in ambient contexts. + ╭─[babel/packages/babel-parser/test/fixtures/typescript/declare/invalid-namespace-await-using/input.ts:3:15] + 2 │ await using A; + 3 │ await using A1 = 0; + · ── 4 │ await using A2: number = 0; ╰──── - × TS(1039): Initializers are not allowed in ambient contexts. - ╭─[babel/packages/babel-parser/test/fixtures/typescript/declare/invalid-namespace-await-using/input.ts:4:28] + × TS(1546): 'await using' declarations are not allowed in ambient contexts. + ╭─[babel/packages/babel-parser/test/fixtures/typescript/declare/invalid-namespace-await-using/input.ts:4:15] 3 │ await using A1 = 0; 4 │ await using A2: number = 0; - · ─ + · ── 5 │ await using B, C; ╰──── - × TS(1039): Initializers are not allowed in ambient contexts. - ╭─[babel/packages/babel-parser/test/fixtures/typescript/declare/invalid-namespace-using/input.ts:3:14] + × TS(1546): 'await using' declarations are not allowed in ambient contexts. + ╭─[babel/packages/babel-parser/test/fixtures/typescript/declare/invalid-namespace-await-using/input.ts:5:15] + 4 │ await using A2: number = 0; + 5 │ await using B, C; + · ─ + 6 │ } + ╰──── + + × TS(1545): 'using' declarations are not allowed in ambient contexts. + ╭─[babel/packages/babel-parser/test/fixtures/typescript/declare/invalid-namespace-using/input.ts:2:9] + 1 │ declare namespace invalid_namespace_var { 2 │ using A; + · ─ 3 │ using A1 = 0; - · ─ + ╰──── + + × TS(1545): 'using' declarations are not allowed in ambient contexts. + ╭─[babel/packages/babel-parser/test/fixtures/typescript/declare/invalid-namespace-using/input.ts:3:9] + 2 │ using A; + 3 │ using A1 = 0; + · ── 4 │ using A2: number = 0; ╰──── - × TS(1039): Initializers are not allowed in ambient contexts. - ╭─[babel/packages/babel-parser/test/fixtures/typescript/declare/invalid-namespace-using/input.ts:4:22] + × TS(1545): 'using' declarations are not allowed in ambient contexts. + ╭─[babel/packages/babel-parser/test/fixtures/typescript/declare/invalid-namespace-using/input.ts:4:9] 3 │ using A1 = 0; 4 │ using A2: number = 0; - · ─ + · ── 5 │ using B, C; ╰──── + × TS(1545): 'using' declarations are not allowed in ambient contexts. + ╭─[babel/packages/babel-parser/test/fixtures/typescript/declare/invalid-namespace-using/input.ts:5:9] + 4 │ using A2: number = 0; + 5 │ using B, C; + · ─ + 6 │ } + ╰──── + × TS(1039): Initializers are not allowed in ambient contexts. ╭─[babel/packages/babel-parser/test/fixtures/typescript/declare/invalid-namespace-var/input.ts:2:11] 1 │ declare namespace invalid_namespace_var { diff --git a/tasks/coverage/snapshots/parser_typescript.snap b/tasks/coverage/snapshots/parser_typescript.snap index a7d6e0f39e035..8addb6c7cc00f 100644 --- a/tasks/coverage/snapshots/parser_typescript.snap +++ b/tasks/coverage/snapshots/parser_typescript.snap @@ -3,7 +3,7 @@ commit: 0c2c7a35 parser_typescript Summary: AST Parsed : 9824/9827 (99.97%) Positive Passed: 9813/9827 (99.86%) -Negative Passed: 1530/2586 (59.16%) +Negative Passed: 1532/2586 (59.24%) Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/FunctionDeclaration3.ts Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/FunctionDeclaration4.ts @@ -1968,12 +1968,8 @@ Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/scanner/e Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/awaitUsingDeclarations.14.ts -Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/awaitUsingDeclarations.16.ts - 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/usingDeclarations.16.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 @@ -25872,6 +25868,38 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/parser/ecmasc ╰──── help: Wrap this code in a block or use a module + × TS(1546): 'await using' declarations are not allowed in ambient contexts. + ╭─[typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/awaitUsingDeclarations.16.ts:2:17] + 1 │ declare namespace N { + 2 │ await using x: { [Symbol.asyncDispose](): Promise }; + · ─ + 3 │ await using y: null; + ╰──── + + × TS(1546): 'await using' declarations are not allowed in ambient contexts. + ╭─[typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/awaitUsingDeclarations.16.ts:3:17] + 2 │ await using x: { [Symbol.asyncDispose](): Promise }; + 3 │ await using y: null; + · ─ + 4 │ } + ╰──── + + × TS(1546): 'await using' declarations are not allowed in ambient contexts. + ╭─[typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/awaitUsingDeclarations.16.ts:6:17] + 5 │ declare module 'M' { + 6 │ await using x: { [Symbol.asyncDispose](): Promise }; + · ─ + 7 │ await using y: null; + ╰──── + + × TS(1546): 'await using' declarations are not allowed in ambient contexts. + ╭─[typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/awaitUsingDeclarations.16.ts:7:17] + 6 │ await using x: { [Symbol.asyncDispose](): Promise }; + 7 │ await using y: null; + · ─ + 8 │ } + ╰──── + × Using declaration cannot appear in the bare case statement. ╭─[typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/awaitUsingDeclarations.17.ts:3:9] 2 │ case 0: @@ -26028,6 +26056,38 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/parser/ecmasc ╰──── help: Remove the `export` here and add `export { x }` as a separate statement to export the declaration + × TS(1545): 'using' declarations are not allowed in ambient contexts. + ╭─[typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/usingDeclarations.16.ts:2:11] + 1 │ declare namespace N { + 2 │ using x: { [Symbol.dispose](): void }; + · ─ + 3 │ using y: null; + ╰──── + + × TS(1545): 'using' declarations are not allowed in ambient contexts. + ╭─[typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/usingDeclarations.16.ts:3:11] + 2 │ using x: { [Symbol.dispose](): void }; + 3 │ using y: null; + · ─ + 4 │ } + ╰──── + + × TS(1545): 'using' declarations are not allowed in ambient contexts. + ╭─[typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/usingDeclarations.16.ts:6:11] + 5 │ declare module 'M' { + 6 │ using x: { [Symbol.dispose](): void }; + · ─ + 7 │ using y: null; + ╰──── + + × TS(1545): 'using' declarations are not allowed in ambient contexts. + ╭─[typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/usingDeclarations.16.ts:7:11] + 6 │ using x: { [Symbol.dispose](): void }; + 7 │ using y: null; + · ─ + 8 │ } + ╰──── + × Using declaration cannot appear in the bare case statement. ╭─[typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/usingDeclarations.17.ts:3:9] 2 │ case 0: