1#[cfg(any(feature = "visit", feature = "visit-mut"))]
2macro_rules! make_visitor {
3 (
4 $(#[$attr:meta])*
5 trait $trait_name:ident $(is $mut:ident)?;
6 ) => {
7 make_visitor! {
8 @impl
9 $(#[$attr])*
10 pub trait $trait_name<'ast> {
11 fn visit_block(&mut v, block: &'ast $($mut)? Block) {
12 for stmt in & $($mut)? block.stmts {
13 v.visit_stmt(stmt);
14 }
15 }
16
17 fn visit_stmt(&mut v, stmt: &'ast $($mut)? Stmt) {
18 match stmt {
19 Stmt::Assembly(asm) => v.visit_stmt_asm(asm),
20 Stmt::Block(block) => v.visit_block(block),
21 Stmt::Break(brk) => v.visit_stmt_break(brk),
22 Stmt::Continue(cont) => v.visit_stmt_continue(cont),
23 Stmt::DoWhile(dowhile) => v.visit_stmt_dowhile(dowhile),
24 Stmt::Emit(emit) => v.visit_stmt_emit(emit),
25 Stmt::Expr(expr) => v.visit_expr(& $($mut)? expr.expr),
26 Stmt::For(f) => v.visit_stmt_for(f),
27 Stmt::If(ifstmt) => v.visit_stmt_if(ifstmt),
28 Stmt::Return(ret) => v.visit_stmt_return(ret),
29 Stmt::Revert(revert) => v.visit_stmt_revert(revert),
30 Stmt::Try(try_stmt) => v.visit_stmt_try(try_stmt),
31 Stmt::UncheckedBlock(ublock) => v.visit_unchecked_block(ublock),
32 Stmt::VarDecl(vard) => v.visit_stmt_var_decl(vard),
33 Stmt::While(w) => v.visit_stmt_while(w),
34 }
35 }
36
37 fn visit_stmt_asm(&mut v, _i: &'ast $($mut)? StmtAssembly) {
38 }
40
41 fn visit_stmt_break(&mut v, _i: &'ast $($mut)? StmtBreak) {
42 }
44
45 fn visit_stmt_continue(&mut v, _i: &'ast $($mut)? StmtContinue) {
46 }
48
49 fn visit_stmt_dowhile(&mut v, stmt_dowhile: &'ast $($mut)? StmtDoWhile) {
50 v.visit_expr(& $($mut)? stmt_dowhile.cond);
51 v.visit_stmt(& $($mut)? stmt_dowhile.body);
52 }
53
54 fn visit_stmt_emit(&mut v, emit: &'ast $($mut)? StmtEmit) {
55 v.visit_expr(& $($mut)? emit.expr);
56 }
57
58 fn visit_stmt_for(&mut v, stmt_for: &'ast $($mut)? StmtFor) {
59 match & $($mut)? stmt_for.init {
60 ForInitStmt::Expr(expr) => v.visit_expr(& $($mut)? expr.expr),
61 ForInitStmt::VarDecl(vard) => v.visit_stmt_var_decl(vard),
62 ForInitStmt::Empty(_) => {}
63 }
64
65 v.visit_stmt(& $($mut)? stmt_for.body);
66 if let Some(cond) = & $($mut)? stmt_for.cond {
67 v.visit_expr(cond);
68 }
69 if let Some(post) = & $($mut)? stmt_for.post {
70 v.visit_expr(post);
71 }
72 }
73
74 fn visit_stmt_if(&mut v, stmt_if: &'ast $($mut)? StmtIf) {
75 v.visit_expr(& $($mut)? stmt_if.cond);
76 v.visit_stmt(& $($mut)? stmt_if.then_branch);
77 if let Some((_, stmt)) = & $($mut)? stmt_if.else_branch {
78 v.visit_stmt(stmt);
79 }
80 }
81
82 fn visit_stmt_return(&mut v, ret: &'ast $($mut)? StmtReturn) {
83 if let Some(ret_expr) = & $($mut)? ret.expr {
84 v.visit_expr(ret_expr);
85 }
86 }
87
88 fn visit_stmt_revert(&mut v, rvert: &'ast $($mut)? StmtRevert) {
89 v.visit_expr(& $($mut)? rvert.expr);
90 }
91
92 fn visit_stmt_try(&mut v, stmt_try: &'ast $($mut)? StmtTry) {
93 v.visit_block(& $($mut)? stmt_try.block);
94 v.visit_expr(& $($mut)? stmt_try.expr);
95
96 for catch in & $($mut)? stmt_try.catch {
97 v.visit_block(& $($mut)? catch.block);
98 for iden in & $($mut)? catch.list {
99 v.visit_variable_declaration(iden);
100 }
101 }
102 if let Some(ret) = & $($mut)? stmt_try.returns {
103 v.visit_parameter_list(& $($mut)? ret.returns);
104 }
105 }
106
107 fn visit_unchecked_block(&mut v, ublock: &'ast $($mut)? UncheckedBlock) {
108 v.visit_block(& $($mut)? ublock.block);
109 }
110
111 fn visit_stmt_var_decl(&mut v, stmt_var_decl: &'ast $($mut)? StmtVarDecl) {
112 if let Some((_, expr)) = & $($mut)? stmt_var_decl.assignment {
113 v.visit_expr(expr);
114 }
115 match & $($mut)? stmt_var_decl.declaration {
116 VarDeclDecl::VarDecl(vard) => v.visit_variable_declaration(vard),
117 VarDeclDecl::Tuple(tuple) => {
118 for var_opt in & $($mut)? tuple.vars {
119 if let Some(var_decl) = var_opt {
120 v.visit_variable_declaration(var_decl);
121 }
122 }
123 }
124 }
125 }
126
127 fn visit_stmt_while(&mut v, stmt_while: &'ast $($mut)? StmtWhile) {
128 v.visit_expr(& $($mut)? stmt_while.cond);
129 v.visit_stmt(& $($mut)? stmt_while.body);
130 }
131
132 fn visit_expr(&mut v, expr: &'ast $($mut)? Expr) {
133 match expr {
134 Expr::Array(array) => v.visit_expr_array(array),
135 Expr::Binary(binary) => v.visit_expr_binary(binary),
136 Expr::Call(call) => v.visit_expr_call(call),
137 Expr::CallOptions(call_options) => v.visit_expr_call_options(call_options),
138 Expr::Delete(delete) => v.visit_expr_delete(delete),
139 Expr::Ident(ident) => v.visit_ident(ident),
140 Expr::Index(index) => v.visit_expr_index(index),
141 Expr::Lit(lit) => v.visit_lit(lit),
142 Expr::LitDenominated(lit_denominated) => v.visit_lit_denominated(lit_denominated),
143 Expr::Member(member) => v.visit_expr_member(member),
144 Expr::New(new) => v.visit_expr_new(new),
145 Expr::Payable(payable) => v.visit_expr_payable(payable),
146 Expr::Postfix(postfix) => v.visit_expr_postfix(postfix),
147 Expr::Ternary(ternary) => v.visit_expr_ternary(ternary),
148 Expr::Tuple(tuple) => v.visit_expr_tuple(tuple),
149 Expr::Type(typ) => v.visit_type(typ),
150 Expr::TypeCall(type_call) => v.visit_expr_type_call(type_call),
151 Expr::Unary(unary) => v.visit_expr_unary(unary),
152 }
153 }
154
155 fn visit_expr_array(&mut v, i: &'ast $($mut)? ExprArray) {
156 for expr in & $($mut)? i.elems {
157 v.visit_expr(expr);
158 }
159 }
160
161 fn visit_expr_binary(&mut v, i: &'ast $($mut)? ExprBinary) {
162 v.visit_expr(& $($mut)? i.left);
163 v.visit_expr(& $($mut)? i.right);
164 }
165
166 fn visit_expr_call(&mut v, i: &'ast $($mut)? ExprCall) {
167 v.visit_expr(& $($mut)? i.expr);
168 match & $($mut)? i.args.list {
169 ArgListImpl::Unnamed(args) => {
170 for arg in args {
171 v.visit_expr(arg);
172 }
173 },
174 ArgListImpl::Named(args) => {
175 for arg in & $($mut)? args.list {
176 v.visit_ident(& $($mut)? arg.name);
177 v.visit_expr(& $($mut)? arg.arg);
178 }
179 },
180 }
181 }
182
183 fn visit_expr_call_options(&mut v, i: &'ast $($mut)? ExprCallOptions) {
184 v.visit_expr(& $($mut)? i.expr);
185 for arg in & $($mut)? i.args.list {
186 v.visit_ident(& $($mut)? arg.name);
187 v.visit_expr(& $($mut)? arg.arg);
188 }
189 }
190
191 fn visit_expr_delete(&mut v, i: &'ast $($mut)? ExprDelete) {
192 v.visit_expr(& $($mut)? i.expr);
193 }
194
195 fn visit_expr_index(&mut v, i: &'ast $($mut)? ExprIndex) {
196 v.visit_expr(& $($mut)? i.expr);
197
198 if let Some(index) = & $($mut)? i.start {
199 v.visit_expr(index);
200 }
201 if let Some(index) = & $($mut)? i.end {
202 v.visit_expr(index);
203 }
204 }
205
206 fn visit_lit(&mut v, i: &'ast $($mut)? Lit) {
207 }
209
210 fn visit_lit_denominated(&mut v, i: &'ast $($mut)? LitDenominated) {
211 }
213
214 fn visit_expr_member(&mut v, i: &'ast $($mut)? ExprMember) {
215 v.visit_expr(& $($mut)? i.expr);
216 v.visit_expr(& $($mut)? i.member);
217 }
218
219 fn visit_expr_new(&mut v, i: &'ast $($mut)? ExprNew) {
220 v.visit_type(& $($mut)? i.ty);
221 }
222
223 fn visit_expr_payable(&mut v, i: &'ast $($mut)? ExprPayable) {
224 match & $($mut)? i.args.list {
225 ArgListImpl::Unnamed(exprs) => {
226 for expr in exprs {
227 v.visit_expr(expr);
228 }
229 }
230 ArgListImpl::Named(named) => {
231 for a in & $($mut)? named.list {
232 v.visit_ident(& $($mut)? a.name);
233 v.visit_expr(& $($mut)? a.arg);
234 }
235 }
236 }
237 }
238
239 fn visit_expr_postfix(&mut v, i: &'ast $($mut)? ExprPostfix) {
240 v.visit_expr(& $($mut)? i.expr);
241 }
242
243 fn visit_expr_ternary(&mut v, i: &'ast $($mut)? ExprTernary) {
244 v.visit_expr(& $($mut)? i.cond);
245 v.visit_expr(& $($mut)? i.if_true);
246 v.visit_expr(& $($mut)? i.if_false);
247 }
248
249 fn visit_expr_tuple(&mut v, i: &'ast $($mut)? ExprTuple) {
250 for expr in & $($mut)? i.elems {
251 v.visit_expr(expr);
252 }
253 }
254
255 fn visit_expr_type_call(&mut v, i: &'ast $($mut)? ExprTypeCall) {
256 v.visit_type(& $($mut)? i.ty);
257 }
258
259 fn visit_expr_unary(&mut v, i: &'ast $($mut)? ExprUnary) {
260 v.visit_expr(& $($mut)? i.expr);
261 }
262
263 fn visit_lit_str(&mut v, lit: &'ast $($mut)? LitStr) {
264 }
266
267 fn visit_ident(&mut v, ident: &'ast $($mut)? SolIdent) {
268 }
270
271 fn visit_path(&mut v, ident: &'ast $($mut)? SolPath) {
272 }
274
275 fn visit_type(&mut v, ty: &'ast $($mut)? Type) {
276 match ty {
277 Type::Address(..)
278 | Type::Bool(_)
279 | Type::Uint(..)
280 | Type::Int(..)
281 | Type::String(_)
282 | Type::Bytes(_)
283 | Type::FixedBytes(..) => {},
284 Type::Array(TypeArray { ty, .. }) => v.visit_type(ty),
285 Type::Tuple(TypeTuple { types, .. }) => {
286 for ty in types {
287 v.visit_type(ty);
288 }
289 },
290 Type::Function(TypeFunction { arguments, returns, .. }) => {
291 v.visit_parameter_list(arguments);
292 if let Some(returns) = returns {
293 v.visit_parameter_list(& $($mut)? returns.returns);
294 }
295 },
296 Type::Mapping(TypeMapping { key, key_name, value, value_name, .. }) => {
297 v.visit_type(key);
298 if let Some(key_name) = key_name {
299 v.visit_ident(key_name);
300 }
301 v.visit_type(value);
302 if let Some(value_name) = value_name {
303 v.visit_ident(value_name);
304 }
305 },
306 Type::Custom(name) => v.visit_path(name),
307 }
308 }
309
310 fn visit_variable_declaration(&mut v, var: &'ast $($mut)? VariableDeclaration) {
311 v.visit_type(& $($mut)? var.ty);
312 if let Some(name) = & $($mut)? var.name {
313 v.visit_ident(name);
314 }
315 }
316
317 fn visit_variable_definition(&mut v, var: &'ast $($mut)? VariableDefinition) {
318 v.visit_type(& $($mut)? var.ty);
319 v.visit_ident(& $($mut)? var.name);
320 }
321
322 fn visit_parameter_list(&mut v, params: &'ast $($mut)? ParameterList) {
323 for param in params {
324 v.visit_variable_declaration(param);
325 }
326 }
327
328 fn visit_field_list(&mut v, params: &'ast $($mut)? FieldList) {
329 for param in params {
330 v.visit_variable_declaration(param);
331 }
332 }
333
334 fn visit_file(&mut v, file: &'ast $($mut)? File) {
335 for item in & $($mut)? file.items {
336 v.visit_item(item);
337 }
338 }
339
340 fn visit_item(&mut v, item: &'ast $($mut)? Item) {
341 match item {
342 Item::Contract(contract) => v.visit_item_contract(contract),
343 Item::Enum(enumm) => v.visit_item_enum(enumm),
344 Item::Error(error) => v.visit_item_error(error),
345 Item::Event(event) => v.visit_item_event(event),
346 Item::Function(function) => v.visit_item_function(function),
347 Item::Import(import) => v.visit_import_directive(import),
348 Item::Pragma(pragma) => v.visit_pragma_directive(pragma),
349 Item::Struct(strukt) => v.visit_item_struct(strukt),
350 Item::Udt(udt) => v.visit_item_udt(udt),
351 Item::Using(using) => v.visit_using_directive(using),
352 Item::Variable(variable) => v.visit_variable_definition(variable),
353 }
354 }
355
356 fn visit_item_contract(&mut v, contract: &'ast $($mut)? ItemContract) {
357 v.visit_ident(& $($mut)? contract.name);
358 for item in & $($mut)? contract.body {
359 v.visit_item(item);
360 }
361 }
362
363 fn visit_item_enum(&mut v, enumm: &'ast $($mut)? ItemEnum) {
364 v.visit_ident(& $($mut)? enumm.name);
365 for Variant { ident, .. } in & $($mut)? enumm.variants {
366 v.visit_ident(ident);
367 }
368 }
369
370 fn visit_item_error(&mut v, error: &'ast $($mut)? ItemError) {
371 v.visit_ident(& $($mut)? error.name);
372 v.visit_parameter_list(& $($mut)? error.parameters);
373 }
374
375 fn visit_item_event(&mut v, event: &'ast $($mut)? ItemEvent) {
376 v.visit_ident(& $($mut)? event.name);
377 for EventParameter { name, ty, .. } in & $($mut)? event.parameters {
378 v.visit_type(ty);
379 if let Some(name) = name {
380 v.visit_ident(name);
381 }
382 }
383 }
384
385 fn visit_item_function(&mut v, function: &'ast $($mut)? ItemFunction) {
386 if let Some(name) = & $($mut)? function.name {
387 v.visit_ident(name);
388 }
389 v.visit_parameter_list(& $($mut)? function.parameters);
390 if let Some(returns) = & $($mut)? function.returns {
391 v.visit_parameter_list(& $($mut)? returns.returns);
392 }
393 if let FunctionBody::Block(block) = & $($mut)? function.body {
394 v.visit_block(block);
395 }
396 }
397
398 fn visit_import_directive(&mut v, import: &'ast $($mut)? ImportDirective) {
399 match & $($mut)? import.path {
400 ImportPath::Plain(ImportPlain { path, alias }) => {
401 v.visit_lit_str(path);
402 if let Some(ImportAlias { alias, .. }) = alias {
403 v.visit_ident(alias);
404 }
405 }
406 ImportPath::Aliases(ImportAliases { imports, path, .. }) => {
407 for (name, alias) in imports {
408 v.visit_ident(name);
409 if let Some(ImportAlias { alias, .. }) = alias {
410 v.visit_ident(alias);
411 }
412 }
413 v.visit_lit_str(path);
414 }
415 ImportPath::Glob(ImportGlob { alias, path, .. }) => {
416 if let Some(ImportAlias { alias, .. }) = alias {
417 v.visit_ident(alias);
418 }
419 v.visit_lit_str(path);
420 }
421 }
422 }
423
424 fn visit_pragma_directive(&mut v, pragma: &'ast $($mut)? PragmaDirective) {
425 }
427
428 fn visit_item_struct(&mut v, strukt: &'ast $($mut)? ItemStruct) {
429 v.visit_ident(& $($mut)? strukt.name);
430 v.visit_field_list(& $($mut)? strukt.fields);
431 }
432
433 fn visit_item_udt(&mut v, udt: &'ast $($mut)? ItemUdt) {
434 v.visit_ident(& $($mut)? udt.name);
435 v.visit_type(& $($mut)? udt.ty);
436 }
437
438 fn visit_using_directive(&mut v, using: &'ast $($mut)? UsingDirective) {
439 }
441 }
442 }
443 };
444
445 (
446 @impl
447 $(#[$attr:meta])*
448 $vis:vis trait $trait_name:ident<'ast> {$(
449 $(#[$fn_attr:meta])*
450 fn $fn_name:ident(&mut $v:ident $(, $arg_name:ident : $arg_ty:ty)*) { $($impl:tt)* }
451 )*}
452 ) => {
453 $(#[$attr])*
454 $vis trait $trait_name<'ast> {$(
455 $(#[$fn_attr])*
456 fn $fn_name(&mut self $(, $arg_name: $arg_ty)*) { $fn_name(self $(, $arg_name)*) }
457 )*}
458
459 $(
460 $(#[$fn_attr])*
461 pub fn $fn_name<'ast, V: ?Sized + $trait_name<'ast>>($v: &mut V $(, $arg_name: $arg_ty)*) {
462 $($impl)*
463 }
464 )*
465 };
466}
467
468macro_rules! kw_enum {
469 (
470 $(#[$attr:meta])*
471 $vis:vis enum $name:ident {$(
472 $(#[$variant_attr:meta])*
473 $variant:ident(kw::$kw:ident)
474 ),+ $(,)?}
475 ) => {
476 $(#[$attr])*
477 #[derive(Clone, Copy)]
478 $vis enum $name {$(
479 #[doc = concat!("`", stringify!($kw), "`\n\n")]
480 $(#[$variant_attr])*
481 $variant($crate::kw::$kw),
482 )+}
483
484 impl std::cmp::PartialEq for $name {
485 #[inline]
486 fn eq(&self, other: &Self) -> bool {
487 std::mem::discriminant(self) == std::mem::discriminant(other)
488 }
489 }
490
491 impl std::cmp::Eq for $name {}
492
493 impl std::hash::Hash for $name {
494 #[inline]
495 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
496 std::hash::Hash::hash(&std::mem::discriminant(self), state)
497 }
498 }
499
500 impl std::fmt::Display for $name {
501 #[inline]
502 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
503 f.write_str(self.as_str())
504 }
505 }
506
507 impl std::fmt::Debug for $name {
508 #[inline]
509 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
510 f.write_str(self.as_debug_str())
511 }
512 }
513
514 impl ::syn::parse::Parse for $name {
515 fn parse(input: ::syn::parse::ParseStream<'_>) -> ::syn::Result<Self> {
516 let lookahead = input.lookahead1();
517 $(
518 if lookahead.peek($crate::kw::$kw) {
519 input.parse::<$crate::kw::$kw>().map(Self::$variant)
520 } else
521 )+
522 {
523 Err(lookahead.error())
524 }
525 }
526 }
527
528 impl $crate::Spanned for $name {
529 fn span(&self) -> ::proc_macro2::Span {
530 match self {$(
531 Self::$variant(kw) => kw.span,
532 )+}
533 }
534
535 fn set_span(&mut self, span: ::proc_macro2::Span) {
536 match self {$(
537 Self::$variant(kw) => kw.span = span,
538 )+}
539 }
540 }
541
542 impl $name {
543 ::paste::paste! {
544 $(
545 #[doc = concat!("Creates a new `", stringify!($variant), "` keyword with the given `span`.")]
546 #[inline]
547 pub fn [<new_ $variant:snake>](span: ::proc_macro2::Span) -> Self {
548 Self::$variant(kw::$kw(span))
549 }
550 )+
551 }
552
553 pub fn parse_opt(input: ::syn::parse::ParseStream<'_>) -> ::syn::Result<Option<Self>> {
554 $(
555 if input.peek($crate::kw::$kw) {
556 input.parse::<$crate::kw::$kw>().map(|kw| Some(Self::$variant(kw)))
557 } else
558 )+
559 {
560 Ok(None)
561 }
562 }
563
564 pub fn peek(lookahead: &::syn::parse::Lookahead1<'_>) -> bool {
565 $( lookahead.peek($crate::kw::$kw) )||+
566 }
567
568 pub const fn as_str(self) -> &'static str {
569 match self {$(
570 Self::$variant(_) => stringify!($kw),
571 )+}
572 }
573
574 pub const fn as_debug_str(self) -> &'static str {
575 match self {$(
576 Self::$variant(_) => stringify!($variant),
577 )+}
578 }
579
580 ::paste::paste! {
581 $(
582 #[doc = concat!("Returns true if `self` matches `Self::", stringify!($variant), "`.")]
583 #[inline]
584 pub const fn [<is_ $variant:snake>](self) -> bool {
585 matches!(self, Self::$variant(_))
586 }
587 )+
588 }
589 }
590 };
591}
592
593macro_rules! op_enum {
594 (@skip $($tt:tt)*) => {};
595 (@first $first:tt $($rest:tt)*) => { ::syn::Token![$first] };
596
597 (@peek $input:ident, $lookahead:ident, $a:tt) => {
598 $lookahead.peek(::syn::Token![$a])
599 };
600 (@peek $input:ident, $lookahead:ident, $a:tt $b:tt $peek:ident) => {
603 $lookahead.peek(::syn::Token![$a])
604 && $input.$peek(::syn::Token![$b])
605 };
606
607 (
608 $(#[$attr:meta])*
609 $vis:vis enum $name:ident {$(
610 $(#[$variant_attr:meta])*
611 $variant:ident($($op:tt)+) $($peek:ident)?
612 ),+ $(,)?}
613 ) => {
614 $(#[$attr])*
615 #[derive(Clone, Copy)]
616 $vis enum $name {$(
617 #[doc = concat!("`", $(stringify!($op),)+ "`\n\n")]
618 $(#[$variant_attr])*
619 $variant($(::syn::Token![$op]),+),
620 )+}
621
622 impl std::cmp::PartialEq for $name {
623 #[inline]
624 fn eq(&self, other: &Self) -> bool {
625 std::mem::discriminant(self) == std::mem::discriminant(other)
626 }
627 }
628
629 impl std::cmp::Eq for $name {}
630
631 impl std::hash::Hash for $name {
632 #[inline]
633 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
634 std::hash::Hash::hash(&std::mem::discriminant(self), state)
635 }
636 }
637
638 impl std::fmt::Display for $name {
639 #[inline]
640 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
641 f.write_str(self.as_str())
642 }
643 }
644
645 impl std::fmt::Debug for $name {
646 #[inline]
647 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
648 f.write_str(self.as_debug_str())
649 }
650 }
651
652 impl ::syn::parse::Parse for $name {
653 fn parse(input: ::syn::parse::ParseStream<'_>) -> ::syn::Result<Self> {
654 let lookahead = input.lookahead1();
655 $(
656 if op_enum!(@peek input, lookahead, $($op)+ $($peek)?) {
657 Ok(Self::$variant(
658 $(input.parse::<::syn::Token![$op]>()?),+
659 ))
660 } else
661 )+
662 {
663 Err(lookahead.error())
664 }
665 }
666 }
667
668 impl $crate::Spanned for $name {
669 fn span(&self) -> ::proc_macro2::Span {
670 match self {$(
671 Self::$variant(kw, ..) => kw.span(),
672 )+}
673 }
674
675 fn set_span(&mut self, span: ::proc_macro2::Span) {
676 match self {$(
677 Self::$variant(kw, ..) => kw.set_span(span),
678 )+}
679 }
680 }
681
682 impl $name {
683 ::paste::paste! {
684 $(
685 #[doc = concat!("Creates a new `", stringify!($variant), "` operator with the given `span`.")]
686 #[inline]
687 pub fn [<new_ $variant:snake>](span: ::proc_macro2::Span) -> Self {
688 Self::$variant($(::syn::Token),+)
689 }
690 )+
691 }
692
693 #[allow(unused_parens, unused_variables)]
694 pub fn peek(input: syn::parse::ParseStream<'_>, lookahead: &::syn::parse::Lookahead1<'_>) -> bool {
695 $(
696 (op_enum!(@peek input, lookahead, $($op)+ $($peek)?))
697 )||+
698 }
699
700 pub const fn as_str(self) -> &'static str {
701 match self {$(
702 Self::$variant(..) => concat!($(stringify!($op)),+),
703 )+}
704 }
705
706 pub const fn as_debug_str(self) -> &'static str {
707 match self {$(
708 Self::$variant(..) => stringify!($variant),
709 )+}
710 }
711
712 ::paste::paste! {
713 $(
714 #[doc = concat!("Returns true if `self` matches `Self::", stringify!($variant), "`.")]
715 #[inline]
716 pub const fn [<is_ $variant:snake>](self) -> bool {
717 matches!(self, Self::$variant(..))
718 }
719 )+
720 }
721 }
722 };
723}
724
725macro_rules! derive_parse {
726 ($($t:ty),+ $(,)?) => {$(
727 impl Parse for $t {
728 fn parse(input: ParseStream<'_>) -> Result<Self> {
729 <Self as $crate::utils::ParseNested>::parse_nested(
730 input.parse()?,
731 input,
732 )
733 }
734 }
735 )+};
736}
737
738macro_rules! debug {
739 ($($t:tt)*) => {
740 if $crate::DEBUG {
741 eprintln!($($t)*)
742 }
743 };
744}