From f8628094e4a8322c899e9691391e32f0f7d527e8 Mon Sep 17 00:00:00 2001 From: Andrew Hyndman Date: Fri, 3 Jun 2016 23:06:50 +1000 Subject: [PATCH 1/4] 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 }); ``` --- lib/rules/arrow-body-style.js | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/lib/rules/arrow-body-style.js b/lib/rules/arrow-body-style.js index 79fde90f805..1b2d1996a67 100644 --- a/lib/rules/arrow-body-style.js +++ b/lib/rules/arrow-body-style.js @@ -18,7 +18,7 @@ module.exports = { schema: [ { - enum: ["always", "as-needed"] + enum: ["always", "as-needed", "never"] } ] }, @@ -26,6 +26,7 @@ module.exports = { create: function(context) { var always = context.options[0] === "always"; var asNeeded = !context.options[0] || context.options[0] === "as-needed"; + var never = context.options[0] === "never"; /** * Determines whether a arrow function body needs braces @@ -36,18 +37,26 @@ module.exports = { var arrowBody = node.body; if (arrowBody.type === "BlockStatement") { - var blockBody = arrowBody.body; - - if (blockBody.length !== 1) { - return; - } - - if (asNeeded && blockBody[0].type === "ReturnStatement") { + if (never) { context.report({ node: node, loc: arrowBody.loc.start, message: "Unexpected block statement surrounding arrow body." }); + } else { + var blockBody = arrowBody.body; + + if (blockBody.length !== 1) { + return; + } + + if (asNeeded && blockBody[0].type === "ReturnStatement") { + context.report({ + node: node, + loc: arrowBody.loc.start, + message: "Unexpected block statement surrounding arrow body." + }); + } } } else { if (always) { From 1899651aa16fd665893473c48c0e03a70021f30f Mon Sep 17 00:00:00 2001 From: Andrew Hyndman Date: Tue, 7 Jun 2016 20:01:48 +1000 Subject: [PATCH 2/4] Update documentation --- docs/rules/arrow-body-style.md | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/docs/rules/arrow-body-style.md b/docs/rules/arrow-body-style.md index 25f3b5129b8..0efe4f0a2a7 100644 --- a/docs/rules/arrow-body-style.md +++ b/docs/rules/arrow-body-style.md @@ -1,10 +1,10 @@ # Require braces in arrow function body (arrow-body-style) -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. +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. ## Rule Details -This rule can enforce the use of braces around arrow function body. +This rule can enforce or disallow the use of braces around arrow function body. ## Options @@ -12,6 +12,7 @@ The rule takes one option, a string, which can be: * `"always"` enforces braces around the function body * `"as-needed"` enforces no braces where they can be omitted (default) +* `"never"` enforces no braces around the function body (constrains arrow functions to the role of returning an expression) ### "always" @@ -84,3 +85,30 @@ let foo = () => { // do nothing. }; ``` + +### "never" + +When the rule is set to `"never"` the following patterns are considered problems: + +```js +/*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: + +```js +/*eslint arrow-body-style: ["error", "as-needed"]*/ +/*eslint-env es6*/ + +let foo = () => 0; +let foo = () => ({ foo: 0 }); +``` From dd480d57a5f21d63692513e0e215c6eaf658b700 Mon Sep 17 00:00:00 2001 From: Andrew Hyndman Date: Tue, 7 Jun 2016 20:28:13 +1000 Subject: [PATCH 3/4] Define bejaviour with unit tests --- tests/lib/rules/arrow-body-style.js | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/tests/lib/rules/arrow-body-style.js b/tests/lib/rules/arrow-body-style.js index fc19dfe081c..a441c751fda 100644 --- a/tests/lib/rules/arrow-body-style.js +++ b/tests/lib/rules/arrow-body-style.js @@ -30,7 +30,9 @@ ruleTester.run("arrow-body-style", rule, { { code: "var foo = () => { b = a };", parserOptions: { ecmaVersion: 6 } }, { code: "var foo = () => { bar: 1 };", parserOptions: { ecmaVersion: 6 } }, { code: "var foo = () => { return 0; };", parserOptions: { ecmaVersion: 6 }, options: ["always"] }, - { code: "var foo = () => { return bar(); };", parserOptions: { ecmaVersion: 6 }, options: ["always"] } + { code: "var foo = () => { return bar(); };", parserOptions: { ecmaVersion: 6 }, options: ["always"] }, + { code: "var foo = () => 0;", parserOptions: { ecmaVersion: 6 }, options: ["never"] }, + { code: "var foo = () => ({ foo: 0 });", parserOptions: { ecmaVersion: 6 }, options: ["never"] } ], invalid: [ { @@ -64,6 +66,22 @@ ruleTester.run("arrow-body-style", rule, { errors: [ { line: 1, column: 17, type: "ArrowFunctionExpression", message: "Unexpected block statement surrounding arrow body." } ] + }, + { + code: "var foo = () => {\nreturn 0;\n};", + parserOptions: { ecmaVersion: 6 }, + options: ["never"], + errors: [ + { line: 1, column: 17, type: "ArrowFunctionExpression", message: "Unexpected block statement surrounding arrow body." } + ] + }, + { + code: "var foo = (retv, name) => {\nretv[name] = true;\nreturn retv;\n};", + parserOptions: { ecmaVersion: 6 }, + options: ["never"], + errors: [ + { line: 1, column: 27, type: "ArrowFunctionExpression", message: "Unexpected block statement surrounding arrow body." } + ] } ] }); From 44fbf7cf9cf9cfb06cf178ea834b7a15e3ba30fe Mon Sep 17 00:00:00 2001 From: Andrew Hyndman Date: Thu, 9 Jun 2016 09:45:15 +1000 Subject: [PATCH 4/4] fixup! Update documentation --- docs/rules/arrow-body-style.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rules/arrow-body-style.md b/docs/rules/arrow-body-style.md index 0efe4f0a2a7..502a48f6307 100644 --- a/docs/rules/arrow-body-style.md +++ b/docs/rules/arrow-body-style.md @@ -106,7 +106,7 @@ let foo = (retv, name) => { The following patterns are not considered problems: ```js -/*eslint arrow-body-style: ["error", "as-needed"]*/ +/*eslint arrow-body-style: ["error", "never"]*/ /*eslint-env es6*/ let foo = () => 0;