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

@ -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(),

View file

@ -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

View file

@ -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,

View file

@ -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 {

View file

@ -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) {}

View file

@ -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,