mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-09 13:18:52 +00:00
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:
parent
ed1b4122d0
commit
15b73bdb8a
19 changed files with 25299 additions and 25824 deletions
|
@ -153,6 +153,36 @@ impl<'a> From<&'a ast::WithItem> for ComparableWithItem<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub struct ComparablePatternArguments<'a> {
|
||||
patterns: Vec<ComparablePattern<'a>>,
|
||||
keywords: Vec<ComparablePatternKeyword<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> From<&'a ast::PatternArguments> for ComparablePatternArguments<'a> {
|
||||
fn from(parameters: &'a ast::PatternArguments) -> Self {
|
||||
Self {
|
||||
patterns: parameters.patterns.iter().map(Into::into).collect(),
|
||||
keywords: parameters.keywords.iter().map(Into::into).collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub struct ComparablePatternKeyword<'a> {
|
||||
attr: &'a str,
|
||||
pattern: ComparablePattern<'a>,
|
||||
}
|
||||
|
||||
impl<'a> From<&'a ast::PatternKeyword> for ComparablePatternKeyword<'a> {
|
||||
fn from(keyword: &'a ast::PatternKeyword) -> Self {
|
||||
Self {
|
||||
attr: keyword.attr.as_str(),
|
||||
pattern: (&keyword.pattern).into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub struct PatternMatchValue<'a> {
|
||||
value: ComparableExpr<'a>,
|
||||
|
@ -178,9 +208,7 @@ pub struct PatternMatchMapping<'a> {
|
|||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub struct PatternMatchClass<'a> {
|
||||
cls: ComparableExpr<'a>,
|
||||
patterns: Vec<ComparablePattern<'a>>,
|
||||
kwd_attrs: Vec<&'a str>,
|
||||
kwd_patterns: Vec<ComparablePattern<'a>>,
|
||||
arguments: ComparablePatternArguments<'a>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
|
@ -240,18 +268,12 @@ impl<'a> From<&'a ast::Pattern> for ComparablePattern<'a> {
|
|||
patterns: patterns.iter().map(Into::into).collect(),
|
||||
rest: rest.as_deref(),
|
||||
}),
|
||||
ast::Pattern::MatchClass(ast::PatternMatchClass {
|
||||
cls,
|
||||
patterns,
|
||||
kwd_attrs,
|
||||
kwd_patterns,
|
||||
..
|
||||
}) => Self::MatchClass(PatternMatchClass {
|
||||
cls: cls.into(),
|
||||
patterns: patterns.iter().map(Into::into).collect(),
|
||||
kwd_attrs: kwd_attrs.iter().map(ast::Identifier::as_str).collect(),
|
||||
kwd_patterns: kwd_patterns.iter().map(Into::into).collect(),
|
||||
}),
|
||||
ast::Pattern::MatchClass(ast::PatternMatchClass { cls, arguments, .. }) => {
|
||||
Self::MatchClass(PatternMatchClass {
|
||||
cls: cls.into(),
|
||||
arguments: arguments.into(),
|
||||
})
|
||||
}
|
||||
ast::Pattern::MatchStar(ast::PatternMatchStar { name, .. }) => {
|
||||
Self::MatchStar(PatternMatchStar {
|
||||
name: name.as_deref(),
|
||||
|
|
|
@ -279,19 +279,16 @@ where
|
|||
.iter()
|
||||
.any(|pattern| any_over_pattern(pattern, func))
|
||||
}
|
||||
Pattern::MatchClass(ast::PatternMatchClass {
|
||||
cls,
|
||||
patterns,
|
||||
kwd_patterns,
|
||||
..
|
||||
}) => {
|
||||
Pattern::MatchClass(ast::PatternMatchClass { cls, arguments, .. }) => {
|
||||
any_over_expr(cls, func)
|
||||
|| patterns
|
||||
|| arguments
|
||||
.patterns
|
||||
.iter()
|
||||
.any(|pattern| any_over_pattern(pattern, func))
|
||||
|| kwd_patterns
|
||||
|| arguments
|
||||
.keywords
|
||||
.iter()
|
||||
.any(|pattern| any_over_pattern(pattern, func))
|
||||
.any(|keyword| any_over_pattern(&keyword.pattern, func))
|
||||
}
|
||||
Pattern::MatchStar(_) => false,
|
||||
Pattern::MatchAs(ast::PatternMatchAs { pattern, .. }) => pattern
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use crate::visitor::preorder::PreorderVisitor;
|
||||
use crate::{
|
||||
self as ast, Alias, Arguments, Comprehension, Decorator, ExceptHandler, Expr, Keyword,
|
||||
MatchCase, Mod, Parameter, ParameterWithDefault, Parameters, Pattern, Ranged, Stmt, TypeParam,
|
||||
TypeParamParamSpec, TypeParamTypeVar, TypeParamTypeVarTuple, TypeParams, WithItem,
|
||||
MatchCase, Mod, Parameter, ParameterWithDefault, Parameters, Pattern, PatternArguments,
|
||||
PatternKeyword, Ranged, Stmt, TypeParam, TypeParamParamSpec, TypeParamTypeVar,
|
||||
TypeParamTypeVarTuple, TypeParams, WithItem,
|
||||
};
|
||||
use ruff_text_size::TextRange;
|
||||
use std::ptr::NonNull;
|
||||
|
@ -90,6 +91,8 @@ pub enum AnyNode {
|
|||
PatternMatchStar(ast::PatternMatchStar),
|
||||
PatternMatchAs(ast::PatternMatchAs),
|
||||
PatternMatchOr(ast::PatternMatchOr),
|
||||
PatternArguments(PatternArguments),
|
||||
PatternKeyword(PatternKeyword),
|
||||
Comprehension(Comprehension),
|
||||
Arguments(Arguments),
|
||||
Parameters(Parameters),
|
||||
|
@ -175,6 +178,8 @@ impl AnyNode {
|
|||
| AnyNode::PatternMatchStar(_)
|
||||
| AnyNode::PatternMatchAs(_)
|
||||
| AnyNode::PatternMatchOr(_)
|
||||
| AnyNode::PatternArguments(_)
|
||||
| AnyNode::PatternKeyword(_)
|
||||
| AnyNode::Comprehension(_)
|
||||
| AnyNode::Arguments(_)
|
||||
| AnyNode::Parameters(_)
|
||||
|
@ -260,6 +265,8 @@ impl AnyNode {
|
|||
| AnyNode::PatternMatchStar(_)
|
||||
| AnyNode::PatternMatchAs(_)
|
||||
| AnyNode::PatternMatchOr(_)
|
||||
| AnyNode::PatternArguments(_)
|
||||
| AnyNode::PatternKeyword(_)
|
||||
| AnyNode::Comprehension(_)
|
||||
| AnyNode::Arguments(_)
|
||||
| AnyNode::Parameters(_)
|
||||
|
@ -345,6 +352,8 @@ impl AnyNode {
|
|||
| AnyNode::PatternMatchStar(_)
|
||||
| AnyNode::PatternMatchAs(_)
|
||||
| AnyNode::PatternMatchOr(_)
|
||||
| AnyNode::PatternArguments(_)
|
||||
| AnyNode::PatternKeyword(_)
|
||||
| AnyNode::Comprehension(_)
|
||||
| AnyNode::Arguments(_)
|
||||
| AnyNode::Parameters(_)
|
||||
|
@ -430,6 +439,8 @@ impl AnyNode {
|
|||
| AnyNode::ExprSlice(_)
|
||||
| AnyNode::ExprIpyEscapeCommand(_)
|
||||
| AnyNode::ExceptHandlerExceptHandler(_)
|
||||
| AnyNode::PatternArguments(_)
|
||||
| AnyNode::PatternKeyword(_)
|
||||
| AnyNode::Comprehension(_)
|
||||
| AnyNode::Arguments(_)
|
||||
| AnyNode::Parameters(_)
|
||||
|
@ -515,6 +526,8 @@ impl AnyNode {
|
|||
| AnyNode::PatternMatchStar(_)
|
||||
| AnyNode::PatternMatchAs(_)
|
||||
| AnyNode::PatternMatchOr(_)
|
||||
| AnyNode::PatternArguments(_)
|
||||
| AnyNode::PatternKeyword(_)
|
||||
| AnyNode::Comprehension(_)
|
||||
| AnyNode::Arguments(_)
|
||||
| AnyNode::Parameters(_)
|
||||
|
@ -619,6 +632,8 @@ impl AnyNode {
|
|||
Self::PatternMatchStar(node) => AnyNodeRef::PatternMatchStar(node),
|
||||
Self::PatternMatchAs(node) => AnyNodeRef::PatternMatchAs(node),
|
||||
Self::PatternMatchOr(node) => AnyNodeRef::PatternMatchOr(node),
|
||||
Self::PatternArguments(node) => AnyNodeRef::PatternArguments(node),
|
||||
Self::PatternKeyword(node) => AnyNodeRef::PatternKeyword(node),
|
||||
Self::Comprehension(node) => AnyNodeRef::Comprehension(node),
|
||||
Self::Arguments(node) => AnyNodeRef::Arguments(node),
|
||||
Self::Parameters(node) => AnyNodeRef::Parameters(node),
|
||||
|
@ -3247,19 +3262,11 @@ impl AstNode for ast::PatternMatchClass {
|
|||
{
|
||||
let ast::PatternMatchClass {
|
||||
cls,
|
||||
patterns,
|
||||
kwd_attrs: _,
|
||||
kwd_patterns,
|
||||
arguments: parameters,
|
||||
range: _,
|
||||
} = self;
|
||||
visitor.visit_expr(cls);
|
||||
for pattern in patterns {
|
||||
visitor.visit_pattern(pattern);
|
||||
}
|
||||
|
||||
for pattern in kwd_patterns {
|
||||
visitor.visit_pattern(pattern);
|
||||
}
|
||||
visitor.visit_pattern_arguments(parameters);
|
||||
}
|
||||
}
|
||||
impl AstNode for ast::PatternMatchStar {
|
||||
|
@ -3378,6 +3385,94 @@ impl AstNode for ast::PatternMatchOr {
|
|||
}
|
||||
}
|
||||
}
|
||||
impl AstNode for PatternArguments {
|
||||
fn cast(kind: AnyNode) -> Option<Self>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
if let AnyNode::PatternArguments(node) = kind {
|
||||
Some(node)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn cast_ref(kind: AnyNodeRef) -> Option<&Self> {
|
||||
if let AnyNodeRef::PatternArguments(node) = kind {
|
||||
Some(node)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn as_any_node_ref(&self) -> AnyNodeRef {
|
||||
AnyNodeRef::from(self)
|
||||
}
|
||||
|
||||
fn into_any_node(self) -> AnyNode {
|
||||
AnyNode::from(self)
|
||||
}
|
||||
|
||||
fn visit_preorder<'a, V>(&'a self, visitor: &mut V)
|
||||
where
|
||||
V: PreorderVisitor<'a> + ?Sized,
|
||||
{
|
||||
let PatternArguments {
|
||||
range: _,
|
||||
patterns,
|
||||
keywords,
|
||||
} = self;
|
||||
|
||||
for pattern in patterns {
|
||||
visitor.visit_pattern(pattern);
|
||||
}
|
||||
|
||||
for keyword in keywords {
|
||||
visitor.visit_pattern_keyword(keyword);
|
||||
}
|
||||
}
|
||||
}
|
||||
impl AstNode for PatternKeyword {
|
||||
fn cast(kind: AnyNode) -> Option<Self>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
if let AnyNode::PatternKeyword(node) = kind {
|
||||
Some(node)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn cast_ref(kind: AnyNodeRef) -> Option<&Self> {
|
||||
if let AnyNodeRef::PatternKeyword(node) = kind {
|
||||
Some(node)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn as_any_node_ref(&self) -> AnyNodeRef {
|
||||
AnyNodeRef::from(self)
|
||||
}
|
||||
|
||||
fn into_any_node(self) -> AnyNode {
|
||||
AnyNode::from(self)
|
||||
}
|
||||
|
||||
fn visit_preorder<'a, V>(&'a self, visitor: &mut V)
|
||||
where
|
||||
V: PreorderVisitor<'a> + ?Sized,
|
||||
{
|
||||
let PatternKeyword {
|
||||
range: _,
|
||||
attr: _,
|
||||
pattern,
|
||||
} = self;
|
||||
|
||||
visitor.visit_pattern(pattern);
|
||||
}
|
||||
}
|
||||
|
||||
impl AstNode for Comprehension {
|
||||
fn cast(kind: AnyNode) -> Option<Self>
|
||||
|
@ -4475,6 +4570,18 @@ impl From<ast::PatternMatchOr> for AnyNode {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<PatternArguments> for AnyNode {
|
||||
fn from(node: PatternArguments) -> Self {
|
||||
AnyNode::PatternArguments(node)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PatternKeyword> for AnyNode {
|
||||
fn from(node: PatternKeyword) -> Self {
|
||||
AnyNode::PatternKeyword(node)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Comprehension> for AnyNode {
|
||||
fn from(node: Comprehension) -> Self {
|
||||
AnyNode::Comprehension(node)
|
||||
|
@ -4615,6 +4722,8 @@ impl Ranged for AnyNode {
|
|||
AnyNode::PatternMatchStar(node) => node.range(),
|
||||
AnyNode::PatternMatchAs(node) => node.range(),
|
||||
AnyNode::PatternMatchOr(node) => node.range(),
|
||||
AnyNode::PatternArguments(node) => node.range(),
|
||||
AnyNode::PatternKeyword(node) => node.range(),
|
||||
AnyNode::Comprehension(node) => node.range(),
|
||||
AnyNode::Arguments(node) => node.range(),
|
||||
AnyNode::Parameters(node) => node.range(),
|
||||
|
@ -4700,6 +4809,8 @@ pub enum AnyNodeRef<'a> {
|
|||
PatternMatchStar(&'a ast::PatternMatchStar),
|
||||
PatternMatchAs(&'a ast::PatternMatchAs),
|
||||
PatternMatchOr(&'a ast::PatternMatchOr),
|
||||
PatternArguments(&'a ast::PatternArguments),
|
||||
PatternKeyword(&'a ast::PatternKeyword),
|
||||
Comprehension(&'a Comprehension),
|
||||
Arguments(&'a Arguments),
|
||||
Parameters(&'a Parameters),
|
||||
|
@ -4784,6 +4895,8 @@ impl AnyNodeRef<'_> {
|
|||
AnyNodeRef::PatternMatchStar(node) => NonNull::from(*node).cast(),
|
||||
AnyNodeRef::PatternMatchAs(node) => NonNull::from(*node).cast(),
|
||||
AnyNodeRef::PatternMatchOr(node) => NonNull::from(*node).cast(),
|
||||
AnyNodeRef::PatternArguments(node) => NonNull::from(*node).cast(),
|
||||
AnyNodeRef::PatternKeyword(node) => NonNull::from(*node).cast(),
|
||||
AnyNodeRef::Comprehension(node) => NonNull::from(*node).cast(),
|
||||
AnyNodeRef::Arguments(node) => NonNull::from(*node).cast(),
|
||||
AnyNodeRef::Parameters(node) => NonNull::from(*node).cast(),
|
||||
|
@ -4874,6 +4987,8 @@ impl AnyNodeRef<'_> {
|
|||
AnyNodeRef::PatternMatchStar(_) => NodeKind::PatternMatchStar,
|
||||
AnyNodeRef::PatternMatchAs(_) => NodeKind::PatternMatchAs,
|
||||
AnyNodeRef::PatternMatchOr(_) => NodeKind::PatternMatchOr,
|
||||
AnyNodeRef::PatternArguments(_) => NodeKind::PatternArguments,
|
||||
AnyNodeRef::PatternKeyword(_) => NodeKind::PatternKeyword,
|
||||
AnyNodeRef::Comprehension(_) => NodeKind::Comprehension,
|
||||
AnyNodeRef::Arguments(_) => NodeKind::Arguments,
|
||||
AnyNodeRef::Parameters(_) => NodeKind::Parameters,
|
||||
|
@ -4959,6 +5074,8 @@ impl AnyNodeRef<'_> {
|
|||
| AnyNodeRef::PatternMatchStar(_)
|
||||
| AnyNodeRef::PatternMatchAs(_)
|
||||
| AnyNodeRef::PatternMatchOr(_)
|
||||
| AnyNodeRef::PatternArguments(_)
|
||||
| AnyNodeRef::PatternKeyword(_)
|
||||
| AnyNodeRef::Comprehension(_)
|
||||
| AnyNodeRef::Arguments(_)
|
||||
| AnyNodeRef::Parameters(_)
|
||||
|
@ -5044,6 +5161,8 @@ impl AnyNodeRef<'_> {
|
|||
| AnyNodeRef::PatternMatchStar(_)
|
||||
| AnyNodeRef::PatternMatchAs(_)
|
||||
| AnyNodeRef::PatternMatchOr(_)
|
||||
| AnyNodeRef::PatternArguments(_)
|
||||
| AnyNodeRef::PatternKeyword(_)
|
||||
| AnyNodeRef::Comprehension(_)
|
||||
| AnyNodeRef::Arguments(_)
|
||||
| AnyNodeRef::Parameters(_)
|
||||
|
@ -5128,6 +5247,8 @@ impl AnyNodeRef<'_> {
|
|||
| AnyNodeRef::PatternMatchStar(_)
|
||||
| AnyNodeRef::PatternMatchAs(_)
|
||||
| AnyNodeRef::PatternMatchOr(_)
|
||||
| AnyNodeRef::PatternArguments(_)
|
||||
| AnyNodeRef::PatternKeyword(_)
|
||||
| AnyNodeRef::Comprehension(_)
|
||||
| AnyNodeRef::Arguments(_)
|
||||
| AnyNodeRef::Parameters(_)
|
||||
|
@ -5212,6 +5333,8 @@ impl AnyNodeRef<'_> {
|
|||
| AnyNodeRef::ExprTuple(_)
|
||||
| AnyNodeRef::ExprSlice(_)
|
||||
| AnyNodeRef::ExprIpyEscapeCommand(_)
|
||||
| AnyNodeRef::PatternArguments(_)
|
||||
| AnyNodeRef::PatternKeyword(_)
|
||||
| AnyNodeRef::ExceptHandlerExceptHandler(_)
|
||||
| AnyNodeRef::Comprehension(_)
|
||||
| AnyNodeRef::Arguments(_)
|
||||
|
@ -5298,6 +5421,8 @@ impl AnyNodeRef<'_> {
|
|||
| AnyNodeRef::PatternMatchStar(_)
|
||||
| AnyNodeRef::PatternMatchAs(_)
|
||||
| AnyNodeRef::PatternMatchOr(_)
|
||||
| AnyNodeRef::PatternArguments(_)
|
||||
| AnyNodeRef::PatternKeyword(_)
|
||||
| AnyNodeRef::Comprehension(_)
|
||||
| AnyNodeRef::Arguments(_)
|
||||
| AnyNodeRef::Parameters(_)
|
||||
|
@ -5411,6 +5536,8 @@ impl AnyNodeRef<'_> {
|
|||
AnyNodeRef::PatternMatchStar(node) => node.visit_preorder(visitor),
|
||||
AnyNodeRef::PatternMatchAs(node) => node.visit_preorder(visitor),
|
||||
AnyNodeRef::PatternMatchOr(node) => node.visit_preorder(visitor),
|
||||
AnyNodeRef::PatternArguments(node) => node.visit_preorder(visitor),
|
||||
AnyNodeRef::PatternKeyword(node) => node.visit_preorder(visitor),
|
||||
AnyNodeRef::Comprehension(node) => node.visit_preorder(visitor),
|
||||
AnyNodeRef::Arguments(node) => node.visit_preorder(visitor),
|
||||
AnyNodeRef::Parameters(node) => node.visit_preorder(visitor),
|
||||
|
@ -5820,6 +5947,18 @@ impl<'a> From<&'a ast::PatternMatchOr> for AnyNodeRef<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a ast::PatternArguments> for AnyNodeRef<'a> {
|
||||
fn from(node: &'a ast::PatternArguments) -> Self {
|
||||
AnyNodeRef::PatternArguments(node)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a ast::PatternKeyword> for AnyNodeRef<'a> {
|
||||
fn from(node: &'a ast::PatternKeyword) -> Self {
|
||||
AnyNodeRef::PatternKeyword(node)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Decorator> for AnyNodeRef<'a> {
|
||||
fn from(node: &'a Decorator) -> Self {
|
||||
AnyNodeRef::Decorator(node)
|
||||
|
@ -6073,6 +6212,8 @@ impl Ranged for AnyNodeRef<'_> {
|
|||
AnyNodeRef::PatternMatchStar(node) => node.range(),
|
||||
AnyNodeRef::PatternMatchAs(node) => node.range(),
|
||||
AnyNodeRef::PatternMatchOr(node) => node.range(),
|
||||
AnyNodeRef::PatternArguments(node) => node.range(),
|
||||
AnyNodeRef::PatternKeyword(node) => node.range(),
|
||||
AnyNodeRef::Comprehension(node) => node.range(),
|
||||
AnyNodeRef::Arguments(node) => node.range(),
|
||||
AnyNodeRef::Parameters(node) => node.range(),
|
||||
|
@ -6160,6 +6301,8 @@ pub enum NodeKind {
|
|||
PatternMatchStar,
|
||||
PatternMatchAs,
|
||||
PatternMatchOr,
|
||||
PatternArguments,
|
||||
PatternKeyword,
|
||||
TypeIgnoreTypeIgnore,
|
||||
Comprehension,
|
||||
Arguments,
|
||||
|
|
|
@ -1900,9 +1900,7 @@ impl From<PatternMatchMapping> for Pattern {
|
|||
pub struct PatternMatchClass {
|
||||
pub range: TextRange,
|
||||
pub cls: Box<Expr>,
|
||||
pub patterns: Vec<Pattern>,
|
||||
pub kwd_attrs: Vec<Identifier>,
|
||||
pub kwd_patterns: Vec<Pattern>,
|
||||
pub arguments: PatternArguments,
|
||||
}
|
||||
|
||||
impl From<PatternMatchClass> for Pattern {
|
||||
|
@ -1911,6 +1909,28 @@ impl From<PatternMatchClass> for Pattern {
|
|||
}
|
||||
}
|
||||
|
||||
/// An AST node to represent the arguments to a [`PatternMatchClass`], i.e., the
|
||||
/// parenthesized contents in `case Point(1, x=0, y=0)`.
|
||||
///
|
||||
/// Like [`Arguments`], but for [`PatternMatchClass`].
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct PatternArguments {
|
||||
pub range: TextRange,
|
||||
pub patterns: Vec<Pattern>,
|
||||
pub keywords: Vec<PatternKeyword>,
|
||||
}
|
||||
|
||||
/// An AST node to represent the keyword arguments to a [`PatternMatchClass`], i.e., the
|
||||
/// `x=0` and `y=0` in `case Point(x=0, y=0)`.
|
||||
///
|
||||
/// Like [`Keyword`], but for [`PatternMatchClass`].
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct PatternKeyword {
|
||||
pub range: TextRange,
|
||||
pub attr: Identifier,
|
||||
pub pattern: Pattern,
|
||||
}
|
||||
|
||||
/// See also [MatchStar](https://docs.python.org/3/library/ast.html#ast.MatchStar)
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct PatternMatchStar {
|
||||
|
@ -3004,6 +3024,16 @@ impl Ranged for crate::Pattern {
|
|||
}
|
||||
}
|
||||
}
|
||||
impl Ranged for crate::nodes::PatternArguments {
|
||||
fn range(&self) -> TextRange {
|
||||
self.range
|
||||
}
|
||||
}
|
||||
impl Ranged for crate::nodes::PatternKeyword {
|
||||
fn range(&self) -> TextRange {
|
||||
self.range
|
||||
}
|
||||
}
|
||||
|
||||
impl Ranged for crate::nodes::TypeParams {
|
||||
fn range(&self) -> TextRange {
|
||||
|
|
|
@ -5,7 +5,8 @@ pub mod preorder;
|
|||
use crate::{
|
||||
self as ast, Alias, Arguments, BoolOp, CmpOp, Comprehension, Decorator, ElifElseClause,
|
||||
ExceptHandler, Expr, ExprContext, Keyword, MatchCase, Operator, Parameter, Parameters, Pattern,
|
||||
Stmt, TypeParam, TypeParamTypeVar, TypeParams, UnaryOp, WithItem,
|
||||
PatternArguments, PatternKeyword, Stmt, TypeParam, TypeParamTypeVar, TypeParams, UnaryOp,
|
||||
WithItem,
|
||||
};
|
||||
|
||||
/// A trait for AST visitors. Visits all nodes in the AST recursively in evaluation-order.
|
||||
|
@ -82,6 +83,12 @@ pub trait Visitor<'a> {
|
|||
fn visit_pattern(&mut self, pattern: &'a Pattern) {
|
||||
walk_pattern(self, pattern);
|
||||
}
|
||||
fn visit_pattern_arguments(&mut self, pattern_arguments: &'a PatternArguments) {
|
||||
walk_pattern_arguments(self, pattern_arguments);
|
||||
}
|
||||
fn visit_pattern_keyword(&mut self, pattern_keyword: &'a PatternKeyword) {
|
||||
walk_pattern_keyword(self, pattern_keyword);
|
||||
}
|
||||
fn visit_body(&mut self, body: &'a [Stmt]) {
|
||||
walk_body(self, body);
|
||||
}
|
||||
|
@ -674,20 +681,9 @@ pub fn walk_pattern<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, pattern: &'a P
|
|||
visitor.visit_pattern(pattern);
|
||||
}
|
||||
}
|
||||
Pattern::MatchClass(ast::PatternMatchClass {
|
||||
cls,
|
||||
patterns,
|
||||
kwd_patterns,
|
||||
..
|
||||
}) => {
|
||||
Pattern::MatchClass(ast::PatternMatchClass { cls, arguments, .. }) => {
|
||||
visitor.visit_expr(cls);
|
||||
for pattern in patterns {
|
||||
visitor.visit_pattern(pattern);
|
||||
}
|
||||
|
||||
for pattern in kwd_patterns {
|
||||
visitor.visit_pattern(pattern);
|
||||
}
|
||||
visitor.visit_pattern_arguments(arguments);
|
||||
}
|
||||
Pattern::MatchStar(_) => {}
|
||||
Pattern::MatchAs(ast::PatternMatchAs { pattern, .. }) => {
|
||||
|
@ -703,6 +699,25 @@ pub fn walk_pattern<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, pattern: &'a P
|
|||
}
|
||||
}
|
||||
|
||||
pub fn walk_pattern_arguments<'a, V: Visitor<'a> + ?Sized>(
|
||||
visitor: &mut V,
|
||||
pattern_arguments: &'a PatternArguments,
|
||||
) {
|
||||
for pattern in &pattern_arguments.patterns {
|
||||
visitor.visit_pattern(pattern);
|
||||
}
|
||||
for keyword in &pattern_arguments.keywords {
|
||||
visitor.visit_pattern_keyword(keyword);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn walk_pattern_keyword<'a, V: Visitor<'a> + ?Sized>(
|
||||
visitor: &mut V,
|
||||
pattern_keyword: &'a PatternKeyword,
|
||||
) {
|
||||
visitor.visit_pattern(&pattern_keyword.pattern);
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
pub fn walk_expr_context<'a, V: Visitor<'a> + ?Sized>(visitor: &V, expr_context: &'a ExprContext) {}
|
||||
|
||||
|
|
|
@ -2,7 +2,8 @@ use crate::node::{AnyNodeRef, AstNode};
|
|||
use crate::{
|
||||
Alias, Arguments, BoolOp, CmpOp, Comprehension, Constant, Decorator, ElifElseClause,
|
||||
ExceptHandler, Expr, Keyword, MatchCase, Mod, Operator, Parameter, ParameterWithDefault,
|
||||
Parameters, Pattern, Stmt, TypeParam, TypeParams, UnaryOp, WithItem,
|
||||
Parameters, Pattern, PatternArguments, PatternKeyword, Stmt, TypeParam, TypeParams, UnaryOp,
|
||||
WithItem,
|
||||
};
|
||||
|
||||
/// Visitor that traverses all nodes recursively in pre-order.
|
||||
|
@ -132,6 +133,17 @@ pub trait PreorderVisitor<'a> {
|
|||
walk_pattern(self, pattern);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_pattern_arguments(&mut self, pattern_arguments: &'a PatternArguments) {
|
||||
walk_pattern_arguments(self, pattern_arguments);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
||||
fn visit_pattern_keyword(&mut self, pattern_keyword: &'a PatternKeyword) {
|
||||
walk_pattern_keyword(self, pattern_keyword);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_body(&mut self, body: &'a [Stmt]) {
|
||||
walk_body(self, body);
|
||||
|
@ -460,6 +472,33 @@ where
|
|||
visitor.leave_node(node);
|
||||
}
|
||||
|
||||
pub fn walk_pattern_arguments<'a, V>(visitor: &mut V, pattern_arguments: &'a PatternArguments)
|
||||
where
|
||||
V: PreorderVisitor<'a> + ?Sized,
|
||||
{
|
||||
let node = AnyNodeRef::from(pattern_arguments);
|
||||
if visitor.enter_node(node).is_traverse() {
|
||||
for pattern in &pattern_arguments.patterns {
|
||||
visitor.visit_pattern(pattern);
|
||||
}
|
||||
for keyword in &pattern_arguments.keywords {
|
||||
visitor.visit_pattern_keyword(keyword);
|
||||
}
|
||||
}
|
||||
visitor.leave_node(node);
|
||||
}
|
||||
|
||||
pub fn walk_pattern_keyword<'a, V>(visitor: &mut V, pattern_keyword: &'a PatternKeyword)
|
||||
where
|
||||
V: PreorderVisitor<'a> + ?Sized,
|
||||
{
|
||||
let node = AnyNodeRef::from(pattern_keyword);
|
||||
if visitor.enter_node(node).is_traverse() {
|
||||
visitor.visit_pattern(&pattern_keyword.pattern);
|
||||
}
|
||||
visitor.leave_node(node);
|
||||
}
|
||||
|
||||
pub fn walk_bool_op<'a, V>(_visitor: &mut V, _bool_op: &'a BoolOp)
|
||||
where
|
||||
V: PreorderVisitor<'a> + ?Sized,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue