Conversation
Member
Author
|
Current dependencies on/for this PR:
This comment was auto-generated by Graphite. |
This was referenced Jun 19, 2023
Merged
Contributor
PR Check ResultsEcosystem✅ ecosystem check detected no changes. BenchmarkLinuxWindows |
f672744 to
89c5ea6
Compare
This was referenced Jun 20, 2023
Merged
konstin
approved these changes
Jun 20, 2023
Member
Author
|
@MichaReiser started a stack merge that includes this pull request via Graphite. |
Member
Author
|
@MichaReiser merged this pull request with Graphite. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
Black supports for layouts when it comes to breaking binary expressions:
Our current implementation only handles
ExpandRightandDefaultcorrectly.ExpandLeftturns out to be surprisingly hard. This PR adds a newBestFittingModeparameter toBestFittingto supportExpandLeft.There are 3 variants that
ExpandLeftmust support:Variant 1: Everything fits on the line (easy)
Variant 2: Left breaks, but right fits on the line. Doesn't need parentheses
Variant 3: The left breaks, but there's still not enough space for the right hand side. Parenthesize the whole expression:
Solving Variant 1 and 2 on their own is straightforward The printer gives us this behavior by nesting right inside of the group of left:
The fundamental problem is that the outer group, which adds the parentheses, always breaks if the left side breaks. That means, we end up with
which is not what we want (we only want parentheses if the right side doesn't fit).
Okay, so nesting groups don't work because of the outer parentheses. Sequencing groups doesn't work because it results in a right-to-left breaking which is the opposite of what we want.
Could we use best fitting? Almost!
I hope I managed to write this up correctly. The problem is that the printer never reaches the 3rd variant because the second variant always fits:
group(&left).should_expand(true)changes the group so that allsoft_line_breaksare turned into hard line breaks. This is necessary because we want to test if the content fits if we break after the[.best_fittingis that you can pretend that some content fits on the line when it actually does not. The way this works is that the printer only tests if all the content of the variant up to the first line break fits on the line (we insert that line break by usingshould_expand(true)). The printer doesn't care whether the resta\n, b\n ] + call fits on (multiple?) lines.Why does breaking right work but not breaking the left? The difference is that we can make the decision whether to parenthesis the expression based on the left expression. We can't do this for breaking left because the decision whether to insert parentheses or not would depend on a lookahead: will the right side break. We simply don't know this yet when printing the parentheses (it would work for the right parentheses but not for the left and indent).
What we kind of want here is to tell the printer: Look, what comes here may or may not fit on a single line but we don't care. Simply test that what comes after fits on a line.
This PR adds a new
BestFittingModethat has a newAllLinesoption that gives us the desired behavior of testing all content and not just up to the first line break.Test Plan
I added a new example to
BestFitting::with_mode