Line data Source code
1 : // Copyright (C) 2020-2026 Free Software Foundation, Inc.
2 :
3 : // This file is part of GCC.
4 :
5 : // GCC is free software; you can redistribute it and/or modify it under
6 : // the terms of the GNU General Public License as published by the Free
7 : // Software Foundation; either version 3, or (at your option) any later
8 : // version.
9 :
10 : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 : // for more details.
14 :
15 : // You should have received a copy of the GNU General Public License
16 : // along with GCC; see the file COPYING3. If not see
17 : // <http://www.gnu.org/licenses/>.
18 :
19 : #include "rust-ast-collector.h"
20 : #include "rust-ast.h"
21 : #include "rust-builtin-ast-nodes.h"
22 : #include "rust-diagnostics.h"
23 : #include "rust-expr.h"
24 : #include "rust-item.h"
25 : #include "rust-keyword-values.h"
26 : #include "rust-path.h"
27 : #include "rust-system.h"
28 : #include "rust-token.h"
29 :
30 : namespace Rust {
31 : namespace AST {
32 :
33 : std::vector<TokenPtr>
34 174 : TokenCollector::collect_tokens () const
35 : {
36 174 : std::vector<TokenPtr> result;
37 9436 : for (auto item : tokens)
38 : {
39 9262 : if (item.get_kind () == CollectItem::Kind::Token)
40 : {
41 3104 : result.emplace_back (item.get_token ());
42 : }
43 9262 : }
44 174 : return result;
45 : }
46 :
47 : std::vector<CollectItem>
48 4308 : TokenCollector::collect () const
49 : {
50 4308 : return tokens;
51 : }
52 :
53 : void
54 4305 : TokenCollector::visit (AST::Crate &crate)
55 : {
56 4305 : visit_items_as_lines (crate.inner_attrs);
57 4305 : visit_items_as_lines (crate.items);
58 4305 : }
59 :
60 : void
61 3 : TokenCollector::visit (AST::Item &item)
62 : {
63 3 : item.accept_vis (*this);
64 3 : }
65 :
66 : void
67 4366 : TokenCollector::trailing_comma ()
68 : {
69 4366 : if (output_trailing_commas)
70 : {
71 0 : push (Rust::Token::make (COMMA, UNDEF_LOCATION));
72 : }
73 4366 : }
74 :
75 : void
76 203625 : TokenCollector::newline ()
77 : {
78 203625 : tokens.emplace_back (CollectItem::Kind::Newline);
79 203625 : }
80 :
81 : void
82 148443 : TokenCollector::indentation ()
83 : {
84 148443 : tokens.emplace_back (indent_level);
85 148443 : }
86 :
87 : void
88 35419 : TokenCollector::increment_indentation ()
89 : {
90 35419 : indent_level++;
91 35419 : }
92 :
93 : void
94 35419 : TokenCollector::decrement_indentation ()
95 : {
96 35419 : rust_assert (indent_level != 0);
97 35419 : indent_level--;
98 35419 : }
99 :
100 : void
101 0 : TokenCollector::comment (std::string comment)
102 : {
103 0 : tokens.emplace_back (CollectItem::make_comment (comment));
104 0 : }
105 :
106 : void
107 674926 : TokenCollector::describe_node (const std::string &node_name,
108 : std::function<void ()> visitor)
109 : {
110 674926 : tokens.emplace_back (CollectItem::make_begin_node_description (node_name));
111 :
112 674926 : visitor ();
113 :
114 674926 : tokens.push_back (CollectItem::make_end_node_description (node_name));
115 674926 : }
116 :
117 : void
118 0 : TokenCollector::visit (Visitable &v)
119 : {
120 0 : v.accept_vis (*this);
121 0 : }
122 :
123 : void
124 10673 : TokenCollector::visit (FunctionParam ¶m)
125 : {
126 10673 : describe_node (std::string ("FunctionParam"), [this, ¶m] () {
127 10673 : visit_items_as_lines (param.get_outer_attrs ());
128 10673 : if (!param.is_variadic ())
129 : {
130 10673 : visit (param.get_pattern ());
131 10673 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
132 10673 : visit (param.get_type ());
133 : }
134 : else
135 : {
136 0 : if (param.has_name ())
137 : {
138 0 : visit (param.get_pattern ());
139 0 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
140 : }
141 0 : push (Rust::Token::make (ELLIPSIS, UNDEF_LOCATION));
142 : }
143 10673 : });
144 10673 : }
145 :
146 : void
147 871 : TokenCollector::visit (VariadicParam ¶m)
148 : {
149 871 : describe_node (std::string ("VariadicParam"), [this, ¶m] () {
150 871 : if (param.has_pattern ())
151 : {
152 9 : visit (param.get_pattern ());
153 18 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
154 : }
155 871 : push (Rust::Token::make (ELLIPSIS, UNDEF_LOCATION));
156 871 : });
157 871 : }
158 :
159 : void
160 26546 : TokenCollector::visit (Attribute &attrib)
161 : {
162 26546 : describe_node (std::string ("Attribute"), [this, &attrib] () {
163 26546 : push (Rust::Token::make (HASH, attrib.get_locus ()));
164 26546 : if (attrib.is_inner_attribute ())
165 22180 : push (Rust::Token::make (EXCLAM, UNDEF_LOCATION));
166 26546 : push (Rust::Token::make (LEFT_SQUARE, UNDEF_LOCATION));
167 26546 : visit (attrib.get_path ());
168 :
169 26546 : if (attrib.has_attr_input ())
170 : {
171 20679 : switch (attrib.get_attr_input ().get_attr_input_type ())
172 : {
173 11189 : case AST::AttrInput::AttrInputType::LITERAL:
174 11189 : {
175 11189 : visit (
176 11189 : static_cast<AttrInputLiteral &> (attrib.get_attr_input ()));
177 11189 : break;
178 : }
179 1 : case AST::AttrInput::AttrInputType::EXPR:
180 1 : {
181 1 : visit (static_cast<AttrInputExpr &> (attrib.get_attr_input ()));
182 1 : break;
183 : }
184 352 : case AST::AttrInput::AttrInputType::META_ITEM:
185 352 : {
186 352 : visit (static_cast<AttrInputMetaItemContainer &> (
187 352 : attrib.get_attr_input ()));
188 352 : break;
189 : }
190 9137 : case AST::AttrInput::AttrInputType::TOKEN_TREE:
191 9137 : {
192 9137 : visit (static_cast<DelimTokenTree &> (attrib.get_attr_input ()));
193 9137 : break;
194 : }
195 0 : default:
196 0 : rust_unreachable ();
197 : }
198 : }
199 26546 : push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION));
200 26546 : });
201 26546 : }
202 :
203 : void
204 27970 : TokenCollector::visit (SimplePath &path)
205 : {
206 27970 : describe_node (std::string ("SimplePath"), [this, &path] () {
207 27970 : if (path.has_opening_scope_resolution ())
208 : {
209 0 : push (Rust::Token::make (SCOPE_RESOLUTION, path.get_locus ()));
210 : }
211 27970 : visit_items_joined_by_separator (path.get_segments (), SCOPE_RESOLUTION);
212 27970 : });
213 27970 : }
214 :
215 : void
216 28936 : TokenCollector::visit (SimplePathSegment &segment)
217 : {
218 28936 : describe_node (std::string ("SimplePathSegment"), [this, &segment] () {
219 28936 : auto name = segment.get_segment_name ();
220 28936 : if (segment.is_crate_path_seg ())
221 : {
222 258 : push (Rust::Token::make (CRATE, segment.get_locus ()));
223 : }
224 28807 : else if (segment.is_super_path_seg ())
225 : {
226 576 : push (Rust::Token::make (SUPER, segment.get_locus ()));
227 : }
228 28519 : else if (segment.is_lower_self_seg ())
229 : {
230 114 : push (Rust::Token::make (SELF, segment.get_locus ()));
231 : }
232 28462 : else if (segment.is_big_self ())
233 : {
234 0 : push (Rust::Token::make (SELF_ALIAS, segment.get_locus ()));
235 : }
236 : else
237 : {
238 56924 : push (Rust::Token::make_identifier (segment.get_locus (),
239 : std::move (name)));
240 : }
241 28936 : });
242 28936 : }
243 :
244 : void
245 27735 : TokenCollector::visit (Visibility &vis)
246 : {
247 27735 : describe_node (std::string ("Visibility"), [this, &vis] () {
248 27735 : switch (vis.get_vis_type ())
249 : {
250 8188 : case Visibility::PUB:
251 8188 : push (Rust::Token::make (PUB, vis.get_locus ()));
252 8188 : break;
253 46 : case Visibility::PUB_CRATE:
254 46 : push (Rust::Token::make (PUB, vis.get_locus ()));
255 46 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
256 46 : push (Rust::Token::make (CRATE, UNDEF_LOCATION));
257 46 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
258 46 : break;
259 0 : case Visibility::PUB_SELF:
260 0 : push (Rust::Token::make (PUB, vis.get_locus ()));
261 0 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
262 0 : push (Rust::Token::make (SELF, UNDEF_LOCATION));
263 0 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
264 0 : break;
265 1 : case Visibility::PUB_SUPER:
266 1 : push (Rust::Token::make (PUB, vis.get_locus ()));
267 1 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
268 1 : push (Rust::Token::make (SUPER, UNDEF_LOCATION));
269 1 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
270 1 : break;
271 3 : case Visibility::PUB_IN_PATH:
272 3 : push (Rust::Token::make (PUB, vis.get_locus ()));
273 3 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
274 3 : push (Rust::Token::make (IN, UNDEF_LOCATION));
275 3 : visit (vis.get_path ());
276 3 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
277 3 : break;
278 : case Visibility::PRIV:
279 : break;
280 : }
281 27735 : });
282 27735 : }
283 :
284 : void
285 8728 : TokenCollector::visit (std::vector<std::unique_ptr<GenericParam>> ¶ms)
286 : {
287 8728 : describe_node (std::string ("GenericParam"), [this, ¶ms] () {
288 8728 : push (Rust::Token::make (LEFT_ANGLE, UNDEF_LOCATION));
289 8728 : visit_items_joined_by_separator (params, COMMA);
290 8728 : push (Rust::Token::make (RIGHT_ANGLE, UNDEF_LOCATION));
291 8728 : });
292 8728 : }
293 :
294 : void
295 1997 : TokenCollector::visit (TupleField &field)
296 : {
297 1997 : describe_node (std::string ("TupleField"), [this, &field] () {
298 2054 : for (auto attr : field.get_outer_attrs ())
299 : {
300 57 : visit (attr);
301 57 : }
302 1997 : visit (field.get_visibility ());
303 1997 : visit (field.get_field_type ());
304 1997 : });
305 1997 : }
306 :
307 : void
308 2212 : TokenCollector::visit (StructField &field)
309 : {
310 2212 : describe_node (std::string ("StructField"), [this, &field] () {
311 2213 : for (auto attr : field.get_outer_attrs ())
312 : {
313 1 : visit (attr);
314 1 : }
315 2212 : visit (field.get_visibility ());
316 4424 : auto name = field.get_field_name ().as_string ();
317 4424 : push (Rust::Token::make_identifier (field.get_locus (), std::move (name)));
318 2212 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
319 2212 : visit (field.get_field_type ());
320 2212 : });
321 2212 : }
322 :
323 : void
324 14 : TokenCollector::visit (std::vector<LifetimeParam> &for_lifetimes)
325 : {
326 14 : describe_node (std::string ("LifetimeParam"), [this, &for_lifetimes] () {
327 14 : push (Rust::Token::make (FOR, UNDEF_LOCATION));
328 14 : push (Rust::Token::make (LEFT_ANGLE, UNDEF_LOCATION));
329 14 : visit_items_joined_by_separator (for_lifetimes, COMMA);
330 14 : push (Rust::Token::make (RIGHT_ANGLE, UNDEF_LOCATION));
331 14 : });
332 14 : }
333 :
334 : void
335 18135 : TokenCollector::visit (FunctionQualifiers &qualifiers)
336 : {
337 : // Syntax:
338 : // `const`? `async`? `unsafe`? (`extern` Abi?)?
339 : // unsafe? (extern Abi?)?
340 18135 : describe_node (std::string ("FunctionQualifiers"), [this, &qualifiers] () {
341 18135 : if (qualifiers.is_async ())
342 2 : push (Rust::Token::make (ASYNC, qualifiers.get_locus ()));
343 18135 : if (qualifiers.is_const ())
344 1758 : push (Rust::Token::make (CONST, qualifiers.get_locus ()));
345 18135 : if (qualifiers.is_unsafe ())
346 992 : push (Rust::Token::make (UNSAFE, qualifiers.get_locus ()));
347 18135 : if (qualifiers.is_extern ())
348 : {
349 70 : push (Rust::Token::make (EXTERN_KW, qualifiers.get_locus ()));
350 70 : if (qualifiers.has_abi ())
351 : {
352 140 : push (Rust::Token::make_string (UNDEF_LOCATION,
353 210 : qualifiers.get_extern_abi ()));
354 : }
355 : }
356 18135 : });
357 18135 : }
358 :
359 : void
360 63 : TokenCollector::visit (MaybeNamedParam ¶m)
361 : {
362 : // Syntax:
363 : // OuterAttribute* ( ( IDENTIFIER | _ ) : )? Type
364 :
365 63 : describe_node (std::string ("MaybeNamedParam"), [this, ¶m] () {
366 63 : for (auto attr : param.get_outer_attrs ())
367 : {
368 0 : visit (attr);
369 0 : }
370 126 : auto param_name = param.get_name ().as_string ();
371 63 : switch (param.get_param_kind ())
372 : {
373 : case MaybeNamedParam::UNNAMED:
374 : break;
375 0 : case MaybeNamedParam::IDENTIFIER:
376 0 : push (Rust::Token::make_identifier (UNDEF_LOCATION,
377 : std::move (param_name)));
378 0 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
379 0 : break;
380 6 : case MaybeNamedParam::WILDCARD:
381 6 : push (Rust::Token::make (UNDERSCORE, UNDEF_LOCATION));
382 6 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
383 6 : break;
384 : }
385 63 : visit (param.get_type ());
386 63 : });
387 63 : }
388 :
389 : void
390 73066 : TokenCollector::visit (Token &tok)
391 : {
392 73066 : std::string data
393 96093 : = tok.get_tok_ptr ()->should_have_str () ? tok.get_str () : "";
394 73066 : switch (tok.get_id ())
395 : {
396 18479 : case IDENTIFIER:
397 36958 : push (Rust::Token::make_identifier (tok.get_locus (), std::move (data)));
398 18479 : break;
399 351 : case INT_LITERAL:
400 351 : {
401 351 : auto suffix_start = data.length ();
402 702 : push (Rust::Token::make_int (tok.get_locus (), std::move (data),
403 : suffix_start, IntegerLiteralBase::Decimal,
404 : tok.get_type_hint ()));
405 351 : break;
406 : }
407 0 : case FLOAT_LITERAL:
408 0 : {
409 0 : auto suffix_start = data.length ();
410 0 : push (Rust::Token::make_float (tok.get_locus (), std::move (data),
411 : suffix_start, tok.get_type_hint ()));
412 0 : break;
413 : }
414 4187 : case STRING_LITERAL:
415 8374 : push (Rust::Token::make_string (tok.get_locus (), std::move (data)));
416 4187 : break;
417 0 : case CHAR_LITERAL:
418 0 : push (Rust::Token::make_char (
419 : tok.get_locus (),
420 : // FIXME: This need to be fixed to properly support UTF-8
421 0 : static_cast<uint32_t> (data[0])));
422 0 : break;
423 0 : case BYTE_CHAR_LITERAL:
424 0 : push (Rust::Token::make_byte_char (tok.get_locus (), data[0]));
425 0 : break;
426 0 : case BYTE_STRING_LITERAL:
427 0 : push (Rust::Token::make_byte_string (tok.get_locus (), std::move (data)));
428 0 : break;
429 0 : case RAW_STRING_LITERAL:
430 0 : push (Rust::Token::make_raw_string (tok.get_locus (), std::move (data)));
431 0 : break;
432 0 : case C_STRING_LITERAL:
433 0 : push (Rust::Token::make_c_string (tok.get_locus (), std::move (data)));
434 0 : break;
435 0 : case INNER_DOC_COMMENT:
436 0 : push (Rust::Token::make_inner_doc_comment (tok.get_locus (),
437 : std::move (data)));
438 0 : break;
439 0 : case OUTER_DOC_COMMENT:
440 0 : push (Rust::Token::make_outer_doc_comment (tok.get_locus (),
441 : std::move (data)));
442 0 : break;
443 10 : case LIFETIME:
444 20 : push (Rust::Token::make_lifetime (tok.get_locus (), std::move (data)));
445 10 : break;
446 50039 : default:
447 100078 : push (Rust::Token::make (tok.get_id (), tok.get_locus ()));
448 : }
449 73066 : }
450 :
451 : void
452 10341 : TokenCollector::visit (DelimTokenTree &delim_tok_tree)
453 : {
454 10341 : describe_node (std::string ("DelimTokenTree"), [this, &delim_tok_tree] () {
455 82943 : for (auto &token : delim_tok_tree.to_token_stream ())
456 : {
457 72602 : visit (token);
458 10341 : }
459 10341 : });
460 10341 : }
461 :
462 : void
463 352 : TokenCollector::visit (AttrInputMetaItemContainer &container)
464 : {
465 352 : describe_node (std::string ("AttrInputMetaItemContainer"),
466 352 : [this, &container] () {
467 704 : for (auto &item : container.get_items ())
468 : {
469 352 : visit (item);
470 : }
471 352 : });
472 352 : }
473 :
474 : void
475 24595 : TokenCollector::visit (IdentifierExpr &ident_expr)
476 : {
477 24595 : describe_node (std::string ("IdentifierExpr"), [this, &ident_expr] () {
478 49190 : auto ident = ident_expr.get_ident ().as_string ();
479 49190 : push (Rust::Token::make_identifier (ident_expr.get_locus (),
480 : std::move (ident)));
481 24595 : });
482 24595 : }
483 :
484 : void
485 9524 : TokenCollector::visit (Lifetime &lifetime)
486 : {
487 : // Syntax:
488 : // Lifetime :
489 : // LIFETIME_OR_LABEL
490 : // | 'static
491 : // | '_
492 :
493 9524 : describe_node (std::string ("Lifetime"), [this, &lifetime] () {
494 9524 : auto name = lifetime.get_lifetime_name ();
495 9524 : switch (lifetime.get_lifetime_type ())
496 : {
497 491 : case Lifetime::LifetimeType::NAMED:
498 491 : push (
499 982 : Rust::Token::make_lifetime (lifetime.get_locus (), std::move (name)));
500 491 : break;
501 111 : case Lifetime::LifetimeType::STATIC:
502 222 : push (Rust::Token::make_lifetime (lifetime.get_locus (),
503 111 : Values::Keywords::STATIC_KW));
504 111 : break;
505 8922 : case Lifetime::LifetimeType::WILDCARD:
506 17844 : push (Rust::Token::make_lifetime (lifetime.get_locus (),
507 8922 : Values::Keywords::UNDERSCORE));
508 8922 : break;
509 : }
510 9524 : });
511 9524 : }
512 :
513 : void
514 158 : TokenCollector::visit (LifetimeParam &lifetime_param)
515 : {
516 : // Syntax:
517 : // LIFETIME_OR_LABEL ( : LifetimeBounds )?
518 : // LifetimeBounds :
519 : // ( Lifetime + )* Lifetime?
520 :
521 : // TODO what to do with outer attr? They are not mentioned in the reference.
522 158 : describe_node (std::string ("LifetimeParam"), [this, &lifetime_param] () {
523 158 : visit_items_as_lines (lifetime_param.get_outer_attrs ());
524 158 : auto lifetime = lifetime_param.get_lifetime ();
525 158 : visit (lifetime);
526 :
527 158 : if (lifetime_param.has_lifetime_bounds ())
528 : {
529 0 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
530 0 : for (auto &bound : lifetime_param.get_lifetime_bounds ())
531 : {
532 0 : visit (bound);
533 : }
534 : }
535 158 : });
536 158 : }
537 :
538 : void
539 72 : TokenCollector::visit (ConstGenericParam ¶m)
540 : {
541 : // Syntax:
542 : // const IDENTIFIER : Type ( = Block | IDENTIFIER | -?LITERAL )?
543 72 : describe_node (std::string ("ConstGenericParam"), [this, ¶m] () {
544 72 : visit_items_as_lines (param.get_outer_attrs ());
545 72 : push (Rust::Token::make (CONST, param.get_locus ()));
546 72 : auto id = param.get_name ().as_string ();
547 144 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
548 72 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
549 72 : if (param.has_type ())
550 72 : visit (param.get_type ());
551 72 : if (param.has_default_value ())
552 : {
553 5 : push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
554 5 : visit (param.get_default_value_unchecked ());
555 : }
556 72 : });
557 72 : }
558 :
559 : void
560 37549 : TokenCollector::visit (PathExprSegment &segment)
561 : {
562 37549 : describe_node (std::string ("PathExprSegment"), [this, &segment] () {
563 37549 : visit (segment.get_ident_segment ());
564 37549 : if (segment.has_generic_args ())
565 : {
566 888 : auto generics = segment.get_generic_args ();
567 888 : push (Rust::Token::make (SCOPE_RESOLUTION, segment.get_locus ()));
568 888 : push (Rust::Token::make (LEFT_ANGLE, generics.get_locus ()));
569 :
570 888 : auto &lifetime_args = generics.get_lifetime_args ();
571 888 : auto &generic_args = generics.get_generic_args ();
572 888 : auto &binding_args = generics.get_binding_args ();
573 :
574 888 : visit_items_joined_by_separator (generic_args, COMMA);
575 :
576 888 : if (!lifetime_args.empty ()
577 888 : && (!generic_args.empty () || !binding_args.empty ()))
578 : {
579 0 : push (Rust::Token::make (COMMA, UNDEF_LOCATION));
580 : }
581 :
582 888 : visit_items_joined_by_separator (binding_args, COMMA);
583 :
584 888 : if (!generic_args.empty () && !binding_args.empty ())
585 : {
586 0 : push (Rust::Token::make (COMMA, UNDEF_LOCATION));
587 : }
588 :
589 888 : visit_items_joined_by_separator (lifetime_args, COMMA);
590 :
591 888 : push (Rust::Token::make (RIGHT_ANGLE, UNDEF_LOCATION));
592 888 : }
593 37549 : });
594 37549 : }
595 :
596 : void
597 25452 : TokenCollector::visit (PathInExpression &path)
598 : {
599 25452 : describe_node (std::string ("PathInExpression"), [this, &path] () {
600 25452 : if (path.is_lang_item ())
601 : {
602 139 : push (Rust::Token::make (TokenId::HASH, path.get_locus ()));
603 139 : push (Rust::Token::make (TokenId::LEFT_SQUARE, path.get_locus ()));
604 278 : push (Rust::Token::make_identifier (path.get_locus (), "lang"));
605 139 : push (Rust::Token::make (TokenId::EQUAL, path.get_locus ()));
606 278 : push (Rust::Token::make_string (
607 139 : path.get_locus (), LangItem::ToString (path.get_lang_item ())));
608 139 : push (Rust::Token::make (TokenId::RIGHT_SQUARE, path.get_locus ()));
609 :
610 139 : return;
611 : }
612 :
613 25313 : if (path.opening_scope_resolution ())
614 762 : push (Rust::Token::make (SCOPE_RESOLUTION, path.get_locus ()));
615 :
616 25313 : visit_items_joined_by_separator (path.get_segments (), SCOPE_RESOLUTION);
617 : });
618 25452 : }
619 :
620 : void
621 54928 : TokenCollector::visit (TypePathSegment &segment)
622 : {
623 : // Syntax:
624 : // PathIdentSegment
625 54928 : describe_node (std::string ("TypePathSegment"), [this, &segment] () {
626 54928 : auto locus = segment.is_lang_item ()
627 54928 : ? segment.get_locus ()
628 54600 : : segment.get_ident_segment ().get_locus ();
629 54928 : auto segment_string = segment.is_lang_item ()
630 54928 : ? LangItem::PrettyString (segment.get_lang_item ())
631 54928 : : segment.get_ident_segment ().as_string ();
632 109856 : push (Rust::Token::make_identifier (locus, std::move (segment_string)));
633 54928 : });
634 54928 : }
635 :
636 : void
637 3039 : TokenCollector::visit (TypePathSegmentGeneric &segment)
638 : {
639 : // Syntax:
640 : // PathIdentSegment `::`? (GenericArgs)?
641 : // GenericArgs :
642 : // `<` `>`
643 : // | `<` ( GenericArg `,` )* GenericArg `,`? `>`
644 3039 : describe_node (std::string ("TypePathSegmentGeneric"), [this, &segment] () {
645 3039 : auto locus = segment.is_lang_item ()
646 3039 : ? segment.get_locus ()
647 2992 : : segment.get_ident_segment ().get_locus ();
648 3039 : auto segment_string = segment.is_lang_item ()
649 3039 : ? LangItem::PrettyString (segment.get_lang_item ())
650 3039 : : segment.get_ident_segment ().as_string ();
651 6078 : push (Rust::Token::make_identifier (locus, std::move (segment_string)));
652 :
653 3039 : push (Rust::Token::make (LEFT_ANGLE, UNDEF_LOCATION));
654 :
655 3039 : {
656 3039 : auto &lifetime_args = segment.get_generic_args ().get_lifetime_args ();
657 3039 : auto &generic_args = segment.get_generic_args ().get_generic_args ();
658 3039 : auto &binding_args = segment.get_generic_args ().get_binding_args ();
659 :
660 3039 : visit_items_joined_by_separator (lifetime_args, COMMA);
661 3039 : if (!lifetime_args.empty ()
662 3039 : && (!generic_args.empty () || !binding_args.empty ()))
663 4 : push (Rust::Token::make (COMMA, UNDEF_LOCATION));
664 3039 : visit_items_joined_by_separator (generic_args, COMMA);
665 3039 : if (!generic_args.empty () && !binding_args.empty ())
666 0 : push (Rust::Token::make (COMMA, UNDEF_LOCATION));
667 3039 : visit_items_joined_by_separator (binding_args, COMMA);
668 : }
669 :
670 6078 : push (Rust::Token::make (RIGHT_ANGLE, UNDEF_LOCATION));
671 3039 : });
672 3039 : }
673 :
674 : void
675 40 : TokenCollector::visit (GenericArgsBinding &binding)
676 : {
677 : // Syntax:
678 : // IDENTIFIER `=` Type
679 40 : describe_node (std::string ("GenericArgsBinding"), [this, &binding] () {
680 80 : auto identifier = binding.get_identifier ().as_string ();
681 80 : push (Rust::Token::make_identifier (binding.get_locus (),
682 : std::move (identifier)));
683 :
684 40 : push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
685 40 : visit (binding.get_type ());
686 40 : });
687 40 : }
688 :
689 : void
690 4146 : TokenCollector::visit (GenericArg &arg)
691 : {
692 : // `GenericArg` implements `accept_vis` but it is not useful for this case
693 : // as it ignores unresolved cases (`Kind::Either`).
694 4146 : describe_node (std::string ("GenericArg"), [this, &arg] () {
695 4146 : switch (arg.get_kind ())
696 : {
697 109 : case GenericArg::Kind::Const:
698 109 : visit (arg.get_expression ());
699 109 : break;
700 4030 : case GenericArg::Kind::Type:
701 4030 : visit (arg.get_type ());
702 4030 : break;
703 7 : case GenericArg::Kind::Either:
704 7 : {
705 7 : auto path = arg.get_path ();
706 7 : push (
707 14 : Rust::Token::make_identifier (UNDEF_LOCATION, std::move (path)));
708 7 : }
709 7 : break;
710 : }
711 4146 : });
712 4146 : }
713 :
714 : void
715 27 : TokenCollector::visit (TypePathSegmentFunction &segment)
716 : {
717 : // Syntax:
718 : // PathIdentSegment `::`? (TypePathFn)?
719 27 : describe_node (std::string ("TypePathSegmentFunction"), [this, &segment] () {
720 27 : auto ident_segment = segment.get_ident_segment ();
721 27 : auto id = ident_segment.as_string ();
722 54 : push (Rust::Token::make_identifier (ident_segment.get_locus (),
723 : std::move (id)));
724 :
725 27 : if (segment.get_separating_scope_resolution ())
726 0 : push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
727 :
728 27 : if (!segment.is_ident_only ())
729 27 : visit (segment.get_type_path_function ());
730 27 : });
731 27 : }
732 :
733 : void
734 27 : TokenCollector::visit (TypePathFunction &type_path_fn)
735 : {
736 : // Syntax:
737 : // `(` TypePathFnInputs? `)` (`->` Type)?
738 : // TypePathFnInputs :
739 : // Type (`,` Type)* `,`?
740 27 : describe_node (std::string ("TypePathFunction"), [this, &type_path_fn] () {
741 27 : push (Rust::Token::make (LEFT_PAREN, type_path_fn.get_locus ()));
742 27 : if (type_path_fn.has_inputs ())
743 27 : visit_items_joined_by_separator (type_path_fn.get_params (), COMMA);
744 27 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
745 :
746 27 : if (type_path_fn.has_return_type ())
747 : {
748 27 : push (Rust::Token::make (RETURN_TYPE, UNDEF_LOCATION));
749 27 : visit (type_path_fn.get_return_type ());
750 : }
751 27 : });
752 27 : }
753 :
754 : void
755 55939 : TokenCollector::visit (TypePath &path)
756 : {
757 : // Syntax:
758 : // `::`? TypePathSegment (`::` TypePathSegment)*
759 55939 : describe_node (std::string ("TypePath"), [this, &path] () {
760 55939 : if (path.has_opening_scope_resolution_op ())
761 708 : push (Rust::Token::make (SCOPE_RESOLUTION, path.get_locus ()));
762 :
763 55939 : visit_items_joined_by_separator (path.get_segments (), SCOPE_RESOLUTION);
764 55939 : });
765 55939 : }
766 :
767 : void
768 37549 : TokenCollector::visit (PathIdentSegment &segment)
769 : {
770 37549 : describe_node (std::string ("PathIdentSegment"), [this, &segment] () {
771 37549 : if (segment.is_super_path_seg ())
772 : {
773 2 : push (Rust::Token::make (SUPER, segment.get_locus ()));
774 : }
775 37548 : else if (segment.is_crate_path_seg ())
776 : {
777 2192 : push (Rust::Token::make (CRATE, segment.get_locus ()));
778 : }
779 36452 : else if (segment.is_lower_self_seg ())
780 : {
781 13440 : push (Rust::Token::make (SELF, segment.get_locus ()));
782 : }
783 29732 : else if (segment.is_big_self_seg ())
784 : {
785 840 : push (Rust::Token::make (SELF_ALIAS, segment.get_locus ()));
786 : }
787 : else
788 : {
789 29312 : auto id = segment.as_string ();
790 29312 : push (
791 58624 : Rust::Token::make_identifier (segment.get_locus (), std::move (id)));
792 29312 : }
793 37549 : });
794 37549 : }
795 :
796 : void
797 112 : TokenCollector::visit (QualifiedPathInExpression &path)
798 : {
799 112 : describe_node (std::string ("QualifiedPathInExpression"), [this, &path] () {
800 112 : visit (path.get_qualified_path_type ());
801 224 : for (auto &segment : path.get_segments ())
802 : {
803 112 : push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
804 112 : visit (segment);
805 : }
806 112 : });
807 112 : }
808 :
809 : void
810 386 : TokenCollector::visit (QualifiedPathType &path)
811 : {
812 386 : describe_node (std::string ("QualifiedPathType"), [this, &path] () {
813 386 : push (Rust::Token::make (LEFT_ANGLE, path.get_locus ()));
814 386 : visit (path.get_type ());
815 386 : if (path.has_as_clause ())
816 : {
817 353 : push (Rust::Token::make (AS, UNDEF_LOCATION));
818 353 : visit (path.get_as_type_path ());
819 : }
820 386 : push (Rust::Token::make (RIGHT_ANGLE, UNDEF_LOCATION));
821 386 : });
822 386 : }
823 :
824 : void
825 274 : TokenCollector::visit (QualifiedPathInType &path)
826 : {
827 274 : describe_node (std::string ("QualifiedPathInType"), [this, &path] () {
828 274 : visit (path.get_qualified_path_type ());
829 :
830 274 : push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
831 274 : visit (path.get_associated_segment ());
832 274 : for (auto &segment : path.get_segments ())
833 : {
834 0 : push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
835 0 : visit (segment);
836 : }
837 274 : });
838 274 : }
839 :
840 : void
841 32292 : TokenCollector::visit (Literal &lit, location_t locus)
842 : {
843 32292 : auto value = lit.as_string ();
844 32292 : switch (lit.get_lit_type ())
845 : {
846 183 : case Literal::LitType::CHAR:
847 183 : push (
848 183 : Rust::Token::make_char (locus,
849 : // TODO: Change this to support utf-8 properly
850 183 : Codepoint (static_cast<uint32_t> (value[0]))));
851 183 : break;
852 13610 : case Literal::LitType::STRING:
853 27220 : push (Rust::Token::make_string (locus, std::move (value)));
854 13610 : break;
855 411 : case Literal::LitType::BYTE:
856 411 : push (Rust::Token::make_byte_char (locus, value[0]));
857 411 : break;
858 35 : case Literal::LitType::BYTE_STRING:
859 70 : push (Rust::Token::make_byte_string (locus, std::move (value)));
860 35 : break;
861 1 : case Literal::LitType::RAW_STRING:
862 2 : push (Rust::Token::make_raw_string (locus, std::move (value)));
863 1 : break;
864 14 : case Literal::LitType::C_STRING:
865 28 : push (Rust::Token::make_c_string (locus, std::move (value)));
866 14 : break;
867 16431 : case Literal::LitType::INT:
868 16431 : {
869 16431 : auto val_len = value.length ();
870 32862 : push (Rust::Token::make_int (locus, std::move (value), val_len,
871 : IntegerLiteralBase::Decimal,
872 : lit.get_type_hint ()));
873 16431 : break;
874 : }
875 329 : case Literal::LitType::FLOAT:
876 329 : {
877 329 : auto val_len = value.length ();
878 658 : push (Rust::Token::make_float (locus, std::move (value), val_len,
879 : lit.get_type_hint ()));
880 329 : break;
881 : }
882 1278 : case Literal::LitType::BOOL:
883 1278 : {
884 1278 : if (value == Values::Keywords::FALSE_LITERAL)
885 1090 : push (Rust::Token::make (FALSE_LITERAL, locus));
886 733 : else if (value == Values::Keywords::TRUE_LITERAL)
887 1466 : push (Rust::Token::make (TRUE_LITERAL, locus));
888 : else
889 0 : rust_unreachable (); // Not a boolean
890 : break;
891 : }
892 0 : case Literal::LitType::ERROR:
893 0 : rust_unreachable ();
894 32292 : break;
895 : }
896 32292 : }
897 :
898 : void
899 31817 : TokenCollector::visit (LiteralExpr &expr)
900 : {
901 31817 : describe_node (std::string ("LiteralExpr"), [this, &expr] () {
902 31817 : auto lit = expr.get_literal ();
903 31817 : visit (lit, expr.get_locus ());
904 31817 : });
905 31817 : }
906 :
907 : void
908 11189 : TokenCollector::visit (AttrInputLiteral &literal)
909 : {
910 11189 : describe_node (std::string ("AttrInputLiteral"), [this, &literal] () {
911 11189 : push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
912 11189 : visit (literal.get_literal ());
913 11189 : });
914 11189 : }
915 :
916 : void
917 1 : TokenCollector::visit (AttrInputExpr &attr)
918 : {
919 1 : describe_node (std::string ("AttrInputExpr"),
920 2 : [this, &attr] () { visit (attr.get_expr ()); });
921 1 : }
922 :
923 : void
924 0 : TokenCollector::visit (MetaItemLitExpr &item)
925 : {
926 0 : describe_node (std::string ("MetaItemLitExpr"), [this, &item] () {
927 0 : auto lit = item.get_literal ();
928 0 : visit (lit);
929 0 : });
930 0 : }
931 :
932 : void
933 0 : TokenCollector::visit (MetaItemPathExpr &item)
934 : {
935 0 : describe_node (std::string ("MetaItemPathLit"), [this, &item] () {
936 0 : auto &path = item.get_path ();
937 0 : auto &expr = item.get_expr ();
938 0 : visit (path);
939 0 : push (Rust::Token::make (EQUAL, item.get_locus ()));
940 0 : visit (expr);
941 0 : });
942 0 : }
943 :
944 : void
945 1919 : TokenCollector::visit (BorrowExpr &expr)
946 : {
947 1919 : describe_node (std::string ("BorrowExpr"), [this, &expr] () {
948 1919 : push (Rust::Token::make (AMP, expr.get_locus ()));
949 1919 : if (expr.get_is_double_borrow ())
950 46 : push (Rust::Token::make (AMP, UNDEF_LOCATION));
951 :
952 1919 : if (expr.is_raw_borrow ())
953 : {
954 8 : push (Rust::Token::make_identifier (expr.get_locus (),
955 4 : Values::WeakKeywords::RAW));
956 4 : if (expr.get_is_mut ())
957 8 : push (Rust::Token::make (MUT, UNDEF_LOCATION));
958 : else
959 0 : push (Rust::Token::make (CONST, UNDEF_LOCATION));
960 : }
961 : else
962 : {
963 1915 : if (expr.get_is_mut ())
964 764 : push (Rust::Token::make (MUT, UNDEF_LOCATION));
965 : }
966 :
967 1919 : if (expr.is_raw_borrow ())
968 : {
969 8 : push (Rust::Token::make_identifier (expr.get_locus (),
970 4 : Values::WeakKeywords::RAW));
971 4 : if (expr.get_is_mut ())
972 8 : push (Rust::Token::make (MUT, UNDEF_LOCATION));
973 : else
974 0 : push (Rust::Token::make (CONST, UNDEF_LOCATION));
975 : }
976 : else
977 : {
978 1915 : if (expr.get_is_mut ())
979 764 : push (Rust::Token::make (MUT, UNDEF_LOCATION));
980 : }
981 :
982 1919 : if (expr.has_borrow_expr ())
983 1919 : visit (expr.get_borrowed_expr ());
984 1919 : });
985 1919 : }
986 :
987 : void
988 3788 : TokenCollector::visit (DereferenceExpr &expr)
989 : {
990 3788 : describe_node (std::string ("DereferenceExpr"), [this, &expr] () {
991 3788 : push (Rust::Token::make (ASTERISK, expr.get_locus ()));
992 3788 : visit (expr.get_dereferenced_expr ());
993 3788 : });
994 3788 : }
995 :
996 : void
997 0 : TokenCollector::visit (ErrorPropagationExpr &expr)
998 : {
999 0 : describe_node (std::string ("ErrorPropagationExpr"), [this, &expr] () {
1000 0 : visit (expr.get_propagating_expr ());
1001 0 : push (Rust::Token::make (QUESTION_MARK, expr.get_locus ()));
1002 0 : });
1003 0 : }
1004 :
1005 : void
1006 855 : TokenCollector::visit (NegationExpr &expr)
1007 : {
1008 855 : describe_node (std::string ("NegationExpr"), [this, &expr] () {
1009 855 : switch (expr.get_expr_type ())
1010 : {
1011 407 : case NegationOperator::NEGATE:
1012 407 : push (Rust::Token::make (MINUS, expr.get_locus ()));
1013 407 : break;
1014 448 : case NegationOperator::NOT:
1015 448 : push (Rust::Token::make (EXCLAM, expr.get_locus ()));
1016 448 : break;
1017 : }
1018 855 : visit (expr.get_negated_expr ());
1019 855 : });
1020 855 : }
1021 :
1022 : void
1023 3410 : TokenCollector::visit (ArithmeticOrLogicalExpr &expr)
1024 : {
1025 3410 : describe_node (std::string ("ArithmeticOrLogicalExpr"), [this, &expr] () {
1026 3410 : visit (expr.get_left_expr ());
1027 3410 : switch (expr.get_expr_type ())
1028 : {
1029 1852 : case ArithmeticOrLogicalOperator::ADD:
1030 1852 : push (Rust::Token::make (PLUS, expr.get_locus ()));
1031 1852 : break;
1032 :
1033 1038 : case ArithmeticOrLogicalOperator::SUBTRACT:
1034 1038 : push (Rust::Token::make (MINUS, expr.get_locus ()));
1035 1038 : break;
1036 :
1037 240 : case ArithmeticOrLogicalOperator::MULTIPLY:
1038 240 : push (Rust::Token::make (ASTERISK, expr.get_locus ()));
1039 240 : break;
1040 :
1041 31 : case ArithmeticOrLogicalOperator::DIVIDE:
1042 31 : push (Rust::Token::make (DIV, expr.get_locus ()));
1043 31 : break;
1044 :
1045 40 : case ArithmeticOrLogicalOperator::MODULUS:
1046 40 : push (Rust::Token::make (PERCENT, expr.get_locus ()));
1047 40 : break;
1048 :
1049 48 : case ArithmeticOrLogicalOperator::BITWISE_AND:
1050 48 : push (Rust::Token::make (AMP, expr.get_locus ()));
1051 48 : break;
1052 :
1053 25 : case ArithmeticOrLogicalOperator::BITWISE_OR:
1054 25 : push (Rust::Token::make (PIPE, expr.get_locus ()));
1055 25 : break;
1056 :
1057 63 : case ArithmeticOrLogicalOperator::BITWISE_XOR:
1058 63 : push (Rust::Token::make (CARET, expr.get_locus ()));
1059 63 : break;
1060 :
1061 51 : case ArithmeticOrLogicalOperator::LEFT_SHIFT:
1062 51 : push (Rust::Token::make (LEFT_SHIFT, expr.get_locus ()));
1063 51 : break;
1064 :
1065 22 : case ArithmeticOrLogicalOperator::RIGHT_SHIFT:
1066 22 : push (Rust::Token::make (RIGHT_SHIFT, expr.get_locus ()));
1067 22 : break;
1068 : }
1069 :
1070 3410 : visit (expr.get_right_expr ());
1071 3410 : });
1072 3410 : }
1073 :
1074 : void
1075 3741 : TokenCollector::visit (ComparisonExpr &expr)
1076 : {
1077 3741 : describe_node (std::string ("ComparisonExpr"), [this, &expr] () {
1078 3741 : visit (expr.get_left_expr ());
1079 :
1080 3741 : switch (expr.get_expr_type ())
1081 : {
1082 893 : case ComparisonOperator::EQUAL:
1083 893 : push (Rust::Token::make (EQUAL_EQUAL, expr.get_locus ()));
1084 893 : break;
1085 1011 : case ComparisonOperator::NOT_EQUAL:
1086 1011 : push (Rust::Token::make (NOT_EQUAL, expr.get_locus ()));
1087 1011 : break;
1088 661 : case ComparisonOperator::GREATER_THAN:
1089 661 : push (Rust::Token::make (RIGHT_ANGLE, expr.get_locus ()));
1090 661 : break;
1091 654 : case ComparisonOperator::LESS_THAN:
1092 654 : push (Rust::Token::make (LEFT_ANGLE, expr.get_locus ()));
1093 654 : break;
1094 236 : case ComparisonOperator::GREATER_OR_EQUAL:
1095 236 : push (Rust::Token::make (GREATER_OR_EQUAL, expr.get_locus ()));
1096 236 : break;
1097 :
1098 286 : case ComparisonOperator::LESS_OR_EQUAL:
1099 286 : push (Rust::Token::make (LESS_OR_EQUAL, expr.get_locus ()));
1100 286 : break;
1101 : }
1102 3741 : visit (expr.get_right_expr ());
1103 3741 : });
1104 3741 : }
1105 :
1106 : void
1107 446 : TokenCollector::visit (LazyBooleanExpr &expr)
1108 : {
1109 446 : describe_node (std::string ("LazyBooleanExpr"), [this, &expr] () {
1110 446 : visit (expr.get_left_expr ());
1111 :
1112 446 : switch (expr.get_expr_type ())
1113 : {
1114 372 : case LazyBooleanOperator::LOGICAL_AND:
1115 372 : push (Rust::Token::make (LOGICAL_AND, expr.get_locus ()));
1116 372 : break;
1117 74 : case LazyBooleanOperator::LOGICAL_OR:
1118 74 : push (Rust::Token::make (OR, expr.get_locus ()));
1119 74 : break;
1120 : }
1121 :
1122 446 : visit (expr.get_right_expr ());
1123 446 : });
1124 446 : }
1125 :
1126 : void
1127 5256 : TokenCollector::visit (TypeCastExpr &expr)
1128 : {
1129 5256 : describe_node (std::string ("TypeCastExpr"), [this, &expr] () {
1130 5256 : visit (expr.get_casted_expr ());
1131 5256 : push (Rust::Token::make (AS, expr.get_locus ()));
1132 5256 : visit (expr.get_type_to_cast_to ());
1133 5256 : });
1134 5256 : }
1135 :
1136 : void
1137 2462 : TokenCollector::visit (AssignmentExpr &expr)
1138 : {
1139 2462 : describe_node (std::string ("AssignementExpr"), [this, &expr] () {
1140 2462 : expr.visit_lhs (*this);
1141 2462 : push (Rust::Token::make (EQUAL, expr.get_locus ()));
1142 2462 : expr.visit_rhs (*this);
1143 2462 : });
1144 2462 : }
1145 :
1146 : void
1147 696 : TokenCollector::visit (CompoundAssignmentExpr &expr)
1148 : {
1149 696 : describe_node (std::string ("CompoundAssignmentExpr"), [this, &expr] () {
1150 696 : visit (expr.get_left_expr ());
1151 :
1152 696 : switch (expr.get_expr_type ())
1153 : {
1154 170 : case CompoundAssignmentOperator::ADD:
1155 170 : push (Rust::Token::make (PLUS_EQ, expr.get_locus ()));
1156 170 : break;
1157 106 : case CompoundAssignmentOperator::SUBTRACT:
1158 106 : push (Rust::Token::make (MINUS_EQ, expr.get_locus ()));
1159 106 : break;
1160 7 : case CompoundAssignmentOperator::MULTIPLY:
1161 7 : push (Rust::Token::make (ASTERISK_EQ, expr.get_locus ()));
1162 7 : break;
1163 7 : case CompoundAssignmentOperator::DIVIDE:
1164 7 : push (Rust::Token::make (DIV_EQ, expr.get_locus ()));
1165 7 : break;
1166 7 : case CompoundAssignmentOperator::MODULUS:
1167 7 : push (Rust::Token::make (PERCENT_EQ, expr.get_locus ()));
1168 7 : break;
1169 21 : case CompoundAssignmentOperator::BITWISE_AND:
1170 21 : push (Rust::Token::make (AMP_EQ, expr.get_locus ()));
1171 21 : break;
1172 28 : case CompoundAssignmentOperator::BITWISE_OR:
1173 28 : push (Rust::Token::make (PIPE_EQ, expr.get_locus ()));
1174 28 : break;
1175 336 : case CompoundAssignmentOperator::BITWISE_XOR:
1176 336 : push (Rust::Token::make (CARET_EQ, expr.get_locus ()));
1177 336 : break;
1178 7 : case CompoundAssignmentOperator::LEFT_SHIFT:
1179 7 : push (Rust::Token::make (LEFT_SHIFT_EQ, expr.get_locus ()));
1180 7 : break;
1181 7 : case CompoundAssignmentOperator::RIGHT_SHIFT:
1182 7 : push (Rust::Token::make (RIGHT_SHIFT_EQ, expr.get_locus ()));
1183 7 : break;
1184 : }
1185 696 : visit (expr.get_right_expr ());
1186 696 : });
1187 696 : }
1188 :
1189 : void
1190 314 : TokenCollector::visit (GroupedExpr &expr)
1191 : {
1192 314 : describe_node (std::string ("GroupedExpr"), [this, &expr] () {
1193 314 : push (Rust::Token::make (LEFT_PAREN, expr.get_locus ()));
1194 314 : visit (expr.get_expr_in_parens ());
1195 314 : push (Rust::Token::make (RIGHT_PAREN, expr.get_locus ()));
1196 314 : });
1197 314 : }
1198 :
1199 : void
1200 288 : TokenCollector::visit (ArrayElemsValues &elems)
1201 : {
1202 288 : describe_node (std::string ("ArraysElemValues"), [this, &elems] () {
1203 288 : visit_items_joined_by_separator (elems.get_values (), COMMA);
1204 288 : });
1205 288 : }
1206 :
1207 : void
1208 113 : TokenCollector::visit (ArrayElemsCopied &elems)
1209 : {
1210 113 : describe_node (std::string ("ArrayElemsCopied"), [this, &elems] () {
1211 113 : visit (elems.get_elem_to_copy ());
1212 113 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
1213 113 : visit (elems.get_num_copies ());
1214 113 : });
1215 113 : }
1216 :
1217 : void
1218 401 : TokenCollector::visit (ArrayExpr &expr)
1219 : {
1220 401 : describe_node (std::string ("ArrayExpr"), [this, &expr] () {
1221 401 : push (Rust::Token::make (LEFT_SQUARE, expr.get_locus ()));
1222 401 : visit (expr.get_array_elems ());
1223 401 : push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION));
1224 401 : });
1225 401 : }
1226 :
1227 : void
1228 296 : TokenCollector::visit (ArrayIndexExpr &expr)
1229 : {
1230 296 : describe_node (std::string ("ArrayIndexExpr"), [this, &expr] () {
1231 296 : visit (expr.get_array_expr ());
1232 296 : push (Rust::Token::make (LEFT_SQUARE, expr.get_locus ()));
1233 296 : visit (expr.get_index_expr ());
1234 296 : push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION));
1235 296 : });
1236 296 : }
1237 :
1238 : void
1239 543 : TokenCollector::visit (TupleExpr &expr)
1240 : {
1241 543 : describe_node (std::string ("TupleExpr"), [this, &expr] () {
1242 543 : visit_items_as_lines (expr.get_outer_attrs ());
1243 543 : push (Rust::Token::make (LEFT_PAREN, expr.get_locus ()));
1244 543 : visit_items_joined_by_separator (expr.get_tuple_elems (), COMMA);
1245 543 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
1246 543 : });
1247 543 : }
1248 :
1249 : void
1250 889 : TokenCollector::visit (TupleIndexExpr &expr)
1251 : {
1252 889 : describe_node (std::string ("TupleIndexExpr"), [this, &expr] () {
1253 889 : visit (expr.get_tuple_expr ());
1254 889 : push (Rust::Token::make (DOT, expr.get_locus ()));
1255 889 : auto str = std::to_string (expr.get_tuple_index ());
1256 889 : auto suffix_start = str.length ();
1257 1778 : push (Rust::Token::make_int (UNDEF_LOCATION, str, suffix_start,
1258 : IntegerLiteralBase::Decimal));
1259 889 : });
1260 889 : }
1261 :
1262 : void
1263 79 : TokenCollector::visit (StructExprStruct &expr)
1264 : {
1265 79 : describe_node (std::string ("StructExprStruct"),
1266 158 : [this, &expr] () { visit (expr.get_struct_name ()); });
1267 79 : }
1268 :
1269 : void
1270 227 : TokenCollector::visit (StructExprFieldIdentifier &expr)
1271 : {
1272 227 : describe_node (std::string ("StructExprFieldIdentifier"), [this, &expr] () {
1273 227 : visit_items_as_lines (expr.get_outer_attrs ());
1274 454 : auto id = expr.get_field_name ().as_string ();
1275 454 : push (Rust::Token::make_identifier (expr.get_locus (), std::move (id)));
1276 227 : });
1277 227 : }
1278 :
1279 : void
1280 2019 : TokenCollector::visit (StructExprFieldIdentifierValue &expr)
1281 : {
1282 2019 : describe_node (std::string ("StructExprFieldIdentifierValue"), [this,
1283 : &expr] () {
1284 2019 : visit_items_as_lines (expr.get_outer_attrs ());
1285 2019 : auto id = expr.get_field_name ();
1286 4038 : push (Rust::Token::make_identifier (expr.get_locus (), std::move (id)));
1287 2019 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
1288 2019 : visit (expr.get_value ());
1289 2019 : });
1290 2019 : }
1291 :
1292 : void
1293 42 : TokenCollector::visit (StructExprFieldIndexValue &expr)
1294 : {
1295 42 : describe_node (std::string ("StructExprFieldIndexValue"), [this, &expr] () {
1296 42 : visit_items_as_lines (expr.get_outer_attrs ());
1297 42 : auto str = std::to_string (expr.get_index ());
1298 42 : auto suffix_start = str.length ();
1299 84 : push (Rust::Token::make_int (expr.get_locus (), str, suffix_start,
1300 : IntegerLiteralBase::Decimal));
1301 42 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
1302 42 : visit (expr.get_value ());
1303 42 : });
1304 42 : }
1305 :
1306 : void
1307 63 : TokenCollector::visit (StructBase &base)
1308 : {
1309 63 : describe_node (std::string ("StructBase"), [this, &base] () {
1310 63 : push (Rust::Token::make (DOT_DOT, UNDEF_LOCATION));
1311 63 : visit (base.get_base_struct ());
1312 63 : });
1313 63 : }
1314 :
1315 : void
1316 1338 : TokenCollector::visit (StructExprStructFields &expr)
1317 : {
1318 1338 : describe_node (std::string ("StructExprStructFields"), [this, &expr] () {
1319 1338 : visit (expr.get_struct_name ());
1320 1338 : push (Rust::Token::make (LEFT_CURLY, expr.get_locus ()));
1321 1338 : visit_items_joined_by_separator (expr.get_fields (), COMMA);
1322 1338 : if (expr.has_struct_base ())
1323 : {
1324 63 : push (Rust::Token::make (COMMA, UNDEF_LOCATION));
1325 63 : visit (expr.get_struct_base ());
1326 : }
1327 : else
1328 : {
1329 1275 : trailing_comma ();
1330 : }
1331 1338 : push (Rust::Token::make (RIGHT_CURLY, expr.get_locus ()));
1332 1338 : });
1333 1338 : }
1334 :
1335 : void
1336 0 : TokenCollector::visit (StructExprStructBase &)
1337 : {
1338 : // FIXME: Implement this node
1339 0 : rust_unreachable ();
1340 : }
1341 :
1342 : void
1343 12456 : TokenCollector::visit (CallExpr &expr)
1344 : {
1345 12456 : describe_node (std::string ("CallExpr"), [this, &expr] () {
1346 12456 : visit (expr.get_function_expr ());
1347 :
1348 12456 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
1349 :
1350 12456 : visit_items_joined_by_separator (expr.get_params (), COMMA);
1351 :
1352 12456 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
1353 12456 : });
1354 12456 : }
1355 :
1356 : void
1357 3091 : TokenCollector::visit (MethodCallExpr &expr)
1358 : {
1359 3091 : describe_node (std::string ("MethodCallExpr"), [this, &expr] () {
1360 3091 : visit (expr.get_receiver_expr ());
1361 3091 : push (Rust::Token::make (DOT, expr.get_locus ()));
1362 3091 : visit (expr.get_method_name ());
1363 3091 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
1364 3091 : visit_items_joined_by_separator (expr.get_params (), COMMA);
1365 3091 : trailing_comma ();
1366 3091 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
1367 3091 : });
1368 3091 : }
1369 :
1370 : void
1371 5085 : TokenCollector::visit (FieldAccessExpr &expr)
1372 : {
1373 5085 : describe_node (std::string ("FieldAccessExpr"), [this, &expr] () {
1374 5085 : visit (expr.get_receiver_expr ());
1375 5085 : push (Rust::Token::make (DOT, expr.get_locus ()));
1376 10170 : auto field_name = expr.get_field_name ().as_string ();
1377 5085 : push (
1378 10170 : Rust::Token::make_identifier (UNDEF_LOCATION, std::move (field_name)));
1379 5085 : });
1380 5085 : }
1381 :
1382 : void
1383 65 : TokenCollector::visit (ClosureParam ¶m)
1384 : {
1385 65 : describe_node (std::string ("ClosureParam"), [this, ¶m] () {
1386 65 : visit_items_as_lines (param.get_outer_attrs ());
1387 65 : visit (param.get_pattern ());
1388 65 : if (param.has_type_given ())
1389 : {
1390 58 : push (Rust::Token::make (COLON, param.get_locus ()));
1391 58 : visit (param.get_type ());
1392 : }
1393 65 : });
1394 65 : }
1395 :
1396 : void
1397 66 : TokenCollector::visit_closure_common (ClosureExpr &expr)
1398 : {
1399 66 : describe_node (std::string ("ClosureExpr"), [this, &expr] () {
1400 66 : if (expr.get_has_move ())
1401 : {
1402 0 : push (Rust::Token::make (MOVE, expr.get_locus ()));
1403 : }
1404 66 : push (Rust::Token::make (PIPE, UNDEF_LOCATION));
1405 66 : visit_items_joined_by_separator (expr.get_params (), COMMA);
1406 66 : push (Rust::Token::make (PIPE, UNDEF_LOCATION));
1407 66 : });
1408 66 : }
1409 :
1410 : void
1411 36 : TokenCollector::visit (ClosureExprInner &expr)
1412 : {
1413 36 : describe_node (std::string ("ClosureExprInner"), [this, &expr] () {
1414 36 : visit_closure_common (expr);
1415 36 : visit (expr.get_definition_expr ());
1416 36 : });
1417 36 : }
1418 :
1419 : void
1420 22823 : TokenCollector::visit (BlockExpr &expr)
1421 : {
1422 22823 : describe_node (std::string ("BlockExpr"), [this, &expr] () {
1423 22823 : visit_items_as_lines (expr.get_outer_attrs ());
1424 22823 : push (Rust::Token::make (LEFT_CURLY, expr.get_locus ()));
1425 22823 : newline ();
1426 22823 : increment_indentation ();
1427 22823 : visit_items_as_lines (expr.get_inner_attrs ());
1428 :
1429 22823 : visit_items_as_lines (expr.get_statements (), {});
1430 :
1431 22823 : if (expr.has_tail_expr ())
1432 : {
1433 16124 : indentation ();
1434 16124 : visit (expr.get_tail_expr ());
1435 16124 : newline ();
1436 : }
1437 :
1438 22823 : decrement_indentation ();
1439 22823 : indentation ();
1440 22823 : push (Rust::Token::make (RIGHT_CURLY, expr.get_locus ()));
1441 22823 : newline ();
1442 22823 : });
1443 22823 : }
1444 :
1445 : void
1446 817 : TokenCollector::visit (AnonConst &expr)
1447 : {
1448 817 : if (!expr.is_deferred ())
1449 : {
1450 797 : visit (expr.get_inner_expr ());
1451 797 : return;
1452 : }
1453 :
1454 40 : push (Rust::Token::make_string (expr.get_locus (), "_"));
1455 : }
1456 :
1457 : void
1458 14 : TokenCollector::visit (ConstBlock &expr)
1459 : {
1460 14 : push (Rust::Token::make (CONST, expr.get_locus ()));
1461 :
1462 : // The inner expression is already a block expr, so we don't need to add
1463 : // curlies
1464 14 : visit (expr.get_const_expr ());
1465 14 : }
1466 :
1467 : void
1468 30 : TokenCollector::visit (ClosureExprInnerTyped &expr)
1469 : {
1470 30 : describe_node (std::string ("ClosureExprInnerTyped"), [this, &expr] () {
1471 30 : visit_closure_common (expr);
1472 30 : push (Rust::Token::make (RETURN_TYPE, expr.get_locus ()));
1473 30 : visit (expr.get_return_type ());
1474 :
1475 30 : visit (expr.get_definition_expr ());
1476 30 : });
1477 30 : }
1478 :
1479 : void
1480 22 : TokenCollector::visit (ContinueExpr &expr)
1481 : {
1482 22 : describe_node (std::string ("ContinueExpr"), [this, &expr] () {
1483 22 : push (Rust::Token::make (CONTINUE, expr.get_locus ()));
1484 22 : if (expr.has_label ())
1485 6 : visit (expr.get_label_unchecked ());
1486 22 : });
1487 22 : }
1488 :
1489 : void
1490 99 : TokenCollector::visit (BreakExpr &expr)
1491 : {
1492 99 : describe_node (std::string ("BreakExpr"), [this, &expr] () {
1493 99 : push (Rust::Token::make (BREAK, expr.get_locus ()));
1494 99 : if (expr.has_label ())
1495 32 : visit (expr.get_label_unchecked ());
1496 99 : if (expr.has_break_expr ())
1497 19 : visit (expr.get_break_expr_unchecked ());
1498 99 : });
1499 99 : }
1500 :
1501 : void
1502 66 : TokenCollector::visit (RangeFromToExpr &expr)
1503 : {
1504 66 : describe_node (std::string ("RangeFromToExpr"), [this, &expr] () {
1505 66 : visit (expr.get_from_expr ());
1506 66 : push (Rust::Token::make (DOT_DOT, expr.get_locus ()));
1507 66 : visit (expr.get_to_expr ());
1508 66 : });
1509 66 : }
1510 :
1511 : void
1512 13 : TokenCollector::visit (RangeFromExpr &expr)
1513 : {
1514 13 : describe_node (std::string ("RangeFromExpr"), [this, &expr] () {
1515 13 : visit (expr.get_from_expr ());
1516 13 : push (Rust::Token::make (DOT_DOT, expr.get_locus ()));
1517 13 : });
1518 13 : }
1519 :
1520 : void
1521 7 : TokenCollector::visit (RangeToExpr &expr)
1522 : {
1523 7 : describe_node (std::string ("RangeToExpr"), [this, &expr] () {
1524 7 : push (Rust::Token::make (DOT_DOT, expr.get_locus ()));
1525 7 : visit (expr.get_to_expr ());
1526 7 : });
1527 7 : }
1528 :
1529 : void
1530 0 : TokenCollector::visit (RangeFullExpr &expr)
1531 : {
1532 0 : describe_node (std::string ("RangeFullExpr"), [this, &expr] () {
1533 0 : push (Rust::Token::make (DOT_DOT, expr.get_locus ()));
1534 0 : });
1535 0 : }
1536 :
1537 : void
1538 7 : TokenCollector::visit (RangeFromToInclExpr &expr)
1539 : {
1540 7 : describe_node (std::string ("RangeFromToInclExpr"), [this, &expr] () {
1541 7 : visit (expr.get_from_expr ());
1542 7 : push (Rust::Token::make (DOT_DOT_EQ, expr.get_locus ()));
1543 7 : visit (expr.get_to_expr ());
1544 7 : });
1545 7 : }
1546 :
1547 : void
1548 0 : TokenCollector::visit (RangeToInclExpr &expr)
1549 : {
1550 0 : describe_node (std::string ("RangeToInclExpr"), [this, &expr] () {
1551 0 : push (Rust::Token::make (DOT_DOT_EQ, expr.get_locus ()));
1552 0 : visit (expr.get_to_expr ());
1553 0 : });
1554 0 : }
1555 :
1556 : void
1557 1 : TokenCollector::visit (BoxExpr &expr)
1558 : {
1559 1 : describe_node (std::string ("BoxExpr"), [this, &expr] () {
1560 1 : push (Rust::Token::make (BOX, expr.get_locus ()));
1561 1 : visit (expr.get_boxed_expr ());
1562 1 : });
1563 1 : }
1564 :
1565 : void
1566 541 : TokenCollector::visit (ReturnExpr &expr)
1567 : {
1568 541 : describe_node (std::string ("ReturnExpr"), [this, &expr] () {
1569 541 : push (Rust::Token::make (RETURN_KW, expr.get_locus ()));
1570 541 : if (expr.has_returned_expr ())
1571 507 : visit (expr.get_returned_expr ());
1572 541 : });
1573 541 : }
1574 :
1575 : void
1576 0 : TokenCollector::visit (TryExpr &expr)
1577 : {
1578 0 : push (Rust::Token::make (TRY, expr.get_locus ()));
1579 0 : visit (expr.get_block_expr ());
1580 0 : }
1581 :
1582 : void
1583 3640 : TokenCollector::visit (UnsafeBlockExpr &expr)
1584 : {
1585 3640 : describe_node (std::string ("UnsafeBlockExpr"), [this, &expr] () {
1586 3640 : push (Rust::Token::make (UNSAFE, expr.get_locus ()));
1587 3640 : visit (expr.get_block_expr ());
1588 3640 : });
1589 3640 : }
1590 :
1591 : void
1592 82 : TokenCollector::visit (LoopLabel &label)
1593 : {
1594 82 : describe_node (std::string ("LoopLabel"), [this, &label] () {
1595 82 : visit (label.get_lifetime ());
1596 82 : push (Rust::Token::make (COLON, label.get_locus ()));
1597 82 : });
1598 82 : }
1599 :
1600 : void
1601 213 : TokenCollector::visit_loop_common (BaseLoopExpr &expr)
1602 : {
1603 213 : describe_node (std::string ("BaseLoopExpr"), [this, &expr] () {
1604 213 : if (expr.has_loop_label ())
1605 50 : visit (expr.get_loop_label ());
1606 213 : });
1607 213 : }
1608 :
1609 : void
1610 133 : TokenCollector::visit (LoopExpr &expr)
1611 : {
1612 133 : describe_node (std::string ("LoopExpr"), [this, &expr] () {
1613 133 : visit_loop_common (expr);
1614 133 : push (Rust::Token::make (LOOP, expr.get_locus ()));
1615 133 : visit (expr.get_loop_block ());
1616 133 : });
1617 133 : }
1618 :
1619 : void
1620 80 : TokenCollector::visit (WhileLoopExpr &expr)
1621 : {
1622 80 : describe_node (std::string ("WhileLoopExpr"), [this, &expr] () {
1623 80 : visit_loop_common (expr);
1624 80 : push (Rust::Token::make (WHILE, expr.get_locus ()));
1625 80 : visit (expr.get_predicate_expr ());
1626 80 : visit (expr.get_loop_block ());
1627 80 : });
1628 80 : }
1629 :
1630 : void
1631 0 : TokenCollector::visit (WhileLetLoopExpr &expr)
1632 : {
1633 0 : describe_node (std::string ("WhileLetLoopExpr"), [this, &expr] () {
1634 0 : visit_loop_common (expr);
1635 0 : push (Rust::Token::make (WHILE, expr.get_locus ()));
1636 0 : push (Rust::Token::make (LET, UNDEF_LOCATION));
1637 0 : visit (expr.get_pattern ());
1638 0 : push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
1639 0 : visit (expr.get_scrutinee_expr ());
1640 0 : visit (expr.get_loop_block ());
1641 0 : });
1642 0 : }
1643 :
1644 : void
1645 0 : TokenCollector::visit (ForLoopExpr &expr)
1646 : {
1647 0 : describe_node (std::string ("ForLoopExpr"), [this, &expr] () {
1648 0 : visit_loop_common (expr);
1649 0 : push (Rust::Token::make (FOR, expr.get_locus ()));
1650 0 : visit (expr.get_pattern ());
1651 0 : push (Rust::Token::make (IN, UNDEF_LOCATION));
1652 0 : visit (expr.get_iterator_expr ());
1653 0 : visit (expr.get_loop_block ());
1654 0 : });
1655 0 : }
1656 :
1657 : void
1658 2671 : TokenCollector::visit (IfExpr &expr)
1659 : {
1660 2671 : describe_node (std::string ("IfExpr"), [this, &expr] () {
1661 2671 : push (Rust::Token::make (IF, expr.get_locus ()));
1662 :
1663 2671 : visit (expr.get_condition_expr ());
1664 2671 : visit (expr.get_if_block ());
1665 2671 : });
1666 2671 : }
1667 :
1668 : void
1669 1255 : TokenCollector::visit (IfExprConseqElse &expr)
1670 : {
1671 1255 : describe_node (std::string ("IfExprConseqElse"), [this, &expr] () {
1672 1255 : visit (static_cast<IfExpr &> (expr));
1673 1255 : indentation ();
1674 1255 : push (Rust::Token::make (ELSE, expr.get_locus ()));
1675 1255 : visit (expr.get_else_block ());
1676 1255 : });
1677 1255 : }
1678 :
1679 : void
1680 29 : TokenCollector::visit (IfLetExpr &expr)
1681 : {
1682 29 : describe_node (std::string ("IfLetExpr"), [this, &expr] () {
1683 29 : push (Rust::Token::make (IF, expr.get_locus ()));
1684 29 : push (Rust::Token::make (LET, UNDEF_LOCATION));
1685 29 : visit (expr.get_pattern ());
1686 29 : push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
1687 29 : visit (expr.get_value_expr ());
1688 29 : visit (expr.get_if_block ());
1689 29 : });
1690 29 : }
1691 :
1692 : void
1693 12 : TokenCollector::visit (IfLetExprConseqElse &expr)
1694 : {
1695 12 : describe_node (std::string ("IfLetExprConseqElse"), [this, &expr] () {
1696 12 : visit (static_cast<IfLetExpr &> (expr));
1697 12 : indentation ();
1698 12 : push (Rust::Token::make (ELSE, expr.get_locus ()));
1699 12 : visit (expr.get_else_block ());
1700 12 : });
1701 12 : }
1702 :
1703 : void
1704 2417 : TokenCollector::visit (MatchArm &arm)
1705 : {
1706 2417 : describe_node (std::string ("MatchArm"), [this, &arm] () {
1707 2417 : visit_items_as_lines (arm.get_outer_attrs ());
1708 2417 : visit (arm.get_pattern ());
1709 2417 : if (arm.has_match_arm_guard ())
1710 : {
1711 1 : push (Rust::Token::make (IF, UNDEF_LOCATION));
1712 1 : visit (arm.get_guard_expr ());
1713 : }
1714 2417 : });
1715 2417 : }
1716 :
1717 : void
1718 2417 : TokenCollector::visit (MatchCase &match_case)
1719 : {
1720 2417 : describe_node (std::string ("MatchCase"), [this, &match_case] () {
1721 2417 : indentation ();
1722 2417 : visit (match_case.get_arm ());
1723 2417 : push (Rust::Token::make (MATCH_ARROW, UNDEF_LOCATION));
1724 2417 : visit (match_case.get_expr ());
1725 2417 : indentation ();
1726 2417 : push (Rust::Token::make (COMMA, UNDEF_LOCATION));
1727 2417 : newline ();
1728 2417 : });
1729 2417 : }
1730 :
1731 : void
1732 1045 : TokenCollector::visit (MatchExpr &expr)
1733 : {
1734 1045 : describe_node (std::string ("MatchExpr"), [this, &expr] () {
1735 1045 : push (Rust::Token::make (MATCH_KW, expr.get_locus ()));
1736 1045 : visit (expr.get_scrutinee_expr ());
1737 1045 : push (Rust::Token::make (LEFT_CURLY, UNDEF_LOCATION));
1738 1045 : newline ();
1739 1045 : increment_indentation ();
1740 1045 : visit_items_as_lines (expr.get_inner_attrs ());
1741 3462 : for (auto &arm : expr.get_match_cases ())
1742 : {
1743 2417 : visit (arm);
1744 : }
1745 1045 : decrement_indentation ();
1746 1045 : indentation ();
1747 1045 : push (Rust::Token::make (RIGHT_CURLY, UNDEF_LOCATION));
1748 1045 : });
1749 1045 : }
1750 :
1751 : void
1752 0 : TokenCollector::visit (AwaitExpr &expr)
1753 : {
1754 0 : describe_node (std::string ("AwaitExpr"), [this, &expr] () {
1755 0 : visit (expr.get_awaited_expr ());
1756 0 : push (Rust::Token::make (DOT, expr.get_locus ()));
1757 : // TODO: Check status of await keyword (Context dependant ?)
1758 0 : push (
1759 0 : Rust::Token::make_identifier (UNDEF_LOCATION, Values::Keywords::AWAIT));
1760 0 : });
1761 0 : }
1762 :
1763 : void
1764 0 : TokenCollector::visit (AsyncBlockExpr &expr)
1765 : {
1766 0 : describe_node (std::string ("AsyncBlockExpr"), [this, &expr] () {
1767 0 : push (Rust::Token::make (ASYNC, expr.get_locus ()));
1768 0 : if (expr.get_has_move ())
1769 0 : push (Rust::Token::make (MOVE, UNDEF_LOCATION));
1770 0 : visit (expr.get_block_expr ());
1771 0 : });
1772 0 : }
1773 :
1774 : void
1775 26 : TokenCollector::visit (InlineAsm &expr)
1776 : {
1777 52 : push (Rust::Token::make_identifier (expr.get_locus (), "asm"));
1778 26 : push (Rust::Token::make (EXCLAM, expr.get_locus ()));
1779 26 : push (Rust::Token::make (LEFT_PAREN, expr.get_locus ()));
1780 :
1781 52 : for (auto &template_str : expr.get_template_strs ())
1782 52 : push (Rust::Token::make_string (template_str.get_locus (),
1783 52 : std::move (template_str.symbol)));
1784 :
1785 26 : push (Rust::Token::make (COLON, expr.get_locus ()));
1786 :
1787 55 : for (auto &operand : expr.get_operands ())
1788 : {
1789 29 : using RegisterType = AST::InlineAsmOperand::RegisterType;
1790 29 : switch (operand.get_register_type ())
1791 : {
1792 10 : case RegisterType::In:
1793 10 : {
1794 10 : visit (operand.get_in ().expr);
1795 10 : break;
1796 : }
1797 17 : case RegisterType::Out:
1798 17 : {
1799 17 : visit (operand.get_out ().expr);
1800 17 : break;
1801 : }
1802 0 : case RegisterType::InOut:
1803 0 : {
1804 0 : visit (operand.get_in_out ().expr);
1805 0 : break;
1806 : }
1807 2 : case RegisterType::SplitInOut:
1808 2 : {
1809 2 : auto split = operand.get_split_in_out ();
1810 2 : visit (split.in_expr);
1811 2 : visit (split.out_expr);
1812 2 : break;
1813 2 : }
1814 0 : case RegisterType::Const:
1815 0 : {
1816 0 : visit (operand.get_const ().anon_const.get_inner_expr ());
1817 0 : break;
1818 : }
1819 0 : case RegisterType::Sym:
1820 0 : {
1821 0 : visit (operand.get_sym ().expr);
1822 0 : break;
1823 : }
1824 0 : case RegisterType::Label:
1825 0 : {
1826 0 : visit (operand.get_label ().expr);
1827 0 : break;
1828 : }
1829 : }
1830 58 : push (Rust::Token::make (COMMA, expr.get_locus ()));
1831 26 : }
1832 26 : push (Rust::Token::make (COLON, expr.get_locus ()));
1833 :
1834 26 : for (auto &clobber : expr.get_clobber_abi ())
1835 : {
1836 0 : push (Rust::Token::make_string (expr.get_locus (),
1837 0 : std::move (clobber.symbol)));
1838 0 : push (Rust::Token::make (COMMA, expr.get_locus ()));
1839 26 : }
1840 26 : push (Rust::Token::make (COLON, expr.get_locus ()));
1841 :
1842 26 : for (auto it = expr.named_args.begin (); it != expr.named_args.end (); ++it)
1843 : {
1844 0 : auto &arg = *it;
1845 0 : push (
1846 0 : Rust::Token::make_identifier (expr.get_locus (), arg.first.c_str ()));
1847 0 : push (Rust::Token::make (EQUAL, expr.get_locus ()));
1848 0 : push (Rust::Token::make_identifier (expr.get_locus (),
1849 0 : std::to_string (arg.second)));
1850 :
1851 0 : push (Rust::Token::make (COMMA, expr.get_locus ()));
1852 : }
1853 :
1854 26 : push (Rust::Token::make (COLON, expr.get_locus ()));
1855 :
1856 31 : for (auto &option : expr.get_options ())
1857 : {
1858 10 : push (Rust::Token::make_identifier (
1859 10 : expr.get_locus (), InlineAsm::option_to_string (option).c_str ()));
1860 10 : push (Rust::Token::make (COMMA, expr.get_locus ()));
1861 26 : }
1862 :
1863 26 : push (Rust::Token::make (RIGHT_PAREN, expr.get_locus ()));
1864 26 : }
1865 :
1866 : void
1867 2 : TokenCollector::visit (LlvmInlineAsm &expr)
1868 : {
1869 4 : push (Rust::Token::make_identifier (expr.get_locus (), "llvm_asm"));
1870 2 : push (Rust::Token::make (EXCLAM, expr.get_locus ()));
1871 2 : push (Rust::Token::make (LEFT_PAREN, expr.get_locus ()));
1872 4 : for (auto &template_str : expr.get_templates ())
1873 4 : push (Rust::Token::make_string (template_str.get_locus (),
1874 2 : std::move (template_str.symbol)));
1875 :
1876 2 : push (Rust::Token::make (COLON, expr.get_locus ()));
1877 2 : for (auto output : expr.get_outputs ())
1878 : {
1879 0 : push (Rust::Token::make_string (expr.get_locus (),
1880 : std::move (output.constraint)));
1881 0 : visit (output.expr);
1882 0 : push (Rust::Token::make (COMMA, expr.get_locus ()));
1883 0 : }
1884 :
1885 2 : push (Rust::Token::make (COLON, expr.get_locus ()));
1886 4 : for (auto input : expr.get_inputs ())
1887 : {
1888 4 : push (Rust::Token::make_string (expr.get_locus (),
1889 : std::move (input.constraint)));
1890 2 : visit (input.expr);
1891 4 : push (Rust::Token::make (COMMA, expr.get_locus ()));
1892 2 : }
1893 :
1894 2 : push (Rust::Token::make (COLON, expr.get_locus ()));
1895 4 : for (auto &clobber : expr.get_clobbers ())
1896 : {
1897 4 : push (Rust::Token::make_string (expr.get_locus (),
1898 2 : std::move (clobber.symbol)));
1899 4 : push (Rust::Token::make (COMMA, expr.get_locus ()));
1900 : }
1901 2 : push (Rust::Token::make (COLON, expr.get_locus ()));
1902 : // Dump options
1903 :
1904 2 : push (Rust::Token::make (RIGHT_PAREN, expr.get_locus ()));
1905 2 : }
1906 :
1907 : // rust-item.h
1908 :
1909 : void
1910 4451 : TokenCollector::visit (TypeParam ¶m)
1911 : {
1912 : // Syntax:
1913 : // IDENTIFIER( : TypeParamBounds? )? ( = Type )?
1914 : // TypeParamBounds :
1915 : // TypeParamBound ( + TypeParamBound )* +?
1916 4451 : describe_node (std::string ("TypeParam"), [this, ¶m] () {
1917 4451 : visit_items_as_lines (param.get_outer_attrs ());
1918 8902 : auto id = param.get_type_representation ().as_string ();
1919 8902 : push (Rust::Token::make_identifier (param.get_locus (), std::move (id)));
1920 4451 : if (param.has_type_param_bounds ())
1921 : {
1922 761 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
1923 761 : visit_items_joined_by_separator (param.get_type_param_bounds (), PLUS);
1924 : }
1925 4451 : if (param.has_type ())
1926 : {
1927 347 : push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
1928 347 : visit (param.get_type ());
1929 : }
1930 4451 : });
1931 4451 : }
1932 :
1933 : void
1934 285 : TokenCollector::visit (WhereClause &rule)
1935 : {
1936 : // Syntax:
1937 : // where ( WhereClauseItem , )* WhereClauseItem ?
1938 : // WhereClauseItem :
1939 : // LifetimeWhereClauseItem
1940 : // | TypeBoundWhereClauseItem
1941 285 : describe_node (std::string ("WhereClause"), [this, &rule] () {
1942 285 : push (Rust::Token::make (WHERE, UNDEF_LOCATION));
1943 285 : newline ();
1944 285 : increment_indentation ();
1945 285 : visit_items_joined_by_separator (rule.get_items (), COMMA);
1946 285 : decrement_indentation ();
1947 285 : });
1948 285 : }
1949 :
1950 : void
1951 0 : TokenCollector::visit (LifetimeWhereClauseItem &item)
1952 : {
1953 : // Syntax:
1954 : // Lifetime : LifetimeBounds
1955 : // LifetimeBounds :
1956 : // ( Lifetime + )* Lifetime?
1957 :
1958 0 : describe_node (std::string ("LifetimeWhereClauseItem"), [this, &item] () {
1959 0 : visit (item.get_lifetime ());
1960 0 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
1961 0 : visit_items_joined_by_separator (item.get_lifetime_bounds (), PLUS);
1962 0 : });
1963 0 : }
1964 :
1965 : void
1966 305 : TokenCollector::visit (TypeBoundWhereClauseItem &item)
1967 : {
1968 : // Syntax:
1969 : // ForLifetimes? Type : TypeParamBounds?
1970 : // TypeParamBounds :
1971 : // TypeParamBound ( + TypeParamBound )* +?
1972 : // TypeParamBound :
1973 : // Lifetime | TraitBound
1974 :
1975 305 : describe_node (std::string ("TypeBoundWhereClauseItem"), [this, &item] () {
1976 305 : if (item.has_for_lifetimes ())
1977 7 : visit (item.get_for_lifetimes ());
1978 :
1979 305 : visit (item.get_type ());
1980 :
1981 305 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
1982 305 : visit_items_joined_by_separator (item.get_type_param_bounds (), PLUS);
1983 305 : });
1984 305 : }
1985 :
1986 : void
1987 1139 : TokenCollector::visit (Module &module)
1988 : {
1989 : // Syntax:
1990 : // mod IDENTIFIER ;
1991 : // | mod IDENTIFIER {
1992 : // InnerAttribute*
1993 : // Item*
1994 : // }
1995 1139 : describe_node (std::string ("Module"), [this, &module] () {
1996 1139 : visit_items_as_lines (module.get_outer_attrs ());
1997 1139 : visit (module.get_visibility ());
1998 2278 : auto name = module.get_name ().as_string ();
1999 1139 : push (Rust::Token::make (MOD, module.get_locus ()));
2000 2278 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (name)));
2001 :
2002 1139 : if (module.get_kind () == Module::UNLOADED)
2003 : {
2004 0 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2005 0 : newline ();
2006 : }
2007 : else /* Module::LOADED */
2008 : {
2009 1139 : push (Rust::Token::make (LEFT_CURLY, UNDEF_LOCATION));
2010 1139 : newline ();
2011 1139 : increment_indentation ();
2012 :
2013 1139 : visit_items_as_lines (module.get_inner_attrs ());
2014 1139 : visit_items_as_lines (module.get_items ());
2015 :
2016 1139 : decrement_indentation ();
2017 :
2018 1139 : push (Rust::Token::make (RIGHT_CURLY, UNDEF_LOCATION));
2019 1139 : newline ();
2020 : }
2021 1139 : });
2022 1139 : }
2023 :
2024 : void
2025 25 : TokenCollector::visit (ExternCrate &crate)
2026 : {
2027 25 : describe_node (std::string ("ExternCrate"), [this, &crate] () {
2028 25 : visit_items_as_lines (crate.get_outer_attrs ());
2029 25 : push (Rust::Token::make (EXTERN_KW, crate.get_locus ()));
2030 25 : push (Rust::Token::make (CRATE, UNDEF_LOCATION));
2031 25 : auto ref = crate.get_referenced_crate ();
2032 50 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (ref)));
2033 25 : if (crate.has_as_clause ())
2034 : {
2035 1 : auto as_clause = crate.get_as_clause ();
2036 1 : push (Rust::Token::make (AS, UNDEF_LOCATION));
2037 1 : push (
2038 2 : Rust::Token::make_identifier (UNDEF_LOCATION, std::move (as_clause)));
2039 1 : }
2040 25 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2041 25 : newline ();
2042 25 : });
2043 25 : }
2044 :
2045 : void
2046 15 : TokenCollector::visit (UseTreeGlob &use_tree)
2047 : {
2048 15 : describe_node (std::string ("UseTreeGlob"), [this, &use_tree] () {
2049 15 : switch (use_tree.get_glob_type ())
2050 : {
2051 14 : case UseTreeGlob::PathType::PATH_PREFIXED:
2052 14 : {
2053 14 : auto path = use_tree.get_path ();
2054 14 : visit (path);
2055 28 : push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
2056 14 : }
2057 14 : break;
2058 0 : case UseTreeGlob::PathType::NO_PATH:
2059 0 : push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
2060 0 : break;
2061 : case UseTreeGlob::PathType::GLOBAL:
2062 : break;
2063 : }
2064 15 : push (Rust::Token::make (ASTERISK, UNDEF_LOCATION));
2065 15 : });
2066 15 : }
2067 :
2068 : void
2069 152 : TokenCollector::visit (UseTreeList &use_tree)
2070 : {
2071 152 : describe_node (std::string ("UseTreeList"), [this, &use_tree] () {
2072 152 : switch (use_tree.get_path_type ())
2073 : {
2074 152 : case UseTreeList::PathType::PATH_PREFIXED:
2075 152 : {
2076 152 : auto path = use_tree.get_path ();
2077 152 : visit (path);
2078 :
2079 304 : push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
2080 152 : }
2081 152 : break;
2082 0 : case UseTreeList::PathType::NO_PATH:
2083 0 : push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
2084 0 : break;
2085 : case UseTreeList::PathType::GLOBAL:
2086 : break;
2087 : }
2088 :
2089 152 : push (Rust::Token::make (LEFT_CURLY, UNDEF_LOCATION));
2090 152 : if (use_tree.has_trees ())
2091 : {
2092 152 : visit_items_joined_by_separator (use_tree.get_trees (), COMMA);
2093 : }
2094 152 : push (Rust::Token::make (RIGHT_CURLY, UNDEF_LOCATION));
2095 152 : });
2096 152 : }
2097 :
2098 : void
2099 1066 : TokenCollector::visit (UseTreeRebind &use_tree)
2100 : {
2101 1066 : describe_node (std::string ("UseTreeRebind"), [this, &use_tree] () {
2102 1066 : auto path = use_tree.get_path ();
2103 1066 : visit (path);
2104 1066 : switch (use_tree.get_new_bind_type ())
2105 : {
2106 2 : case UseTreeRebind::NewBindType::IDENTIFIER:
2107 2 : {
2108 2 : push (Rust::Token::make (AS, UNDEF_LOCATION));
2109 2 : auto id = use_tree.get_identifier ().as_string ();
2110 4 : push (Rust::Token::make_identifier (use_tree.get_locus (),
2111 : std::move (id)));
2112 2 : }
2113 2 : break;
2114 2 : case UseTreeRebind::NewBindType::WILDCARD:
2115 2 : push (Rust::Token::make (AS, UNDEF_LOCATION));
2116 2 : push (Rust::Token::make (UNDERSCORE, use_tree.get_locus ()));
2117 2 : break;
2118 : case UseTreeRebind::NewBindType::NONE:
2119 : break;
2120 : }
2121 1066 : });
2122 1066 : }
2123 :
2124 : void
2125 655 : TokenCollector::visit (UseDeclaration &decl)
2126 : {
2127 655 : describe_node (std::string ("UseDeclaration"), [this, &decl] () {
2128 655 : visit_items_as_lines (decl.get_outer_attrs ());
2129 655 : push (Rust::Token::make (USE, decl.get_locus ()));
2130 655 : visit (*decl.get_tree ());
2131 655 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2132 655 : newline ();
2133 655 : });
2134 655 : }
2135 :
2136 : void
2137 18056 : TokenCollector::visit (Function &function)
2138 : {
2139 : // Syntax:
2140 : // FunctionQualifiers fn IDENTIFIER GenericParams?
2141 : // ( FunctionParameters? )
2142 : // FunctionReturnType? WhereClause?
2143 : // ( BlockExpression | ; )
2144 18056 : describe_node (std::string ("Function"), [this, &function] () {
2145 18056 : visit_items_as_lines (function.get_outer_attrs ());
2146 :
2147 18056 : visit (function.get_visibility ());
2148 18056 : auto qualifiers = function.get_qualifiers ();
2149 18056 : visit (qualifiers);
2150 :
2151 18056 : push (Rust::Token::make (FN_KW, function.get_locus ()));
2152 36112 : auto name = function.get_function_name ().as_string ();
2153 36112 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (name)));
2154 18056 : if (function.has_generics ())
2155 1641 : visit (function.get_generic_params ());
2156 :
2157 18056 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
2158 :
2159 18056 : visit_items_joined_by_separator (function.get_function_params ());
2160 18056 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
2161 :
2162 18056 : if (function.has_return_type ())
2163 : {
2164 12971 : push (Rust::Token::make (RETURN_TYPE, UNDEF_LOCATION));
2165 12971 : visit (function.get_return_type ());
2166 : }
2167 :
2168 18056 : if (function.has_where_clause ())
2169 200 : visit (function.get_where_clause ());
2170 :
2171 18056 : if (function.has_body ())
2172 13892 : visit (*function.get_definition ());
2173 : else
2174 8328 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2175 18056 : newline ();
2176 18056 : });
2177 18056 : }
2178 :
2179 : void
2180 1236 : TokenCollector::visit (TypeAlias &type_alias)
2181 : {
2182 : // Syntax:
2183 : // Visibility? type IDENTIFIER GenericParams? WhereClause? = Type;
2184 :
2185 : // Note: Associated types are handled by `AST::TraitItemType`.
2186 1236 : describe_node (std::string ("TypeAlias"), [this, &type_alias] () {
2187 1236 : visit_items_as_lines (type_alias.get_outer_attrs ());
2188 1236 : if (type_alias.has_visibility ())
2189 16 : visit (type_alias.get_visibility ());
2190 2472 : auto alias_name = type_alias.get_new_type_name ().as_string ();
2191 1236 : push (Rust::Token::make (TYPE, type_alias.get_locus ()));
2192 1236 : push (
2193 2472 : Rust::Token::make_identifier (UNDEF_LOCATION, std::move (alias_name)));
2194 :
2195 1236 : if (type_alias.has_generics ())
2196 22 : visit (type_alias.get_generic_params ());
2197 :
2198 1236 : if (type_alias.has_where_clause ())
2199 0 : visit (type_alias.get_where_clause ());
2200 :
2201 1236 : push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
2202 1236 : visit (type_alias.get_type_aliased ());
2203 2472 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2204 1236 : });
2205 1236 : }
2206 :
2207 : void
2208 1482 : TokenCollector::visit (StructStruct &struct_item)
2209 : {
2210 1482 : describe_node (std::string ("StructStruct"), [this, &struct_item] () {
2211 1482 : visit_items_as_lines (struct_item.get_outer_attrs ());
2212 1482 : if (struct_item.has_visibility ())
2213 332 : visit (struct_item.get_visibility ());
2214 2964 : auto struct_name = struct_item.get_identifier ().as_string ();
2215 1482 : push (Rust::Token::make (STRUCT_KW, struct_item.get_locus ()));
2216 1482 : push (
2217 2964 : Rust::Token::make_identifier (UNDEF_LOCATION, std::move (struct_name)));
2218 :
2219 1482 : if (struct_item.has_generics ())
2220 468 : visit (struct_item.get_generic_params ());
2221 1482 : if (struct_item.has_where_clause ())
2222 2 : visit (struct_item.get_where_clause ());
2223 1482 : if (struct_item.is_unit_struct ())
2224 : {
2225 521 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2226 521 : newline ();
2227 : }
2228 : else
2229 1922 : visit_items_as_block (struct_item.get_fields (),
2230 : {Rust::Token::make (COMMA, UNDEF_LOCATION)});
2231 1482 : });
2232 1482 : }
2233 :
2234 : void
2235 933 : TokenCollector::visit (TupleStruct &tuple_struct)
2236 : {
2237 933 : describe_node (std::string ("TupleStruct"), [this, &tuple_struct] () {
2238 933 : visit_items_as_lines (tuple_struct.get_outer_attrs ());
2239 1866 : auto struct_name = tuple_struct.get_identifier ().as_string ();
2240 933 : push (Rust::Token::make (STRUCT_KW, tuple_struct.get_locus ()));
2241 933 : push (
2242 1866 : Rust::Token::make_identifier (UNDEF_LOCATION, std::move (struct_name)));
2243 933 : if (tuple_struct.has_generics ())
2244 283 : visit (tuple_struct.get_generic_params ());
2245 933 : if (tuple_struct.has_where_clause ())
2246 0 : visit (tuple_struct.get_where_clause ());
2247 :
2248 933 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
2249 933 : visit_items_joined_by_separator (tuple_struct.get_fields (), COMMA);
2250 933 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
2251 933 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2252 933 : newline ();
2253 933 : });
2254 933 : }
2255 :
2256 : void
2257 421 : TokenCollector::visit (EnumItem &item)
2258 : {
2259 421 : describe_node (std::string ("EnumItem"), [this, &item] () {
2260 421 : visit_items_as_lines (item.get_outer_attrs ());
2261 842 : auto id = item.get_identifier ().as_string ();
2262 842 : push (Rust::Token::make_identifier (item.get_locus (), std::move (id)));
2263 421 : });
2264 421 : }
2265 :
2266 : void
2267 391 : TokenCollector::visit (EnumItemTuple &item)
2268 : {
2269 391 : describe_node (std::string ("EnumItemTuple"), [this, &item] () {
2270 782 : auto id = item.get_identifier ().as_string ();
2271 782 : push (Rust::Token::make_identifier (item.get_locus (), std::move (id)));
2272 391 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
2273 391 : visit_items_joined_by_separator (item.get_tuple_fields (), COMMA);
2274 782 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
2275 391 : });
2276 391 : }
2277 :
2278 : void
2279 79 : TokenCollector::visit (EnumItemStruct &item)
2280 : {
2281 79 : describe_node (std::string ("EnumItemStruct"), [this, &item] () {
2282 158 : auto id = item.get_identifier ().as_string ();
2283 158 : push (Rust::Token::make_identifier (item.get_locus (), std::move (id)));
2284 158 : visit_items_as_block (item.get_struct_fields (),
2285 : {Rust::Token::make (COMMA, UNDEF_LOCATION)});
2286 79 : });
2287 79 : }
2288 :
2289 : void
2290 273 : TokenCollector::visit (EnumItemDiscriminant &item)
2291 : {
2292 273 : describe_node (std::string ("EnumItemDiscriminant"), [this, &item] () {
2293 546 : auto id = item.get_identifier ().as_string ();
2294 546 : push (Rust::Token::make_identifier (item.get_locus (), std::move (id)));
2295 273 : push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
2296 273 : visit (item.get_expr ());
2297 273 : });
2298 273 : }
2299 :
2300 : void
2301 495 : TokenCollector::visit (Enum &enumeration)
2302 : {
2303 495 : describe_node (std::string ("Enum"), [this, &enumeration] () {
2304 495 : visit_items_as_lines (enumeration.get_outer_attrs ());
2305 495 : if (enumeration.has_visibility ())
2306 263 : visit (enumeration.get_visibility ());
2307 495 : push (Rust::Token::make (ENUM_KW, enumeration.get_locus ()));
2308 990 : auto id = enumeration.get_identifier ().as_string ();
2309 495 : push (
2310 990 : Rust::Token::make_identifier (enumeration.get_locus (), std::move (id)));
2311 495 : if (enumeration.has_generics ())
2312 226 : visit (enumeration.get_generic_params ());
2313 495 : if (enumeration.has_where_clause ())
2314 0 : visit (enumeration.get_where_clause ());
2315 :
2316 990 : visit_items_as_block (enumeration.get_variants (),
2317 : {Rust::Token::make (COMMA, UNDEF_LOCATION)});
2318 495 : });
2319 495 : }
2320 :
2321 : void
2322 101 : TokenCollector::visit (Union &union_item)
2323 : {
2324 101 : describe_node (std::string ("Union"), [this, &union_item] () {
2325 101 : visit_items_as_lines (union_item.get_outer_attrs ());
2326 202 : auto id = union_item.get_identifier ().as_string ();
2327 202 : push (Rust::Token::make_identifier (union_item.get_locus (),
2328 101 : Values::WeakKeywords::UNION));
2329 202 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2330 :
2331 101 : if (union_item.has_generics ())
2332 74 : visit (union_item.get_generic_params ());
2333 :
2334 101 : if (union_item.has_where_clause ())
2335 0 : visit (union_item.get_where_clause ());
2336 :
2337 202 : visit_items_as_block (union_item.get_variants (),
2338 : {Rust::Token::make (COMMA, UNDEF_LOCATION)});
2339 101 : });
2340 101 : }
2341 :
2342 : void
2343 539 : TokenCollector::visit (ConstantItem &item)
2344 : {
2345 539 : describe_node (std::string ("ConstantItem"), [this, &item] () {
2346 539 : visit_items_as_lines (item.get_outer_attrs ());
2347 539 : push (Rust::Token::make (CONST, item.get_locus ()));
2348 539 : if (item.is_unnamed ())
2349 : {
2350 10 : push (Rust::Token::make (UNDERSCORE, UNDEF_LOCATION));
2351 : }
2352 : else
2353 : {
2354 1068 : push (Rust::Token::make_identifier (item.get_identifier ()));
2355 : }
2356 539 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
2357 539 : visit (item.get_type ());
2358 539 : if (item.has_expr ())
2359 : {
2360 516 : push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
2361 516 : visit (item.get_expr ());
2362 : }
2363 539 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2364 539 : });
2365 539 : }
2366 :
2367 : void
2368 49 : TokenCollector::visit (StaticItem &item)
2369 : {
2370 49 : describe_node (std::string ("StaticItem"), [this, &item] () {
2371 49 : visit_items_as_lines (item.get_outer_attrs ());
2372 49 : push (Rust::Token::make (STATIC_KW, item.get_locus ()));
2373 49 : if (item.is_mutable ())
2374 6 : push (Rust::Token::make (MUT, UNDEF_LOCATION));
2375 :
2376 98 : auto id = item.get_identifier ().as_string ();
2377 98 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2378 49 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
2379 :
2380 49 : visit (item.get_type ());
2381 :
2382 49 : if (item.has_expr ())
2383 : {
2384 49 : push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
2385 49 : visit (item.get_expr ());
2386 : }
2387 98 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2388 49 : });
2389 49 : }
2390 :
2391 : void
2392 0 : TokenCollector::visit_function_common (std::unique_ptr<Type> &return_type,
2393 : std::unique_ptr<BlockExpr> &block)
2394 : {
2395 : // FIXME: This should format the `<vis> fn <name> ( [args] )` as well
2396 0 : if (return_type)
2397 : {
2398 0 : push (Rust::Token::make (RETURN_TYPE, UNDEF_LOCATION));
2399 0 : visit (return_type);
2400 : }
2401 :
2402 0 : if (block)
2403 : {
2404 0 : visit (block);
2405 : }
2406 : else
2407 : {
2408 0 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2409 0 : newline ();
2410 : }
2411 0 : }
2412 :
2413 : void
2414 7874 : TokenCollector::visit (SelfParam ¶m)
2415 : {
2416 7874 : describe_node (std::string ("SelfParam"), [this, ¶m] () {
2417 7874 : if (param.get_has_ref ())
2418 : {
2419 4804 : push (Rust::Token::make (AMP, UNDEF_LOCATION));
2420 4804 : if (param.has_lifetime ())
2421 : {
2422 4549 : auto lifetime = param.get_lifetime ();
2423 4549 : visit (lifetime);
2424 4549 : }
2425 4804 : if (param.get_is_mut ())
2426 730 : push (Rust::Token::make (MUT, UNDEF_LOCATION));
2427 : }
2428 7874 : push (Rust::Token::make (SELF, UNDEF_LOCATION));
2429 7874 : if (param.has_type ())
2430 : {
2431 1 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
2432 1 : visit (param.get_type ());
2433 : }
2434 7874 : });
2435 7874 : }
2436 :
2437 : void
2438 710 : TokenCollector::visit (TraitItemType &item)
2439 : {
2440 710 : describe_node (std::string ("TraitItemType"), [this, &item] () {
2441 710 : visit_items_as_lines (item.get_outer_attrs ());
2442 1420 : auto id = item.get_identifier ().as_string ();
2443 710 : indentation ();
2444 :
2445 710 : push (Rust::Token::make (TYPE, item.get_locus ()));
2446 1420 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2447 710 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2448 710 : newline ();
2449 710 : });
2450 710 : }
2451 :
2452 : void
2453 3720 : TokenCollector::visit (Trait &trait)
2454 : {
2455 3720 : describe_node (std::string ("Trait"), [this, &trait] () {
2456 7501 : for (auto &attr : trait.get_outer_attrs ())
2457 : {
2458 3781 : visit (attr);
2459 3781 : newline ();
2460 3781 : indentation ();
2461 : }
2462 :
2463 3720 : visit (trait.get_visibility ());
2464 :
2465 7440 : auto id = trait.get_identifier ().as_string ();
2466 3720 : push (Rust::Token::make (TRAIT, trait.get_locus ()));
2467 7440 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2468 :
2469 3720 : if (trait.has_generics ())
2470 601 : visit (trait.get_generic_params ());
2471 3720 : if (!trait.get_type_param_bounds ().empty ())
2472 1014 : push (Rust::Token::make ((COLON), trait.get_locus ()));
2473 3720 : visit_items_joined_by_separator (trait.get_type_param_bounds (), PLUS);
2474 :
2475 3720 : visit_items_as_block (trait.get_trait_items (), {});
2476 3720 : });
2477 3720 : }
2478 :
2479 : void
2480 942 : TokenCollector::visit (InherentImpl &impl)
2481 : {
2482 942 : describe_node (std::string ("InherentImpl"), [this, &impl] () {
2483 942 : visit_items_as_lines (impl.get_outer_attrs ());
2484 942 : push (Rust::Token::make (IMPL, impl.get_locus ()));
2485 942 : visit (impl.get_generic_params ());
2486 :
2487 942 : visit (impl.get_type ());
2488 :
2489 942 : if (impl.has_where_clause ())
2490 0 : visit (impl.get_where_clause ());
2491 :
2492 : // FIXME: Handle inner attributes
2493 :
2494 942 : visit_items_as_block (impl.get_impl_items (), {});
2495 942 : });
2496 942 : }
2497 :
2498 : void
2499 4471 : TokenCollector::visit (TraitImpl &impl)
2500 : {
2501 4471 : describe_node (std::string ("TraitImpl"), [this, &impl] () {
2502 4471 : visit_items_as_lines (impl.get_outer_attrs ());
2503 4471 : push (Rust::Token::make (IMPL, impl.get_locus ()));
2504 4471 : visit (impl.get_generic_params ());
2505 4471 : if (impl.is_exclam ())
2506 10 : push (Rust::Token::make (EXCLAM, UNDEF_LOCATION));
2507 4471 : visit (impl.get_trait_path ());
2508 4471 : push (Rust::Token::make (FOR, UNDEF_LOCATION));
2509 4471 : visit (impl.get_type ());
2510 :
2511 4471 : if (impl.has_where_clause ())
2512 83 : visit (impl.get_where_clause ());
2513 4471 : });
2514 4471 : visit_items_as_block (impl.get_impl_items ());
2515 4471 : }
2516 :
2517 : void
2518 0 : TokenCollector::visit (ExternalTypeItem &type)
2519 : {
2520 0 : describe_node (std::string ("ExternalTypeItem"), [this, &type] () {
2521 0 : visit (type.get_visibility ());
2522 :
2523 0 : auto id = type.get_identifier ().as_string ();
2524 :
2525 0 : push (Rust::Token::make (TYPE, UNDEF_LOCATION));
2526 0 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2527 0 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2528 0 : });
2529 0 : }
2530 :
2531 : void
2532 0 : TokenCollector::visit (ExternalStaticItem &item)
2533 : {
2534 0 : describe_node (std::string ("ExternalStaticItem"), [this, &item] () {
2535 0 : auto id = item.get_identifier ().as_string ();
2536 0 : visit_items_as_lines (item.get_outer_attrs ());
2537 0 : if (item.has_visibility ())
2538 0 : visit (item.get_visibility ());
2539 0 : push (Rust::Token::make (STATIC_KW, item.get_locus ()));
2540 0 : if (item.is_mut ())
2541 0 : push (Rust::Token::make (MUT, UNDEF_LOCATION));
2542 0 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2543 0 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
2544 0 : visit (item.get_type ());
2545 : // TODO: No expr ? The "(= Expression)?" part from the reference seems
2546 : // missing in the ast.
2547 0 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2548 0 : });
2549 0 : }
2550 :
2551 : void
2552 1630 : TokenCollector::visit (ExternBlock &block)
2553 : {
2554 1630 : describe_node (std::string ("ExternBlock"), [this, &block] () {
2555 1630 : visit_items_as_lines (block.get_outer_attrs ());
2556 1630 : push (Rust::Token::make (EXTERN_KW, block.get_locus ()));
2557 :
2558 1630 : if (block.has_abi ())
2559 : {
2560 1629 : auto abi = block.get_abi ();
2561 3258 : push (Rust::Token::make_string (UNDEF_LOCATION, std::move (abi)));
2562 1629 : }
2563 :
2564 1630 : visit_items_as_block (block.get_extern_items (), {});
2565 1630 : });
2566 1630 : }
2567 :
2568 : static std::pair<TokenId, TokenId>
2569 1089 : get_delimiters (DelimType delim)
2570 : {
2571 1089 : switch (delim)
2572 : {
2573 1039 : case PARENS:
2574 1039 : return {LEFT_PAREN, RIGHT_PAREN};
2575 36 : case SQUARE:
2576 36 : return {LEFT_SQUARE, RIGHT_SQUARE};
2577 14 : case CURLY:
2578 14 : return {LEFT_CURLY, RIGHT_CURLY};
2579 0 : default:
2580 0 : rust_unreachable ();
2581 : }
2582 : }
2583 :
2584 : void
2585 888 : TokenCollector::visit (MacroMatchFragment &match)
2586 : {
2587 888 : describe_node (std::string ("MacroMatchFragment"), [this, &match] () {
2588 1776 : auto id = match.get_ident ().as_string ();
2589 888 : auto frag_spec = match.get_frag_spec ().as_string ();
2590 888 : push (Rust::Token::make (DOLLAR_SIGN, UNDEF_LOCATION));
2591 1776 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2592 888 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
2593 1776 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (frag_spec)));
2594 888 : });
2595 888 : }
2596 :
2597 : void
2598 471 : TokenCollector::visit (MacroMatchRepetition &repetition)
2599 : {
2600 471 : describe_node (std::string ("MacroMatchRepetition"), [this, &repetition] () {
2601 471 : push (Rust::Token::make (DOLLAR_SIGN, UNDEF_LOCATION));
2602 471 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
2603 :
2604 1040 : for (auto &match : repetition.get_matches ())
2605 : {
2606 569 : visit (match);
2607 : }
2608 :
2609 471 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
2610 :
2611 471 : if (repetition.has_sep ())
2612 : {
2613 248 : push (Rust::Token::make (repetition.get_sep ()->get_id (),
2614 124 : repetition.get_sep ()->get_locus ()));
2615 : }
2616 471 : switch (repetition.get_op ())
2617 : {
2618 405 : case MacroMatchRepetition::ANY:
2619 405 : push (Rust::Token::make (ASTERISK, UNDEF_LOCATION));
2620 405 : break;
2621 33 : case MacroMatchRepetition::ONE_OR_MORE:
2622 33 : push (Rust::Token::make (PLUS, UNDEF_LOCATION));
2623 33 : break;
2624 33 : case MacroMatchRepetition::ZERO_OR_ONE:
2625 33 : push (Rust::Token::make (QUESTION_MARK, UNDEF_LOCATION));
2626 33 : break;
2627 : case MacroMatchRepetition::NONE:
2628 : break;
2629 : }
2630 471 : });
2631 471 : }
2632 :
2633 : void
2634 1089 : TokenCollector::visit (MacroMatcher &matcher)
2635 : {
2636 1089 : describe_node (std::string ("MacroMatcher"), [this, &matcher] () {
2637 1089 : auto delimiters = get_delimiters (matcher.get_delim_type ());
2638 :
2639 1089 : push (Rust::Token::make (delimiters.first, UNDEF_LOCATION));
2640 :
2641 2403 : for (auto &item : matcher.get_matches ())
2642 : {
2643 1314 : visit (item);
2644 : }
2645 :
2646 1089 : push (Rust::Token::make (delimiters.second, UNDEF_LOCATION));
2647 1089 : });
2648 1089 : }
2649 :
2650 : void
2651 1029 : TokenCollector::visit (MacroRule &rule)
2652 : {
2653 1029 : describe_node (std::string ("MacroRule"), [this, &rule] () {
2654 1029 : visit (rule.get_matcher ());
2655 1029 : push (Rust::Token::make (MATCH_ARROW, rule.get_locus ()));
2656 1029 : visit (rule.get_transcriber ().get_token_tree ());
2657 1029 : });
2658 1029 : }
2659 :
2660 : void
2661 891 : TokenCollector::visit (MacroRulesDefinition &rules_def)
2662 : {
2663 891 : describe_node (std::string ("MacroRulesDefinition"), [this, &rules_def] () {
2664 1034 : for (auto &outer_attr : rules_def.get_outer_attrs ())
2665 143 : visit (outer_attr);
2666 :
2667 1782 : auto rule_name = rules_def.get_rule_name ().as_string ();
2668 :
2669 1782 : push (Rust::Token::make_identifier (rules_def.get_locus (),
2670 891 : Values::WeakKeywords::MACRO_RULES));
2671 891 : push (Rust::Token::make (EXCLAM, UNDEF_LOCATION));
2672 :
2673 1782 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (rule_name)));
2674 :
2675 1782 : visit_items_as_block (rules_def.get_rules (),
2676 : {Rust::Token::make (SEMICOLON, UNDEF_LOCATION)});
2677 891 : });
2678 891 : }
2679 :
2680 : void
2681 175 : TokenCollector::visit (MacroInvocation &invocation)
2682 : {
2683 175 : describe_node (std::string ("MacroInvocation"), [this, &invocation] () {
2684 175 : auto data = invocation.get_invoc_data ();
2685 175 : visit (data.get_path ());
2686 175 : push (Rust::Token::make (EXCLAM, UNDEF_LOCATION));
2687 175 : visit (data.get_delim_tok_tree ());
2688 175 : if (invocation.has_semicolon ())
2689 348 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2690 175 : });
2691 175 : }
2692 :
2693 : void
2694 0 : TokenCollector::visit (MetaItemPath &item)
2695 : {
2696 0 : describe_node (std::string ("MetaItemPath"), [this, &item] () {
2697 0 : auto path = item.to_path_item ();
2698 0 : visit (path);
2699 0 : });
2700 0 : }
2701 :
2702 : void
2703 14 : TokenCollector::visit (MetaItemSeq &item)
2704 : {
2705 14 : describe_node (std::string ("MetaItemSeq"), [this, &item] () {
2706 14 : visit (item.get_path ());
2707 : // TODO: Double check this, there is probably a mistake.
2708 14 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
2709 14 : visit_items_joined_by_separator (item.get_seq (), COMMA);
2710 14 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
2711 14 : });
2712 14 : }
2713 :
2714 : void
2715 42 : TokenCollector::visit (MetaWord &word)
2716 : {
2717 42 : describe_node (std::string ("MetaWord"), [this, &word] () {
2718 42 : auto id = word.get_ident ().as_string ();
2719 :
2720 84 : push (Rust::Token::make_identifier (word.get_locus (), std::move (id)));
2721 42 : });
2722 42 : }
2723 :
2724 : void
2725 318 : TokenCollector::visit (MetaNameValueStr &name)
2726 : {
2727 318 : describe_node (std::string ("MetaNameValueStr"), [this, &name] () {
2728 318 : auto pair = name.get_name_value_pair ();
2729 318 : auto id = std::get<0> (pair).as_string ();
2730 318 : auto value = std::get<1> (pair);
2731 :
2732 636 : push (Rust::Token::make_identifier (name.get_locus (), std::move (id)));
2733 318 : push (Rust::Token::make (EQUAL, name.get_locus ()));
2734 318 : push (Rust::Token::make (DOUBLE_QUOTE, UNDEF_LOCATION));
2735 636 : push (Rust::Token::make_identifier (name.get_locus (), std::move (value)));
2736 636 : push (Rust::Token::make (DOUBLE_QUOTE, UNDEF_LOCATION));
2737 318 : });
2738 318 : }
2739 :
2740 : void
2741 0 : TokenCollector::visit (MetaListPaths &list)
2742 : {
2743 0 : describe_node (std::string ("MetaListPath"), [this, &list] () {
2744 0 : auto id = list.get_ident ().as_string ();
2745 :
2746 0 : push (Rust::Token::make_identifier (list.get_locus (), std::move (id)));
2747 0 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
2748 :
2749 0 : visit_items_joined_by_separator (list.get_paths (), COMMA);
2750 :
2751 0 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
2752 0 : });
2753 0 : }
2754 :
2755 : void
2756 0 : TokenCollector::visit (MetaListNameValueStr &list)
2757 : {
2758 0 : describe_node (std::string ("MetaListNameValueStr"), [this, &list] () {
2759 0 : auto id = list.get_ident ().as_string ();
2760 :
2761 0 : push (Rust::Token::make_identifier (list.get_locus (), std::move (id)));
2762 0 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
2763 :
2764 0 : visit_items_joined_by_separator (list.get_values (), COMMA);
2765 :
2766 0 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
2767 0 : });
2768 0 : }
2769 :
2770 : // rust-pattern.h
2771 : void
2772 414 : TokenCollector::visit (LiteralPattern &pattern)
2773 : {
2774 414 : describe_node (std::string ("LiteralPattern"), [this, &pattern] () {
2775 414 : visit (pattern.get_literal (), pattern.get_locus ());
2776 414 : });
2777 414 : }
2778 :
2779 : void
2780 23992 : TokenCollector::visit (IdentifierPattern &pattern)
2781 : {
2782 23992 : describe_node (std::string ("IdentifierPattern"), [this, &pattern] () {
2783 23992 : if (pattern.get_is_ref ())
2784 : {
2785 4 : push (Rust::Token::make (REF, pattern.get_locus ()));
2786 : }
2787 23992 : if (pattern.get_is_mut ())
2788 : {
2789 1844 : push (Rust::Token::make (MUT, UNDEF_LOCATION));
2790 : }
2791 :
2792 47984 : auto id = pattern.get_ident ().as_string ();
2793 47984 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2794 :
2795 23992 : if (pattern.has_subpattern ())
2796 : {
2797 20 : push (Rust::Token::make (PATTERN_BIND, UNDEF_LOCATION));
2798 20 : visit (pattern.get_subpattern ());
2799 : }
2800 23992 : });
2801 23992 : }
2802 :
2803 : void
2804 1091 : TokenCollector::visit (WildcardPattern &pattern)
2805 : {
2806 1091 : describe_node (std::string ("WildcardPattern"), [this, &pattern] () {
2807 1091 : push (Rust::Token::make (UNDERSCORE, pattern.get_locus ()));
2808 1091 : });
2809 1091 : }
2810 :
2811 : void
2812 44 : TokenCollector::visit (RestPattern &pattern)
2813 : {
2814 44 : describe_node (std::string ("RestPattern"), [this, &pattern] () {
2815 44 : push (Rust::Token::make (DOT_DOT, pattern.get_locus ()));
2816 44 : });
2817 44 : }
2818 :
2819 : // void TokenCollector::visit(RangePatternBound& ){}
2820 :
2821 : void
2822 61 : TokenCollector::visit (RangePatternBoundLiteral &pattern)
2823 : {
2824 61 : describe_node (std::string ("RangePatternBoundLiteral"), [this, &pattern] () {
2825 61 : if (pattern.get_has_minus ())
2826 : {
2827 48 : push (Rust::Token::make (MINUS, pattern.get_locus ()));
2828 : }
2829 61 : auto literal = pattern.get_literal ();
2830 61 : visit (literal);
2831 61 : });
2832 61 : }
2833 :
2834 : void
2835 21 : TokenCollector::visit (RangePatternBoundPath &pattern)
2836 : {
2837 21 : describe_node (std::string ("RangePatternBoundPath"),
2838 42 : [this, &pattern] () { visit (pattern.get_path ()); });
2839 21 : }
2840 :
2841 : void
2842 0 : TokenCollector::visit (RangePatternBoundQualPath &pattern)
2843 : {
2844 0 : describe_node (std::string ("RangePatternBoundQualPath"),
2845 0 : [this, &pattern] () {
2846 0 : visit (pattern.get_qualified_path ());
2847 : });
2848 0 : }
2849 :
2850 : void
2851 41 : TokenCollector::visit (RangePattern &pattern)
2852 : {
2853 41 : describe_node (std::string ("RangePattern"), [this, &pattern] () {
2854 41 : if (pattern.get_has_lower_bound () && pattern.get_has_upper_bound ())
2855 : {
2856 41 : visit (pattern.get_lower_bound ());
2857 41 : if (pattern.get_has_ellipsis_syntax ())
2858 0 : push (Rust::Token::make (ELLIPSIS, pattern.get_locus ()));
2859 : else
2860 82 : push (Rust::Token::make (DOT_DOT_EQ, pattern.get_locus ()));
2861 41 : visit (pattern.get_upper_bound ());
2862 : }
2863 0 : else if (pattern.get_has_lower_bound ())
2864 : {
2865 0 : visit (pattern.get_lower_bound ());
2866 0 : push (Rust::Token::make (DOT_DOT, pattern.get_locus ()));
2867 : }
2868 : else
2869 : {
2870 0 : push (Rust::Token::make (DOT_DOT_EQ, pattern.get_locus ()));
2871 0 : visit (pattern.get_upper_bound ());
2872 : }
2873 41 : });
2874 41 : }
2875 :
2876 : void
2877 198 : TokenCollector::visit (ReferencePattern &pattern)
2878 :
2879 : {
2880 198 : describe_node (std::string ("ReferencePattern"), [this, &pattern] () {
2881 198 : if (pattern.is_double_reference ())
2882 : {
2883 20 : push (Rust::Token::make (LOGICAL_AND, pattern.get_locus ()));
2884 : }
2885 : else
2886 : {
2887 376 : push (Rust::Token::make (AMP, pattern.get_locus ()));
2888 : }
2889 :
2890 198 : if (pattern.get_is_mut ())
2891 : {
2892 0 : push (Rust::Token::make (MUT, UNDEF_LOCATION));
2893 : }
2894 :
2895 198 : visit (pattern.get_referenced_pattern ());
2896 198 : });
2897 198 : }
2898 :
2899 : // void TokenCollector::visit(StructPatternField& ){}
2900 :
2901 : void
2902 18 : TokenCollector::visit (StructPatternFieldTuplePat &pattern)
2903 : {
2904 18 : describe_node (std::string ("StructPatternFieldTuplePat"), [this,
2905 : &pattern] () {
2906 18 : visit_items_as_lines (pattern.get_outer_attrs ());
2907 18 : auto str = std::to_string (pattern.get_index ());
2908 18 : auto suffix_start = str.length ();
2909 36 : push (Rust::Token::make_int (pattern.get_locus (), str, suffix_start,
2910 : IntegerLiteralBase::Decimal));
2911 18 : push (Rust::Token::make (COLON, pattern.get_locus ()));
2912 18 : visit (pattern.get_index_pattern ());
2913 18 : });
2914 18 : }
2915 :
2916 : void
2917 131 : TokenCollector::visit (StructPatternFieldIdentPat &pattern)
2918 : {
2919 131 : describe_node (std::string ("StructPatternFieldIdentPat"), [this,
2920 : &pattern] () {
2921 131 : visit_items_as_lines (pattern.get_outer_attrs ());
2922 :
2923 131 : auto id = pattern.get_identifier ().as_string ();
2924 262 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2925 :
2926 131 : push (Rust::Token::make (COLON, pattern.get_locus ()));
2927 :
2928 131 : visit (pattern.get_ident_pattern ());
2929 131 : });
2930 131 : }
2931 :
2932 : void
2933 91 : TokenCollector::visit (StructPatternFieldIdent &pattern)
2934 : {
2935 91 : describe_node (std::string ("StructPatternFieldIdent"), [this, &pattern] () {
2936 91 : visit_items_as_lines (pattern.get_outer_attrs ());
2937 91 : if (pattern.is_ref ())
2938 0 : push (Rust::Token::make (REF, UNDEF_LOCATION));
2939 91 : if (pattern.is_mut ())
2940 4 : push (Rust::Token::make (MUT, UNDEF_LOCATION));
2941 :
2942 91 : auto id = pattern.get_identifier ().as_string ();
2943 182 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2944 91 : });
2945 91 : }
2946 :
2947 : void
2948 141 : TokenCollector::visit (StructPattern &pattern)
2949 : {
2950 141 : describe_node (std::string ("StructPattern"), [this, &pattern] () {
2951 141 : visit (pattern.get_path ());
2952 141 : push (Rust::Token::make (LEFT_CURLY, pattern.get_locus ()));
2953 141 : auto elems = pattern.get_struct_pattern_elems ();
2954 141 : if (elems.has_struct_pattern_fields ())
2955 : {
2956 140 : visit_items_joined_by_separator (elems.get_struct_pattern_fields ());
2957 140 : if (elems.has_rest ())
2958 : {
2959 3 : push (Rust::Token::make (COMMA, UNDEF_LOCATION));
2960 3 : visit_items_as_lines (elems.get_etc_outer_attrs ());
2961 : }
2962 : }
2963 : else
2964 : {
2965 1 : visit_items_as_lines (elems.get_etc_outer_attrs ());
2966 : }
2967 :
2968 282 : push (Rust::Token::make (RIGHT_CURLY, UNDEF_LOCATION));
2969 141 : });
2970 141 : }
2971 :
2972 : // void TokenCollector::visit(TupleStructItems& ){}
2973 :
2974 : void
2975 936 : TokenCollector::visit (TupleStructItemsNoRest &pattern)
2976 : {
2977 936 : describe_node (std::string ("TupleStructItemsNoRange"), [this, &pattern] () {
2978 936 : visit_items_joined_by_separator (pattern.get_patterns ());
2979 936 : });
2980 936 : }
2981 :
2982 : void
2983 36 : TokenCollector::visit (TupleStructItemsHasRest &pattern)
2984 : {
2985 36 : describe_node (std::string ("TupleStructItemsRange"), [this, &pattern] () {
2986 65 : for (auto &lower : pattern.get_lower_patterns ())
2987 : {
2988 29 : visit (lower);
2989 : }
2990 36 : push (Rust::Token::make (DOT_DOT, UNDEF_LOCATION));
2991 65 : for (auto &upper : pattern.get_lower_patterns ())
2992 : {
2993 29 : visit (upper);
2994 : }
2995 36 : });
2996 36 : }
2997 :
2998 : void
2999 972 : TokenCollector::visit (TupleStructPattern &pattern)
3000 : {
3001 972 : describe_node (std::string ("TupleStructPattern"), [this, &pattern] () {
3002 972 : visit (pattern.get_path ());
3003 972 : push (Rust::Token::make (LEFT_PAREN, pattern.get_locus ()));
3004 972 : visit (pattern.get_items ());
3005 972 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
3006 972 : });
3007 972 : }
3008 :
3009 : // void
3010 : // TokenCollector::visit (TuplePatternItems &)
3011 : // {}
3012 :
3013 : void
3014 412 : TokenCollector::visit (TuplePatternItemsNoRest &pattern)
3015 : {
3016 412 : describe_node (std::string ("TuplePatternItemsMultiple"), [this,
3017 : &pattern] () {
3018 412 : visit_items_joined_by_separator (pattern.get_patterns (), COMMA);
3019 412 : });
3020 412 : }
3021 :
3022 : void
3023 31 : TokenCollector::visit (TuplePatternItemsHasRest &pattern)
3024 : {
3025 31 : describe_node (std::string ("TuplePatternItemsRanged"), [this, &pattern] () {
3026 58 : for (auto &lower : pattern.get_lower_patterns ())
3027 : {
3028 27 : visit (lower);
3029 : }
3030 31 : push (Rust::Token::make (DOT_DOT, UNDEF_LOCATION));
3031 58 : for (auto &upper : pattern.get_lower_patterns ())
3032 : {
3033 27 : visit (upper);
3034 : }
3035 31 : });
3036 31 : }
3037 :
3038 : void
3039 443 : TokenCollector::visit (TuplePattern &pattern)
3040 : {
3041 443 : describe_node (std::string ("TuplePattern"), [this, &pattern] () {
3042 443 : push (Rust::Token::make (LEFT_PAREN, pattern.get_locus ()));
3043 443 : visit (pattern.get_items ());
3044 443 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
3045 443 : });
3046 443 : }
3047 :
3048 : void
3049 1 : TokenCollector::visit (GroupedPattern &pattern)
3050 : {
3051 1 : describe_node (std::string ("GroupedPattern"), [this, &pattern] () {
3052 1 : push (Rust::Token::make (LEFT_PAREN, pattern.get_locus ()));
3053 1 : visit (pattern.get_pattern_in_parens ());
3054 1 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
3055 1 : });
3056 1 : }
3057 :
3058 : void
3059 75 : TokenCollector::visit (SlicePattern &pattern)
3060 : {
3061 75 : describe_node (std::string ("SlicePattern"), [this, &pattern] () {
3062 75 : push (Rust::Token::make (LEFT_SQUARE, pattern.get_locus ()));
3063 75 : visit_items_joined_by_separator (pattern.get_patterns (), COMMA);
3064 75 : push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION));
3065 75 : });
3066 75 : }
3067 :
3068 : void
3069 145 : TokenCollector::visit (AltPattern &pattern)
3070 : {
3071 145 : describe_node (std::string ("AltPattern"), [this, &pattern] () {
3072 145 : visit_items_joined_by_separator (pattern.get_alts (), PIPE);
3073 145 : });
3074 145 : }
3075 :
3076 : // rust-stmt.h
3077 : void
3078 45 : TokenCollector::visit (EmptyStmt &)
3079 45 : {}
3080 :
3081 : void
3082 12628 : TokenCollector::visit (LetStmt &stmt)
3083 : {
3084 12628 : describe_node (std::string ("LetStmt"), [this, &stmt] () {
3085 12628 : push (Rust::Token::make (LET, stmt.get_locus ()));
3086 12628 : auto &pattern = stmt.get_pattern ();
3087 12628 : visit (pattern);
3088 :
3089 12628 : if (stmt.has_type ())
3090 : {
3091 2089 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
3092 2089 : visit (stmt.get_type ());
3093 : }
3094 :
3095 12628 : if (stmt.has_type ())
3096 : {
3097 2089 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
3098 2089 : visit (stmt.get_type ());
3099 : }
3100 :
3101 12628 : if (stmt.has_init_expr ())
3102 : {
3103 11510 : push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
3104 11510 : visit (stmt.get_init_expr ());
3105 : }
3106 :
3107 12628 : if (stmt.has_else_expr ())
3108 : {
3109 5 : push (Rust::Token::make (ELSE, UNDEF_LOCATION));
3110 5 : visit (stmt.get_else_expr ());
3111 : }
3112 :
3113 12628 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
3114 12628 : });
3115 12628 : }
3116 :
3117 : void
3118 11019 : TokenCollector::visit (ExprStmt &stmt)
3119 : {
3120 11019 : describe_node (std::string ("ExprStmt"), [this, &stmt] () {
3121 11019 : visit (stmt.get_expr ());
3122 :
3123 11019 : if (stmt.is_semicolon_followed ())
3124 17534 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
3125 11019 : });
3126 11019 : }
3127 :
3128 : // rust-type.h
3129 : void
3130 2044 : TokenCollector::visit (TraitBound &bound)
3131 : {
3132 : // Syntax:
3133 : // ?? ForLifetimes? TypePath
3134 : // | ( ?? ForLifetimes? TypePath )
3135 2044 : describe_node (std::string ("TraitBound"), [this, &bound] () {
3136 2044 : if (bound.has_opening_question_mark ())
3137 716 : push (Rust::Token::make (QUESTION_MARK, bound.get_locus ()));
3138 :
3139 2044 : if (bound.has_for_lifetimes ())
3140 7 : visit (bound.get_for_lifetimes ());
3141 :
3142 2044 : visit (bound.get_type_path ());
3143 2044 : });
3144 2044 : }
3145 :
3146 : void
3147 0 : TokenCollector::visit (ImplTraitType &type)
3148 : {
3149 : // Syntax:
3150 : // impl TypeParamBounds
3151 : // TypeParamBounds :
3152 : // TypeParamBound ( + TypeParamBound )* +?
3153 0 : describe_node (std::string ("ImplTraitType"), [this, &type] () {
3154 0 : push (Rust::Token::make (IMPL, type.get_locus ()));
3155 0 : visit_items_joined_by_separator (type.get_type_param_bounds (), PLUS);
3156 0 : });
3157 0 : }
3158 :
3159 : void
3160 10 : TokenCollector::visit (TraitObjectType &type)
3161 : {
3162 : // Syntax:
3163 : // dyn? TypeParamBounds
3164 : // TypeParamBounds :
3165 : // TypeParamBound ( + TypeParamBound )* +?
3166 10 : describe_node (std::string ("TraiObjectType"), [this, &type] () {
3167 10 : if (type.is_dyn ())
3168 20 : push (Rust::Token::make (DYN, type.get_locus ()));
3169 10 : visit_items_joined_by_separator (type.get_type_param_bounds (), PLUS);
3170 10 : });
3171 10 : }
3172 :
3173 : void
3174 5 : TokenCollector::visit (ParenthesisedType &type)
3175 : {
3176 : // Syntax:
3177 : // ( Type )
3178 5 : describe_node (std::string ("ParenthesisedType"), [this, &type] () {
3179 5 : push (Rust::Token::make (LEFT_PAREN, type.get_locus ()));
3180 5 : visit (type.get_type_in_parens ());
3181 5 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
3182 5 : });
3183 5 : }
3184 :
3185 : void
3186 28 : TokenCollector::visit (ImplTraitTypeOneBound &type)
3187 : {
3188 : // Syntax:
3189 : // impl TraitBound
3190 :
3191 28 : describe_node (std::string ("ImplTraitTypeOneBound"), [this, &type] () {
3192 28 : push (Rust::Token::make (IMPL, type.get_locus ()));
3193 28 : visit (type.get_trait_bound ());
3194 28 : });
3195 28 : }
3196 :
3197 : void
3198 310 : TokenCollector::visit (TraitObjectTypeOneBound &type)
3199 : {
3200 : // Syntax:
3201 : // dyn? TraitBound
3202 310 : describe_node (std::string ("TraitObjectTypeOneBound"), [this, &type] () {
3203 310 : if (type.is_dyn ())
3204 620 : push (Rust::Token::make (DYN, type.get_locus ()));
3205 310 : visit (type.get_trait_bound ());
3206 310 : });
3207 310 : }
3208 :
3209 : void
3210 406 : TokenCollector::visit (TupleType &type)
3211 : {
3212 : // Syntax:
3213 : // ( )
3214 : // | ( ( Type , )+ Type? )
3215 :
3216 406 : describe_node (std::string ("TupleType"), [this, &type] () {
3217 406 : push (Rust::Token::make (LEFT_PAREN, type.get_locus ()));
3218 406 : visit_items_joined_by_separator (type.get_elems (), COMMA);
3219 406 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
3220 406 : });
3221 406 : }
3222 :
3223 : void
3224 185 : TokenCollector::visit (NeverType &type)
3225 : {
3226 : // Syntax:
3227 : // !
3228 :
3229 185 : describe_node (std::string ("NeverType"), [this, &type] () {
3230 185 : push (Rust::Token::make (EXCLAM, type.get_locus ()));
3231 185 : });
3232 185 : }
3233 :
3234 : void
3235 6873 : TokenCollector::visit (RawPointerType &type)
3236 : {
3237 : // Syntax:
3238 : // * ( mut | const ) TypeNoBounds
3239 6873 : describe_node (std::string ("RawPointerType"), [this, &type] () {
3240 6873 : push (Rust::Token::make (ASTERISK, type.get_locus ()));
3241 6873 : if (type.get_pointer_type () == RawPointerType::MUT)
3242 1484 : push (Rust::Token::make (MUT, UNDEF_LOCATION));
3243 : else /* RawPointerType::CONST */
3244 12262 : push (Rust::Token::make (CONST, UNDEF_LOCATION));
3245 :
3246 6873 : visit (type.get_type_pointed_to ());
3247 6873 : });
3248 6873 : }
3249 :
3250 : void
3251 4696 : TokenCollector::visit (ReferenceType &type)
3252 : {
3253 : // Syntax:
3254 : // & Lifetime? mut? TypeNoBounds
3255 4696 : describe_node (std::string ("ReferenceType"), [this, &type] () {
3256 4696 : push (Rust::Token::make (AMP, type.get_locus ()));
3257 :
3258 4696 : if (type.has_lifetime ())
3259 : {
3260 4696 : visit (type.get_lifetime ());
3261 : }
3262 :
3263 4696 : if (type.get_has_mut ())
3264 636 : push (Rust::Token::make (MUT, UNDEF_LOCATION));
3265 :
3266 4696 : visit (type.get_type_referenced ());
3267 4696 : });
3268 4696 : }
3269 :
3270 : void
3271 803 : TokenCollector::visit (ArrayType &type)
3272 : {
3273 : // Syntax:
3274 : // [type Type ; Expression ]
3275 803 : describe_node (std::string ("ArrayType"), [this, &type] () {
3276 803 : push (Rust::Token::make (LEFT_SQUARE, type.get_locus ()));
3277 803 : visit (type.get_elem_type ());
3278 803 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
3279 803 : visit (type.get_size_expr ());
3280 803 : push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION));
3281 803 : });
3282 803 : }
3283 :
3284 : void
3285 889 : TokenCollector::visit (SliceType &type)
3286 : {
3287 : // Syntax:
3288 : // [type Type ]
3289 :
3290 889 : describe_node (std::string ("SliceType"), [this, &type] () {
3291 889 : push (Rust::Token::make (LEFT_SQUARE, type.get_locus ()));
3292 889 : visit (type.get_elem_type ());
3293 889 : push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION));
3294 889 : });
3295 889 : }
3296 :
3297 : void
3298 261 : TokenCollector::visit (InferredType &type)
3299 : {
3300 : // Syntax:
3301 : // _
3302 261 : describe_node (std::string ("InferredType"), [this, &type] () {
3303 261 : push (Rust::Token::make (UNDERSCORE, type.get_locus ()));
3304 261 : });
3305 261 : }
3306 :
3307 : void
3308 79 : TokenCollector::visit (BareFunctionType &type)
3309 : {
3310 : // Syntax:
3311 : // ForLifetimes? FunctionTypeQualifiers fn
3312 : // ( FunctionParametersMaybeNamedVariadic? )
3313 : // BareFunctionReturnType?
3314 : //
3315 : // BareFunctionReturnType:
3316 : // -> TypeNoBounds
3317 : //
3318 : // FunctionParametersMaybeNamedVariadic :
3319 : // MaybeNamedFunctionParameters |
3320 : // MaybeNamedFunctionParametersVariadic
3321 : //
3322 : // MaybeNamedFunctionParameters :
3323 : // MaybeNamedParam ( , MaybeNamedParam )* ,?
3324 : //
3325 : // MaybeNamedFunctionParametersVariadic :
3326 : // ( MaybeNamedParam , )* MaybeNamedParam , OuterAttribute* ...
3327 79 : describe_node (std::string ("BareFunctionType"), [this, &type] () {
3328 79 : if (type.has_for_lifetimes ())
3329 0 : visit (type.get_for_lifetimes ());
3330 :
3331 79 : visit (type.get_function_qualifiers ());
3332 :
3333 79 : push (Rust::Token::make (FN_KW, type.get_locus ()));
3334 79 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
3335 :
3336 79 : visit_items_joined_by_separator (type.get_function_params (), COMMA);
3337 :
3338 79 : if (type.is_variadic ())
3339 : {
3340 0 : push (Rust::Token::make (COMMA, UNDEF_LOCATION));
3341 0 : for (auto &item : type.get_variadic_attr ())
3342 : {
3343 0 : visit (item);
3344 : }
3345 0 : push (Rust::Token::make (ELLIPSIS, UNDEF_LOCATION));
3346 : }
3347 :
3348 79 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
3349 :
3350 79 : if (type.has_return_type ())
3351 : {
3352 65 : push (Rust::Token::make (RETURN_TYPE, UNDEF_LOCATION));
3353 65 : visit (type.get_return_type ());
3354 : }
3355 79 : });
3356 79 : }
3357 :
3358 : void
3359 0 : TokenCollector::visit (AST::FormatArgs &fmt)
3360 : {
3361 0 : push (Rust::Token::make_identifier (fmt.get_locus (), "format_args"));
3362 0 : push (Rust::Token::make (EXCLAM, fmt.get_locus ()));
3363 0 : push (Rust::Token::make (LEFT_PAREN, fmt.get_locus ()));
3364 :
3365 0 : std::string reconstructed_template = "\"";
3366 0 : const auto &template_pieces = fmt.get_template ();
3367 :
3368 0 : for (const auto &piece : template_pieces.get_pieces ())
3369 : {
3370 0 : if (piece.tag == Fmt::ffi::Piece::Tag::String)
3371 : {
3372 0 : std::string literal = piece.string._0.to_string ();
3373 0 : for (char c : literal)
3374 : {
3375 0 : if (c == '"' || c == '\\')
3376 : {
3377 0 : reconstructed_template += '\\';
3378 : }
3379 0 : else if (c == '\n')
3380 : {
3381 0 : reconstructed_template += "\\n";
3382 0 : continue;
3383 : }
3384 0 : else if (c == '\r')
3385 : {
3386 0 : reconstructed_template += "\\r";
3387 0 : continue;
3388 : }
3389 0 : else if (c == '\t')
3390 : {
3391 0 : reconstructed_template += "\\t";
3392 0 : continue;
3393 : }
3394 0 : reconstructed_template += c;
3395 : }
3396 0 : }
3397 0 : else if (piece.tag == Fmt::ffi::Piece::Tag::NextArgument)
3398 : {
3399 0 : reconstructed_template += "{";
3400 :
3401 0 : const auto &argument = piece.next_argument._0;
3402 0 : const auto &position = argument.position;
3403 :
3404 0 : switch (position.tag)
3405 : {
3406 : case Fmt::ffi::Position::Tag::ArgumentImplicitlyIs:
3407 : break;
3408 0 : case Fmt::ffi::Position::Tag::ArgumentIs:
3409 0 : reconstructed_template
3410 0 : += std::to_string (position.argument_is._0);
3411 0 : break;
3412 0 : case Fmt::ffi::Position::Tag::ArgumentNamed:
3413 0 : reconstructed_template += position.argument_named._0.to_string ();
3414 0 : break;
3415 : }
3416 :
3417 : // Add format specifiers if any (like :?, :x, etc.)
3418 0 : const auto &format_spec = argument.format;
3419 :
3420 0 : bool has_format_spec = false;
3421 0 : std::string format_part;
3422 :
3423 : // For now, skipping the complex format specifications that
3424 : // use FFIOpt since FFIOpt::get_opt() has a bug.
3425 :
3426 : // Alignment
3427 0 : if (format_spec.align != Fmt::ffi::Alignment::AlignUnknown)
3428 : {
3429 0 : has_format_spec = true;
3430 0 : switch (format_spec.align)
3431 : {
3432 0 : case Fmt::ffi::Alignment::AlignLeft:
3433 0 : format_part += "<";
3434 0 : break;
3435 0 : case Fmt::ffi::Alignment::AlignRight:
3436 0 : format_part += ">";
3437 0 : break;
3438 0 : case Fmt::ffi::Alignment::AlignCenter:
3439 0 : format_part += "^";
3440 0 : break;
3441 : case Fmt::ffi::Alignment::AlignUnknown:
3442 : break;
3443 : }
3444 : }
3445 :
3446 : // Alternate flag
3447 0 : if (format_spec.alternate)
3448 : {
3449 0 : has_format_spec = true;
3450 0 : format_part += "#";
3451 : }
3452 :
3453 : // Zero pad flag
3454 0 : if (format_spec.zero_pad)
3455 : {
3456 0 : has_format_spec = true;
3457 0 : format_part += "0";
3458 : }
3459 :
3460 : // Width
3461 0 : if (format_spec.width.tag != Fmt::ffi::Count::Tag::CountImplied)
3462 : {
3463 0 : has_format_spec = true;
3464 0 : switch (format_spec.width.tag)
3465 : {
3466 0 : case Fmt::ffi::Count::Tag::CountIs:
3467 0 : format_part += std::to_string (format_spec.width.count_is._0);
3468 0 : break;
3469 0 : case Fmt::ffi::Count::Tag::CountIsParam:
3470 0 : format_part
3471 0 : += std::to_string (format_spec.width.count_is_param._0)
3472 0 : + "$";
3473 0 : break;
3474 0 : case Fmt::ffi::Count::Tag::CountIsName:
3475 0 : format_part
3476 0 : += format_spec.width.count_is_name._0.to_string () + "$";
3477 0 : break;
3478 0 : case Fmt::ffi::Count::Tag::CountIsStar:
3479 0 : format_part += "*";
3480 0 : break;
3481 : case Fmt::ffi::Count::Tag::CountImplied:
3482 : break;
3483 : }
3484 : }
3485 :
3486 : // Precision
3487 0 : if (format_spec.precision.tag != Fmt::ffi::Count::Tag::CountImplied)
3488 : {
3489 0 : has_format_spec = true;
3490 0 : format_part += ".";
3491 0 : switch (format_spec.precision.tag)
3492 : {
3493 0 : case Fmt::ffi::Count::Tag::CountIs:
3494 0 : format_part
3495 0 : += std::to_string (format_spec.precision.count_is._0);
3496 0 : break;
3497 0 : case Fmt::ffi::Count::Tag::CountIsParam:
3498 0 : format_part
3499 0 : += std::to_string (format_spec.precision.count_is_param._0)
3500 0 : + "$";
3501 0 : break;
3502 0 : case Fmt::ffi::Count::Tag::CountIsName:
3503 0 : format_part
3504 0 : += format_spec.precision.count_is_name._0.to_string ()
3505 0 : + "$";
3506 0 : break;
3507 0 : case Fmt::ffi::Count::Tag::CountIsStar:
3508 0 : format_part += "*";
3509 0 : break;
3510 : case Fmt::ffi::Count::Tag::CountImplied:
3511 : break;
3512 : }
3513 : }
3514 :
3515 : // Type/trait (like ?, x, X, etc.)
3516 0 : std::string type_str = format_spec.ty.to_string ();
3517 0 : if (!type_str.empty ())
3518 : {
3519 0 : has_format_spec = true;
3520 0 : format_part += type_str;
3521 : }
3522 :
3523 : // Add the format specification if any
3524 0 : if (has_format_spec)
3525 : {
3526 0 : reconstructed_template += ":";
3527 0 : reconstructed_template += format_part;
3528 : }
3529 :
3530 0 : reconstructed_template += "}";
3531 : }
3532 : }
3533 0 : reconstructed_template += "\"";
3534 :
3535 0 : push (Rust::Token::make_string (fmt.get_locus (), reconstructed_template));
3536 :
3537 : // Visit format arguments if any exist
3538 0 : auto &arguments = fmt.get_arguments ();
3539 0 : if (!arguments.empty ())
3540 : {
3541 0 : push (Rust::Token::make (COMMA, fmt.get_locus ()));
3542 :
3543 0 : auto &args = arguments.get_args ();
3544 0 : for (size_t i = 0; i < args.size (); ++i)
3545 : {
3546 0 : if (i > 0)
3547 : {
3548 0 : push (Rust::Token::make (COMMA, fmt.get_locus ()));
3549 : }
3550 :
3551 0 : auto kind = args[i].get_kind ();
3552 :
3553 : // Handle named arguments: name = expr
3554 0 : if (kind.kind == FormatArgumentKind::Kind::Named)
3555 : {
3556 0 : auto ident = kind.get_ident ().as_string ();
3557 0 : push (Rust::Token::make_identifier (fmt.get_locus (),
3558 : std::move (ident)));
3559 0 : push (Rust::Token::make (EQUAL, fmt.get_locus ()));
3560 0 : }
3561 : // Note: Captured arguments are handled implicitly in the
3562 : // template reconstruction They don't need explicit "name ="
3563 : // syntax in the reconstructed macro call
3564 :
3565 0 : auto &expr = args[i].get_expr ();
3566 0 : expr.accept_vis (*this);
3567 0 : }
3568 : }
3569 :
3570 0 : push (Rust::Token::make (RIGHT_PAREN, fmt.get_locus ()));
3571 0 : }
3572 :
3573 : void
3574 14 : TokenCollector::visit (AST::OffsetOf &offset_of)
3575 : {
3576 14 : auto loc = offset_of.get_locus ();
3577 :
3578 28 : push (Rust::Token::make_identifier (loc, "offset_of"));
3579 14 : push (Rust::Token::make (EXCLAM, loc));
3580 14 : push (Rust::Token::make (LEFT_PAREN, loc));
3581 :
3582 14 : visit (offset_of.get_type ());
3583 :
3584 14 : push (Rust::Token::make (COMMA, loc));
3585 :
3586 14 : push (Rust::Token::make_identifier (offset_of.get_field ()));
3587 :
3588 14 : push (Rust::Token::make (RIGHT_PAREN, loc));
3589 14 : }
3590 :
3591 : } // namespace AST
3592 : } // namespace Rust
|