feat(parser): report error for missing initializer in using decl (#19824)

This commit is contained in:
camc314 committed 2026-02-28 13:12:03 +00:00
1 parent 7682e5a1bc
commit 42bd431db5
3 files changed
+28 -149

No files matched your search

+8 -9
View File
@@ -161,6 +161,8 @@ impl<'a, C: Config> ParserImpl<'a, C> {
} else if decl.kind == VariableDeclarationKind::Const {
// It is a Syntax Error if Initializer is not present and IsConstantDeclaration of the LexicalDeclaration containing this LexicalBinding is true.
self.error(diagnostics::missing_initializer_in_const(decl.id.span()));
} else if decl.kind.is_using() {
self.error(diagnostics::using_declarations_must_be_initialized(decl.id.span()));
}
}
}
@@ -186,8 +188,12 @@ impl<'a, C: Config> ParserImpl<'a, C> {
// BindingList[?In, ?Yield, ?Await, ~Pattern]
let mut declarations = self.ast.vec();
loop {
let declaration =
self.parse_variable_declarator(VariableDeclarationParent::Statement, kind);
let decl_parent = if matches!(statement_ctx, StatementContext::For) {
VariableDeclarationParent::For
} else {
VariableDeclarationParent::Statement
};
let declaration = self.parse_variable_declarator(decl_parent, kind);
if !matches!(declaration.id, BindingPattern::BindingIdentifier(_)) {
self.error(diagnostics::invalid_identifier_in_using_declaration(
@@ -195,13 +201,6 @@ impl<'a, C: Config> ParserImpl<'a, C> {
));
}
// Excluding `for` loops, an initializer is required in a UsingDeclaration.
if declaration.init.is_none() && !matches!(statement_ctx, StatementContext::For) {
self.error(diagnostics::using_declarations_must_be_initialized(
declaration.id.span(),
));
}
declarations.push(declaration);
if !self.eat(Kind::Comma) {
break;
+8 -57
View File
@@ -3,9 +3,7 @@ commit: 308c8d85
parser_babel Summary:
AST Parsed : 2227/2227 (100.00%)
Positive Passed: 2214/2227 (99.42%)
Negative Passed: 1675/1692 (99.00%)
Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2026/explicit-resource-management/invalid-for-using-of-no-initializer/input.js
Negative Passed: 1676/1692 (99.05%)
Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/typescript/cast/unparenthesized-assert-and-assign/input.ts
Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/typescript/cast/unparenthesized-type-assertion-and-assign/input.ts
@@ -8949,6 +8947,13 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc
· ──
╰────
× Using declarations must have an initializer.
╭─[babel/packages/babel-parser/test/fixtures/es2026/explicit-resource-management/invalid-for-using-of-no-initializer/input.js:1:12]
1 │ for (using of;of.isValid;);
· ──
╰────
help: Add an initializer (e.g. ` = undefined`) here
× 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 │ {
@@ -13175,15 +13180,6 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc
╰────
help: Try inserting a semicolon here
× Using declarations must have an initializer.
╭─[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;
╰────
help: Add an initializer (e.g. ` = undefined`) 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]
2 │ await using A;
@@ -13200,33 +13196,6 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc
5 │ await using B, C;
╰────
× Using declarations must have an initializer.
╭─[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 │ }
╰────
help: Add an initializer (e.g. ` = undefined`) here
× Using declarations must have an initializer.
╭─[babel/packages/babel-parser/test/fixtures/typescript/declare/invalid-namespace-await-using/input.ts:5:18]
4 │ await using A2: number = 0;
5 │ await using B, C;
· ─
6 │ }
╰────
help: Add an initializer (e.g. ` = undefined`) here
× Using declarations must have an initializer.
╭─[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;
╰────
help: Add an initializer (e.g. ` = undefined`) here
× TS(1039): Initializers are not allowed in ambient contexts.
╭─[babel/packages/babel-parser/test/fixtures/typescript/declare/invalid-namespace-using/input.ts:3:14]
2 │ using A;
@@ -13243,24 +13212,6 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc
5 │ using B, C;
╰────
× Using declarations must have an initializer.
╭─[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 │ }
╰────
help: Add an initializer (e.g. ` = undefined`) here
× Using declarations must have an initializer.
╭─[babel/packages/babel-parser/test/fixtures/typescript/declare/invalid-namespace-using/input.ts:5:12]
4 │ using A2: number = 0;
5 │ using B, C;
· ─
6 │ }
╰────
help: Add an initializer (e.g. ` = undefined`) here
× 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 {
+12 -83
View File
@@ -3,7 +3,7 @@ commit: 34725489
parser_typescript Summary:
AST Parsed : 9831/9834 (99.97%)
Positive Passed: 9820/9834 (99.86%)
Negative Passed: 1528/2578 (59.27%)
Negative Passed: 1527/2578 (59.23%)
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/FunctionDeclaration3.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/FunctionDeclaration4.ts
@@ -1954,9 +1954,11 @@ 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/usingDeclarationsInForOf.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
@@ -25842,42 +25844,6 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/parser/ecmasc
╰────
help: Wrap this code in a block or use a module
× Using declarations must have an initializer.
╭─[typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/awaitUsingDeclarations.16.ts:2:17]
1 │ declare namespace N {
2 │ await using x: { [Symbol.asyncDispose](): Promise<void> };
· ─
3 │ await using y: null;
╰────
help: Add an initializer (e.g. ` = undefined`) here
× Using declarations must have an initializer.
╭─[typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/awaitUsingDeclarations.16.ts:3:17]
2 │ await using x: { [Symbol.asyncDispose](): Promise<void> };
3 │ await using y: null;
· ─
4 │ }
╰────
help: Add an initializer (e.g. ` = undefined`) here
× Using declarations must have an initializer.
╭─[typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/awaitUsingDeclarations.16.ts:6:17]
5 │ declare module 'M' {
6 │ await using x: { [Symbol.asyncDispose](): Promise<void> };
· ─
7 │ await using y: null;
╰────
help: Add an initializer (e.g. ` = undefined`) here
× Using declarations must have an initializer.
╭─[typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/awaitUsingDeclarations.16.ts:7:17]
6 │ await using x: { [Symbol.asyncDispose](): Promise<void> };
7 │ await using y: null;
· ─
8 │ }
╰────
help: Add an initializer (e.g. ` = undefined`) here
× Using declaration cannot appear in the bare case statement.
╭─[typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/awaitUsingDeclarations.17.ts:3:9]
2 │ case 0:
@@ -25993,15 +25959,6 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/parser/ecmasc
╰────
help: Did you mean to use a for...of statement?
× Missing initializer in destructuring declaration
╭─[typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/awaitUsingDeclarationsInForOf.3.ts:2:22]
1 │ async function main() {
2 │ for (await using {} of []) {
· ──
3 │ }
╰────
help: Add an initializer (e.g. ` = undefined`) here
× Using declarations may not have binding patterns.
╭─[typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/awaitUsingDeclarationsInForOf.3.ts:2:22]
1 │ async function main() {
@@ -26043,42 +26000,6 @@ 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
× Using declarations must have an initializer.
╭─[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;
╰────
help: Add an initializer (e.g. ` = undefined`) here
× Using declarations must have an initializer.
╭─[typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/usingDeclarations.16.ts:3:11]
2 │ using x: { [Symbol.dispose](): void };
3 │ using y: null;
· ─
4 │ }
╰────
help: Add an initializer (e.g. ` = undefined`) here
× Using declarations must have an initializer.
╭─[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;
╰────
help: Add an initializer (e.g. ` = undefined`) here
× Using declarations must have an initializer.
╭─[typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/usingDeclarations.16.ts:7:11]
6 │ using x: { [Symbol.dispose](): void };
7 │ using y: null;
· ─
8 │ }
╰────
help: Add an initializer (e.g. ` = undefined`) here
× Using declaration cannot appear in the bare case statement.
╭─[typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/usingDeclarations.17.ts:3:9]
2 │ case 0:
@@ -26180,6 +26101,14 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/parser/ecmasc
2 │ }
╰────
× Using declarations must have an initializer.
╭─[typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/usingDeclarationsInForOf.4.ts:3:12]
2 │ for (using of: null = null;;) break;
3 │ for (using of;;) break;
· ──
╰────
help: Add an initializer (e.g. ` = undefined`) here
× Illegal break statement
╭─[typescript/tests/cases/conformance/statements/breakStatements/invalidDoWhileBreakStatements.ts:4:1]
3 │ // naked break not allowed