Skip to content

Commit b51d077

Browse files
authored
Update: add ignoreNonDeclaration to no-multi-assign rule (fixes #12545) (#14185)
* Update: add an option to ignore non declaration (refs #12545) * Doc: add description of the option (refs #12545) * Chore: reflect review comments (refs #12545) * Chore: modify the document according to comments (refs #12545)
1 parent c981fb1 commit b51d077

File tree

3 files changed

+83
-3
lines changed

3 files changed

+83
-3
lines changed

docs/rules/no-multi-assign.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,38 @@ let a = c;
4343
let b = c;
4444
```
4545

46+
## Options
47+
48+
This rule has an object option:
49+
50+
* `"ignoreNonDeclaration"`: When set to `true`, the rule allows chains that don't include initializing a variable in a declaration. Default is `false`.
51+
52+
### ignoreNonDeclaration
53+
54+
Examples of **correct** code for the `{ "ignoreNonDeclaration": true }` option:
55+
56+
```js
57+
/*eslint no-multi-assign: ["error", { "ignoreNonDeclaration": true }]*/
58+
59+
let a;
60+
let b;
61+
a = b = "baz";
62+
63+
const x = {};
64+
const y = {};
65+
x.one = y.one = 1;
66+
```
67+
68+
Examples of **incorrect** code for the `{ "ignoreNonDeclaration": true }` option:
69+
70+
```js
71+
/*eslint no-multi-assign: ["error", { "ignoreNonDeclaration": true }]*/
72+
73+
let a = b = "baz";
74+
75+
const foo = bar = 1;
76+
```
77+
4678
## Related Rules
4779

4880
* [max-statements-per-line](max-statements-per-line.md)

lib/rules/no-multi-assign.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,16 @@ module.exports = {
2121
url: "https://eslint.org/docs/rules/no-multi-assign"
2222
},
2323

24-
schema: [],
24+
schema: [{
25+
type: "object",
26+
properties: {
27+
ignoreNonDeclaration: {
28+
type: "boolean",
29+
default: false
30+
}
31+
},
32+
additionalProperties: false
33+
}],
2534

2635
messages: {
2736
unexpectedChain: "Unexpected chained assignment."
@@ -33,10 +42,14 @@ module.exports = {
3342
//--------------------------------------------------------------------------
3443
// Public
3544
//--------------------------------------------------------------------------
45+
const options = context.options[0] || {
46+
ignoreNonDeclaration: false
47+
};
48+
const targetParent = options.ignoreNonDeclaration ? ["VariableDeclarator"] : ["AssignmentExpression", "VariableDeclarator"];
3649

3750
return {
3851
AssignmentExpression(node) {
39-
if (["AssignmentExpression", "VariableDeclarator"].indexOf(node.parent.type) !== -1) {
52+
if (targetParent.indexOf(node.parent.type) !== -1) {
4053
context.report({
4154
node,
4255
messageId: "unexpectedChain"

tests/lib/rules/no-multi-assign.js

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ ruleTester.run("no-mutli-assign", rule, {
5151
{ code: "for(let a = 0, b = 0;;){}", parserOptions: { ecmaVersion: 6 } },
5252
{ code: "for(const a = 0, b = 0;;){}", parserOptions: { ecmaVersion: 6 } },
5353
{ code: "export let a, b;", parserOptions: { ecmaVersion: 6, sourceType: "module" } },
54-
{ code: "export let a,\n b = 0;", parserOptions: { ecmaVersion: 6, sourceType: "module" } }
54+
{ code: "export let a,\n b = 0;", parserOptions: { ecmaVersion: 6, sourceType: "module" } },
55+
{ code: "const x = {};const y = {};x.one = y.one = 1;", options: [{ ignoreNonDeclaration: true }], parserOptions: { ecmaVersion: 6 } },
56+
{ code: "let a, b;a = b = 1", options: [{ ignoreNonDeclaration: true }], parserOptions: { ecmaVersion: 6 } }
5557
],
5658

5759
invalid: [
@@ -137,6 +139,39 @@ ruleTester.run("no-mutli-assign", rule, {
137139
errors: [
138140
errorAt(1, 5, "AssignmentExpression")
139141
]
142+
},
143+
{
144+
code: "const x = {};\nconst y = x.one = 1;",
145+
options: [{ ignoreNonDeclaration: true }],
146+
parserOptions: { ecmaVersion: 6 },
147+
errors: [
148+
errorAt(2, 11, "AssignmentExpression")
149+
]
150+
151+
},
152+
{
153+
code: "let a, b;a = b = 1",
154+
options: [{}],
155+
parserOptions: { ecmaVersion: 6 },
156+
errors: [
157+
errorAt(1, 14, "AssignmentExpression")
158+
]
159+
},
160+
{
161+
code: "let x, y;x = y = 'baz'",
162+
options: [{ ignoreNonDeclaration: false }],
163+
parserOptions: { ecmaVersion: 6 },
164+
errors: [
165+
errorAt(1, 14, "AssignmentExpression")
166+
]
167+
},
168+
{
169+
code: "const a = b = 1",
170+
options: [{ ignoreNonDeclaration: true }],
171+
parserOptions: { ecmaVersion: 6 },
172+
errors: [
173+
errorAt(1, 11, "AssignmentExpression")
174+
]
140175
}
141176
]
142177
});

0 commit comments

Comments
 (0)