Call pattern formatting (#6594)

This commit is contained in:
Micha Reiser 2023-08-16 05:01:25 +02:00 committed by GitHub
parent 9bf6713b76
commit 897cce83b3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 473 additions and 330 deletions

View file

@ -1,10 +1,12 @@
use ruff_formatter::{write, Buffer, FormatResult};
use ruff_python_ast::MatchCase;
use ruff_formatter::{format_args, write, Buffer, FormatResult};
use ruff_python_ast::{MatchCase, Pattern, Ranged};
use ruff_python_trivia::{SimpleTokenKind, SimpleTokenizer};
use ruff_text_size::TextRange;
use crate::comments::{trailing_comments, SourceComment};
use crate::not_yet_implemented_custom_text;
use crate::comments::{leading_comments, trailing_comments, SourceComment};
use crate::expression::parentheses::parenthesized;
use crate::prelude::*;
use crate::{FormatNodeRule, PyFormatter};
use crate::{FormatError, FormatNodeRule, PyFormatter};
#[derive(Default)]
pub struct FormatMatchCase;
@ -21,24 +23,20 @@ impl FormatNodeRule<MatchCase> for FormatMatchCase {
let comments = f.context().comments().clone();
let dangling_item_comments = comments.dangling_comments(item);
write!(
f,
[
text("case"),
space(),
format_with(|f: &mut PyFormatter| {
let comments = f.context().comments();
for comment in comments.leading_trailing_comments(pattern) {
// This is a lie, but let's go with it.
comment.mark_formatted();
}
// Replace the whole `format_with` with `pattern.format()` once pattern formatting is implemented.
not_yet_implemented_custom_text("NOT_YET_IMPLEMENTED_Pattern", pattern).fmt(f)
}),
]
)?;
write!(f, [text("case"), space()])?;
let leading_pattern_comments = comments.leading_comments(pattern);
if !leading_pattern_comments.is_empty() {
parenthesized(
"(",
&format_args![leading_comments(leading_pattern_comments), pattern.format()],
")",
)
.fmt(f)?;
} else if is_match_case_pattern_parenthesized(item, pattern, f.context())? {
parenthesized("(", &pattern.format(), ")").fmt(f)?;
} else {
pattern.format().fmt(f)?;
}
if let Some(guard) = guard {
write!(f, [space(), text("if"), space(), guard.format()])?;
@ -63,3 +61,33 @@ impl FormatNodeRule<MatchCase> for FormatMatchCase {
Ok(())
}
}
fn is_match_case_pattern_parenthesized(
case: &MatchCase,
pattern: &Pattern,
context: &PyFormatContext,
) -> FormatResult<bool> {
let mut tokenizer = SimpleTokenizer::new(
context.source(),
TextRange::new(case.range().start(), pattern.range().start()),
)
.skip_trivia();
let case_keyword = tokenizer.next().ok_or(FormatError::syntax_error(
"Expected a `case` keyword, didn't find any token",
))?;
debug_assert_eq!(
case_keyword.kind(),
SimpleTokenKind::Case,
"Expected `case` keyword but at {case_keyword:?}"
);
match tokenizer.next() {
Some(left_paren) => {
debug_assert_eq!(left_paren.kind(), SimpleTokenKind::LParen);
Ok(true)
}
None => Ok(false),
}
}