Skip to main content

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 { value, .. }) => {
163            if let Some(expr) = value {
164                visitor.visit_expr(expr);
165            }
166        }
167        Stmt::Delete(ast::StmtDelete { targets, .. }) => {
168            for expr in targets {
169                visitor.visit_expr(expr);
170            }
171        }
172        Stmt::TypeAlias(ast::StmtTypeAlias {
173            range: _,
174            node_index: _,
175            name,
176            type_params,
177            value,
178        }) => {
179            visitor.visit_expr(value);
180            if let Some(type_params) = type_params {
181                visitor.visit_type_params(type_params);
182            }
183            visitor.visit_expr(name);
184        }
185        Stmt::Assign(ast::StmtAssign { targets, value, .. }) => {
186            visitor.visit_expr(value);
187            for expr in targets {
188                visitor.visit_expr(expr);
189            }
190        }
191        Stmt::AugAssign(ast::StmtAugAssign {
192            target, op, value, ..
193        }) => {
194            visitor.visit_expr(value);
195            visitor.visit_operator(op);
196            visitor.visit_expr(target);
197        }
198        Stmt::AnnAssign(ast::StmtAnnAssign {
199            target,
200            annotation,
201            value,
202            ..
203        }) => {
204            if let Some(expr) = value {
205                visitor.visit_expr(expr);
206            }
207            visitor.visit_annotation(annotation);
208            visitor.visit_expr(target);
209        }
210        Stmt::For(ast::StmtFor {
211            target,
212            iter,
213            body,
214            orelse,
215            ..
216        }) => {
217            visitor.visit_expr(iter);
218            visitor.visit_expr(target);
219            visitor.visit_body(body);
220            visitor.visit_body(orelse);
221        }
222        Stmt::While(ast::StmtWhile {
223            test, body, orelse, ..
224        }) => {
225            visitor.visit_expr(test);
226            visitor.visit_body(body);
227            visitor.visit_body(orelse);
228        }
229        Stmt::If(ast::StmtIf {
230            test,
231            body,
232            elif_else_clauses,
233            ..
234        }) => {
235            visitor.visit_expr(test);
236            visitor.visit_body(body);
237            for clause in elif_else_clauses {
238                visitor.visit_elif_else_clause(clause);
239            }
240        }
241        Stmt::With(ast::StmtWith { items, body, .. }) => {
242            for with_item in items {
243                visitor.visit_with_item(with_item);
244            }
245            visitor.visit_body(body);
246        }
247        Stmt::Match(ast::StmtMatch { subject, cases, .. }) => {
248            visitor.visit_expr(subject);
249            for match_case in cases {
250                visitor.visit_match_case(match_case);
251            }
252        }
253        Stmt::Raise(ast::StmtRaise { exc, cause, .. }) => {
254            if let Some(expr) = exc {
255                visitor.visit_expr(expr);
256            }
257            if let Some(expr) = cause {
258                visitor.visit_expr(expr);
259            }
260        }
261        Stmt::Try(ast::StmtTry {
262            body,
263            handlers,
264            orelse,
265            finalbody,
266            ..
267        }) => {
268            visitor.visit_body(body);
269            for except_handler in handlers {
270                visitor.visit_except_handler(except_handler);
271            }
272            visitor.visit_body(orelse);
273            visitor.visit_body(finalbody);
274        }
275        Stmt::Assert(ast::StmtAssert { test, msg, .. }) => {
276            visitor.visit_expr(test);
277            if let Some(expr) = msg {
278                visitor.visit_expr(expr);
279            }
280        }
281        Stmt::Import(ast::StmtImport { names, .. }) => {
282            for alias in names {
283                visitor.visit_alias(alias);
284            }
285        }
286        Stmt::ImportFrom(ast::StmtImportFrom { names, .. }) => {
287            for alias in names {
288                visitor.visit_alias(alias);
289            }
290        }
291        Stmt::Global(_) => {}
292        Stmt::Nonlocal(_) => {}
293        Stmt::Expr(ast::StmtExpr { value, .. }) => visitor.visit_expr(value),
294        Stmt::Pass(_) | Stmt::Break(_) | Stmt::Continue(_) | Stmt::IpyEscapeCommand(_) => {}
295    }
296}
297
298pub fn walk_annotation<V: Transformer + ?Sized>(visitor: &V, expr: &mut Expr) {
299    visitor.visit_expr(expr);
300}
301
302pub fn walk_decorator<V: Transformer + ?Sized>(visitor: &V, decorator: &mut Decorator) {
303    visitor.visit_expr(&mut decorator.expression);
304}
305
306pub fn walk_expr<V: Transformer + ?Sized>(visitor: &V, expr: &mut Expr) {
307    match expr {
308        Expr::BoolOp(ast::ExprBoolOp { op, values, .. }) => {
309            visitor.visit_bool_op(op);
310            for expr in values {
311                visitor.visit_expr(expr);
312            }
313        }
314        Expr::Named(ast::ExprNamed { target, value, .. }) => {
315            visitor.visit_expr(value);
316            visitor.visit_expr(target);
317        }
318        Expr::BinOp(ast::ExprBinOp {
319            left, op, right, ..
320        }) => {
321            visitor.visit_expr(left);
322            visitor.visit_operator(op);
323            visitor.visit_expr(right);
324        }
325        Expr::UnaryOp(ast::ExprUnaryOp { op, operand, .. }) => {
326            visitor.visit_unary_op(op);
327            visitor.visit_expr(operand);
328        }
329        Expr::Lambda(ast::ExprLambda {
330            parameters, body, ..
331        }) => {
332            if let Some(parameters) = parameters {
333                visitor.visit_parameters(parameters);
334            }
335            visitor.visit_expr(body);
336        }
337        Expr::If(ast::ExprIf {
338            test, body, orelse, ..
339        }) => {
340            visitor.visit_expr(test);
341            visitor.visit_expr(body);
342            visitor.visit_expr(orelse);
343        }
344        Expr::Dict(ast::ExprDict { items, .. }) => {
345            for ast::DictItem { key, value } in items {
346                if let Some(key) = key {
347                    visitor.visit_expr(key);
348                }
349                visitor.visit_expr(value);
350            }
351        }
352        Expr::Set(ast::ExprSet { elts, .. }) => {
353            for expr in elts {
354                visitor.visit_expr(expr);
355            }
356        }
357        Expr::ListComp(ast::ExprListComp {
358            elt, generators, ..
359        }) => {
360            for comprehension in generators {
361                visitor.visit_comprehension(comprehension);
362            }
363            visitor.visit_expr(elt);
364        }
365        Expr::SetComp(ast::ExprSetComp {
366            elt, generators, ..
367        }) => {
368            for comprehension in generators {
369                visitor.visit_comprehension(comprehension);
370            }
371            visitor.visit_expr(elt);
372        }
373        Expr::DictComp(ast::ExprDictComp {
374            key,
375            value,
376            generators,
377            ..
378        }) => {
379            for comprehension in generators {
380                visitor.visit_comprehension(comprehension);
381            }
382            if let Some(key) = key {
383                visitor.visit_expr(key);
384            }
385            visitor.visit_expr(value);
386        }
387        Expr::Generator(ast::ExprGenerator {
388            elt, generators, ..
389        }) => {
390            for comprehension in generators {
391                visitor.visit_comprehension(comprehension);
392            }
393            visitor.visit_expr(elt);
394        }
395        Expr::Await(ast::ExprAwait { value, .. }) => visitor.visit_expr(value),
396        Expr::Yield(ast::ExprYield { value, .. }) => {
397            if let Some(expr) = value {
398                visitor.visit_expr(expr);
399            }
400        }
401        Expr::YieldFrom(ast::ExprYieldFrom { value, .. }) => visitor.visit_expr(value),
402        Expr::Compare(ast::ExprCompare {
403            left,
404            ops,
405            comparators,
406            ..
407        }) => {
408            visitor.visit_expr(left);
409            for cmp_op in &mut **ops {
410                visitor.visit_cmp_op(cmp_op);
411            }
412            for expr in &mut **comparators {
413                visitor.visit_expr(expr);
414            }
415        }
416        Expr::Call(ast::ExprCall {
417            func, arguments, ..
418        }) => {
419            visitor.visit_expr(func);
420            visitor.visit_arguments(arguments);
421        }
422        Expr::FString(ast::ExprFString { value, .. }) => {
423            for f_string_part in value.iter_mut() {
424                match f_string_part {
425                    ast::FStringPart::Literal(string_literal) => {
426                        visitor.visit_string_literal(string_literal);
427                    }
428                    ast::FStringPart::FString(f_string) => {
429                        visitor.visit_f_string(f_string);
430                    }
431                }
432            }
433        }
434        Expr::TString(ast::ExprTString { value, .. }) => {
435            for t_string in value.iter_mut() {
436                visitor.visit_t_string(t_string);
437            }
438        }
439        Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) => {
440            for string_literal in value.iter_mut() {
441                visitor.visit_string_literal(string_literal);
442            }
443        }
444        Expr::BytesLiteral(ast::ExprBytesLiteral { value, .. }) => {
445            for bytes_literal in value.iter_mut() {
446                visitor.visit_bytes_literal(bytes_literal);
447            }
448        }
449        Expr::NumberLiteral(_)
450        | Expr::Constant(_)
451        | Expr::BooleanLiteral(_)
452        | Expr::NoneLiteral(_)
453        | Expr::EllipsisLiteral(_) => {}
454        Expr::Attribute(ast::ExprAttribute { value, ctx, .. }) => {
455            visitor.visit_expr(value);
456            visitor.visit_expr_context(ctx);
457        }
458        Expr::Subscript(ast::ExprSubscript {
459            value, slice, ctx, ..
460        }) => {
461            visitor.visit_expr(value);
462            visitor.visit_expr(slice);
463            visitor.visit_expr_context(ctx);
464        }
465        Expr::Starred(ast::ExprStarred { value, ctx, .. }) => {
466            visitor.visit_expr(value);
467            visitor.visit_expr_context(ctx);
468        }
469        Expr::Name(ast::ExprName { ctx, .. }) => {
470            visitor.visit_expr_context(ctx);
471        }
472        Expr::List(ast::ExprList { elts, ctx, .. }) => {
473            for expr in elts {
474                visitor.visit_expr(expr);
475            }
476            visitor.visit_expr_context(ctx);
477        }
478        Expr::Tuple(ast::ExprTuple { elts, ctx, .. }) => {
479            for expr in elts {
480                visitor.visit_expr(expr);
481            }
482            visitor.visit_expr_context(ctx);
483        }
484        Expr::Slice(ast::ExprSlice {
485            lower, upper, step, ..
486        }) => {
487            if let Some(expr) = lower {
488                visitor.visit_expr(expr);
489            }
490            if let Some(expr) = upper {
491                visitor.visit_expr(expr);
492            }
493            if let Some(expr) = step {
494                visitor.visit_expr(expr);
495            }
496        }
497        Expr::IpyEscapeCommand(_) => {}
498    }
499}
500
501pub fn walk_comprehension<V: Transformer + ?Sized>(visitor: &V, comprehension: &mut Comprehension) {
502    visitor.visit_expr(&mut comprehension.iter);
503    visitor.visit_expr(&mut comprehension.target);
504    for expr in &mut comprehension.ifs {
505        visitor.visit_expr(expr);
506    }
507}
508
509pub fn walk_except_handler<V: Transformer + ?Sized>(
510    visitor: &V,
511    except_handler: &mut ExceptHandler,
512) {
513    match except_handler {
514        ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { type_, body, .. }) => {
515            if let Some(expr) = type_ {
516                visitor.visit_expr(expr);
517            }
518            visitor.visit_body(body);
519        }
520    }
521}
522
523pub fn walk_arguments<V: Transformer + ?Sized>(visitor: &V, arguments: &mut Arguments) {
524    // Note that there might be keywords before the last arg, e.g. in
525    // f(*args, a=2, *args2, **kwargs)`, but we follow Python in evaluating first `args` and then
526    // `keywords`. See also [Arguments::arguments_source_order`].
527    for arg in &mut *arguments.args {
528        visitor.visit_expr(arg);
529    }
530    for keyword in &mut *arguments.keywords {
531        visitor.visit_keyword(keyword);
532    }
533}
534
535pub fn walk_parameters<V: Transformer + ?Sized>(visitor: &V, parameters: &mut Parameters) {
536    // Defaults are evaluated before annotations.
537    for arg in &mut parameters.posonlyargs {
538        if let Some(default) = &mut arg.default {
539            visitor.visit_expr(default);
540        }
541    }
542    for arg in &mut parameters.args {
543        if let Some(default) = &mut arg.default {
544            visitor.visit_expr(default);
545        }
546    }
547    for arg in &mut parameters.kwonlyargs {
548        if let Some(default) = &mut arg.default {
549            visitor.visit_expr(default);
550        }
551    }
552
553    for arg in &mut parameters.posonlyargs {
554        visitor.visit_parameter(&mut arg.parameter);
555    }
556    for arg in &mut parameters.args {
557        visitor.visit_parameter(&mut arg.parameter);
558    }
559    if let Some(arg) = &mut parameters.vararg {
560        visitor.visit_parameter(arg);
561    }
562    for arg in &mut parameters.kwonlyargs {
563        visitor.visit_parameter(&mut arg.parameter);
564    }
565    if let Some(arg) = &mut parameters.kwarg {
566        visitor.visit_parameter(arg);
567    }
568}
569
570pub fn walk_parameter<V: Transformer + ?Sized>(visitor: &V, parameter: &mut Parameter) {
571    if let Some(expr) = &mut parameter.annotation {
572        visitor.visit_annotation(expr);
573    }
574}
575
576pub fn walk_keyword<V: Transformer + ?Sized>(visitor: &V, keyword: &mut Keyword) {
577    visitor.visit_expr(&mut keyword.value);
578}
579
580pub fn walk_with_item<V: Transformer + ?Sized>(visitor: &V, with_item: &mut WithItem) {
581    visitor.visit_expr(&mut with_item.context_expr);
582    if let Some(expr) = &mut with_item.optional_vars {
583        visitor.visit_expr(expr);
584    }
585}
586
587pub fn walk_type_params<V: Transformer + ?Sized>(visitor: &V, type_params: &mut TypeParams) {
588    for type_param in &mut type_params.type_params {
589        visitor.visit_type_param(type_param);
590    }
591}
592
593pub fn walk_type_param<V: Transformer + ?Sized>(visitor: &V, type_param: &mut TypeParam) {
594    match type_param {
595        TypeParam::TypeVar(TypeParamTypeVar { bound, default, .. }) => {
596            if let Some(expr) = bound {
597                visitor.visit_expr(expr);
598            }
599            if let Some(expr) = default {
600                visitor.visit_expr(expr);
601            }
602        }
603        TypeParam::TypeVarTuple(TypeParamTypeVarTuple { default, .. }) => {
604            if let Some(expr) = default {
605                visitor.visit_expr(expr);
606            }
607        }
608        TypeParam::ParamSpec(TypeParamParamSpec { default, .. }) => {
609            if let Some(expr) = default {
610                visitor.visit_expr(expr);
611            }
612        }
613    }
614}
615
616pub fn walk_match_case<V: Transformer + ?Sized>(visitor: &V, match_case: &mut MatchCase) {
617    visitor.visit_pattern(&mut match_case.pattern);
618    if let Some(expr) = &mut match_case.guard {
619        visitor.visit_expr(expr);
620    }
621    visitor.visit_body(&mut match_case.body);
622}
623
624pub fn walk_pattern<V: Transformer + ?Sized>(visitor: &V, pattern: &mut Pattern) {
625    match pattern {
626        Pattern::MatchValue(ast::PatternMatchValue { value, .. }) => {
627            visitor.visit_expr(value);
628        }
629        Pattern::MatchSingleton(_) => {}
630        Pattern::MatchSequence(ast::PatternMatchSequence { patterns, .. }) => {
631            for pattern in patterns {
632                visitor.visit_pattern(pattern);
633            }
634        }
635        Pattern::MatchMapping(ast::PatternMatchMapping { keys, patterns, .. }) => {
636            for expr in keys {
637                visitor.visit_expr(expr);
638            }
639            for pattern in patterns {
640                visitor.visit_pattern(pattern);
641            }
642        }
643        Pattern::MatchClass(ast::PatternMatchClass { cls, arguments, .. }) => {
644            visitor.visit_expr(cls);
645            visitor.visit_pattern_arguments(arguments);
646        }
647        Pattern::MatchStar(_) => {}
648        Pattern::MatchAs(ast::PatternMatchAs { pattern, .. }) => {
649            if let Some(pattern) = pattern {
650                visitor.visit_pattern(pattern);
651            }
652        }
653        Pattern::MatchOr(ast::PatternMatchOr { patterns, .. }) => {
654            for pattern in patterns {
655                visitor.visit_pattern(pattern);
656            }
657        }
658    }
659}
660
661pub fn walk_pattern_arguments<V: Transformer + ?Sized>(
662    visitor: &V,
663    pattern_arguments: &mut PatternArguments,
664) {
665    for pattern in &mut pattern_arguments.patterns {
666        visitor.visit_pattern(pattern);
667    }
668    for keyword in &mut pattern_arguments.keywords {
669        visitor.visit_pattern_keyword(keyword);
670    }
671}
672
673pub fn walk_pattern_keyword<V: Transformer + ?Sized>(
674    visitor: &V,
675    pattern_keyword: &mut PatternKeyword,
676) {
677    visitor.visit_pattern(&mut pattern_keyword.pattern);
678}
679
680pub fn walk_f_string<V: Transformer + ?Sized>(visitor: &V, f_string: &mut FString) {
681    for element in &mut f_string.elements {
682        visitor.visit_interpolated_string_element(element);
683    }
684}
685
686pub fn walk_interpolated_string_element<V: Transformer + ?Sized>(
687    visitor: &V,
688    interpolated_string_element: &mut InterpolatedStringElement,
689) {
690    if let ast::InterpolatedStringElement::Interpolation(ast::InterpolatedElement {
691        expression,
692        format_spec,
693        ..
694    }) = interpolated_string_element
695    {
696        visitor.visit_expr(expression);
697        if let Some(format_spec) = format_spec {
698            for spec_element in &mut format_spec.elements {
699                visitor.visit_interpolated_string_element(spec_element);
700            }
701        }
702    }
703}
704
705pub fn walk_t_string<V: Transformer + ?Sized>(visitor: &V, t_string: &mut TString) {
706    for element in &mut t_string.elements {
707        visitor.visit_interpolated_string_element(element);
708    }
709}
710
711pub fn walk_expr_context<V: Transformer + ?Sized>(_visitor: &V, _expr_context: &mut ExprContext) {}
712
713pub fn walk_bool_op<V: Transformer + ?Sized>(_visitor: &V, _bool_op: &mut BoolOp) {}
714
715pub fn walk_operator<V: Transformer + ?Sized>(_visitor: &V, _operator: &mut Operator) {}
716
717pub fn walk_unary_op<V: Transformer + ?Sized>(_visitor: &V, _unary_op: &mut UnaryOp) {}
718
719pub fn walk_cmp_op<V: Transformer + ?Sized>(_visitor: &V, _cmp_op: &mut CmpOp) {}
720
721pub fn walk_alias<V: Transformer + ?Sized>(_visitor: &V, _alias: &mut Alias) {}
722
723pub fn walk_string_literal<V: Transformer + ?Sized>(
724    _visitor: &V,
725    _string_literal: &mut StringLiteral,
726) {
727}
728
729pub fn walk_bytes_literal<V: Transformer + ?Sized>(
730    _visitor: &V,
731    _bytes_literal: &mut BytesLiteral,
732) {
733}