mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-02 09:52:18 +00:00
Format binary expressions (#4862)
* Format Binary Expressions * Extract NeedsParentheses trait
This commit is contained in:
parent
775326790e
commit
3f032cf09d
47 changed files with 1122 additions and 217 deletions
|
@ -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()]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -103,8 +103,8 @@ use crate::comments::map::MultiMap;
|
|||
use crate::comments::node_key::NodeRefEqualityKey;
|
||||
use crate::comments::visitor::CommentsVisitor;
|
||||
pub(crate) use format::{
|
||||
dangling_node_comments, leading_alternate_branch_comments, leading_node_comments,
|
||||
trailing_comments, trailing_node_comments,
|
||||
dangling_comments, dangling_node_comments, leading_alternate_branch_comments,
|
||||
leading_node_comments, trailing_comments, trailing_node_comments,
|
||||
};
|
||||
use ruff_formatter::{SourceCode, SourceCodeSlice};
|
||||
use ruff_python_ast::node::AnyNodeRef;
|
||||
|
|
|
@ -520,8 +520,8 @@ fn handle_trailing_end_of_line_condition_comment<'a>(
|
|||
if preceding.ptr_eq(last_before_colon) {
|
||||
let mut start = preceding.end();
|
||||
while let Some((offset, c)) = find_first_non_trivia_character_in_range(
|
||||
locator.contents(),
|
||||
TextRange::new(start, following.start()),
|
||||
locator.contents(),
|
||||
) {
|
||||
match c {
|
||||
':' => {
|
||||
|
@ -655,7 +655,7 @@ fn handle_trailing_binary_expression_left_or_operator_comment<'a>(
|
|||
);
|
||||
|
||||
let operator_offset = loop {
|
||||
match find_first_non_trivia_character_in_range(locator.contents(), between_operands_range) {
|
||||
match find_first_non_trivia_character_in_range(between_operands_range, locator.contents()) {
|
||||
// Skip over closing parens
|
||||
Some((offset, ')')) => {
|
||||
between_operands_range =
|
||||
|
@ -733,17 +733,17 @@ fn find_pos_only_slash_offset(
|
|||
locator: &Locator,
|
||||
) -> Option<TextSize> {
|
||||
// First find the comma separating the two arguments
|
||||
find_first_non_trivia_character_in_range(locator.contents(), between_arguments_range).and_then(
|
||||
find_first_non_trivia_character_in_range(between_arguments_range, locator.contents()).and_then(
|
||||
|(comma_offset, comma)| {
|
||||
debug_assert_eq!(comma, ',');
|
||||
|
||||
// Then find the position of the `/` operator
|
||||
find_first_non_trivia_character_in_range(
|
||||
locator.contents(),
|
||||
TextRange::new(
|
||||
comma_offset + TextSize::new(1),
|
||||
between_arguments_range.end(),
|
||||
),
|
||||
locator.contents(),
|
||||
)
|
||||
.map(|(offset, c)| {
|
||||
debug_assert_eq!(c, '/');
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue