mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-21 20:15:11 +00:00
Add formatting for MatchCase
(#6360)
## Summary This PR adds formatting support for `MatchCase` node with subs for the `Pattern` nodes. ## Test Plan Added test cases for case node handling with comments, newlines. resolves: #6299
This commit is contained in:
parent
8b24238d19
commit
c434bdd2bd
10 changed files with 256 additions and 29 deletions
|
@ -213,6 +213,7 @@ fn is_first_statement_in_body(statement: AnyNodeRef, has_body: AnyNodeRef) -> bo
|
|||
| AnyNodeRef::ExceptHandlerExceptHandler(ast::ExceptHandlerExceptHandler {
|
||||
body, ..
|
||||
})
|
||||
| AnyNodeRef::MatchCase(ast::MatchCase { body, .. })
|
||||
| AnyNodeRef::StmtFunctionDef(ast::StmtFunctionDef { body, .. })
|
||||
| AnyNodeRef::StmtClassDef(ast::StmtClassDef { body, .. }) => {
|
||||
are_same_optional(statement, body.first())
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
use ruff_formatter::{write, Buffer, FormatResult};
|
||||
use ruff_python_ast::MatchCase;
|
||||
|
||||
use crate::expression::maybe_parenthesize_expression;
|
||||
use crate::expression::parentheses::Parenthesize;
|
||||
use crate::comments::trailing_comments;
|
||||
use crate::not_yet_implemented_custom_text;
|
||||
use crate::prelude::*;
|
||||
use crate::{FormatNodeRule, PyFormatter};
|
||||
|
@ -19,6 +18,9 @@ impl FormatNodeRule<MatchCase> for FormatMatchCase {
|
|||
body,
|
||||
} = item;
|
||||
|
||||
let comments = f.context().comments().clone();
|
||||
let dangling_item_comments = comments.dangling_comments(item);
|
||||
|
||||
write!(
|
||||
f,
|
||||
[
|
||||
|
@ -39,17 +41,21 @@ impl FormatNodeRule<MatchCase> for FormatMatchCase {
|
|||
)?;
|
||||
|
||||
if let Some(guard) = guard {
|
||||
write!(
|
||||
f,
|
||||
[
|
||||
space(),
|
||||
text("if"),
|
||||
space(),
|
||||
maybe_parenthesize_expression(guard, item, Parenthesize::IfBreaks)
|
||||
]
|
||||
)?;
|
||||
write!(f, [space(), text("if"), space(), guard.format()])?;
|
||||
}
|
||||
|
||||
write!(f, [text(":"), block_indent(&body.format())])
|
||||
write!(
|
||||
f,
|
||||
[
|
||||
text(":"),
|
||||
trailing_comments(dangling_item_comments),
|
||||
block_indent(&body.format())
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
fn fmt_dangling_comments(&self, _node: &MatchCase, _f: &mut PyFormatter) -> FormatResult<()> {
|
||||
// Handled as part of `fmt_fields`
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
use ruff_formatter::{FormatOwnedWithRule, FormatRefWithRule};
|
||||
use ruff_python_ast::Pattern;
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
pub(crate) mod pattern_match_as;
|
||||
pub(crate) mod pattern_match_class;
|
||||
pub(crate) mod pattern_match_mapping;
|
||||
|
@ -6,3 +11,37 @@ pub(crate) mod pattern_match_sequence;
|
|||
pub(crate) mod pattern_match_singleton;
|
||||
pub(crate) mod pattern_match_star;
|
||||
pub(crate) mod pattern_match_value;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatPattern;
|
||||
|
||||
impl FormatRule<Pattern, PyFormatContext<'_>> for FormatPattern {
|
||||
fn fmt(&self, item: &Pattern, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
match item {
|
||||
Pattern::MatchValue(p) => p.format().fmt(f),
|
||||
Pattern::MatchSingleton(p) => p.format().fmt(f),
|
||||
Pattern::MatchSequence(p) => p.format().fmt(f),
|
||||
Pattern::MatchMapping(p) => p.format().fmt(f),
|
||||
Pattern::MatchClass(p) => p.format().fmt(f),
|
||||
Pattern::MatchStar(p) => p.format().fmt(f),
|
||||
Pattern::MatchAs(p) => p.format().fmt(f),
|
||||
Pattern::MatchOr(p) => p.format().fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> AsFormat<PyFormatContext<'ast>> for Pattern {
|
||||
type Format<'a> = FormatRefWithRule<'a, Pattern, FormatPattern, PyFormatContext<'ast>>;
|
||||
|
||||
fn format(&self) -> Self::Format<'_> {
|
||||
FormatRefWithRule::new(self, FormatPattern)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> IntoFormat<PyFormatContext<'ast>> for Pattern {
|
||||
type Format = FormatOwnedWithRule<Pattern, FormatPattern, PyFormatContext<'ast>>;
|
||||
|
||||
fn into_format(self) -> Self::Format {
|
||||
FormatOwnedWithRule::new(self, FormatPattern)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
use ruff_formatter::{write, Buffer, FormatResult};
|
||||
use ruff_formatter::{format_args, write, Buffer, FormatResult};
|
||||
use ruff_python_ast::StmtMatch;
|
||||
|
||||
use crate::comments::trailing_comments;
|
||||
use crate::comments::{leading_alternate_branch_comments, trailing_comments};
|
||||
use crate::context::{NodeLevel, WithNodeLevel};
|
||||
use crate::expression::maybe_parenthesize_expression;
|
||||
use crate::expression::parentheses::Parenthesize;
|
||||
use crate::prelude::*;
|
||||
|
@ -35,8 +36,29 @@ impl FormatNodeRule<StmtMatch> for FormatStmtMatch {
|
|||
]
|
||||
)?;
|
||||
|
||||
for case in cases {
|
||||
write!(f, [block_indent(&case.format())])?;
|
||||
let mut cases_iter = cases.iter();
|
||||
let Some(first) = cases_iter.next() else {
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
// The new level is for the `case` nodes.
|
||||
let mut f = WithNodeLevel::new(NodeLevel::CompoundStatement, f);
|
||||
|
||||
write!(f, [block_indent(&first.format())])?;
|
||||
let mut last_case = first;
|
||||
|
||||
for case in cases_iter {
|
||||
write!(
|
||||
f,
|
||||
[block_indent(&format_args!(
|
||||
&leading_alternate_branch_comments(
|
||||
comments.leading_comments(case),
|
||||
last_case.body.last(),
|
||||
),
|
||||
&case.format()
|
||||
))]
|
||||
)?;
|
||||
last_case = case;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue