From 597e136d9ac1f9e4763317bcbeec6fd8729c7184 Mon Sep 17 00:00:00 2001 From: t-mangoe Date: Sat, 6 Mar 2021 10:20:09 +0900 Subject: [PATCH 1/4] Update: add an option to ignore non declaration (refs #12545) --- lib/rules/no-multi-assign.js | 18 ++++++++++++++++-- tests/lib/rules/no-multi-assign.js | 13 ++++++++++++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/lib/rules/no-multi-assign.js b/lib/rules/no-multi-assign.js index ab6430c19ef..7cee1a914b8 100644 --- a/lib/rules/no-multi-assign.js +++ b/lib/rules/no-multi-assign.js @@ -21,7 +21,16 @@ module.exports = { url: "https://eslint.org/docs/rules/no-multi-assign" }, - schema: [], + schema: [{ + type: "object", + properties: { + ignoreNonDeclaration: { + type: "boolean", + default: false + } + }, + additionalProperties: false + }], messages: { unexpectedChain: "Unexpected chained assignment." @@ -33,10 +42,15 @@ module.exports = { //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- + const options = context.options[0] || { + ignoreNonDeclaration: false + }; return { AssignmentExpression(node) { - if (["AssignmentExpression", "VariableDeclarator"].indexOf(node.parent.type) !== -1) { + const target = options.ignoreNonDeclaration ? ["VariableDeclarator"] : ["AssignmentExpression", "VariableDeclarator"]; + + if (target.indexOf(node.parent.type) !== -1) { context.report({ node, messageId: "unexpectedChain" diff --git a/tests/lib/rules/no-multi-assign.js b/tests/lib/rules/no-multi-assign.js index dc907465c60..ba1c6e434b3 100644 --- a/tests/lib/rules/no-multi-assign.js +++ b/tests/lib/rules/no-multi-assign.js @@ -39,6 +39,7 @@ function errorAt(line, column, type) { //------------------------------------------------------------------------------ const ruleTester = new RuleTester(); +const options = [{ ignoreNonDeclaration: true }]; ruleTester.run("no-mutli-assign", rule, { valid: [ @@ -51,7 +52,8 @@ ruleTester.run("no-mutli-assign", rule, { { code: "for(let a = 0, b = 0;;){}", parserOptions: { ecmaVersion: 6 } }, { code: "for(const a = 0, b = 0;;){}", parserOptions: { ecmaVersion: 6 } }, { code: "export let a, b;", parserOptions: { ecmaVersion: 6, sourceType: "module" } }, - { code: "export let a,\n b = 0;", parserOptions: { ecmaVersion: 6, sourceType: "module" } } + { code: "export let a,\n b = 0;", parserOptions: { ecmaVersion: 6, sourceType: "module" } }, + { code: "const x = {};const y = {};x.one = y.one = 1;", options, parserOptions: { ecmaVersion: 6 } } ], invalid: [ @@ -137,6 +139,15 @@ ruleTester.run("no-mutli-assign", rule, { errors: [ errorAt(1, 5, "AssignmentExpression") ] + }, + { + code: "const x = {};\nconst y = x.one = 1;", + options, + parserOptions: { ecmaVersion: 6 }, + errors: [ + errorAt(2, 11, "AssignmentExpression") + ] + } ] }); From bcf8026d5df6dc1b8be37af7b0574dd06386b106 Mon Sep 17 00:00:00 2001 From: t-mangoe Date: Sat, 13 Mar 2021 10:03:06 +0900 Subject: [PATCH 2/4] Doc: add description of the option (refs #12545) --- docs/rules/no-multi-assign.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/rules/no-multi-assign.md b/docs/rules/no-multi-assign.md index 41bba9ad6a9..c8e152bf5ed 100644 --- a/docs/rules/no-multi-assign.md +++ b/docs/rules/no-multi-assign.md @@ -43,6 +43,21 @@ let a = c; let b = c; ``` +## Options + +This rule has an object option: + +* `"ignoreNonDeclaration": false` (default) disallows using multiple assignments to already declared variables. + +Examples of **correct** code for the `{ "ignoreNonDeclaration": true }` option: + +```js +/*eslint no-multi-assign: ["error", { ignoreNonDeclaration: true }]*/ +const x = {}; +const y = {}; +x.one = y.one = 1; // this is allowed. +``` + ## Related Rules * [max-statements-per-line](max-statements-per-line.md) From 44be9d39f4ddd0e7b07304922a66aad309d86e6e Mon Sep 17 00:00:00 2001 From: t-mangoe Date: Sat, 27 Mar 2021 09:55:35 +0900 Subject: [PATCH 3/4] Chore: reflect review comments (refs #12545) --- docs/rules/no-multi-assign.md | 21 +++++++++++++++++++-- lib/rules/no-multi-assign.js | 5 ++--- tests/lib/rules/no-multi-assign.js | 30 +++++++++++++++++++++++++++--- 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/docs/rules/no-multi-assign.md b/docs/rules/no-multi-assign.md index c8e152bf5ed..d5a3bd41023 100644 --- a/docs/rules/no-multi-assign.md +++ b/docs/rules/no-multi-assign.md @@ -47,15 +47,32 @@ let b = c; This rule has an object option: -* `"ignoreNonDeclaration": false` (default) disallows using multiple assignments to already declared variables. +* `"ignoreNonDeclaration"`: When set to `true`, the rule allows chains that don't include initializing a variable in a declaration. Default is `false`. + +### ignoreNonDeclaration Examples of **correct** code for the `{ "ignoreNonDeclaration": true }` option: ```js /*eslint no-multi-assign: ["error", { ignoreNonDeclaration: true }]*/ + +let a; +let b; +a = b = "baz"; + const x = {}; const y = {}; -x.one = y.one = 1; // this is allowed. +x.one = y.one = 1; +``` + +Examples of **incorrect** code for the `{ "ignoreNonDeclaration": true }` option: + +```js +/*eslint no-multi-assign: ["error", { ignoreNonDeclaration: true }]*/ + +let a = b = "baz"; + +const foo = bar = 1; ``` ## Related Rules diff --git a/lib/rules/no-multi-assign.js b/lib/rules/no-multi-assign.js index 7cee1a914b8..d2606a1502a 100644 --- a/lib/rules/no-multi-assign.js +++ b/lib/rules/no-multi-assign.js @@ -45,12 +45,11 @@ module.exports = { const options = context.options[0] || { ignoreNonDeclaration: false }; + const targetParent = options.ignoreNonDeclaration ? ["VariableDeclarator"] : ["AssignmentExpression", "VariableDeclarator"]; return { AssignmentExpression(node) { - const target = options.ignoreNonDeclaration ? ["VariableDeclarator"] : ["AssignmentExpression", "VariableDeclarator"]; - - if (target.indexOf(node.parent.type) !== -1) { + if (targetParent.indexOf(node.parent.type) !== -1) { context.report({ node, messageId: "unexpectedChain" diff --git a/tests/lib/rules/no-multi-assign.js b/tests/lib/rules/no-multi-assign.js index ba1c6e434b3..c534f55b33f 100644 --- a/tests/lib/rules/no-multi-assign.js +++ b/tests/lib/rules/no-multi-assign.js @@ -39,7 +39,6 @@ function errorAt(line, column, type) { //------------------------------------------------------------------------------ const ruleTester = new RuleTester(); -const options = [{ ignoreNonDeclaration: true }]; ruleTester.run("no-mutli-assign", rule, { valid: [ @@ -53,7 +52,8 @@ ruleTester.run("no-mutli-assign", rule, { { code: "for(const a = 0, b = 0;;){}", parserOptions: { ecmaVersion: 6 } }, { code: "export let a, b;", parserOptions: { ecmaVersion: 6, sourceType: "module" } }, { code: "export let a,\n b = 0;", parserOptions: { ecmaVersion: 6, sourceType: "module" } }, - { code: "const x = {};const y = {};x.one = y.one = 1;", options, parserOptions: { ecmaVersion: 6 } } + { code: "const x = {};const y = {};x.one = y.one = 1;", options: [{ ignoreNonDeclaration: true }], parserOptions: { ecmaVersion: 6 } }, + { code: "let a, b;a = b = 1", options: [{ ignoreNonDeclaration: true }], parserOptions: { ecmaVersion: 6 } } ], invalid: [ @@ -142,12 +142,36 @@ ruleTester.run("no-mutli-assign", rule, { }, { code: "const x = {};\nconst y = x.one = 1;", - options, + options: [{ ignoreNonDeclaration: true }], parserOptions: { ecmaVersion: 6 }, errors: [ errorAt(2, 11, "AssignmentExpression") ] + }, + { + code: "let a, b;a = b = 1", + options: [{}], + parserOptions: { ecmaVersion: 6 }, + errors: [ + errorAt(1, 14, "AssignmentExpression") + ] + }, + { + code: "let x, y;x = y = 'baz'", + options: [{ ignoreNonDeclaration: false }], + parserOptions: { ecmaVersion: 6 }, + errors: [ + errorAt(1, 14, "AssignmentExpression") + ] + }, + { + code: "const a = b = 1", + options: [{ ignoreNonDeclaration: true }], + parserOptions: { ecmaVersion: 6 }, + errors: [ + errorAt(1, 11, "AssignmentExpression") + ] } ] }); From cdc417f32ad7855d696ae720b9bcc71e8200fc36 Mon Sep 17 00:00:00 2001 From: t-mangoe Date: Sat, 3 Apr 2021 17:25:47 +0900 Subject: [PATCH 4/4] =?UTF-8?q?Chore:=20modify=20the=20document=20accordin?= =?UTF-8?q?g=20to=20comments=E3=80=80(refs=20#12545)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/rules/no-multi-assign.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/rules/no-multi-assign.md b/docs/rules/no-multi-assign.md index d5a3bd41023..7ef70567593 100644 --- a/docs/rules/no-multi-assign.md +++ b/docs/rules/no-multi-assign.md @@ -54,7 +54,7 @@ This rule has an object option: Examples of **correct** code for the `{ "ignoreNonDeclaration": true }` option: ```js -/*eslint no-multi-assign: ["error", { ignoreNonDeclaration: true }]*/ +/*eslint no-multi-assign: ["error", { "ignoreNonDeclaration": true }]*/ let a; let b; @@ -68,7 +68,7 @@ x.one = y.one = 1; Examples of **incorrect** code for the `{ "ignoreNonDeclaration": true }` option: ```js -/*eslint no-multi-assign: ["error", { ignoreNonDeclaration: true }]*/ +/*eslint no-multi-assign: ["error", { "ignoreNonDeclaration": true }]*/ let a = b = "baz";