Skip to content

Commit 5848216

Browse files
authored
feat: support explicit resource management in init-declarations (#19893)
1 parent bb370b8 commit 5848216

File tree

3 files changed

+35
-3
lines changed

3 files changed

+35
-3
lines changed

docs/src/rules/init-declarations.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ This rule aims to bring consistency to variable initializations and declarations
3636

3737
The rule takes two options:
3838

39-
1. A string which must be either `"always"` (the default), to enforce initialization at declaration, or `"never"` to disallow initialization during declaration. This rule applies to `var`, `let`, and `const` variables, however `"never"` is ignored for `const` variables, as unassigned `const`s generate a parse error.
39+
1. A string which must be either `"always"` (the default), to enforce initialization at declaration, or `"never"` to disallow initialization during declaration. This rule applies to `var`, `let`, `const`, `using`, and `await using` variables, however `"never"` is ignored for `const`, `using`, and `await using` variables, as not initializing these variables would generate a parse error.
4040
2. An object that further controls the behavior of this rule. Currently, the only available parameter is `ignoreForLoopInit`, which indicates if initialization at declaration is allowed in `for` loops when `"never"` is set, since it is a very typical use case.
4141

4242
You can configure the rule as follows:
@@ -93,6 +93,11 @@ function foo() {
9393
var bar = 1;
9494
let baz = 2;
9595
const qux = 3;
96+
using quux = getSomething();
97+
}
98+
99+
async function foobar() {
100+
await using quux = getSomething();
96101
}
97102
```
98103

@@ -128,12 +133,17 @@ function foo() {
128133
var bar;
129134
let baz;
130135
const buzz = 1;
136+
using quux = getSomething();
137+
}
138+
139+
async function foobar() {
140+
await using quux = getSomething();
131141
}
132142
```
133143

134144
:::
135145

136-
The `"never"` option ignores `const` variable initializations.
146+
The `"never"` option ignores `const`, `using`, and `await using` variable initializations.
137147

138148
### ignoreForLoopInit
139149

lib/rules/init-declarations.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
// Helpers
1010
//------------------------------------------------------------------------------
1111

12+
const CONSTANT_BINDINGS = new Set(["const", "using", "await using"]);
13+
1214
/**
1315
* Checks whether or not a given node is a for loop.
1416
* @param {ASTNode} block A node to check.
@@ -147,7 +149,7 @@ module.exports = {
147149
messageId = "initialized";
148150
} else if (
149151
mode === MODE_NEVER &&
150-
kind !== "const" &&
152+
!CONSTANT_BINDINGS.has(kind) &&
151153
initialized &&
152154
!isIgnoredForLoop
153155
) {

tests/lib/rules/init-declarations.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,16 @@ ruleTester.run("init-declarations", rule, {
3939
options: ["always"],
4040
languageOptions: { ecmaVersion: 6 },
4141
},
42+
{
43+
code: "using a = foo();",
44+
options: ["always"],
45+
languageOptions: { ecmaVersion: 2026 },
46+
},
47+
{
48+
code: "await using a = foo();",
49+
options: ["always"],
50+
languageOptions: { ecmaVersion: 2026 },
51+
},
4252
{
4353
code: "function foo() { let a = 1, b = false; if (a) { let c = 3, d = null; } }",
4454
options: ["always"],
@@ -79,6 +89,16 @@ ruleTester.run("init-declarations", rule, {
7989
options: ["never"],
8090
languageOptions: { ecmaVersion: 6 },
8191
},
92+
{
93+
code: "using a = foo();",
94+
options: ["never"],
95+
languageOptions: { ecmaVersion: 2026 },
96+
},
97+
{
98+
code: "await using a = foo();",
99+
options: ["never"],
100+
languageOptions: { ecmaVersion: 2026 },
101+
},
82102
{
83103
code: "function foo() { let a, b; if (a) { let c, d; } }",
84104
options: ["never"],

0 commit comments

Comments
 (0)