Format binary expressions (#4862)

* Format Binary Expressions

* Extract NeedsParentheses trait
This commit is contained in:
Micha Reiser
2023-06-06 10:34:53 +02:00
committed by GitHub
parent 775326790e
commit 3f032cf09d
47 changed files with 1122 additions and 217 deletions

View File

@@ -39,7 +39,7 @@ impl Format<PyFormatContext<'_>> for FormatLeadingComments<'_> {
for comment in leading_comments {
let slice = comment.slice();
let lines_after_comment = lines_after(f.context().contents(), slice.end());
let lines_after_comment = lines_after(slice.end(), f.context().contents());
write!(
f,
[format_comment(comment), empty_lines(lines_after_comment)]
@@ -80,7 +80,7 @@ impl Format<PyFormatContext<'_>> for FormatLeadingAlternateBranchComments<'_> {
if let Some(first_leading) = self.comments.first() {
// Leading comments only preserves the lines after the comment but not before.
// Insert the necessary lines.
if lines_before(f.context().contents(), first_leading.slice().start()) > 1 {
if lines_before(first_leading.slice().start(), f.context().contents()) > 1 {
write!(f, [empty_line()])?;
}
@@ -88,7 +88,7 @@ impl Format<PyFormatContext<'_>> for FormatLeadingAlternateBranchComments<'_> {
} else if let Some(last_preceding) = self.last_node {
// The leading comments formatting ensures that it preserves the right amount of lines after
// We need to take care of this ourselves, if there's no leading `else` comment.
if lines_after(f.context().contents(), last_preceding.end()) > 1 {
if lines_after(last_preceding.end(), f.context().contents()) > 1 {
write!(f, [empty_line()])?;
}
}
@@ -132,7 +132,7 @@ impl Format<PyFormatContext<'_>> for FormatTrailingComments<'_> {
has_trailing_own_line_comment |= trailing.position().is_own_line();
if has_trailing_own_line_comment {
let lines_before_comment = lines_before(f.context().contents(), slice.start());
let lines_before_comment = lines_before(slice.start(), f.context().contents());
// A trailing comment at the end of a body or list
// ```python
@@ -175,20 +175,26 @@ pub(crate) fn dangling_node_comments<T>(node: &T) -> FormatDanglingComments
where
T: AstNode,
{
FormatDanglingComments {
node: node.as_any_node_ref(),
}
FormatDanglingComments::Node(node.as_any_node_ref())
}
pub(crate) struct FormatDanglingComments<'a> {
node: AnyNodeRef<'a>,
pub(crate) fn dangling_comments(comments: &[SourceComment]) -> FormatDanglingComments {
FormatDanglingComments::Comments(comments)
}
pub(crate) enum FormatDanglingComments<'a> {
Node(AnyNodeRef<'a>),
Comments(&'a [SourceComment]),
}
impl Format<PyFormatContext<'_>> for FormatDanglingComments<'_> {
fn fmt(&self, f: &mut Formatter<PyFormatContext>) -> FormatResult<()> {
let comments = f.context().comments().clone();
let dangling_comments = comments.dangling_comments(self.node);
let dangling_comments = match self {
Self::Comments(comments) => comments,
Self::Node(node) => comments.dangling_comments(*node),
};
let mut first = true;
for comment in dangling_comments {
@@ -200,7 +206,7 @@ impl Format<PyFormatContext<'_>> for FormatDanglingComments<'_> {
f,
[
format_comment(comment),
empty_lines(lines_after(f.context().contents(), comment.slice().end()))
empty_lines(lines_after(comment.slice().end(), f.context().contents()))
]
)?;
@@ -301,7 +307,7 @@ impl Format<PyFormatContext<'_>> for FormatEmptyLines {
},
// Remove all whitespace in parenthesized expressions
NodeLevel::Parenthesized => write!(f, [hard_line_break()]),
NodeLevel::Expression => write!(f, [hard_line_break()]),
}
}
}