Skip to content

Commit

Permalink
Update: enforceForSequenceExpressions to no-extra-parens (fixes #11916)…
Browse files Browse the repository at this point in the history
… (#12142)
  • Loading branch information
mdjermanovic authored and btmills committed Aug 30, 2019
1 parent aab1b84 commit 020f952
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 22 deletions.
15 changes: 15 additions & 0 deletions docs/rules/no-extra-parens.md
Expand Up @@ -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

Expand Down Expand Up @@ -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:
Expand Down
9 changes: 8 additions & 1 deletion lib/rules/no-extra-parens.js
Expand Up @@ -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
}
Expand Down Expand Up @@ -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" });
Expand Down Expand Up @@ -115,6 +118,10 @@ module.exports = {
}
}

if (node.type === "SequenceExpression" && IGNORE_SEQUENCE_EXPRESSIONS) {
return false;
}

return ALL_NODES || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression";
}

Expand Down
150 changes: 129 additions & 21 deletions tests/lib/rules/no-extra-parens.js
Expand Up @@ -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 }",
{
Expand Down Expand Up @@ -836,7 +842,7 @@ ruleTester.run("no-extra-parens", rule, {
options: ["all", { returnAssign: false }],
errors: [
{
messgeId: "unexpected",
messageId: "unexpected",
type: "LogicalExpression"
}
]
Expand All @@ -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"
}
]
Expand All @@ -856,7 +862,7 @@ ruleTester.run("no-extra-parens", rule, {
output: "function a(b) { return b = 1; }",
errors: [
{
messgeId: "unexpected",
messageId: "unexpected",
type: "AssignmentExpression"
}
]
Expand All @@ -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"
}
]
Expand All @@ -882,7 +888,7 @@ ruleTester.run("no-extra-parens", rule, {

errors: [
{
messgeId: "unexpected",
messageId: "unexpected",
type: "LogicalExpression"
}
]
Expand All @@ -892,7 +898,7 @@ ruleTester.run("no-extra-parens", rule, {
output: "b => (b = c) || (d = e);",
errors: [
{
messgeId: "unexpected",
messageId: "unexpected",
type: "LogicalExpression"
}
]
Expand All @@ -902,7 +908,7 @@ ruleTester.run("no-extra-parens", rule, {
output: "b => b = 1;",
errors: [
{
messgeId: "unexpected",
messageId: "unexpected",
type: "AssignmentExpression"
}
]
Expand All @@ -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"
}
]
Expand All @@ -927,7 +933,7 @@ ruleTester.run("no-extra-parens", rule, {
options: ["all", { returnAssign: false }],
errors: [
{
messgeId: "unexpected",
messageId: "unexpected",
type: "LogicalExpression"
}
]
Expand All @@ -937,7 +943,7 @@ ruleTester.run("no-extra-parens", rule, {
output: "b => { return (b = c) || (d = e) };",
errors: [
{
messgeId: "unexpected",
messageId: "unexpected",
type: "LogicalExpression"
}
]
Expand All @@ -947,7 +953,7 @@ ruleTester.run("no-extra-parens", rule, {
output: "b => { return b = 1 };",
errors: [
{
messgeId: "unexpected",
messageId: "unexpected",
type: "AssignmentExpression"
}
]
Expand All @@ -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"
}
]
Expand All @@ -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"
}
]
Expand Down Expand Up @@ -1058,7 +1064,7 @@ ruleTester.run("no-extra-parens", rule, {
options: ["all", { enforceForArrowConditionals: true }],
errors: [
{
messgeId: "unexpected"
messageId: "unexpected"
}
]
},
Expand All @@ -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"
}
]
},
Expand Down Expand Up @@ -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] = []; ;);",
Expand Down Expand Up @@ -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 } = {}; ;);",
Expand All @@ -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}`; ;);",
Expand All @@ -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) => {}; ;);",
Expand Down Expand Up @@ -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);",
Expand Down

0 comments on commit 020f952

Please sign in to comment.