1use crate::ast::*;
4use solar_interface::{Ident, Span, Spanned};
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 var in vars.iter #_mut().flatten() {
308 self.visit_variable_definition #_mut(var)?;
309 }
310 self.visit_expr #_mut(expr)?;
311 }
312 StmtKind::Block(block) => {
313 self.visit_block #_mut(block)?;
314 }
315 StmtKind::Break => {}
316 StmtKind::Continue => {}
317 StmtKind::DoWhile(stmt, expr) => {
318 self.visit_stmt #_mut(stmt)?;
319 self.visit_expr #_mut(expr)?;
320 }
321 StmtKind::Emit(path, args) => {
322 self.visit_path #_mut(path)?;
323 self.visit_call_args #_mut(args)?;
324 }
325 StmtKind::Expr(expr) => {
326 self.visit_expr #_mut(expr)?;
327 }
328 StmtKind::For { init, cond, next, body } => {
329 if let Some(init) = init {
330 self.visit_stmt #_mut(init)?;
331 }
332 if let Some(cond) = cond {
333 self.visit_expr #_mut(cond)?;
334 }
335 if let Some(next) = next {
336 self.visit_expr #_mut(next)?;
337 }
338 self.visit_stmt #_mut(body)?;
339 }
340 StmtKind::If(cond, then, else_) => {
341 self.visit_expr #_mut(cond)?;
342 self.visit_stmt #_mut(then)?;
343 if let Some(else_) = else_ {
344 self.visit_stmt #_mut(else_)?;
345 }
346 }
347 StmtKind::Return(expr) => {
348 if let Some(expr) = expr {
349 self.visit_expr #_mut(expr)?;
350 }
351 }
352 StmtKind::Revert(path, args) => {
353 self.visit_path #_mut(path)?;
354 self.visit_call_args #_mut(args)?;
355 }
356 StmtKind::Try(try_) => {
357 self.visit_stmt_try #_mut(try_)?;
358 }
359 StmtKind::UncheckedBlock(block) => {
360 self.visit_block #_mut(block)?;
361 }
362 StmtKind::While(cond, stmt) => {
363 self.visit_expr #_mut(cond)?;
364 self.visit_stmt #_mut(stmt)?;
365 }
366 StmtKind::Placeholder => {}
367 }
368 ControlFlow::Continue(())
369 }
370
371 fn visit_stmt_assembly(&mut self, assembly: &'ast #mut StmtAssembly<'ast>) -> ControlFlow<Self::BreakValue> {
372 let StmtAssembly { dialect: _, flags: _, block } = assembly;
373 self.visit_yul_block #_mut(block)?;
374 ControlFlow::Continue(())
375 }
376
377 fn visit_stmt_try(&mut self, try_: &'ast #mut StmtTry<'ast>) -> ControlFlow<Self::BreakValue> {
378 let StmtTry { expr, clauses } = try_;
379 self.visit_expr #_mut(expr)?;
380 for catch in clauses.iter #_mut() {
381 self.visit_try_catch_clause #_mut(catch)?;
382 }
383 ControlFlow::Continue(())
384 }
385
386 fn visit_try_catch_clause(&mut self, catch: &'ast #mut TryCatchClause<'ast>) -> ControlFlow<Self::BreakValue> {
387 let TryCatchClause { span, name, args, block } = catch;
388 self.visit_span #_mut(span)?;
389 if let Some(name) = name {
390 self.visit_ident #_mut(name)?;
391 }
392 self.visit_parameter_list #_mut(args)?;
393 self.visit_block #_mut(block)?;
394 ControlFlow::Continue(())
395 }
396
397 fn visit_block(&mut self, block: &'ast #mut Block<'ast>) -> ControlFlow<Self::BreakValue> {
398 let Block { span, stmts } = block;
399 self.visit_span #_mut(span)?;
400 for stmt in stmts.iter #_mut() {
401 self.visit_stmt #_mut(stmt)?;
402 }
403 ControlFlow::Continue(())
404 }
405
406 fn visit_expr(&mut self, expr: &'ast #mut Expr<'ast>) -> ControlFlow<Self::BreakValue> {
407 let Expr { span, kind } = expr;
408 self.visit_span #_mut(span)?;
409 match kind {
410 ExprKind::Array(exprs) => {
411 for expr in exprs.iter #_mut() {
412 self.visit_expr #_mut(expr)?;
413 }
414 }
415 ExprKind::Assign(lhs, _op, rhs) => {
416 self.visit_expr #_mut(lhs)?;
417 self.visit_expr #_mut(rhs)?;
418 }
419 ExprKind::Binary(lhs, _op, rhs) => {
420 self.visit_expr #_mut(lhs)?;
421 self.visit_expr #_mut(rhs)?;
422 }
423 ExprKind::Call(lhs, args) => {
424 self.visit_expr #_mut(lhs)?;
425 self.visit_call_args #_mut(args)?;
426 }
427 ExprKind::CallOptions(lhs, args) => {
428 self.visit_expr #_mut(lhs)?;
429 self.visit_named_args #_mut(args)?;
430 }
431 ExprKind::Delete(expr) => {
432 self.visit_expr #_mut(expr)?;
433 }
434 ExprKind::Ident(ident) => {
435 self.visit_ident #_mut(ident)?;
436 }
437 ExprKind::Index(lhs, kind) => {
438 self.visit_expr #_mut(lhs)?;
439 match kind {
440 IndexKind::Index(expr) => {
441 if let Some(expr) = expr {
442 self.visit_expr #_mut(expr)?;
443 }
444 }
445 IndexKind::Range(start, end) => {
446 if let Some(start) = start {
447 self.visit_expr #_mut(start)?;
448 }
449 if let Some(end) = end {
450 self.visit_expr #_mut(end)?;
451 }
452 }
453 }
454 }
455 ExprKind::Lit(lit, _sub) => {
456 self.visit_lit #_mut(lit)?;
457 }
458 ExprKind::Member(expr, member) => {
459 self.visit_expr #_mut(expr)?;
460 self.visit_ident #_mut(member)?;
461 }
462 ExprKind::New(ty) => {
463 self.visit_ty #_mut(ty)?;
464 }
465 ExprKind::Payable(args) => {
466 self.visit_call_args #_mut(args)?;
467 }
468 ExprKind::Ternary(cond, true_, false_) => {
469 self.visit_expr #_mut(cond)?;
470 self.visit_expr #_mut(true_)?;
471 self.visit_expr #_mut(false_)?;
472 }
473 ExprKind::Tuple(exprs) => {
474 for expr in exprs.iter #_mut().flatten() {
475 self.visit_expr #_mut(expr)?;
476 }
477 }
478 ExprKind::TypeCall(ty) => {
479 self.visit_ty #_mut(ty)?;
480 }
481 ExprKind::Type(ty) => {
482 self.visit_ty #_mut(ty)?;
483 }
484 ExprKind::Unary(_op, expr) => {
485 self.visit_expr #_mut(expr)?;
486 }
487 }
488 ControlFlow::Continue(())
489 }
490
491 fn visit_parameter_list(&mut self, list: &'ast #mut ParameterList<'ast>) -> ControlFlow<Self::BreakValue> {
492 let ParameterList { span, vars } = list;
493 for param in vars.iter #_mut() {
494 self.visit_variable_definition #_mut(param)?;
495 }
496 self.visit_span #_mut(span)?;
497 ControlFlow::Continue(())
498 }
499
500 fn visit_lit(&mut self, lit: &'ast #mut Lit<'_>) -> ControlFlow<Self::BreakValue> {
501 let Lit { span, symbol: _, kind: _ } = lit;
502 self.visit_span #_mut(span)?;
503 ControlFlow::Continue(())
504 }
505
506 fn visit_yul_stmt(&mut self, stmt: &'ast #mut yul::Stmt<'ast>) -> ControlFlow<Self::BreakValue> {
507 let yul::Stmt { docs, span, kind } = stmt;
508 self.visit_doc_comments #_mut(docs)?;
509 self.visit_span #_mut(span)?;
510 match kind {
511 yul::StmtKind::Block(block) => {
512 self.visit_yul_block #_mut(block)?;
513 }
514 yul::StmtKind::AssignSingle(path, expr) => {
515 self.visit_path #_mut(path)?;
516 self.visit_yul_expr #_mut(expr)?;
517 }
518 yul::StmtKind::AssignMulti(paths, call) => {
519 for path in paths.iter #_mut() {
520 self.visit_path #_mut(path)?;
521 }
522 self.visit_yul_expr_call #_mut(call)?;
523 }
524 yul::StmtKind::Expr(call) => {
525 self.visit_yul_expr_call #_mut(call)?;
526 }
527 yul::StmtKind::If(expr, block) => {
528 self.visit_yul_expr #_mut(expr)?;
529 self.visit_yul_block #_mut(block)?;
530 }
531 yul::StmtKind::For { init, cond, step, body } => {
532 self.visit_yul_block #_mut(init)?;
533 self.visit_yul_expr #_mut(cond)?;
534 self.visit_yul_block #_mut(step)?;
535 self.visit_yul_block #_mut(body)?;
536 }
537 yul::StmtKind::Switch(switch) => {
538 self.visit_yul_stmt_switch #_mut(switch)?;
539 }
540 yul::StmtKind::Leave => {}
541 yul::StmtKind::Break => {}
542 yul::StmtKind::Continue => {}
543 yul::StmtKind::FunctionDef(function) => {
544 self.visit_yul_function #_mut(function)?;
545 }
546 yul::StmtKind::VarDecl(idents, expr) => {
547 for ident in idents.iter #_mut() {
548 self.visit_ident #_mut(ident)?;
549 }
550 if let Some(expr) = expr {
551 self.visit_yul_expr #_mut(expr)?;
552 }
553 }
554 }
555 ControlFlow::Continue(())
556 }
557
558 fn visit_yul_block(&mut self, block: &'ast #mut yul::Block<'ast>) -> ControlFlow<Self::BreakValue> {
559 let yul::Block { span, stmts } = block;
560 self.visit_span #_mut(span)?;
561 for stmt in stmts.iter #_mut() {
562 self.visit_yul_stmt #_mut(stmt)?;
563 }
564 ControlFlow::Continue(())
565 }
566
567 fn visit_yul_stmt_switch(&mut self, switch: &'ast #mut yul::StmtSwitch<'ast>) -> ControlFlow<Self::BreakValue> {
568 let yul::StmtSwitch { selector, cases } = switch;
569 self.visit_yul_expr #_mut(selector)?;
570 for case in cases.iter #_mut() {
571 self.visit_yul_stmt_case #_mut(case)?;
572 }
573 ControlFlow::Continue(())
574 }
575
576 fn visit_yul_stmt_case(&mut self, case: &'ast #mut yul::StmtSwitchCase<'ast>) -> ControlFlow<Self::BreakValue> {
577 let yul::StmtSwitchCase { span, constant, body } = case;
578 self.visit_span #_mut(span)?;
579 if let Some(constant) = constant {
580 self.visit_lit #_mut(constant)?;
581 }
582 self.visit_yul_block #_mut(body)?;
583 ControlFlow::Continue(())
584 }
585
586 fn visit_yul_function(&mut self, function: &'ast #mut yul::Function<'ast>) -> ControlFlow<Self::BreakValue> {
587 let yul::Function { name, parameters, returns, body } = function;
588 self.visit_ident #_mut(name)?;
589 for ident in parameters.iter #_mut() {
590 self.visit_ident #_mut(ident)?;
591 }
592 for ident in returns.iter #_mut() {
593 self.visit_ident #_mut(ident)?;
594 }
595 self.visit_yul_block #_mut(body)?;
596 ControlFlow::Continue(())
597 }
598
599 fn visit_yul_expr(&mut self, expr: &'ast #mut yul::Expr<'ast>) -> ControlFlow<Self::BreakValue> {
600 let yul::Expr { span, kind } = expr;
601 self.visit_span #_mut(span)?;
602 match kind {
603 yul::ExprKind::Path(path) => {
604 self.visit_path #_mut(path)?;
605 }
606 yul::ExprKind::Call(call) => {
607 self.visit_yul_expr_call #_mut(call)?;
608 }
609 yul::ExprKind::Lit(lit) => {
610 self.visit_lit #_mut(lit)?;
611 }
612 }
613 ControlFlow::Continue(())
614 }
615
616 fn visit_yul_expr_call(&mut self, call: &'ast #mut yul::ExprCall<'ast>) -> ControlFlow<Self::BreakValue> {
617 let yul::ExprCall { name, arguments } = call;
618 self.visit_ident #_mut(name)?;
619 for arg in arguments.iter #_mut() {
620 self.visit_yul_expr #_mut(arg)?;
621 }
622 ControlFlow::Continue(())
623 }
624
625 fn visit_doc_comments(&mut self, doc_comments: &'ast #mut DocComments<'ast>) -> ControlFlow<Self::BreakValue> {
626 for doc_comment in doc_comments.iter #_mut() {
627 self.visit_doc_comment #_mut(doc_comment)?;
628 }
629 ControlFlow::Continue(())
630 }
631
632 fn visit_doc_comment(&mut self, doc_comment: &'ast #mut DocComment) -> ControlFlow<Self::BreakValue> {
633 let DocComment { kind: _, span, symbol: _ } = doc_comment;
634 self.visit_span #_mut(span)?;
635 ControlFlow::Continue(())
636 }
637
638 fn visit_path(&mut self, path: &'ast #mut PathSlice) -> ControlFlow<Self::BreakValue> {
639 for ident in path.segments #_mut() {
640 self.visit_ident #_mut(ident)?;
641 }
642 ControlFlow::Continue(())
643 }
644
645 fn visit_ident(&mut self, ident: &'ast #mut Ident) -> ControlFlow<Self::BreakValue> {
646 let Ident { name: _, span } = ident;
647 self.visit_span #_mut(span)?;
648 ControlFlow::Continue(())
649 }
650
651 fn visit_span(&mut self, span: &'ast #mut Span) -> ControlFlow<Self::BreakValue> {
652 let _ = span;
654 ControlFlow::Continue(())
655 }
656 }
657}