1use crate::ast::*;
4use solar_interface::{Ident, Span, Spanned, SpannedOption};
5use solar_macros::declare_visitors;
6use std::ops::ControlFlow;
7
8declare_visitors! {
9 pub trait Visit VisitMut <'ast> {
11 type BreakValue;
16
17 fn visit_source_unit(&mut self, source_unit: &'ast #mut SourceUnit<'ast>) -> ControlFlow<Self::BreakValue> {
18 let SourceUnit { items } = source_unit;
19 for item in items.iter #_mut() {
20 self.visit_item #_mut(item)?;
21 }
22 ControlFlow::Continue(())
23 }
24
25 fn visit_item(&mut self, item: &'ast #mut Item<'ast>) -> ControlFlow<Self::BreakValue> {
26 let Item { docs, span, kind } = item;
27 self.visit_span #_mut(span)?;
28 self.visit_doc_comments #_mut(docs)?;
29 match kind {
30 ItemKind::Pragma(item) => self.visit_pragma_directive #_mut(item)?,
31 ItemKind::Import(item) => self.visit_import_directive #_mut(item)?,
32 ItemKind::Using(item) => self.visit_using_directive #_mut(item)?,
33 ItemKind::Contract(item) => self.visit_item_contract #_mut(item)?,
34 ItemKind::Function(item) => self.visit_item_function #_mut(item)?,
35 ItemKind::Variable(item) => self.visit_variable_definition #_mut(item)?,
36 ItemKind::Struct(item) => self.visit_item_struct #_mut(item)?,
37 ItemKind::Enum(item) => self.visit_item_enum #_mut(item)?,
38 ItemKind::Udvt(item) => self.visit_item_udvt #_mut(item)?,
39 ItemKind::Error(item) => self.visit_item_error #_mut(item)?,
40 ItemKind::Event(item) => self.visit_item_event #_mut(item)?,
41 }
42 ControlFlow::Continue(())
43 }
44
45 fn visit_pragma_directive(&mut self, pragma: &'ast #mut PragmaDirective<'ast>) -> ControlFlow<Self::BreakValue> {
46 let PragmaDirective { tokens: _ } = pragma;
48 ControlFlow::Continue(())
49 }
50
51 fn visit_import_directive(&mut self, import: &'ast #mut ImportDirective<'ast>) -> ControlFlow<Self::BreakValue> {
52 let ImportDirective { path, items } = import;
53 let _ = path; match items {
55 ImportItems::Plain(alias) => {
56 if let Some(alias) = alias {
57 self.visit_ident #_mut(alias)?;
58 }
59 }
60 ImportItems::Aliases(paths) => {
61 for (import, alias) in paths.iter #_mut() {
62 self.visit_ident #_mut(import)?;
63 if let Some(alias) = alias {
64 self.visit_ident #_mut(alias)?;
65 }
66 }
67 }
68 ImportItems::Glob(alias) => {
69 self.visit_ident #_mut(alias)?;
70 }
71 }
72 ControlFlow::Continue(())
73 }
74
75 fn visit_using_directive(&mut self, using: &'ast #mut UsingDirective<'ast>) -> ControlFlow<Self::BreakValue> {
76 let UsingDirective { list, ty, global: _ } = using;
77 match list {
78 UsingList::Single(path) => {
79 self.visit_path #_mut(path)?;
80 }
81 UsingList::Multiple(paths) => {
82 for (path, _) in paths.iter #_mut() {
83 self.visit_path #_mut(path)?;
84 }
85 }
86 }
87 if let Some(ty) = ty {
88 self.visit_ty #_mut(ty)?;
89 }
90 ControlFlow::Continue(())
91 }
92
93 fn visit_item_contract(&mut self, contract: &'ast #mut ItemContract<'ast>) -> ControlFlow<Self::BreakValue> {
94 let ItemContract { kind: _, name, layout, bases, body } = contract;
95 self.visit_ident #_mut(name)?;
96 if let Some(StorageLayoutSpecifier { span, slot }) = layout {
97 self.visit_span #_mut(span)?;
98 self.visit_expr #_mut(slot)?;
99 }
100 for base in bases.iter #_mut() {
101 self.visit_modifier #_mut(base)?;
102 }
103 for item in body.iter #_mut() {
104 self.visit_item #_mut(item)?;
105 }
106 ControlFlow::Continue(())
107 }
108
109 fn visit_item_function(&mut self, function: &'ast #mut ItemFunction<'ast>) -> ControlFlow<Self::BreakValue> {
110 let ItemFunction { kind: _, header, body, body_span } = function;
111 self.visit_function_header #_mut(header)?;
112 if let Some(body) = body {
113 self.visit_block #_mut(body)?;
114 }
115 self.visit_span #_mut(body_span)?;
116 ControlFlow::Continue(())
117 }
118
119 fn visit_item_struct(&mut self, strukt: &'ast #mut ItemStruct<'ast>) -> ControlFlow<Self::BreakValue> {
120 let ItemStruct { name, fields } = strukt;
121 self.visit_ident #_mut(name)?;
122 for field in fields.iter #_mut() {
123 self.visit_variable_definition #_mut(field)?;
124 }
125 ControlFlow::Continue(())
126 }
127
128 fn visit_item_enum(&mut self, enum_: &'ast #mut ItemEnum<'ast>) -> ControlFlow<Self::BreakValue> {
129 let ItemEnum { name, variants } = enum_;
130 self.visit_ident #_mut(name)?;
131 for variant in variants.iter #_mut() {
132 self.visit_ident #_mut(variant)?;
133 }
134 ControlFlow::Continue(())
135 }
136
137 fn visit_item_udvt(&mut self, udvt: &'ast #mut ItemUdvt<'ast>) -> ControlFlow<Self::BreakValue> {
138 let ItemUdvt { name, ty } = udvt;
139 self.visit_ident #_mut(name)?;
140 self.visit_ty #_mut(ty)?;
141 ControlFlow::Continue(())
142 }
143
144 fn visit_item_error(&mut self, error: &'ast #mut ItemError<'ast>) -> ControlFlow<Self::BreakValue> {
145 let ItemError { name, parameters } = error;
146 self.visit_ident #_mut(name)?;
147 self.visit_parameter_list #_mut(parameters)?;
148 ControlFlow::Continue(())
149 }
150
151 fn visit_item_event(&mut self, event: &'ast #mut ItemEvent<'ast>) -> ControlFlow<Self::BreakValue> {
152 let ItemEvent { name, parameters, anonymous: _ } = event;
153 self.visit_ident #_mut(name)?;
154 self.visit_parameter_list #_mut(parameters)?;
155 ControlFlow::Continue(())
156 }
157
158 fn visit_variable_definition(&mut self, var: &'ast #mut VariableDefinition<'ast>) -> ControlFlow<Self::BreakValue> {
159 let VariableDefinition {
160 span,
161 ty,
162 visibility: _,
163 mutability: _,
164 data_location: _,
165 override_: _,
166 indexed: _,
167 name,
168 initializer,
169 } = var;
170 self.visit_span #_mut(span)?;
171 self.visit_ty #_mut(ty)?;
172 if let Some(name) = name {
173 self.visit_ident #_mut(name)?;
174 }
175 if let Some(initializer) = initializer {
176 self.visit_expr #_mut(initializer)?;
177 }
178 ControlFlow::Continue(())
179 }
180
181 fn visit_ty(&mut self, ty: &'ast #mut Type<'ast>) -> ControlFlow<Self::BreakValue> {
182 let Type { span, kind } = ty;
183 self.visit_span #_mut(span)?;
184 match kind {
185 TypeKind::Elementary(_) => {}
186 TypeKind::Array(array) => {
187 let TypeArray { element, size } = &#mut **array;
188 self.visit_ty #_mut(element)?;
189 if let Some(size) = size {
190 self.visit_expr #_mut(size)?;
191 }
192 }
193 TypeKind::Function(function) => {
194 let TypeFunction { parameters, visibility: _, state_mutability: _, returns } = &#mut **function;
195 self.visit_parameter_list #_mut(parameters)?;
196 if let Some(returns) = returns {
197 self.visit_parameter_list #_mut(returns)?;
198 }
199 }
200 TypeKind::Mapping(mapping) => {
201 let TypeMapping { key, key_name, value, value_name } = &#mut **mapping;
202 self.visit_ty #_mut(key)?;
203 if let Some(key_name) = key_name {
204 self.visit_ident #_mut(key_name)?;
205 }
206 self.visit_ty #_mut(value)?;
207 if let Some(value_name) = value_name {
208 self.visit_ident #_mut(value_name)?;
209 }
210 }
211 TypeKind::Custom(path) => {
212 self.visit_path #_mut(path)?;
213 }
214 }
215 ControlFlow::Continue(())
216 }
217
218 fn visit_function_header(&mut self, header: &'ast #mut FunctionHeader<'ast>) -> ControlFlow<Self::BreakValue> {
219 let FunctionHeader {
220 span,
221 name,
222 parameters,
223 visibility,
224 state_mutability,
225 modifiers,
226 virtual_: _,
227 override_,
228 returns,
229 } = header;
230 self.visit_span #_mut(span)?;
231 if let Some(name) = name {
232 self.visit_ident #_mut(name)?;
233 }
234 self.visit_parameter_list #_mut(parameters)?;
235 if let Some(vis) = visibility {
236 let Spanned { span: vis_span, .. } = vis;
237 self.visit_span #_mut(vis_span)?;
238 }
239 if let Some(state_mut) = state_mutability {
240 let Spanned { span: state_mut_span, .. } = state_mut;
241 self.visit_span #_mut(state_mut_span)?;
242 }
243 for modifier in modifiers.iter #_mut() {
244 self.visit_modifier #_mut(modifier)?;
245 }
246 if let Some(returns) = returns {
247 self.visit_parameter_list #_mut(returns)?;
248 }
249 if let Some(override_) = override_ {
250 self.visit_override #_mut(override_)?;
251 }
252 ControlFlow::Continue(())
253 }
254
255 fn visit_modifier(&mut self, modifier: &'ast #mut Modifier<'ast>) -> ControlFlow<Self::BreakValue> {
256 let Modifier { name, arguments } = modifier;
257 self.visit_path #_mut(name)?;
258 self.visit_call_args #_mut(arguments)?;
259 ControlFlow::Continue(())
260 }
261
262 fn visit_override(&mut self, override_: &'ast #mut Override<'ast>) -> ControlFlow<Self::BreakValue> {
263 let Override { span, paths } = override_;
264 self.visit_span #_mut(span)?;
265 for path in paths.iter #_mut() {
266 self.visit_path #_mut(path)?;
267 }
268 ControlFlow::Continue(())
269 }
270
271 fn visit_call_args(&mut self, args: &'ast #mut CallArgs<'ast>) -> ControlFlow<Self::BreakValue> {
272 let CallArgs { span, kind } = args;
273 self.visit_span #_mut(span)?;
274 match kind {
275 CallArgsKind::Named(named) => {
276 self.visit_named_args #_mut(named)?;
277 }
278 CallArgsKind::Unnamed(unnamed) => {
279 for arg in unnamed.iter #_mut() {
280 self.visit_expr #_mut(arg)?;
281 }
282 }
283 }
284 ControlFlow::Continue(())
285 }
286
287 fn visit_named_args(&mut self, args: &'ast #mut NamedArgList<'ast>) -> ControlFlow<Self::BreakValue> {
288 for NamedArg { name, value } in args.iter #_mut() {
289 self.visit_ident #_mut(name)?;
290 self.visit_expr #_mut(value)?;
291 }
292 ControlFlow::Continue(())
293 }
294
295 fn visit_stmt(&mut self, stmt: &'ast #mut Stmt<'ast>) -> ControlFlow<Self::BreakValue> {
296 let Stmt { docs, span, kind } = stmt;
297 self.visit_doc_comments #_mut(docs)?;
298 self.visit_span #_mut(span)?;
299 match kind {
300 StmtKind::Assembly(assembly) => {
301 self.visit_stmt_assembly #_mut(assembly)?;
302 }
303 StmtKind::DeclSingle(var) => {
304 self.visit_variable_definition #_mut(var)?;
305 }
306 StmtKind::DeclMulti(vars, expr) => {
307 for spanned_var in vars.iter #_mut() {
308 match spanned_var {
309 SpannedOption::Some(var) => self.visit_variable_definition #_mut(var)?,
310 SpannedOption::None(span) => self.visit_span #_mut(span)?,
311 }
312 }
313 self.visit_expr #_mut(expr)?;
314 }
315 StmtKind::Block(block) => {
316 self.visit_block #_mut(block)?;
317 }
318 StmtKind::Break => {}
319 StmtKind::Continue => {}
320 StmtKind::DoWhile(stmt, expr) => {
321 self.visit_stmt #_mut(stmt)?;
322 self.visit_expr #_mut(expr)?;
323 }
324 StmtKind::Emit(path, args) => {
325 self.visit_path #_mut(path)?;
326 self.visit_call_args #_mut(args)?;
327 }
328 StmtKind::Expr(expr) => {
329 self.visit_expr #_mut(expr)?;
330 }
331 StmtKind::For { init, cond, next, body } => {
332 if let Some(init) = init {
333 self.visit_stmt #_mut(init)?;
334 }
335 if let Some(cond) = cond {
336 self.visit_expr #_mut(cond)?;
337 }
338 if let Some(next) = next {
339 self.visit_expr #_mut(next)?;
340 }
341 self.visit_stmt #_mut(body)?;
342 }
343 StmtKind::If(cond, then, else_) => {
344 self.visit_expr #_mut(cond)?;
345 self.visit_stmt #_mut(then)?;
346 if let Some(else_) = else_ {
347 self.visit_stmt #_mut(else_)?;
348 }
349 }
350 StmtKind::Return(expr) => {
351 if let Some(expr) = expr {
352 self.visit_expr #_mut(expr)?;
353 }
354 }
355 StmtKind::Revert(path, args) => {
356 self.visit_path #_mut(path)?;
357 self.visit_call_args #_mut(args)?;
358 }
359 StmtKind::Try(try_) => {
360 self.visit_stmt_try #_mut(try_)?;
361 }
362 StmtKind::UncheckedBlock(block) => {
363 self.visit_block #_mut(block)?;
364 }
365 StmtKind::While(cond, stmt) => {
366 self.visit_expr #_mut(cond)?;
367 self.visit_stmt #_mut(stmt)?;
368 }
369 StmtKind::Placeholder => {}
370 }
371 ControlFlow::Continue(())
372 }
373
374 fn visit_stmt_assembly(&mut self, assembly: &'ast #mut StmtAssembly<'ast>) -> ControlFlow<Self::BreakValue> {
375 let StmtAssembly { dialect: _, flags: _, block } = assembly;
376 self.visit_yul_block #_mut(block)?;
377 ControlFlow::Continue(())
378 }
379
380 fn visit_stmt_try(&mut self, try_: &'ast #mut StmtTry<'ast>) -> ControlFlow<Self::BreakValue> {
381 let StmtTry { expr, clauses } = try_;
382 self.visit_expr #_mut(expr)?;
383 for catch in clauses.iter #_mut() {
384 self.visit_try_catch_clause #_mut(catch)?;
385 }
386 ControlFlow::Continue(())
387 }
388
389 fn visit_try_catch_clause(&mut self, catch: &'ast #mut TryCatchClause<'ast>) -> ControlFlow<Self::BreakValue> {
390 let TryCatchClause { span, name, args, block } = catch;
391 self.visit_span #_mut(span)?;
392 if let Some(name) = name {
393 self.visit_ident #_mut(name)?;
394 }
395 self.visit_parameter_list #_mut(args)?;
396 self.visit_block #_mut(block)?;
397 ControlFlow::Continue(())
398 }
399
400 fn visit_block(&mut self, block: &'ast #mut Block<'ast>) -> ControlFlow<Self::BreakValue> {
401 let Block { span, stmts } = block;
402 self.visit_span #_mut(span)?;
403 for stmt in stmts.iter #_mut() {
404 self.visit_stmt #_mut(stmt)?;
405 }
406 ControlFlow::Continue(())
407 }
408
409 fn visit_expr(&mut self, expr: &'ast #mut Expr<'ast>) -> ControlFlow<Self::BreakValue> {
410 let Expr { span, kind } = expr;
411 self.visit_span #_mut(span)?;
412 match kind {
413 ExprKind::Array(exprs) => {
414 for expr in exprs.iter #_mut() {
415 self.visit_expr #_mut(expr)?;
416 }
417 }
418 ExprKind::Assign(lhs, _op, rhs) => {
419 self.visit_expr #_mut(lhs)?;
420 self.visit_expr #_mut(rhs)?;
421 }
422 ExprKind::Binary(lhs, _op, rhs) => {
423 self.visit_expr #_mut(lhs)?;
424 self.visit_expr #_mut(rhs)?;
425 }
426 ExprKind::Call(lhs, args) => {
427 self.visit_expr #_mut(lhs)?;
428 self.visit_call_args #_mut(args)?;
429 }
430 ExprKind::CallOptions(lhs, args) => {
431 self.visit_expr #_mut(lhs)?;
432 self.visit_named_args #_mut(args)?;
433 }
434 ExprKind::Delete(expr) => {
435 self.visit_expr #_mut(expr)?;
436 }
437 ExprKind::Ident(ident) => {
438 self.visit_ident #_mut(ident)?;
439 }
440 ExprKind::Index(lhs, kind) => {
441 self.visit_expr #_mut(lhs)?;
442 match kind {
443 IndexKind::Index(expr) => {
444 if let Some(expr) = expr {
445 self.visit_expr #_mut(expr)?;
446 }
447 }
448 IndexKind::Range(start, end) => {
449 if let Some(start) = start {
450 self.visit_expr #_mut(start)?;
451 }
452 if let Some(end) = end {
453 self.visit_expr #_mut(end)?;
454 }
455 }
456 }
457 }
458 ExprKind::Lit(lit, _sub) => {
459 self.visit_lit #_mut(lit)?;
460 }
461 ExprKind::Member(expr, member) => {
462 self.visit_expr #_mut(expr)?;
463 self.visit_ident #_mut(member)?;
464 }
465 ExprKind::New(ty) => {
466 self.visit_ty #_mut(ty)?;
467 }
468 ExprKind::Payable(args) => {
469 self.visit_call_args #_mut(args)?;
470 }
471 ExprKind::Ternary(cond, true_, false_) => {
472 self.visit_expr #_mut(cond)?;
473 self.visit_expr #_mut(true_)?;
474 self.visit_expr #_mut(false_)?;
475 }
476 ExprKind::Tuple(exprs) => {
477 for spanned_expr in exprs.iter #_mut() {
478 match spanned_expr {
479 SpannedOption::Some(expr) => self.visit_expr #_mut(expr)?,
480 SpannedOption::None(span) => self.visit_span #_mut(span)?,
481 }
482 }
483 }
484 ExprKind::TypeCall(ty) => {
485 self.visit_ty #_mut(ty)?;
486 }
487 ExprKind::Type(ty) => {
488 self.visit_ty #_mut(ty)?;
489 }
490 ExprKind::Unary(_op, expr) => {
491 self.visit_expr #_mut(expr)?;
492 }
493 }
494 ControlFlow::Continue(())
495 }
496
497 fn visit_parameter_list(&mut self, list: &'ast #mut ParameterList<'ast>) -> ControlFlow<Self::BreakValue> {
498 let ParameterList { span, vars } = list;
499 for param in vars.iter #_mut() {
500 self.visit_variable_definition #_mut(param)?;
501 }
502 self.visit_span #_mut(span)?;
503 ControlFlow::Continue(())
504 }
505
506 fn visit_lit(&mut self, lit: &'ast #mut Lit<'_>) -> ControlFlow<Self::BreakValue> {
507 let Lit { span, symbol: _, kind: _ } = lit;
508 self.visit_span #_mut(span)?;
509 ControlFlow::Continue(())
510 }
511
512 fn visit_yul_stmt(&mut self, stmt: &'ast #mut yul::Stmt<'ast>) -> ControlFlow<Self::BreakValue> {
513 let yul::Stmt { docs, span, kind } = stmt;
514 self.visit_doc_comments #_mut(docs)?;
515 self.visit_span #_mut(span)?;
516 match kind {
517 yul::StmtKind::Block(block) => {
518 self.visit_yul_block #_mut(block)?;
519 }
520 yul::StmtKind::AssignSingle(path, expr) => {
521 self.visit_path #_mut(path)?;
522 self.visit_yul_expr #_mut(expr)?;
523 }
524 yul::StmtKind::AssignMulti(paths, expr) => {
525 for path in paths.iter #_mut() {
526 self.visit_path #_mut(path)?;
527 }
528 self.visit_yul_expr #_mut(expr)?;
529 }
530 yul::StmtKind::Expr(expr) => {
531 self.visit_yul_expr #_mut(expr)?;
532 }
533 yul::StmtKind::If(expr, block) => {
534 self.visit_yul_expr #_mut(expr)?;
535 self.visit_yul_block #_mut(block)?;
536 }
537 yul::StmtKind::For(yul::StmtFor { init, cond, step, body }) => {
538 self.visit_yul_block #_mut(init)?;
539 self.visit_yul_expr #_mut(cond)?;
540 self.visit_yul_block #_mut(step)?;
541 self.visit_yul_block #_mut(body)?;
542 }
543 yul::StmtKind::Switch(switch) => {
544 self.visit_yul_stmt_switch #_mut(switch)?;
545 }
546 yul::StmtKind::Leave => {}
547 yul::StmtKind::Break => {}
548 yul::StmtKind::Continue => {}
549 yul::StmtKind::FunctionDef(function) => {
550 self.visit_yul_function #_mut(function)?;
551 }
552 yul::StmtKind::VarDecl(idents, expr) => {
553 for ident in idents.iter #_mut() {
554 self.visit_ident #_mut(ident)?;
555 }
556 if let Some(expr) = expr {
557 self.visit_yul_expr #_mut(expr)?;
558 }
559 }
560 }
561 ControlFlow::Continue(())
562 }
563
564 fn visit_yul_block(&mut self, block: &'ast #mut yul::Block<'ast>) -> ControlFlow<Self::BreakValue> {
565 let yul::Block { span, stmts } = block;
566 self.visit_span #_mut(span)?;
567 for stmt in stmts.iter #_mut() {
568 self.visit_yul_stmt #_mut(stmt)?;
569 }
570 ControlFlow::Continue(())
571 }
572
573 fn visit_yul_stmt_switch(&mut self, switch: &'ast #mut yul::StmtSwitch<'ast>) -> ControlFlow<Self::BreakValue> {
574 let yul::StmtSwitch { selector, cases } = switch;
575 self.visit_yul_expr #_mut(selector)?;
576 for case in cases.iter #_mut() {
577 self.visit_yul_stmt_case #_mut(case)?;
578 }
579 ControlFlow::Continue(())
580 }
581
582 fn visit_yul_stmt_case(&mut self, case: &'ast #mut yul::StmtSwitchCase<'ast>) -> ControlFlow<Self::BreakValue> {
583 let yul::StmtSwitchCase { span, constant, body } = case;
584 self.visit_span #_mut(span)?;
585 if let Some(constant) = constant {
586 self.visit_lit #_mut(constant)?;
587 }
588 self.visit_yul_block #_mut(body)?;
589 ControlFlow::Continue(())
590 }
591
592 fn visit_yul_function(&mut self, function: &'ast #mut yul::Function<'ast>) -> ControlFlow<Self::BreakValue> {
593 let yul::Function { name, parameters, returns, body } = function;
594 self.visit_ident #_mut(name)?;
595 for ident in parameters.iter #_mut() {
596 self.visit_ident #_mut(ident)?;
597 }
598 for ident in returns.iter #_mut() {
599 self.visit_ident #_mut(ident)?;
600 }
601 self.visit_yul_block #_mut(body)?;
602 ControlFlow::Continue(())
603 }
604
605 fn visit_yul_expr(&mut self, expr: &'ast #mut yul::Expr<'ast>) -> ControlFlow<Self::BreakValue> {
606 let yul::Expr { span, kind } = expr;
607 self.visit_span #_mut(span)?;
608 match kind {
609 yul::ExprKind::Path(path) => {
610 self.visit_path #_mut(path)?;
611 }
612 yul::ExprKind::Call(call) => {
613 self.visit_yul_expr_call #_mut(call)?;
614 }
615 yul::ExprKind::Lit(lit) => {
616 self.visit_lit #_mut(lit)?;
617 }
618 }
619 ControlFlow::Continue(())
620 }
621
622 fn visit_yul_expr_call(&mut self, call: &'ast #mut yul::ExprCall<'ast>) -> ControlFlow<Self::BreakValue> {
623 let yul::ExprCall { name, arguments } = call;
624 self.visit_ident #_mut(name)?;
625 for arg in arguments.iter #_mut() {
626 self.visit_yul_expr #_mut(arg)?;
627 }
628 ControlFlow::Continue(())
629 }
630
631 fn visit_doc_comments(&mut self, doc_comments: &'ast #mut DocComments<'ast>) -> ControlFlow<Self::BreakValue> {
632 for doc_comment in doc_comments.iter #_mut() {
633 self.visit_doc_comment #_mut(doc_comment)?;
634 }
635 ControlFlow::Continue(())
636 }
637
638 fn visit_doc_comment(&mut self, doc_comment: &'ast #mut DocComment) -> ControlFlow<Self::BreakValue> {
639 let DocComment { kind: _, span, symbol: _ } = doc_comment;
640 self.visit_span #_mut(span)?;
641 ControlFlow::Continue(())
642 }
643
644 fn visit_path(&mut self, path: &'ast #mut PathSlice) -> ControlFlow<Self::BreakValue> {
645 for ident in path.segments #_mut() {
646 self.visit_ident #_mut(ident)?;
647 }
648 ControlFlow::Continue(())
649 }
650
651 fn visit_ident(&mut self, ident: &'ast #mut Ident) -> ControlFlow<Self::BreakValue> {
652 let Ident { name: _, span } = ident;
653 self.visit_span #_mut(span)?;
654 ControlFlow::Continue(())
655 }
656
657 fn visit_span(&mut self, span: &'ast #mut Span) -> ControlFlow<Self::BreakValue> {
658 let _ = span;
660 ControlFlow::Continue(())
661 }
662 }
663}