From 020f9526b618a191566acea3e17e20815d484c58 Mon Sep 17 00:00:00 2001 From: Milos Djermanovic Date: Fri, 30 Aug 2019 21:20:28 +0200 Subject: [PATCH] Update: enforceForSequenceExpressions to no-extra-parens (fixes #11916) (#12142) --- docs/rules/no-extra-parens.md | 15 +++ lib/rules/no-extra-parens.js | 9 +- tests/lib/rules/no-extra-parens.js | 150 +++++++++++++++++++++++++---- 3 files changed, 152 insertions(+), 22 deletions(-) diff --git a/docs/rules/no-extra-parens.md b/docs/rules/no-extra-parens.md index 61fb50dc3e0..1896d0a9ee2 100644 --- a/docs/rules/no-extra-parens.md +++ b/docs/rules/no-extra-parens.md @@ -24,6 +24,7 @@ This rule has an object option for exceptions to the `"all"` option: * `"nestedBinaryExpressions": false` allows extra parentheses in nested binary expressions * `"ignoreJSX": "none|all|multi-line|single-line"` allows extra parentheses around no/all/multi-line/single-line JSX components. Defaults to `none`. * `"enforceForArrowConditionals": false` allows extra parentheses around ternary expressions which are the body of an arrow function +* `"enforceForSequenceExpressions": false` allows extra parentheses around sequence expressions ### all @@ -192,6 +193,20 @@ const b = a => 1 ? 2 : 3; const d = c => (1 ? 2 : 3); ``` +### enforceForSequenceExpressions + +Examples of **correct** code for this rule with the `"all"` and `{ "enforceForSequenceExpressions": false }` options: + +```js +/* eslint no-extra-parens: ["error", "all", { "enforceForSequenceExpressions": false }] */ + +(a, b); + +if ((val = foo(), val < 10)) {} + +while ((val = foo(), val < 10)); +``` + ### functions Examples of **incorrect** code for this rule with the `"functions"` option: diff --git a/lib/rules/no-extra-parens.js b/lib/rules/no-extra-parens.js index aa455c6a254..c5cf7904774 100644 --- a/lib/rules/no-extra-parens.js +++ b/lib/rules/no-extra-parens.js @@ -49,7 +49,8 @@ module.exports = { nestedBinaryExpressions: { type: "boolean" }, returnAssign: { type: "boolean" }, ignoreJSX: { enum: ["none", "all", "single-line", "multi-line"] }, - enforceForArrowConditionals: { type: "boolean" } + enforceForArrowConditionals: { type: "boolean" }, + enforceForSequenceExpressions: { type: "boolean" } }, additionalProperties: false } @@ -77,6 +78,8 @@ module.exports = { const IGNORE_JSX = ALL_NODES && context.options[1] && context.options[1].ignoreJSX; const IGNORE_ARROW_CONDITIONALS = ALL_NODES && context.options[1] && context.options[1].enforceForArrowConditionals === false; + const IGNORE_SEQUENCE_EXPRESSIONS = ALL_NODES && context.options[1] && + context.options[1].enforceForSequenceExpressions === false; const PRECEDENCE_OF_ASSIGNMENT_EXPR = precedence({ type: "AssignmentExpression" }); const PRECEDENCE_OF_UPDATE_EXPR = precedence({ type: "UpdateExpression" }); @@ -115,6 +118,10 @@ module.exports = { } } + if (node.type === "SequenceExpression" && IGNORE_SEQUENCE_EXPRESSIONS) { + return false; + } + return ALL_NODES || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression"; } diff --git a/tests/lib/rules/no-extra-parens.js b/tests/lib/rules/no-extra-parens.js index 2b20f20f6b0..788823e0434 100644 --- a/tests/lib/rules/no-extra-parens.js +++ b/tests/lib/rules/no-extra-parens.js @@ -439,6 +439,12 @@ ruleTester.run("no-extra-parens", rule, { { code: "var a = b => 1 ? 2 : 3", options: ["all", { enforceForArrowConditionals: false }] }, { code: "var a = (b) => (1 ? 2 : 3)", options: ["all", { enforceForArrowConditionals: false }] }, + // ["all", { enforceForSequenceExpressions: false }] + { code: "(a, b)", options: ["all", { enforceForSequenceExpressions: false }] }, + { code: "(foo(), bar());", options: ["all", { enforceForSequenceExpressions: false }] }, + { code: "if((a, b)){}", options: ["all", { enforceForSequenceExpressions: false }] }, + { code: "while ((val = foo(), val < 10));", options: ["all", { enforceForSequenceExpressions: false }] }, + "let a = [ ...b ]", "let a = { ...b }", { @@ -836,7 +842,7 @@ ruleTester.run("no-extra-parens", rule, { options: ["all", { returnAssign: false }], errors: [ { - messgeId: "unexpected", + messageId: "unexpected", type: "LogicalExpression" } ] @@ -846,7 +852,7 @@ ruleTester.run("no-extra-parens", rule, { output: "function a(b) { return (b = c) || (d = e); }", errors: [ { - messgeId: "unexpected", + messageId: "unexpected", type: "LogicalExpression" } ] @@ -856,7 +862,7 @@ ruleTester.run("no-extra-parens", rule, { output: "function a(b) { return b = 1; }", errors: [ { - messgeId: "unexpected", + messageId: "unexpected", type: "AssignmentExpression" } ] @@ -866,11 +872,11 @@ ruleTester.run("no-extra-parens", rule, { output: "function a(b) { return c ? d = b : e = b; }", errors: [ { - messgeId: "unexpected", + messageId: "unexpected", type: "AssignmentExpression" }, { - messgeId: "unexpected", + messageId: "unexpected", type: "AssignmentExpression" } ] @@ -882,7 +888,7 @@ ruleTester.run("no-extra-parens", rule, { errors: [ { - messgeId: "unexpected", + messageId: "unexpected", type: "LogicalExpression" } ] @@ -892,7 +898,7 @@ ruleTester.run("no-extra-parens", rule, { output: "b => (b = c) || (d = e);", errors: [ { - messgeId: "unexpected", + messageId: "unexpected", type: "LogicalExpression" } ] @@ -902,7 +908,7 @@ ruleTester.run("no-extra-parens", rule, { output: "b => b = 1;", errors: [ { - messgeId: "unexpected", + messageId: "unexpected", type: "AssignmentExpression" } ] @@ -912,11 +918,11 @@ ruleTester.run("no-extra-parens", rule, { output: "b => c ? d = b : e = b;", errors: [ { - messgeId: "unexpected", + messageId: "unexpected", type: "AssignmentExpression" }, { - messgeId: "unexpected", + messageId: "unexpected", type: "AssignmentExpression" } ] @@ -927,7 +933,7 @@ ruleTester.run("no-extra-parens", rule, { options: ["all", { returnAssign: false }], errors: [ { - messgeId: "unexpected", + messageId: "unexpected", type: "LogicalExpression" } ] @@ -937,7 +943,7 @@ ruleTester.run("no-extra-parens", rule, { output: "b => { return (b = c) || (d = e) };", errors: [ { - messgeId: "unexpected", + messageId: "unexpected", type: "LogicalExpression" } ] @@ -947,7 +953,7 @@ ruleTester.run("no-extra-parens", rule, { output: "b => { return b = 1 };", errors: [ { - messgeId: "unexpected", + messageId: "unexpected", type: "AssignmentExpression" } ] @@ -957,11 +963,11 @@ ruleTester.run("no-extra-parens", rule, { output: "b => { return c ? d = b : e = b; }", errors: [ { - messgeId: "unexpected", + messageId: "unexpected", type: "AssignmentExpression" }, { - messgeId: "unexpected", + messageId: "unexpected", type: "AssignmentExpression" } ] @@ -973,11 +979,11 @@ ruleTester.run("no-extra-parens", rule, { output: "async function a() { await a + await b; }", errors: [ { - messgeId: "unexpected", + messageId: "unexpected", type: "AwaitExpression" }, { - messgeId: "unexpected", + messageId: "unexpected", type: "AwaitExpression" } ] @@ -1058,7 +1064,7 @@ ruleTester.run("no-extra-parens", rule, { options: ["all", { enforceForArrowConditionals: true }], errors: [ { - messgeId: "unexpected" + messageId: "unexpected" } ] }, @@ -1070,7 +1076,75 @@ ruleTester.run("no-extra-parens", rule, { options: ["all", { enforceForArrowConditionals: false }], errors: [ { - messgeId: "unexpected" + messageId: "unexpected" + } + ] + }, + + // ["all", { enforceForSequenceExpressions: true }] + { + code: "(a, b)", + output: "a, b", + options: ["all"], + errors: [ + { + messageId: "unexpected", + type: "SequenceExpression" + } + ] + }, + { + code: "(a, b)", + output: "a, b", + options: ["all", {}], + errors: [ + { + messageId: "unexpected", + type: "SequenceExpression" + } + ] + }, + { + code: "(a, b)", + output: "a, b", + options: ["all", { enforceForSequenceExpressions: true }], + errors: [ + { + messageId: "unexpected", + type: "SequenceExpression" + } + ] + }, + { + code: "(foo(), bar());", + output: "foo(), bar();", + options: ["all", { enforceForSequenceExpressions: true }], + errors: [ + { + messageId: "unexpected", + type: "SequenceExpression" + } + ] + }, + { + code: "if((a, b)){}", + output: "if(a, b){}", + options: ["all", { enforceForSequenceExpressions: true }], + errors: [ + { + messageId: "unexpected", + type: "SequenceExpression" + } + ] + }, + { + code: "while ((val = foo(), val < 10));", + output: "while (val = foo(), val < 10);", + options: ["all", { enforceForSequenceExpressions: true }], + errors: [ + { + messageId: "unexpected", + type: "SequenceExpression" } ] }, @@ -1360,6 +1434,15 @@ ruleTester.run("no-extra-parens", rule, { } ] }, + { + code: "for (let [a = (b in c)] = []; ;);", + output: "for (let [a = b in c] = []; ;);", + errors: [ + { + messageId: "unexpected" + } + ] + }, { code: "for (let [a = b && (c in d)] = []; ;);", output: "for (let [a = b && c in d] = []; ;);", @@ -1414,6 +1497,15 @@ ruleTester.run("no-extra-parens", rule, { } ] }, + { + code: "for (let { a = (b in c) } = {}; ;);", + output: "for (let { a = b in c } = {}; ;);", + errors: [ + { + messageId: "unexpected" + } + ] + }, { code: "for (let { a = b && (c in d) } = {}; ;);", output: "for (let { a = b && c in d } = {}; ;);", @@ -1432,6 +1524,15 @@ ruleTester.run("no-extra-parens", rule, { } ] }, + { + code: "for (let a = `${(a in b)}`; ;);", + output: "for (let a = `${a in b}`; ;);", + errors: [ + { + messageId: "unexpected" + } + ] + }, { code: "for (let a = `${a && (b in c)}`; ;);", output: "for (let a = `${a && b in c}`; ;);", @@ -1441,6 +1542,15 @@ ruleTester.run("no-extra-parens", rule, { } ] }, + { + code: "for (let a = (b = (c in d)) => {}; ;);", + output: "for (let a = (b = c in d) => {}; ;);", + errors: [ + { + messageId: "unexpected" + } + ] + }, { code: "for (let a = (b = c && (d in e)) => {}; ;);", output: "for (let a = (b = c && d in e) => {}; ;);", @@ -1703,8 +1813,6 @@ ruleTester.run("no-extra-parens", rule, { ) }, - // TODO: Add '`in` inside a for-loop' first level tests for AssignmentPattern (param, obj, ary) and TemplateLiteral when these become supported. - // https://github.com/eslint/eslint/issues/11706 regression tests (also in valid[]) { code: "for (let a = (b); a > (b); a = (b)) a = (b); a = (b);",