Skip to main content

rustpython_ruff_python_ast/visitor/
transformer.rs

1use crate::{
2    self as ast, Alias, Arguments, BoolOp, BytesLiteral, CmpOp, Comprehension, Decorator,
3    ElifElseClause, ExceptHandler, Expr, ExprContext, FString, InterpolatedStringElement, Keyword,
4    MatchCase, Operator, Parameter, Parameters, Pattern, PatternArguments, PatternKeyword, Stmt,
5    StringLiteral, TString, TypeParam, TypeParamParamSpec, TypeParamTypeVar, TypeParamTypeVarTuple,
6    TypeParams, UnaryOp, WithItem,
7};
8
9/// A trait for transforming ASTs. Visits all nodes in the AST recursively in evaluation-order.
10pub trait Transformer {
11    fn visit_stmt(&self, stmt: &mut Stmt) {
12        walk_stmt(self, stmt);
13    }
14    fn visit_annotation(&self, expr: &mut Expr) {
15        walk_annotation(self, expr);
16    }
17    fn visit_decorator(&self, decorator: &mut Decorator) {
18        walk_decorator(self, decorator);
19    }
20    fn visit_expr(&self, expr: &mut Expr) {
21        walk_expr(self, expr);
22    }
23    fn visit_expr_context(&self, expr_context: &mut ExprContext) {
24        walk_expr_context(self, expr_context);
25    }
26    fn visit_bool_op(&self, bool_op: &mut BoolOp) {
27        walk_bool_op(self, bool_op);
28    }
29    fn visit_operator(&self, operator: &mut Operator) {
30        walk_operator(self, operator);
31    }
32    fn visit_unary_op(&self, unary_op: &mut UnaryOp) {
33        walk_unary_op(self, unary_op);
34    }
35    fn visit_cmp_op(&self, cmp_op: &mut CmpOp) {
36        walk_cmp_op(self, cmp_op);
37    }
38    fn visit_comprehension(&self, comprehension: &mut Comprehension) {
39        walk_comprehension(self, comprehension);
40    }
41    fn visit_except_handler(&self, except_handler: &mut ExceptHandler) {
42        walk_except_handler(self, except_handler);
43    }
44    fn visit_arguments(&self, arguments: &mut Arguments) {
45        walk_arguments(self, arguments);
46    }
47    fn visit_parameters(&self, parameters: &mut Parameters) {
48        walk_parameters(self, parameters);
49    }
50    fn visit_parameter(&self, parameter: &mut Parameter) {
51        walk_parameter(self, parameter);
52    }
53    fn visit_keyword(&self, keyword: &mut Keyword) {
54        walk_keyword(self, keyword);
55    }
56    fn visit_alias(&self, alias: &mut Alias) {
57        walk_alias(self, alias);
58    }
59    fn visit_with_item(&self, with_item: &mut WithItem) {
60        walk_with_item(self, with_item);
61    }
62    fn visit_type_params(&self, type_params: &mut TypeParams) {
63        walk_type_params(self, type_params);
64    }
65    fn visit_type_param(&self, type_param: &mut TypeParam) {
66        walk_type_param(self, type_param);
67    }
68    fn visit_match_case(&self, match_case: &mut MatchCase) {
69        walk_match_case(self, match_case);
70    }
71    fn visit_pattern(&self, pattern: &mut Pattern) {
72        walk_pattern(self, pattern);
73    }
74    fn visit_pattern_arguments(&self, pattern_arguments: &mut PatternArguments) {
75        walk_pattern_arguments(self, pattern_arguments);
76    }
77    fn visit_pattern_keyword(&self, pattern_keyword: &mut PatternKeyword) {
78        walk_pattern_keyword(self, pattern_keyword);
79    }
80    fn visit_body(&self, body: &mut [Stmt]) {
81        walk_body(self, body);
82    }
83    fn visit_elif_else_clause(&self, elif_else_clause: &mut ElifElseClause) {
84        walk_elif_else_clause(self, elif_else_clause);
85    }
86    fn visit_f_string(&self, f_string: &mut FString) {
87        walk_f_string(self, f_string);
88    }
89    fn visit_interpolated_string_element(
90        &self,
91        interpolated_string_element: &mut InterpolatedStringElement,
92    ) {
93        walk_interpolated_string_element(self, interpolated_string_element);
94    }
95    fn visit_t_string(&self, t_string: &mut TString) {
96        walk_t_string(self, t_string);
97    }
98    fn visit_string_literal(&self, string_literal: &mut StringLiteral) {
99        walk_string_literal(self, string_literal);
100    }
101    fn visit_bytes_literal(&self, bytes_literal: &mut BytesLiteral) {
102        walk_bytes_literal(self, bytes_literal);
103    }
104}
105
106pub fn walk_body<V: Transformer + ?Sized>(visitor: &V, body: &mut [Stmt]) {
107    for stmt in body {
108        visitor.visit_stmt(stmt);
109    }
110}
111
112pub fn walk_elif_else_clause<V: Transformer + ?Sized>(
113    visitor: &V,
114    elif_else_clause: &mut ElifElseClause,
115) {
116    if let Some(test) = &mut elif_else_clause.test {
117        visitor.visit_expr(test);
118    }
119    visitor.visit_body(&mut elif_else_clause.body);
120}
121
122pub fn walk_stmt<V: Transformer + ?Sized>(visitor: &V, stmt: &mut Stmt) {
123    match stmt {
124        Stmt::FunctionDef(ast::StmtFunctionDef {
125            parameters,
126            body,
127            decorator_list,
128            returns,
129            type_params,
130            ..
131        }) => {
132            for decorator in decorator_list {
133                visitor.visit_decorator(decorator);
134            }
135            if let Some(type_params) = type_params {
136                visitor.visit_type_params(type_params);
137            }
138            visitor.visit_parameters(parameters);
139            if let Some(expr) = returns {
140                visitor.visit_annotation(expr);
141            }
142            visitor.visit_body(body);
143        }
144        Stmt::ClassDef(ast::StmtClassDef {
145            arguments,
146            body,
147            decorator_list,
148            type_params,
149            ..
150        }) => {
151            for decorator in decorator_list {
152                visitor.visit_decorator(decorator);
153            }
154            if let Some(type_params) = type_params {
155                visitor.visit_type_params(type_params);
156            }
157            if let Some(arguments) = arguments {
158                visitor.visit_arguments(arguments);
159            }
160            visitor.visit_body(body);
161        }
162        Stmt::Return(ast::StmtReturn {
163            value,
164            range: _,
165            node_index: _,
166        }) => {
167            if let Some(expr) = value {
168                visitor.visit_expr(expr);
169            }
170        }
171        Stmt::Delete(ast::StmtDelete {
172            targets,
173            range: _,
174            node_index: _,
175        }) => {
176            for expr in targets {
177                visitor.visit_expr(expr);
178            }
179        }
180        Stmt::TypeAlias(ast::StmtTypeAlias {
181            range: _,
182            node_index: _,
183            name,
184            type_params,
185            value,
186        }) => {
187            visitor.visit_expr(value);
188            if let Some(type_params) = type_params {
189                visitor.visit_type_params(type_params);
190            }
191            visitor.visit_expr(name);
192        }
193        Stmt::Assign(ast::StmtAssign { targets, value, .. }) => {
194            visitor.visit_expr(value);
195            for expr in targets {
196                visitor.visit_expr(expr);
197            }
198        }
199        Stmt::AugAssign(ast::StmtAugAssign {
200            target,
201            op,
202            value,
203            range: _,
204            node_index: _,
205        }) => {
206            visitor.visit_expr(value);
207            visitor.visit_operator(op);
208            visitor.visit_expr(target);
209        }
210        Stmt::AnnAssign(ast::StmtAnnAssign {
211            target,
212            annotation,
213            value,
214            ..
215        }) => {
216            if let Some(expr) = value {
217                visitor.visit_expr(expr);
218            }
219            visitor.visit_annotation(annotation);
220            visitor.visit_expr(target);
221        }
222        Stmt::For(ast::StmtFor {
223            target,
224            iter,
225            body,
226            orelse,
227            ..
228        }) => {
229            visitor.visit_expr(iter);
230            visitor.visit_expr(target);
231            visitor.visit_body(body);
232            visitor.visit_body(orelse);
233        }
234        Stmt::While(ast::StmtWhile {
235            test,
236            body,
237            orelse,
238            range: _,
239            node_index: _,
240        }) => {
241            visitor.visit_expr(test);
242            visitor.visit_body(body);
243            visitor.visit_body(orelse);
244        }
245        Stmt::If(ast::StmtIf {
246            test,
247            body,
248            elif_else_clauses,
249            range: _,
250            node_index: _,
251        }) => {
252            visitor.visit_expr(test);
253            visitor.visit_body(body);
254            for clause in elif_else_clauses {
255                walk_elif_else_clause(visitor, clause);
256            }
257        }
258        Stmt::With(ast::StmtWith { items, body, .. }) => {
259            for with_item in items {
260                visitor.visit_with_item(with_item);
261            }
262            visitor.visit_body(body);
263        }
264        Stmt::Match(ast::StmtMatch {
265            subject,
266            cases,
267            range: _,
268            node_index: _,
269        }) => {
270            visitor.visit_expr(subject);
271            for match_case in cases {
272                visitor.visit_match_case(match_case);
273            }
274        }
275        Stmt::Raise(ast::StmtRaise {
276            exc,
277            cause,
278            range: _,
279            node_index: _,
280        }) => {
281            if let Some(expr) = exc {
282                visitor.visit_expr(expr);
283            }
284            if let Some(expr) = cause {
285                visitor.visit_expr(expr);
286            }
287        }
288        Stmt::Try(ast::StmtTry {
289            body,
290            handlers,
291            orelse,
292            finalbody,
293            is_star: _,
294            range: _,
295            node_index: _,
296        }) => {
297            visitor.visit_body(body);
298            for except_handler in handlers {
299                visitor.visit_except_handler(except_handler);
300            }
301            visitor.visit_body(orelse);
302            visitor.visit_body(finalbody);
303        }
304        Stmt::Assert(ast::StmtAssert {
305            test,
306            msg,
307            range: _,
308            node_index: _,
309        }) => {
310            visitor.visit_expr(test);
311            if let Some(expr) = msg {
312                visitor.visit_expr(expr);
313            }
314        }
315        Stmt::Import(ast::StmtImport {
316            names,
317            is_lazy: _,
318            range: _,
319            node_index: _,
320        }) => {
321            for alias in names {
322                visitor.visit_alias(alias);
323            }
324        }
325        Stmt::ImportFrom(ast::StmtImportFrom { names, .. }) => {
326            for alias in names {
327                visitor.visit_alias(alias);
328            }
329        }
330        Stmt::Global(_) => {}
331        Stmt::Nonlocal(_) => {}
332        Stmt::Expr(ast::StmtExpr {
333            value,
334            range: _,
335            node_index: _,
336        }) => visitor.visit_expr(value),
337        Stmt::Pass(_) | Stmt::Break(_) | Stmt::Continue(_) | Stmt::IpyEscapeCommand(_) => {}
338    }
339}
340
341pub fn walk_annotation<V: Transformer + ?Sized>(visitor: &V, expr: &mut Expr) {
342    visitor.visit_expr(expr);
343}
344
345pub fn walk_decorator<V: Transformer + ?Sized>(visitor: &V, decorator: &mut Decorator) {
346    visitor.visit_expr(&mut decorator.expression);
347}
348
349pub fn walk_expr<V: Transformer + ?Sized>(visitor: &V, expr: &mut Expr) {
350    match expr {
351        Expr::BoolOp(ast::ExprBoolOp {
352            op,
353            values,
354            range: _,
355            node_index: _,
356        }) => {
357            visitor.visit_bool_op(op);
358            for expr in values {
359                visitor.visit_expr(expr);
360            }
361        }
362        Expr::Named(ast::ExprNamed {
363            target,
364            value,
365            range: _,
366            node_index: _,
367        }) => {
368            visitor.visit_expr(value);
369            visitor.visit_expr(target);
370        }
371        Expr::BinOp(ast::ExprBinOp {
372            left,
373            op,
374            right,
375            range: _,
376            node_index: _,
377        }) => {
378            visitor.visit_expr(left);
379            visitor.visit_operator(op);
380            visitor.visit_expr(right);
381        }
382        Expr::UnaryOp(ast::ExprUnaryOp {
383            op,
384            operand,
385            range: _,
386            node_index: _,
387        }) => {
388            visitor.visit_unary_op(op);
389            visitor.visit_expr(operand);
390        }
391        Expr::Lambda(ast::ExprLambda {
392            parameters,
393            body,
394            range: _,
395            node_index: _,
396        }) => {
397            if let Some(parameters) = parameters {
398                visitor.visit_parameters(parameters);
399            }
400            visitor.visit_expr(body);
401        }
402        Expr::If(ast::ExprIf {
403            test,
404            body,
405            orelse,
406            range: _,
407            node_index: _,
408        }) => {
409            visitor.visit_expr(test);
410            visitor.visit_expr(body);
411            visitor.visit_expr(orelse);
412        }
413        Expr::Dict(ast::ExprDict {
414            items,
415            range: _,
416            node_index: _,
417        }) => {
418            for ast::DictItem { key, value } in items {
419                if let Some(key) = key {
420                    visitor.visit_expr(key);
421                }
422                visitor.visit_expr(value);
423            }
424        }
425        Expr::Set(ast::ExprSet {
426            elts,
427            range: _,
428            node_index: _,
429        }) => {
430            for expr in elts {
431                visitor.visit_expr(expr);
432            }
433        }
434        Expr::ListComp(ast::ExprListComp {
435            elt,
436            generators,
437            range: _,
438            node_index: _,
439        }) => {
440            for comprehension in generators {
441                visitor.visit_comprehension(comprehension);
442            }
443            visitor.visit_expr(elt);
444        }
445        Expr::SetComp(ast::ExprSetComp {
446            elt,
447            generators,
448            range: _,
449            node_index: _,
450        }) => {
451            for comprehension in generators {
452                visitor.visit_comprehension(comprehension);
453            }
454            visitor.visit_expr(elt);
455        }
456        Expr::DictComp(ast::ExprDictComp {
457            key,
458            value,
459            generators,
460            range: _,
461            node_index: _,
462        }) => {
463            for comprehension in generators {
464                visitor.visit_comprehension(comprehension);
465            }
466            visitor.visit_expr(key);
467            visitor.visit_expr(value);
468        }
469        Expr::Generator(ast::ExprGenerator {
470            elt,
471            generators,
472            range: _,
473            node_index: _,
474            parenthesized: _,
475        }) => {
476            for comprehension in generators {
477                visitor.visit_comprehension(comprehension);
478            }
479            visitor.visit_expr(elt);
480        }
481        Expr::Await(ast::ExprAwait {
482            value,
483            range: _,
484            node_index: _,
485        }) => visitor.visit_expr(value),
486        Expr::Yield(ast::ExprYield {
487            value,
488            range: _,
489            node_index: _,
490        }) => {
491            if let Some(expr) = value {
492                visitor.visit_expr(expr);
493            }
494        }
495        Expr::YieldFrom(ast::ExprYieldFrom {
496            value,
497            range: _,
498            node_index: _,
499        }) => visitor.visit_expr(value),
500        Expr::Compare(ast::ExprCompare {
501            left,
502            ops,
503            comparators,
504            range: _,
505            node_index: _,
506        }) => {
507            visitor.visit_expr(left);
508            for cmp_op in &mut **ops {
509                visitor.visit_cmp_op(cmp_op);
510            }
511            for expr in &mut **comparators {
512                visitor.visit_expr(expr);
513            }
514        }
515        Expr::Call(ast::ExprCall {
516            func,
517            arguments,
518            range: _,
519            node_index: _,
520        }) => {
521            visitor.visit_expr(func);
522            visitor.visit_arguments(arguments);
523        }
524        Expr::FString(ast::ExprFString { value, .. }) => {
525            for f_string_part in value.iter_mut() {
526                match f_string_part {
527                    ast::FStringPart::Literal(string_literal) => {
528                        visitor.visit_string_literal(string_literal);
529                    }
530                    ast::FStringPart::FString(f_string) => {
531                        visitor.visit_f_string(f_string);
532                    }
533                }
534            }
535        }
536        Expr::TString(ast::ExprTString { value, .. }) => {
537            for t_string in value.iter_mut() {
538                visitor.visit_t_string(t_string);
539            }
540        }
541        Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) => {
542            for string_literal in value.iter_mut() {
543                visitor.visit_string_literal(string_literal);
544            }
545        }
546        Expr::BytesLiteral(ast::ExprBytesLiteral { value, .. }) => {
547            for bytes_literal in value.iter_mut() {
548                visitor.visit_bytes_literal(bytes_literal);
549            }
550        }
551        Expr::NumberLiteral(_)
552        | Expr::BooleanLiteral(_)
553        | Expr::NoneLiteral(_)
554        | Expr::EllipsisLiteral(_) => {}
555        Expr::Attribute(ast::ExprAttribute { value, ctx, .. }) => {
556            visitor.visit_expr(value);
557            visitor.visit_expr_context(ctx);
558        }
559        Expr::Subscript(ast::ExprSubscript {
560            value,
561            slice,
562            ctx,
563            range: _,
564            node_index: _,
565        }) => {
566            visitor.visit_expr(value);
567            visitor.visit_expr(slice);
568            visitor.visit_expr_context(ctx);
569        }
570        Expr::Starred(ast::ExprStarred {
571            value,
572            ctx,
573            range: _,
574            node_index: _,
575        }) => {
576            visitor.visit_expr(value);
577            visitor.visit_expr_context(ctx);
578        }
579        Expr::Name(ast::ExprName { ctx, .. }) => {
580            visitor.visit_expr_context(ctx);
581        }
582        Expr::List(ast::ExprList {
583            elts,
584            ctx,
585            range: _,
586            node_index: _,
587        }) => {
588            for expr in elts {
589                visitor.visit_expr(expr);
590            }
591            visitor.visit_expr_context(ctx);
592        }
593        Expr::Tuple(ast::ExprTuple {
594            elts,
595            ctx,
596            range: _,
597            node_index: _,
598            parenthesized: _,
599        }) => {
600            for expr in elts {
601                visitor.visit_expr(expr);
602            }
603            visitor.visit_expr_context(ctx);
604        }
605        Expr::Slice(ast::ExprSlice {
606            lower,
607            upper,
608            step,
609            range: _,
610            node_index: _,
611        }) => {
612            if let Some(expr) = lower {
613                visitor.visit_expr(expr);
614            }
615            if let Some(expr) = upper {
616                visitor.visit_expr(expr);
617            }
618            if let Some(expr) = step {
619                visitor.visit_expr(expr);
620            }
621        }
622        Expr::IpyEscapeCommand(_) => {}
623    }
624}
625
626pub fn walk_comprehension<V: Transformer + ?Sized>(visitor: &V, comprehension: &mut Comprehension) {
627    visitor.visit_expr(&mut comprehension.iter);
628    visitor.visit_expr(&mut comprehension.target);
629    for expr in &mut comprehension.ifs {
630        visitor.visit_expr(expr);
631    }
632}
633
634pub fn walk_except_handler<V: Transformer + ?Sized>(
635    visitor: &V,
636    except_handler: &mut ExceptHandler,
637) {
638    match except_handler {
639        ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { type_, body, .. }) => {
640            if let Some(expr) = type_ {
641                visitor.visit_expr(expr);
642            }
643            visitor.visit_body(body);
644        }
645    }
646}
647
648pub fn walk_arguments<V: Transformer + ?Sized>(visitor: &V, arguments: &mut Arguments) {
649    // Note that there might be keywords before the last arg, e.g. in
650    // f(*args, a=2, *args2, **kwargs)`, but we follow Python in evaluating first `args` and then
651    // `keywords`. See also [Arguments::arguments_source_order`].
652    for arg in &mut *arguments.args {
653        visitor.visit_expr(arg);
654    }
655    for keyword in &mut *arguments.keywords {
656        visitor.visit_keyword(keyword);
657    }
658}
659
660pub fn walk_parameters<V: Transformer + ?Sized>(visitor: &V, parameters: &mut Parameters) {
661    // Defaults are evaluated before annotations.
662    for arg in &mut parameters.posonlyargs {
663        if let Some(default) = &mut arg.default {
664            visitor.visit_expr(default);
665        }
666    }
667    for arg in &mut parameters.args {
668        if let Some(default) = &mut arg.default {
669            visitor.visit_expr(default);
670        }
671    }
672    for arg in &mut parameters.kwonlyargs {
673        if let Some(default) = &mut arg.default {
674            visitor.visit_expr(default);
675        }
676    }
677
678    for arg in &mut parameters.posonlyargs {
679        visitor.visit_parameter(&mut arg.parameter);
680    }
681    for arg in &mut parameters.args {
682        visitor.visit_parameter(&mut arg.parameter);
683    }
684    if let Some(arg) = &mut parameters.vararg {
685        visitor.visit_parameter(arg);
686    }
687    for arg in &mut parameters.kwonlyargs {
688        visitor.visit_parameter(&mut arg.parameter);
689    }
690    if let Some(arg) = &mut parameters.kwarg {
691        visitor.visit_parameter(arg);
692    }
693}
694
695pub fn walk_parameter<V: Transformer + ?Sized>(visitor: &V, parameter: &mut Parameter) {
696    if let Some(expr) = &mut parameter.annotation {
697        visitor.visit_annotation(expr);
698    }
699}
700
701pub fn walk_keyword<V: Transformer + ?Sized>(visitor: &V, keyword: &mut Keyword) {
702    visitor.visit_expr(&mut keyword.value);
703}
704
705pub fn walk_with_item<V: Transformer + ?Sized>(visitor: &V, with_item: &mut WithItem) {
706    visitor.visit_expr(&mut with_item.context_expr);
707    if let Some(expr) = &mut with_item.optional_vars {
708        visitor.visit_expr(expr);
709    }
710}
711
712pub fn walk_type_params<V: Transformer + ?Sized>(visitor: &V, type_params: &mut TypeParams) {
713    for type_param in &mut type_params.type_params {
714        visitor.visit_type_param(type_param);
715    }
716}
717
718pub fn walk_type_param<V: Transformer + ?Sized>(visitor: &V, type_param: &mut TypeParam) {
719    match type_param {
720        TypeParam::TypeVar(TypeParamTypeVar {
721            bound,
722            default,
723            name: _,
724            range: _,
725            node_index: _,
726        }) => {
727            if let Some(expr) = bound {
728                visitor.visit_expr(expr);
729            }
730            if let Some(expr) = default {
731                visitor.visit_expr(expr);
732            }
733        }
734        TypeParam::TypeVarTuple(TypeParamTypeVarTuple {
735            default,
736            name: _,
737            range: _,
738            node_index: _,
739        }) => {
740            if let Some(expr) = default {
741                visitor.visit_expr(expr);
742            }
743        }
744        TypeParam::ParamSpec(TypeParamParamSpec {
745            default,
746            name: _,
747            range: _,
748            node_index: _,
749        }) => {
750            if let Some(expr) = default {
751                visitor.visit_expr(expr);
752            }
753        }
754    }
755}
756
757pub fn walk_match_case<V: Transformer + ?Sized>(visitor: &V, match_case: &mut MatchCase) {
758    visitor.visit_pattern(&mut match_case.pattern);
759    if let Some(expr) = &mut match_case.guard {
760        visitor.visit_expr(expr);
761    }
762    visitor.visit_body(&mut match_case.body);
763}
764
765pub fn walk_pattern<V: Transformer + ?Sized>(visitor: &V, pattern: &mut Pattern) {
766    match pattern {
767        Pattern::MatchValue(ast::PatternMatchValue { value, .. }) => {
768            visitor.visit_expr(value);
769        }
770        Pattern::MatchSingleton(_) => {}
771        Pattern::MatchSequence(ast::PatternMatchSequence { patterns, .. }) => {
772            for pattern in patterns {
773                visitor.visit_pattern(pattern);
774            }
775        }
776        Pattern::MatchMapping(ast::PatternMatchMapping { keys, patterns, .. }) => {
777            for expr in keys {
778                visitor.visit_expr(expr);
779            }
780            for pattern in patterns {
781                visitor.visit_pattern(pattern);
782            }
783        }
784        Pattern::MatchClass(ast::PatternMatchClass { cls, arguments, .. }) => {
785            visitor.visit_expr(cls);
786            visitor.visit_pattern_arguments(arguments);
787        }
788        Pattern::MatchStar(_) => {}
789        Pattern::MatchAs(ast::PatternMatchAs { pattern, .. }) => {
790            if let Some(pattern) = pattern {
791                visitor.visit_pattern(pattern);
792            }
793        }
794        Pattern::MatchOr(ast::PatternMatchOr { patterns, .. }) => {
795            for pattern in patterns {
796                visitor.visit_pattern(pattern);
797            }
798        }
799    }
800}
801
802pub fn walk_pattern_arguments<V: Transformer + ?Sized>(
803    visitor: &V,
804    pattern_arguments: &mut PatternArguments,
805) {
806    for pattern in &mut pattern_arguments.patterns {
807        visitor.visit_pattern(pattern);
808    }
809    for keyword in &mut pattern_arguments.keywords {
810        visitor.visit_pattern_keyword(keyword);
811    }
812}
813
814pub fn walk_pattern_keyword<V: Transformer + ?Sized>(
815    visitor: &V,
816    pattern_keyword: &mut PatternKeyword,
817) {
818    visitor.visit_pattern(&mut pattern_keyword.pattern);
819}
820
821pub fn walk_f_string<V: Transformer + ?Sized>(visitor: &V, f_string: &mut FString) {
822    for element in &mut f_string.elements {
823        visitor.visit_interpolated_string_element(element);
824    }
825}
826
827pub fn walk_interpolated_string_element<V: Transformer + ?Sized>(
828    visitor: &V,
829    interpolated_string_element: &mut InterpolatedStringElement,
830) {
831    if let ast::InterpolatedStringElement::Interpolation(ast::InterpolatedElement {
832        expression,
833        format_spec,
834        ..
835    }) = interpolated_string_element
836    {
837        visitor.visit_expr(expression);
838        if let Some(format_spec) = format_spec {
839            for spec_element in &mut format_spec.elements {
840                visitor.visit_interpolated_string_element(spec_element);
841            }
842        }
843    }
844}
845
846pub fn walk_t_string<V: Transformer + ?Sized>(visitor: &V, t_string: &mut TString) {
847    for element in &mut t_string.elements {
848        visitor.visit_interpolated_string_element(element);
849    }
850}
851
852pub fn walk_expr_context<V: Transformer + ?Sized>(_visitor: &V, _expr_context: &mut ExprContext) {}
853
854pub fn walk_bool_op<V: Transformer + ?Sized>(_visitor: &V, _bool_op: &mut BoolOp) {}
855
856pub fn walk_operator<V: Transformer + ?Sized>(_visitor: &V, _operator: &mut Operator) {}
857
858pub fn walk_unary_op<V: Transformer + ?Sized>(_visitor: &V, _unary_op: &mut UnaryOp) {}
859
860pub fn walk_cmp_op<V: Transformer + ?Sized>(_visitor: &V, _cmp_op: &mut CmpOp) {}
861
862pub fn walk_alias<V: Transformer + ?Sized>(_visitor: &V, _alias: &mut Alias) {}
863
864pub fn walk_string_literal<V: Transformer + ?Sized>(
865    _visitor: &V,
866    _string_literal: &mut StringLiteral,
867) {
868}
869
870pub fn walk_bytes_literal<V: Transformer + ?Sized>(
871    _visitor: &V,
872    _bytes_literal: &mut BytesLiteral,
873) {
874}