-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
New: Adds implicit-arrow-linebreak rule (refs #9510) #9629
New: Adds implicit-arrow-linebreak rule (refs #9510) #9629
Conversation
6203a23
to
fc7bbca
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
This needs a champion as well as support from one more team member. Something to note is that this rule is incompatible with |
@kaicataldo how do I find someone to champion this rule? Should I make an issue with the rule proposal? |
@sharmilajesupaul No need to do anything! Thanks for a great PR. @eslint/eslint-team Looks like we have support from three team members and just need someone to step up to champion. |
I'll champion this. Marking as accepted. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally looks good to me. My only concern is possible user confusion about whether arrow-linebreak
also applies to arrow functions with block statements. Therefore I would like to suggest that some or all of the following changes be considered:
- Add documentation about which rule would control line breaks around braces (brace-style maybe?)
- Consider renaming the rule to something like
concise-arrow-linebreak
orimplicit-arrow-linebreak
to help make clear that this doesn't apply to non-concise arrow function bodies
Thanks!
"concise" refers to concise object methods; i'd prefer "implicit". |
I've heard it both ways (and I use "shorthand" for those object methods). I'm not going to insist strongly on a name change, but I do think it would help. |
|
Agreed full stop. However, the rule name and documentation could confuse a new user into thinking that the rule should cover that scenario (until you read some of the examples, anyway). So it makes sense for a See Also section to reference |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR! This mostly looks good to me, I just have a few small suggestions.
docs/rules/arrow-linebreak.md
Outdated
@@ -0,0 +1,84 @@ | |||
# Enforce the location of arrow function bodies with implicit returns (arrow-linebreak) | |||
|
|||
An arrow function body can contain an implicit return as a single statement instead of a block. It can be useful to enforce a consistent location for the arrow function body. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: The body of implicit-return arrow functions is actually an expression, not a statement.
lib/rules/arrow-linebreak.js
Outdated
* @param {string} keywordName The applicable keyword name for the arrow function body | ||
* @returns {void} | ||
*/ | ||
function validateStatement(node) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: I think this function should be called something like validateExpression
rather than validateStatement
, because there aren't any statements being used here.
docs/rules/arrow-linebreak.md
Outdated
return bar(); | ||
} | ||
|
||
(foo) => ( // a function body with a leading parentheses is also always allowed with this rule |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the reasoning for always allowing this? I would have expected that an opening parenthesis on the first line would be treated the same way as anything else on the first line (i.e. allowed with beside
, disallowed with below
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the review! I originally made this rule to be able to enforce that our code doesn't have lines that end in a =>
, but I wanted to make an exception for cases like:
(foo) => (
bar
);
// &
(foo) =>
(
bar
);
However, I agree with you, treating them the same way will make this rule much clearer. The first case above should be allowed with beside
and the second with below
. I'll update the logic for this.
lib/rules/arrow-linebreak.js
Outdated
|
||
if (hasParens) { | ||
fixerTarget = tokenBefore; | ||
tokenBefore = sourceCode.getTokenBefore(fixerTarget); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this won't be correct if the arrow function body is surrounded by multiple sets of parentheses:
var x = foo =>
((((bar))));
In that case, tokenBefore
will refer to the wrong thing because it will still be an opening paren.
Instead, one option would be to use some thing like
sourceCode.getTokenBefore(node.body, token => token.value !== "(")
...which will get the first token before the body that isn't an opening paren.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call, I completely missed this case entirely 馃様 Will make an update soon.
Adds a new rule that enforces consistency of arrow function bodies that contain an implicit return.
fc7bbca
to
cedf6b2
Compare
Made some improvements:
ptal @not-an-aardvark, @platinumazure, & @ljharb, thanks! |
fixerTarget = sourceCode.getTokenAfter(tokenBefore); | ||
} | ||
|
||
if (tokenBefore.loc.end.line === fixerTarget.loc.start.line && option === "below") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I would check for the option first so that we can short-circuit quicker. Same applies below also
// Public | ||
//---------------------------------------------------------------------- | ||
return { | ||
ArrowFunctionExpression: node => validateExpression(node) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
directly use the function here
ArrowFunctionExpression: validateExpression
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm. thanks.
just 2 nitpicks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, this looks good to me. I just have a few minor nitpicks.
Examples of **incorrect** code for this rule with the default `"beside"` option: | ||
|
||
```js | ||
/* eslint arrow-linebreak: ["error", "beside"] */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The rule has been renamed to implicit-arrow-linebreak
, but this comment still calls it arrow-linebreak
. (There are a few other comments like it in this file.)
|
||
const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } }); | ||
|
||
ruleTester.run("arrow-linebreak", rule, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The rule has been renamed to implicit-arrow-linebreak
, but this line still calls it arrow-linebreak
.
@sharmilajesupaul I hope it's okay that I fixed some of the last "arrow-linebreak" references on your branch. Of course I know you were more than capable of doing it, but there's a (slim) chance we might still release this weekend despite the US holiday and I wanted to save you some time. Thanks again for contributing! EDIT: And I renamed the PR title for the same reason. Thanks for your understanding! |
Thanks for contributing! |
What is the purpose of this pull request? (put an "X" next to item)
What changes did you make? (Give an overview)
Introduces a new rule enforcing the location of arrow function bodies with implicit returns. Also adds tests and docs.
Refs: #9510 & #6067
Is there anything you'd like reviewers to focus on?
I think this rule gets a little less intuitive when it comes to function bodies surrounded by parentheses.
I would like to make sure that this rule never warns on a case where parentheses are used to surround a multiline body, like this:
However, currently, it does warn on cases like:
I'm not sure if that's the best way to handle this 馃
cc. @ljharb, @not-an-aardvark
more discussion: #9623.