-
-
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’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update: add fixer for arrow-body-style
#7240
Conversation
@not-an-aardvark, thanks for your PR! By analyzing the annotation information on this pull request, we identified @ajhyndman, @alberto and @vitorbal to be potential reviewers |
LGTM |
I'll champion this. |
@not-an-aardvark championing also means you need to drum up support for this amongst the team, gathering the necessary 👍s. (Just don't want this to sit around ignored) |
We have received many questions "how to fix this So I think the autofix of |
} | ||
|
||
if (asNeeded && requireReturnForObjectLiteral && blockBody[0].type === "ReturnStatement" && | ||
blockBody[0].argument.type === "ObjectExpression") { |
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.
ReturnStatement#argument
property needs null check.
Chould you add tests like a => { return }
?
const sourceText = sourceCode.getText(); | ||
const textBeforeReturn = sourceText.slice(arrowBody.range[0] + 1, blockBody[0].range[0]); | ||
const textBetweenReturnAndValue = sourceText.slice(sourceCode.getFirstToken(blockBody[0]).range[1], returnValue.range[0]); | ||
const returnValueText = returnValue.type === "ObjectExpression" ? `(${sourceCode.getText(returnValue)})` : sourceCode.getText(returnValue); |
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.
This can cause a syntax error after autofix. It needs parentheses if the first token of returnValue
is {
.
key => {
return {a: 1, b: 2}[key]
}
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.
Also, it seems wrong if the returnValue
is parenthesized.
() => {
return ({a: 1, b: 2})
}
// ↓ fixed
() =>
(({a: 1, b: 2})
|
||
return fixer.replaceTextRange( | ||
[firstBodyToken.range[0], node.range[1]], | ||
`{return ${sourceCode.getText().slice(firstBodyToken.range[0], node.range[1])}}` |
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.
In my ideal, it removes parentheses which are enclosing the body if the first token of the body is {
because it's restricted by syntax.
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 thought of doing that, but that could cause comments to get removed:
var foo = () => ( /* comment */ {ok: true});
// gets fixed to:
var foo = () => {return ( /* comment */ {ok: true});};
I think users can use no-extra-parens
if they want to avoid the unnecessary parens.
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.
Fair enough.
Thank you!
LGTM |
I think the new commit addresses all of the issues. |
5d04d67
to
8e74916
Compare
LGTM |
Great! |
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, thank you!
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 found a problem now
let a = () => {
return 1
}
(() => doSomething())()
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.
Never mind...
In this case, originate code has a problem...
I think that is actually a problem with this fixer: var x = () => { return 1 } // <-- ASI inserts a semicolon here, x will always return 1
(2) // <-- This is an ExpressionStatement with the literal 2
// ↓ fixed
var x = () => 1 // <-- ASI does not insert a semicolon here, x will throw a TypeError when called
(2) // <-- This is an argument of calling 1 as a function So I suppose we should avoid fixes if the next line begins with edit: Actually, we don't need to account for |
My brain had been confused since it was right after waking. 😅 |
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.
There is the ASI problem.
A thought: Should we just always wrap the value in parentheses, and then let no-extra-parens decide if the parentheses can be removed? |
@platinumazure Could you elaborate on why always wrapping the value in parentheses would be beneficial? I don't understand why we would want to do that. |
Hmm. Originally it was for ASI reasons, but I'm realizing that it doesn't fix all such situations. Useful fix: () => { return x++ } // becomes: () => (x++), avoids ASI problems on next line Less useful: () => { return x } // becomes () => (x)\n(1), does not solve ASI problem
(1) So my suggestion wasn't as good as I thought. |
I don't think () => { return x++ }
foo
// ↓ fixed
() => x++ // this still increases x and not foo, because the ++ is on the same line as x.
foo |
LGTM |
f6703c5
to
a2ea590
Compare
LGTM |
a2ea590
to
ce9fbcf
Compare
LGTM |
@@ -72,6 +84,7 @@ ruleTester.run("arrow-body-style", rule, { | |||
}, | |||
{ | |||
code: "var foo = () => { return bar(); };", | |||
output: "var foo = () => bar() ;", |
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.
Can we strip the extra spaces before bar()
? It seems like you'd expect just one space because that's what is between return
and bar()
.
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 two extra spaces are from after the arrow, and after the opening curly. At the moment, the fixer keeps all text between the tokens in case it contains comments, newlines, etc. I think people can use no-multi-spaces
and semi-spacing
if they don't want the extra spaces.
Would you recommend that we special-case the fixes where there are only space characters between these tokens?
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.
Yeah, I think we have to special case this. I can't see anyone being happy with more than one space after =>
.
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.
Updated to add a special case for this.
LGTM |
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.
What is the purpose of this pull request? (put an "X" next to item)
[ ] Documentation update
[ ] Bug fix (template)
[ ] New rule (template)
[ ] Changes an existing rule (template)
[x] Add autofixing to a rule
[ ] Add a CLI option
[ ] Add something to the core
[ ] Other, please explain:
Please check each item to ensure your pull request is ready:
What changes did you make? (Give an overview)
This adds a fixer for
arrow-body-style
.The fixer preserves all comments and whitespace. On the next pass, the fixers for
brace-style
,indent
,no-multi-spaces
,no-extra-parens
,semi
, andkeyword-spacing
will be able to clean up stylistic issues from the outputted code.Is there anything you'd like reviewers to focus on?
We should make sure there are no cases where replacing a block body with a literal (or vice versa) causes a SyntaxError.
The build will fail at the moment due to #7239. I'll rebase onto master after that's fixed.