Skip to content

Commit

Permalink
Update: Add a 'requireForBlockBody' modifier to the 'arrow-parens' ru…
Browse files Browse the repository at this point in the history
…le (fixes #6557)

The `'as-needed'` option can now be modified with the `{requireForBlockBody: true}` option allowing to
 require parentheses for arrow functions whose body is wrapped into curly braces like the following:
 ```js
 (a) => {}
 ```
  • Loading branch information
nfroidure committed Jul 22, 2016
1 parent e2b2030 commit 1d74cfa
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 4 deletions.
46 changes: 44 additions & 2 deletions docs/rules/arrow-parens.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ a => {}

## Options

The rule takes one option, a string, which could be either `"always"` or `"as-needed"`. The default is `"always"`.
The rule takes one option, a string, which could be `"always"`, `"as-needed"`
or `"when-brace"`. The default is `"always"`.

You can set the option in configuration like this:

Expand Down Expand Up @@ -176,4 +177,45 @@ a.then(foo => { if (true) {}; });
(a = 10) => a;
([a, b]) => a;
({a, b}) => a;
```
```


### "when-brace"

When the rule is set to `"when-brace"` the following patterns are considered problems:

```js
/*eslint arrow-parens: [2, "when-brace"]*/
/*eslint-env es6*/

(a) => a;
a => {};
a => {'\n'};
a.map((x) => x * x);
a.map(x => {
return x * x;
});
a.then(foo => {});
```

The following patterns are not considered problems:

```js
/*eslint arrow-parens: [2, "when-brace"]*/
/*eslint-env es6*/

(a) => {};
(a) => {'\n'};
() => {};
a => a;
a.then((foo) => {});
a.then(foo => { if (true) {}; });
a((foo) => { if (true) {}; });
(a, b, c) => a;
(a = 10) => a;
([a, b]) => a;
({a, b}) => a;
```

The `"when-brace"` rule is directly inspired by the Airbnb
[JS Style Guide](https://github.com/airbnb/javascript#arrows--one-arg-parens).
29 changes: 28 additions & 1 deletion lib/rules/arrow-parens.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ module.exports = {

schema: [
{
enum: ["always", "as-needed"]
enum: ["always", "as-needed", "when-brace"]
}
]
},
Expand All @@ -29,6 +29,8 @@ module.exports = {
var message = "Expected parentheses around arrow function argument.";
var asNeededMessage = "Unexpected parentheses around single function argument";
var asNeeded = context.options[0] === "as-needed";
var whenBraceMessage = "Unexpected parentheses around single function argument having a body with no curly braces";
var whenBrace = context.options[0] === "when-brace";

var sourceCode = context.getSourceCode();

Expand All @@ -39,6 +41,7 @@ module.exports = {
*/
function parens(node) {
var token = sourceCode.getFirstToken(node);
var bodyToken = sourceCode.getFirstToken(node.body);

// as-needed: x => x
if (asNeeded && node.params.length === 1 && node.params[0].type === "Identifier") {
Expand All @@ -60,6 +63,30 @@ module.exports = {
return;
}

// when-brace: x => x
if (
whenBrace &&
node.params.length === 1 && node.params[0].type === "Identifier" &&
bodyToken.type !== "Punctuator" && bodyToken.value !== "{"
) {
if (token.type === "Punctuator" && token.value === "(") {
context.report({
node: node,
message: whenBraceMessage,
fix: function(fixer) {
var paramToken = context.getTokenAfter(token);
var closingParenToken = context.getTokenAfter(paramToken);

return fixer.replaceTextRange([
token.range[0],
closingParenToken.range[1]
], paramToken.value);
}
});
}
return;
}

if (token.type === "Identifier") {
var after = sourceCode.getTokenAfter(token);

Expand Down
50 changes: 49 additions & 1 deletion tests/lib/rules/arrow-parens.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,22 @@ var valid = [
{ code: "({ a, b }) => {}", options: ["as-needed"], parserOptions: { ecmaVersion: 6 } },
{ code: "(a = 10) => {}", options: ["as-needed"], parserOptions: { ecmaVersion: 6 } },
{ code: "(...a) => a[0]", options: ["as-needed"], parserOptions: { ecmaVersion: 6 } },
{ code: "(a, b) => {}", options: ["as-needed"], parserOptions: { ecmaVersion: 6 } }
{ code: "(a, b) => {}", options: ["as-needed"], parserOptions: { ecmaVersion: 6 } },

// when-brace
{ code: "() => {}", options: ["when-brace"], parserOptions: { ecmaVersion: 6 } },
{ code: "a => a", options: ["when-brace"], parserOptions: { ecmaVersion: 6 } },
{ code: "([a, b]) => {}", options: ["when-brace"], parserOptions: { ecmaVersion: 6 } },
{ code: "({ a, b }) => {}", options: ["when-brace"], parserOptions: { ecmaVersion: 6 } },
{ code: "(a = 10) => {}", options: ["when-brace"], parserOptions: { ecmaVersion: 6 } },
{ code: "(...a) => a[0]", options: ["when-brace"], parserOptions: { ecmaVersion: 6 } },
{ code: "(a, b) => {}", options: ["when-brace"], parserOptions: { ecmaVersion: 6 } }

];

var message = "Expected parentheses around arrow function argument.";
var asNeededMessage = "Unexpected parentheses around single function argument";
var whenBraceMessage = "Unexpected parentheses around single function argument having a body with no curly braces";
var type = "ArrowFunctionExpression";

var invalid = [
Expand Down Expand Up @@ -133,6 +143,44 @@ var invalid = [
message: asNeededMessage,
type: type
}]
},

// when-brace
{
code: "a => {}",
output: "(a) => {}",
options: ["when-brace"],
parserOptions: { ecmaVersion: 6 },
errors: [{
line: 1,
column: 1,
message: message,
type: type
}]
},
{
code: "(a) => a",
output: "a => a",
options: ["when-brace"],
parserOptions: { ecmaVersion: 6 },
errors: [{
line: 1,
column: 1,
message: whenBraceMessage,
type: type
}]
},
{
code: "(b) => b",
output: "b => b",
options: ["when-brace"],
parserOptions: { ecmaVersion: 6 },
errors: [{
line: 1,
column: 1,
message: whenBraceMessage,
type: type
}]
}

];
Expand Down

0 comments on commit 1d74cfa

Please sign in to comment.