-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Correctly handle left/right breaking of binary expression #4985
Conversation
Current dependencies on/for this PR:
This comment was auto-generated by Graphite. |
PR Check ResultsEcosystem✅ ecosystem check detected no changes. BenchmarkLinux
Windows
|
BinaryLayout::Default => { | ||
let comments = f.context().comments().clone(); | ||
let operator_comments = comments.dangling_comments(item.as_any_node_ref()); | ||
let needs_space = !is_simple_power_expression(item); | ||
|
||
let before_operator_space = if needs_space { | ||
soft_line_break_or_space() | ||
} else { | ||
soft_line_break() | ||
}; | ||
|
||
write!( | ||
f, | ||
[ | ||
left.format(), | ||
before_operator_space, | ||
op.format(), | ||
trailing_comments(operator_comments), | ||
] | ||
)?; | ||
|
||
// Format the operator on its own line if the right side has any leading comments. | ||
if comments.has_leading_comments(right.as_ref()) { | ||
write!(f, [hard_line_break()])?; | ||
} else if needs_space { | ||
write!(f, [space()])?; | ||
} | ||
|
||
write!(f, [group(&right.format())]) | ||
} |
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.
Unchanged, moved up
write!( | ||
f, | ||
[ | ||
// Wrap the left in a group and gives it an id. The printer first breaks the | ||
// right side if `right` contains any line break because the printer breaks | ||
// sequences of groups from right to left. | ||
// Indents the left side if the group breaks. | ||
group(&format_args![ | ||
if_group_breaks(&text("(")), | ||
indent_if_group_breaks( | ||
&format_args![ | ||
soft_line_break(), | ||
left.format(), | ||
soft_line_break_or_space(), | ||
op.format(), | ||
space() | ||
], | ||
left_group | ||
) | ||
]) | ||
.with_group_id(Some(left_group)), | ||
// Wrap the right in a group and indents its content but only if the left side breaks | ||
group(&indent_if_group_breaks(&right.format(), left_group)), | ||
// If the left side breaks, insert a hard line break to finish the indent and close the open paren. | ||
if_group_breaks(&format_args![hard_line_break(), text(")")]) | ||
.with_group_id(Some(left_group)) | ||
] | ||
) | ||
} |
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.
Unchanged
a315ff0
to
5243b37
Compare
439c585
to
a39dded
Compare
a39dded
to
d785d44
Compare
f672744
to
89c5ea6
Compare
d785d44
to
5c30e73
Compare
d6272b0
to
d90460d
Compare
5c30e73
to
516784c
Compare
text("("), | ||
block_indent(&format_args![ | ||
left, | ||
hard_line_break(), |
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 formatting always looks kinda odd to me but i guess python doesn't allow much better
// Wrap the left in a group and gives it an id. The printer first breaks the | ||
// right side if `right` contains any line break because the printer breaks | ||
// sequences of groups from right to left. | ||
// Indents the left side if the group breaks. |
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'm having trouble following this code, shouldn't right breaks and if right is expanded but this is insufficient the whole thing should be parenthesized and indented?
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'm not entirely sure if I understand this comment.
The formatter measures the left group to see if it fits. It does that by measuring if all the content up to the first line break (soft or hard) in the right group (or whatever comes after) fits on a line. It doesn't expand the left group if that's the case.
This is is the behavior that we want. We want to expand the right first and not add parentheses in that case. We only want to add parentheses and indent the code if the left expands. That's why indent_if_group_breaks
and the if_group_breaks
refer to the left group and not their enclosing group.
516784c
to
c99b89b
Compare
@MichaReiser merged this pull request with Graphite. |
Summary
Black supports for layouts when it comes to breaking binary expressions:
Our current implementation only handles
ExpandRight
andDefault
correctly. This PR adds support forExpandRightThenLeft
andExpandLeft
.Test Plan
I added tests that play through all 4 binary expression layouts.