mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-23 13:05:06 +00:00
Add API to chain comment placement operations (#6319)
## Summary This PR adds an API for chaining comment placement methods based on the [`then_with`](https://doc.rust-lang.org/std/cmp/enum.Ordering.html#method.then_with) from `Ordering` in the standard library. For example, you can now do: ```rust try_some_case(comment).then_with(|comment| try_some_other_case_if_still_default(comment)) ``` This lets us avoid this kind of pattern, which I've seen in `placement.rs` and used myself before: ```rust let comment = match handle_own_line_comment_between_branches(comment, preceding, locator) { CommentPlacement::Default(comment) => comment, placement => return placement, }; ```
This commit is contained in:
parent
9ae498595c
commit
d3aa8b4ee0
2 changed files with 27 additions and 30 deletions
|
@ -25,24 +25,14 @@ pub(super) fn place_comment<'a>(
|
||||||
) -> CommentPlacement<'a> {
|
) -> CommentPlacement<'a> {
|
||||||
// Handle comments before and after bodies such as the different branches of an if statement.
|
// Handle comments before and after bodies such as the different branches of an if statement.
|
||||||
let comment = if comment.line_position().is_own_line() {
|
let comment = if comment.line_position().is_own_line() {
|
||||||
match handle_own_line_comment_around_body(comment, locator) {
|
handle_own_line_comment_around_body(comment, locator)
|
||||||
CommentPlacement::Default(comment) => comment,
|
|
||||||
placement => {
|
|
||||||
return placement;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
match handle_end_of_line_comment_around_body(comment, locator) {
|
handle_end_of_line_comment_around_body(comment, locator)
|
||||||
CommentPlacement::Default(comment) => comment,
|
|
||||||
placement => {
|
|
||||||
return placement;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Change comment placement depending on the node type. These can be seen as node-specific
|
// Change comment placement depending on the node type. These can be seen as node-specific
|
||||||
// fixups.
|
// fixups.
|
||||||
match comment.enclosing_node() {
|
comment.then_with(|comment| match comment.enclosing_node() {
|
||||||
AnyNodeRef::Parameters(arguments) => {
|
AnyNodeRef::Parameters(arguments) => {
|
||||||
handle_parameters_separator_comment(comment, arguments, locator)
|
handle_parameters_separator_comment(comment, arguments, locator)
|
||||||
}
|
}
|
||||||
|
@ -88,7 +78,7 @@ pub(super) fn place_comment<'a>(
|
||||||
}
|
}
|
||||||
AnyNodeRef::StmtImportFrom(import_from) => handle_import_from_comment(comment, import_from),
|
AnyNodeRef::StmtImportFrom(import_from) => handle_import_from_comment(comment, import_from),
|
||||||
_ => CommentPlacement::Default(comment),
|
_ => CommentPlacement::Default(comment),
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_end_of_line_comment_around_body<'a>(
|
fn handle_end_of_line_comment_around_body<'a>(
|
||||||
|
@ -275,22 +265,18 @@ fn handle_own_line_comment_around_body<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we're between bodies and should attach to the following body.
|
// Check if we're between bodies and should attach to the following body.
|
||||||
let comment = match handle_own_line_comment_between_branches(comment, preceding, locator) {
|
handle_own_line_comment_between_branches(comment, preceding, locator)
|
||||||
CommentPlacement::Default(comment) => comment,
|
.then_with(|comment| {
|
||||||
placement => return placement,
|
// Otherwise, there's no following branch or the indentation is too deep, so attach to the
|
||||||
};
|
// recursively last statement in the preceding body with the matching indentation.
|
||||||
|
handle_own_line_comment_after_branch(comment, preceding, locator)
|
||||||
// Otherwise, there's no following branch or the indentation is too deep, so attach to the
|
})
|
||||||
// recursively last statement in the preceding body with the matching indentation.
|
.then_with(|comment| {
|
||||||
let comment = match handle_own_line_comment_after_branch(comment, preceding, locator) {
|
// If the following node is the first in its body, and there's a non-trivia token between the
|
||||||
CommentPlacement::Default(comment) => comment,
|
// comment and the following node (like a parenthesis), then it means the comment is trailing
|
||||||
placement => return placement,
|
// the preceding node, not leading the following one.
|
||||||
};
|
handle_own_line_comment_in_clause(comment, preceding, locator)
|
||||||
|
})
|
||||||
// If the following node is the first in its body, and there's a non-trivia token between the
|
|
||||||
// comment and the following node (like a parenthesis), then it means the comment is trailing
|
|
||||||
// the preceding node, not leading the following one.
|
|
||||||
handle_own_line_comment_in_clause(comment, preceding, locator)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handles own line comments between two branches of a node.
|
/// Handles own line comments between two branches of a node.
|
||||||
|
|
|
@ -658,6 +658,17 @@ impl<'a> CommentPlacement<'a> {
|
||||||
comment: comment.into(),
|
comment: comment.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Chains the placement with the given function.
|
||||||
|
///
|
||||||
|
/// Returns `self` when the placement is non-[`CommentPlacement::Default`]. Otherwise, calls the
|
||||||
|
/// function with the comment and returns the result.
|
||||||
|
pub(super) fn then_with<F: FnOnce(DecoratedComment<'a>) -> Self>(self, f: F) -> Self {
|
||||||
|
match self {
|
||||||
|
Self::Default(comment) => f(comment),
|
||||||
|
_ => self,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue