mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-03 02:12:22 +00:00
Call pattern formatting (#6594)
This commit is contained in:
parent
9bf6713b76
commit
897cce83b3
22 changed files with 473 additions and 330 deletions
|
@ -388,6 +388,7 @@ impl<'a> Comments<'a> {
|
|||
}
|
||||
|
||||
/// Returns an iterator over the [leading](self#leading-comments) and [trailing comments](self#trailing-comments) of `node`.
|
||||
#[allow(unused)]
|
||||
pub(crate) fn leading_trailing_comments<T>(
|
||||
&self,
|
||||
node: T,
|
||||
|
|
|
@ -152,40 +152,6 @@ pub fn format_node<'a>(
|
|||
Ok(formatted)
|
||||
}
|
||||
|
||||
pub(crate) struct NotYetImplemented<'a>(AnyNodeRef<'a>);
|
||||
|
||||
/// Formats a placeholder for nodes that have not yet been implemented
|
||||
pub(crate) fn not_yet_implemented<'a, T>(node: T) -> NotYetImplemented<'a>
|
||||
where
|
||||
T: Into<AnyNodeRef<'a>>,
|
||||
{
|
||||
NotYetImplemented(node.into())
|
||||
}
|
||||
|
||||
impl Format<PyFormatContext<'_>> for NotYetImplemented<'_> {
|
||||
fn fmt(&self, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
let text = std::format!("NOT_YET_IMPLEMENTED_{:?}", self.0.kind());
|
||||
|
||||
f.write_element(FormatElement::Tag(Tag::StartVerbatim(
|
||||
tag::VerbatimKind::Verbatim {
|
||||
length: text.text_len(),
|
||||
},
|
||||
)))?;
|
||||
|
||||
f.write_element(FormatElement::DynamicText {
|
||||
text: Box::from(text),
|
||||
})?;
|
||||
|
||||
f.write_element(FormatElement::Tag(Tag::EndVerbatim))?;
|
||||
|
||||
f.context()
|
||||
.comments()
|
||||
.mark_verbatim_node_comments_formatted(self.0);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct NotYetImplementedCustomText<'a> {
|
||||
text: &'static str,
|
||||
node: AnyNodeRef<'a>,
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
use crate::{not_yet_implemented, FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::{write, Buffer, FormatResult};
|
||||
use ruff_python_ast::PatternMatchAs;
|
||||
|
||||
use crate::{not_yet_implemented_custom_text, FormatNodeRule, PyFormatter};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatPatternMatchAs;
|
||||
|
||||
impl FormatNodeRule<PatternMatchAs> for FormatPatternMatchAs {
|
||||
fn fmt_fields(&self, item: &PatternMatchAs, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
write!(f, [not_yet_implemented(item)])
|
||||
write!(
|
||||
f,
|
||||
[not_yet_implemented_custom_text(
|
||||
"x as NOT_YET_IMPLEMENTED_PatternMatchAs",
|
||||
item
|
||||
)]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
use crate::{not_yet_implemented, FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::{write, Buffer, FormatResult};
|
||||
use ruff_python_ast::PatternMatchClass;
|
||||
|
||||
use crate::{not_yet_implemented_custom_text, FormatNodeRule, PyFormatter};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatPatternMatchClass;
|
||||
|
||||
impl FormatNodeRule<PatternMatchClass> for FormatPatternMatchClass {
|
||||
fn fmt_fields(&self, item: &PatternMatchClass, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
write!(f, [not_yet_implemented(item)])
|
||||
write!(
|
||||
f,
|
||||
[not_yet_implemented_custom_text(
|
||||
"NOT_YET_IMPLEMENTED_PatternMatchClass(0, 0)",
|
||||
item
|
||||
)]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
use crate::{not_yet_implemented, FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::{write, Buffer, FormatResult};
|
||||
use ruff_python_ast::PatternMatchMapping;
|
||||
|
||||
use crate::{not_yet_implemented_custom_text, FormatNodeRule, PyFormatter};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatPatternMatchMapping;
|
||||
|
||||
impl FormatNodeRule<PatternMatchMapping> for FormatPatternMatchMapping {
|
||||
fn fmt_fields(&self, item: &PatternMatchMapping, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
write!(f, [not_yet_implemented(item)])
|
||||
write!(
|
||||
f,
|
||||
[not_yet_implemented_custom_text(
|
||||
"{\"NOT_YET_IMPLEMENTED_PatternMatchMapping\": _, 2: _}",
|
||||
item
|
||||
)]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
use crate::{not_yet_implemented, FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::{write, Buffer, FormatResult};
|
||||
use ruff_python_ast::PatternMatchOr;
|
||||
|
||||
use crate::{not_yet_implemented_custom_text, FormatNodeRule, PyFormatter};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatPatternMatchOr;
|
||||
|
||||
impl FormatNodeRule<PatternMatchOr> for FormatPatternMatchOr {
|
||||
fn fmt_fields(&self, item: &PatternMatchOr, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
write!(f, [not_yet_implemented(item)])
|
||||
write!(
|
||||
f,
|
||||
[not_yet_implemented_custom_text(
|
||||
"NOT_YET_IMPLEMENTED_PatternMatchOf | (y)",
|
||||
item
|
||||
)]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
use crate::{not_yet_implemented, FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::{write, Buffer, FormatResult};
|
||||
use ruff_python_ast::PatternMatchSequence;
|
||||
|
||||
use crate::{not_yet_implemented_custom_text, FormatNodeRule, PyFormatter};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatPatternMatchSequence;
|
||||
|
||||
impl FormatNodeRule<PatternMatchSequence> for FormatPatternMatchSequence {
|
||||
fn fmt_fields(&self, item: &PatternMatchSequence, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
write!(f, [not_yet_implemented(item)])
|
||||
write!(
|
||||
f,
|
||||
[not_yet_implemented_custom_text(
|
||||
"[NOT_YET_IMPLEMENTED_PatternMatchSequence, 2]",
|
||||
item
|
||||
)]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
use crate::{not_yet_implemented, FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::{write, Buffer, FormatResult};
|
||||
use ruff_python_ast::PatternMatchSingleton;
|
||||
|
||||
use crate::{not_yet_implemented_custom_text, FormatNodeRule, PyFormatter};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatPatternMatchSingleton;
|
||||
|
||||
impl FormatNodeRule<PatternMatchSingleton> for FormatPatternMatchSingleton {
|
||||
fn fmt_fields(&self, item: &PatternMatchSingleton, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
write!(f, [not_yet_implemented(item)])
|
||||
write!(f, [not_yet_implemented_custom_text("None", item)])
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
use crate::{not_yet_implemented, FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::{write, Buffer, FormatResult};
|
||||
use ruff_python_ast::PatternMatchStar;
|
||||
|
||||
use crate::{not_yet_implemented_custom_text, FormatNodeRule, PyFormatter};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatPatternMatchStar;
|
||||
|
||||
impl FormatNodeRule<PatternMatchStar> for FormatPatternMatchStar {
|
||||
fn fmt_fields(&self, item: &PatternMatchStar, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
write!(f, [not_yet_implemented(item)])
|
||||
write!(
|
||||
f,
|
||||
[not_yet_implemented_custom_text(
|
||||
"*NOT_YET_IMPLEMENTED_PatternMatchStar",
|
||||
item
|
||||
)]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,19 @@
|
|||
use ruff_formatter::{write, Buffer, FormatResult};
|
||||
use ruff_python_ast::PatternMatchValue;
|
||||
|
||||
use ruff_formatter::{write, Buffer, FormatResult};
|
||||
|
||||
use crate::{not_yet_implemented, FormatNodeRule, PyFormatter};
|
||||
use crate::{not_yet_implemented_custom_text, FormatNodeRule, PyFormatter};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatPatternMatchValue;
|
||||
|
||||
impl FormatNodeRule<PatternMatchValue> for FormatPatternMatchValue {
|
||||
fn fmt_fields(&self, item: &PatternMatchValue, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
write!(f, [not_yet_implemented(item)])
|
||||
write!(
|
||||
f,
|
||||
[not_yet_implemented_custom_text(
|
||||
"\"NOT_YET_IMPLEMENTED_PatternMatchValue\"",
|
||||
item
|
||||
)]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,11 +51,11 @@ impl FormatNodeRule<StmtMatch> for FormatStmtMatch {
|
|||
write!(
|
||||
f,
|
||||
[block_indent(&format_args!(
|
||||
&leading_alternate_branch_comments(
|
||||
leading_alternate_branch_comments(
|
||||
comments.leading_comments(case),
|
||||
last_case.body.last(),
|
||||
),
|
||||
&case.format()
|
||||
case.format()
|
||||
))]
|
||||
)?;
|
||||
last_case = case;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue