-
Notifications
You must be signed in to change notification settings - Fork 1.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
Mixed shorthand function with arrow function in object literal is mis-formatted #602
Comments
Is this ES6? Please provide a link and exmples. |
Yeah this is ES6, sorry for not specifying that. and this example for usage: var a = [
"Hydrogen",
"Helium",
"Lithium",
"Beryllium"
];
var a2 = a.map(function(s){ return s.length });
var a3 = a.map( s => s.length ); And this is a link to shorthand object literal: // Shorthand method names (ES6)
var o = {
property([parameters]) {},
get property() {},
set property(value) {},
* generator() {}
}; |
Thanks for the report and clear information. |
I'm pretty certain this isn't just an issue with the Enhanced Object Literals for functions and not the arrow functions. We are having a similar issue but we are not using arrow functions. e.g. in:
out:
These are just hand coded examples, I would love to add a test but I'm finding it hard to figure out where the test should go 😕 would you recommend adding it to this file: https://github.com/beautify-web/js-beautify/blob/master/js/test/beautify-javascript-tests.js |
@bitwiseman I'd be interested in taking a look at the fix for this - could you point me in the right direction? (apart from going to |
@bitwiseman I have a couple potential options to fix this, but I'd like some feedback. Both options address the fact that mode ObjectLiteral is not detected when the first property is a shorthand function, so it remains as mode BlockStatement. I noticed in The two options I did are:
Thoughts? |
@r-murphy: IGNORE THE REST OF THIS COMMENT! Neither option 1 or option 2 are sufficient. See next comment. Option 2 seems brittle. Because the beautifier is not precise about parsing, it's okay to take reasonable guesses. print_token();
// Some object literal cases are hard to detect.
// Best to assume that when we see a comma in a block statement, it is actually an object literal.
if (flags.mode === MODE.Statement && flags.parent.mode === MODE.BlockStatement) {
flags.parent.mode = MODE.ObjectLiteral
}
if (flags.mode === MODE.ObjectLiteral ||
(flags.mode === MODE.Statement && flags.parent.mode === MODE.ObjectLiteral)) {
if (flags.mode === MODE.Statement) {
... This will make other formatting that depends on ObjectLiteral work correctly. (This is what we used to do. I thought we could get away from it, but no.) For example, another test you should add: var obj = {
func1() {},
a: 1,
func2() {}
}; So, yeah, a modified option 1 and a few more tests. Please continue and submit a PR! |
Thinking about it for a bit more, do not use either of the options you've mentioned. The most highly requested feature (#315) will require that we know if we're dealing with an ObjectLiteral at the start of that first curly-brace, not at some later point. That is why I have all the ObjectLiteral detection to occur at the start of the block. So, you'll need to look for ways to detect ObjectLiteral at the starting curly. #812 is the most recent improvement, but I'm not sure how you're going to reliably detect this case. You could mostly close this by look at the surrounding context. In assignment or locations that expect expressions you get an Object, but after |
Thanks for the feedback. Agreed that detecting it in the That's a good idea to use the surrounding context. Although certainly possible to detect the shorthand function by checking if the 2nd token is '(' and then looping forward, the loop exit conditions would have to be robust to avoid infinite loops in case of invalid javascript on the user's part. Checking the surrounding context is much safer. I'm thinking to check the following whitelist of last_types, rather than trying to come up with all the block preceding keywords such as } else if (in_array(last_type, ['TK_EQUALS', 'TK_START_EXPR', 'TK_COMMA'])) {
// If the block is being assigned or passed to a function, treat as an ObjectLiteral
set_mode(MODE.ObjectLiteral);
} I currently have this after the Thanks |
That is a fine start but you're going to have to check for keywords. The following is way too common: function someFunc() {
return { ... };
} The only way to determine that is an ObjectLiteral is to check You might add a check for I understand if this more than you wanted to take on. If you get tired of running down all the corner case, I'd be happy to see a partial fix go in as long is it has tests for the supported cases and includes the matching the python implementation. Thanks again! |
I can't believe I forget I'll try to come up with more corner cases tomorrow and send a PR. Thanks for the guidance and for the great tool. |
… context, to handle when ES6 shorthand function is first prop
… context, to handle when ES6 shorthand function is first prop
… context, to handle when ES6 shorthand function is first prop
Resolves #602: Detect ObjectLiteral for ES6 shorthand function
… context, to handle when ES6 shorthand function is first prop
Mixed object literal with shorthand functions and arrow functions get mis-aligned:
in:
out:
expected:
The text was updated successfully, but these errors were encountered: