Skip to content

method chain breaking heuristic#6685

Merged
thorn0 merged 23 commits intoprettier:nextfrom
mmkal:chain-breaking-heuristic
Jan 10, 2020
Merged

method chain breaking heuristic#6685
thorn0 merged 23 commits intoprettier:nextfrom
mmkal:chain-breaking-heuristic

Conversation

@mmkal
Copy link
Copy Markdown
Contributor

@mmkal mmkal commented Oct 19, 2019

Addresses #3107

A more opinionated alternative to #4765; this solution doesn't depend on the formatting of the input. Instead it uses a heuristic for the complexity of the arguments in the chained method call. Right now, this heuristic is just a regex - if there are any non-whitelisted characters, prettier will break. The heuristic can be gradually improved, this is a starting point.

I've included examples from #3107, #4765, #1565 and #4125 as tests. In the majority of cases, prettier is now doing what the commenter wanted - both those in the generally-prefer-multiline camp and the generally-prefer-one-line camp. I added the examples before making the prettier changes, so you can view the diff here: 613d83e?w=1

It's still not perfect, of course. But I've been on teams which have done each one of

  • not used prettier because of this
  • littered the codebase with many // prettier-ignores
  • committed code like this

All of which lead to bikeshedding on PRs and ugly code, the two keys things prettier is designed to avoid.

@sharmilajesupaul @j-f1 @SimenB @RyanZim @azz would be interested to hear your thoughts on this.

  • I’ve added tests to confirm my change works.
  • I’ve added my changes to the CHANGELOG.unreleased.md file following the template.
  • I’ve read the contributing guidelines.

Try the playground for this PR

@lydell
Copy link
Copy Markdown
Member

lydell commented Oct 19, 2019

Hi!

Thanks for taking the time to experiment with this!

I don’t think using a regex is going to be a sustainable solution. Isn’t it unexpected that the following two lines are formatted differently?

Prettier pr-6685
Playground link

--parser babylon

Input:

name.toLowerCase().replace("hi", "hello").trim();
name.toLowerCase().replace("hi!", "hello").trim();

Output:

name.toLowerCase().replace("hi", "hello").trim();
name
  .toLowerCase()
  .replace("hi!", "hello")
  .trim();

@mmkal
Copy link
Copy Markdown
Contributor Author

mmkal commented Oct 19, 2019

@lydell agreed, am working on working on replacing the regex with a function that makes sure the arguments are in a whitelist.

Edit: have now updated to use a function.

@mmkal mmkal changed the title Chain breaking heuristic method chain breaking heuristic Oct 19, 2019
@nextmat
Copy link
Copy Markdown

nextmat commented Oct 30, 2019

This looks really nice, excited to see a viable solution for this!

@lydell
Copy link
Copy Markdown
Member

lydell commented Nov 3, 2019

@mmkal What’s the status on this one?

@mmkal
Copy link
Copy Markdown
Contributor Author

mmkal commented Nov 3, 2019

@lydell just awaiting feedback - then I need to add to the changelog, but that's about it. Was there something you think I should add/remove to the heuristic?

@lydell
Copy link
Copy Markdown
Member

lydell commented Nov 3, 2019

Cool, I wasn’t aware you were finished. We’ll need to review then.

@janhesters
Copy link
Copy Markdown

Looking forward to this 😍

Comment on lines +904 to +932
db.branch(
db
.table("users")
.filter({ email })
.count(),
db.table("users").insert({ email }),
db.table("users").filter({ email })
);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This inconsistency is somewhat unexpected to me.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, the decision to exclude the last chain member from the isSimple check looks questionable to me. Also I think simple shortcut object literals like { email } should pass this check.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point about object literals with shorthand properties, will add them. I'll also see what difference including the last chain member makes, I'm not too tied to it being all but one. I made it that way to start with because the chains can still be pretty readable, but I don't see it making a huge difference.

Comment on lines +131 to +132
a
.b()
.c()
// Comment
?.d()
a.b().c()// Comment
?.d()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this still be broken onto multiple lines? This doesn’t look very good, especially the missing space before the inline comment.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, thought I had addressed this. Will push a fix shortly

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like it’s still happening?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, as I said I missed it. Thought I'd fixed but must have been looking in the wrong spot. I'm doing this outside of work so will @ you when it's fixed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@j-f1 I did some digging, and it might be that this PR has unearthed a pre-existing issue, since the same bug can be reproduced by just changing the break length from 3 to 4: master...mmkal:optional-chaining-comment-bug . That said, I'll look into this more anyway - if it wasn't possible before and now is, it's a regression even if the code causing it has always been there.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@j-f1 now (actually) fixed.

@mmkal
Copy link
Copy Markdown
Contributor Author

mmkal commented Nov 7, 2019

@j-f1 @thorn0 @lydell updated to address PR comments, and added to changelog. Anything else I should do to get this merged?

@thorn0
Copy link
Copy Markdown
Member

thorn0 commented Nov 8, 2019

@mmkal Two more things.

  1. Did you intentionally exclude unary expressions like !x and -1 from the isSimple check?
  2. isSimple should be renamed to something more descriptive (isSimpleCallArgument?) to avoid confusion as we already have other functions with similar names: isSimpleTemplateLiteral, isSimpleFlowType. And let's move it to utils.js.

@mmkal
Copy link
Copy Markdown
Contributor Author

mmkal commented Nov 8, 2019

I excluded unaries because I would want non-simple things like ~x stand out, but it may make sense to have a unary operator whitelist, what do you think?

Will move to utils and rename this weekend.

@thorn0
Copy link
Copy Markdown
Member

thorn0 commented Nov 8, 2019

I think !x and -1 should be considered simple.

@thorn0 thorn0 force-pushed the chain-breaking-heuristic branch from bc85c8a to 605c894 Compare November 8, 2019 22:03
@lydell lydell added this to the 2.0 milestone Nov 9, 2019
@thorn0 thorn0 force-pushed the chain-breaking-heuristic branch 2 times, most recently from ba9580d to a11836f Compare November 9, 2019 18:50
@mmkal
Copy link
Copy Markdown
Contributor Author

mmkal commented Nov 15, 2019

@thorn0 @lydell @sosukesuzuki anything left on this I need to do to get it merged? I see the 2.0 label has been added, does that mean it won't go into master until January? I'm a little worried about merge conflicts.

@thorn0 thorn0 force-pushed the chain-breaking-heuristic branch from a11836f to 34cfd82 Compare January 9, 2020 17:03
@thorn0 thorn0 force-pushed the next branch 2 times, most recently from e16f758 to 7d88fb8 Compare January 10, 2020 00:39
@thorn0 thorn0 merged commit 911fe77 into prettier:next Jan 10, 2020
@alexander-akait
Copy link
Copy Markdown
Member

alexander-akait commented Jan 10, 2020

/cc @thorn0 please do not merge PR in future without minimum 3 approved, especial on this big changes, you can ping any if approves is not enough, thanks

@mrchief
Copy link
Copy Markdown

mrchief commented Jan 10, 2020

@evilebottnawi I believe you can update the branch protection settings to mandate minimum 3 approvals.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

locked-due-to-inactivity Please open a new issue and fill out the template instead of commenting.

Projects

None yet

Development

Successfully merging this pull request may close these issues.