Introduce AST nodes for PatternMatchClass arguments (#6881)

## Summary

This PR introduces two new AST nodes to improve the representation of
`PatternMatchClass`. As a reminder, `PatternMatchClass` looks like this:

```python
case Point2D(0, 0, x=1, y=2):
  ...
```

Historically, this was represented as a vector of patterns (for the `0,
0` portion) and parallel vectors of keyword names (for `x` and `y`) and
values (for `1` and `2`). This introduces a bunch of challenges for the
formatter, but importantly, it's also really different from how we
represent similar nodes, like arguments (`func(0, 0, x=1, y=2)`) or
parameters (`def func(x, y)`).

So, firstly, we now use a single node (`PatternArguments`) for the
entire parenthesized region, making it much more consistent with our
other nodes. So, above, `PatternArguments` would be `(0, 0, x=1, y=2)`.

Secondly, we now have a `PatternKeyword` node for `x=1` and `y=2`. This
is much more similar to the how `Keyword` is represented within
`Arguments` for call expressions.

Closes https://github.com/astral-sh/ruff/issues/6866.

Closes https://github.com/astral-sh/ruff/issues/6880.
This commit is contained in:
Charlie Marsh 2023-08-26 10:45:44 -04:00 committed by GitHub
parent ed1b4122d0
commit 15b73bdb8a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 25299 additions and 25824 deletions

View file

@ -2256,6 +2256,78 @@ impl<'ast> IntoFormat<PyFormatContext<'ast>> for ast::PatternMatchOr {
}
}
impl FormatRule<ast::PatternArguments, PyFormatContext<'_>>
for crate::pattern::pattern_arguments::FormatPatternArguments
{
#[inline]
fn fmt(&self, node: &ast::PatternArguments, f: &mut PyFormatter) -> FormatResult<()> {
FormatNodeRule::<ast::PatternArguments>::fmt(self, node, f)
}
}
impl<'ast> AsFormat<PyFormatContext<'ast>> for ast::PatternArguments {
type Format<'a> = FormatRefWithRule<
'a,
ast::PatternArguments,
crate::pattern::pattern_arguments::FormatPatternArguments,
PyFormatContext<'ast>,
>;
fn format(&self) -> Self::Format<'_> {
FormatRefWithRule::new(
self,
crate::pattern::pattern_arguments::FormatPatternArguments::default(),
)
}
}
impl<'ast> IntoFormat<PyFormatContext<'ast>> for ast::PatternArguments {
type Format = FormatOwnedWithRule<
ast::PatternArguments,
crate::pattern::pattern_arguments::FormatPatternArguments,
PyFormatContext<'ast>,
>;
fn into_format(self) -> Self::Format {
FormatOwnedWithRule::new(
self,
crate::pattern::pattern_arguments::FormatPatternArguments::default(),
)
}
}
impl FormatRule<ast::PatternKeyword, PyFormatContext<'_>>
for crate::pattern::pattern_keyword::FormatPatternKeyword
{
#[inline]
fn fmt(&self, node: &ast::PatternKeyword, f: &mut PyFormatter) -> FormatResult<()> {
FormatNodeRule::<ast::PatternKeyword>::fmt(self, node, f)
}
}
impl<'ast> AsFormat<PyFormatContext<'ast>> for ast::PatternKeyword {
type Format<'a> = FormatRefWithRule<
'a,
ast::PatternKeyword,
crate::pattern::pattern_keyword::FormatPatternKeyword,
PyFormatContext<'ast>,
>;
fn format(&self) -> Self::Format<'_> {
FormatRefWithRule::new(
self,
crate::pattern::pattern_keyword::FormatPatternKeyword::default(),
)
}
}
impl<'ast> IntoFormat<PyFormatContext<'ast>> for ast::PatternKeyword {
type Format = FormatOwnedWithRule<
ast::PatternKeyword,
crate::pattern::pattern_keyword::FormatPatternKeyword,
PyFormatContext<'ast>,
>;
fn into_format(self) -> Self::Format {
FormatOwnedWithRule::new(
self,
crate::pattern::pattern_keyword::FormatPatternKeyword::default(),
)
}
}
impl FormatRule<ast::Comprehension, PyFormatContext<'_>>
for crate::other::comprehension::FormatComprehension
{