Skip to content

Commit 6e03c4b

Browse files
ajhyndmanilyavolodin
authored andcommitted
Update: Add never option to arrow-body-style (fixes #6317) (#6318)
* Update: Add never option to arrow-body-style (fixes #6317) Arrow functions that return object literals can look very similar to arrow functions with brace bodies. Some syntactic ambiguity can be avoided by disallowing block-style arrow functions in favour of ES5 function expressions. **Outcome** The following patterns are considered problems: ``` /*eslint arrow-body-style: ["error", "never"]*/ /*eslint-env es6*/ let foo = () => { return 0; }; let foo = (retv, name) => { retv[name] = true; return retv; }; ``` The following patterns are not considered problems: ``` /*eslint arrow-body-style: ["error", "never"]*/ /*eslint-env es6*/ let foo = () => 0; let foo = () => ({ key: 0 }); ``` * Update documentation * Define bejaviour with unit tests * fixup! Update documentation
1 parent f804397 commit 6e03c4b

File tree

3 files changed

+66
-11
lines changed

3 files changed

+66
-11
lines changed

docs/rules/arrow-body-style.md

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
# Require braces in arrow function body (arrow-body-style)
22

3-
Arrow functions can omit braces when there is a single statement in the body. This rule enforces the consistent use of braces in arrow functions.
3+
Arrow functions have two syntactic forms for their function bodies. They may be defined with a *block* body (denoted by curly braces) `() => { ... }` or with a single expression `() => ...`, whose value is implicitly returned.
44

55
## Rule Details
66

7-
This rule can enforce the use of braces around arrow function body.
7+
This rule can enforce or disallow the use of braces around arrow function body.
88

99
## Options
1010

1111
The rule takes one option, a string, which can be:
1212

1313
* `"always"` enforces braces around the function body
1414
* `"as-needed"` enforces no braces where they can be omitted (default)
15+
* `"never"` enforces no braces around the function body (constrains arrow functions to the role of returning an expression)
1516

1617
### "always"
1718

@@ -84,3 +85,30 @@ let foo = () => {
8485
// do nothing.
8586
};
8687
```
88+
89+
### "never"
90+
91+
When the rule is set to `"never"` the following patterns are considered problems:
92+
93+
```js
94+
/*eslint arrow-body-style: ["error", "never"]*/
95+
/*eslint-env es6*/
96+
97+
let foo = () => {
98+
return 0;
99+
};
100+
let foo = (retv, name) => {
101+
retv[name] = true;
102+
return retv;
103+
};
104+
```
105+
106+
The following patterns are not considered problems:
107+
108+
```js
109+
/*eslint arrow-body-style: ["error", "never"]*/
110+
/*eslint-env es6*/
111+
112+
let foo = () => 0;
113+
let foo = () => ({ foo: 0 });
114+
```

lib/rules/arrow-body-style.js

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,15 @@ module.exports = {
1818

1919
schema: [
2020
{
21-
enum: ["always", "as-needed"]
21+
enum: ["always", "as-needed", "never"]
2222
}
2323
]
2424
},
2525

2626
create: function(context) {
2727
var always = context.options[0] === "always";
2828
var asNeeded = !context.options[0] || context.options[0] === "as-needed";
29+
var never = context.options[0] === "never";
2930

3031
/**
3132
* Determines whether a arrow function body needs braces
@@ -36,18 +37,26 @@ module.exports = {
3637
var arrowBody = node.body;
3738

3839
if (arrowBody.type === "BlockStatement") {
39-
var blockBody = arrowBody.body;
40-
41-
if (blockBody.length !== 1) {
42-
return;
43-
}
44-
45-
if (asNeeded && blockBody[0].type === "ReturnStatement") {
40+
if (never) {
4641
context.report({
4742
node: node,
4843
loc: arrowBody.loc.start,
4944
message: "Unexpected block statement surrounding arrow body."
5045
});
46+
} else {
47+
var blockBody = arrowBody.body;
48+
49+
if (blockBody.length !== 1) {
50+
return;
51+
}
52+
53+
if (asNeeded && blockBody[0].type === "ReturnStatement") {
54+
context.report({
55+
node: node,
56+
loc: arrowBody.loc.start,
57+
message: "Unexpected block statement surrounding arrow body."
58+
});
59+
}
5160
}
5261
} else {
5362
if (always) {

tests/lib/rules/arrow-body-style.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ ruleTester.run("arrow-body-style", rule, {
3030
{ code: "var foo = () => { b = a };", parserOptions: { ecmaVersion: 6 } },
3131
{ code: "var foo = () => { bar: 1 };", parserOptions: { ecmaVersion: 6 } },
3232
{ code: "var foo = () => { return 0; };", parserOptions: { ecmaVersion: 6 }, options: ["always"] },
33-
{ code: "var foo = () => { return bar(); };", parserOptions: { ecmaVersion: 6 }, options: ["always"] }
33+
{ code: "var foo = () => { return bar(); };", parserOptions: { ecmaVersion: 6 }, options: ["always"] },
34+
{ code: "var foo = () => 0;", parserOptions: { ecmaVersion: 6 }, options: ["never"] },
35+
{ code: "var foo = () => ({ foo: 0 });", parserOptions: { ecmaVersion: 6 }, options: ["never"] }
3436
],
3537
invalid: [
3638
{
@@ -64,6 +66,22 @@ ruleTester.run("arrow-body-style", rule, {
6466
errors: [
6567
{ line: 1, column: 17, type: "ArrowFunctionExpression", message: "Unexpected block statement surrounding arrow body." }
6668
]
69+
},
70+
{
71+
code: "var foo = () => {\nreturn 0;\n};",
72+
parserOptions: { ecmaVersion: 6 },
73+
options: ["never"],
74+
errors: [
75+
{ line: 1, column: 17, type: "ArrowFunctionExpression", message: "Unexpected block statement surrounding arrow body." }
76+
]
77+
},
78+
{
79+
code: "var foo = (retv, name) => {\nretv[name] = true;\nreturn retv;\n};",
80+
parserOptions: { ecmaVersion: 6 },
81+
options: ["never"],
82+
errors: [
83+
{ line: 1, column: 27, type: "ArrowFunctionExpression", message: "Unexpected block statement surrounding arrow body." }
84+
]
6785
}
6886
]
6987
});

0 commit comments

Comments
 (0)