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 4397 : TokenCollector::collect () const
49 : {
50 4397 : return tokens;
51 : }
52 :
53 : void
54 4394 : TokenCollector::visit (AST::Crate &crate)
55 : {
56 4394 : visit_items_as_lines (crate.inner_attrs);
57 4394 : visit_items_as_lines (crate.items);
58 4394 : }
59 :
60 : void
61 3 : TokenCollector::visit (AST::Item &item)
62 : {
63 3 : item.accept_vis (*this);
64 3 : }
65 :
66 : void
67 4503 : TokenCollector::trailing_comma ()
68 : {
69 4503 : if (output_trailing_commas)
70 : {
71 0 : push (Rust::Token::make (COMMA, UNDEF_LOCATION));
72 : }
73 4503 : }
74 :
75 : void
76 216272 : TokenCollector::newline ()
77 : {
78 216272 : tokens.emplace_back (CollectItem::Kind::Newline);
79 216272 : }
80 :
81 : void
82 157044 : TokenCollector::indentation ()
83 : {
84 157044 : tokens.emplace_back (indent_level);
85 157044 : }
86 :
87 : void
88 37957 : TokenCollector::increment_indentation ()
89 : {
90 37957 : indent_level++;
91 37957 : }
92 :
93 : void
94 37957 : TokenCollector::decrement_indentation ()
95 : {
96 37957 : rust_assert (indent_level != 0);
97 37957 : indent_level--;
98 37957 : }
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 717455 : TokenCollector::describe_node (const std::string &node_name,
108 : std::function<void ()> visitor)
109 : {
110 717455 : tokens.emplace_back (CollectItem::make_begin_node_description (node_name));
111 :
112 717455 : visitor ();
113 :
114 717455 : tokens.push_back (CollectItem::make_end_node_description (node_name));
115 717455 : }
116 :
117 : void
118 0 : TokenCollector::visit (Visitable &v)
119 : {
120 0 : v.accept_vis (*this);
121 0 : }
122 :
123 : void
124 11729 : TokenCollector::visit (FunctionParam ¶m)
125 : {
126 11729 : describe_node (std::string ("FunctionParam"), [this, ¶m] () {
127 11729 : visit_items_as_lines (param.get_outer_attrs ());
128 11729 : if (!param.is_variadic ())
129 : {
130 11729 : visit (param.get_pattern ());
131 11729 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
132 11729 : 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 11729 : });
144 11729 : }
145 :
146 : void
147 883 : TokenCollector::visit (VariadicParam ¶m)
148 : {
149 883 : describe_node (std::string ("VariadicParam"), [this, ¶m] () {
150 883 : if (param.has_pattern ())
151 : {
152 9 : visit (param.get_pattern ());
153 18 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
154 : }
155 883 : push (Rust::Token::make (ELLIPSIS, UNDEF_LOCATION));
156 883 : });
157 883 : }
158 :
159 : void
160 27329 : TokenCollector::visit (Attribute &attrib)
161 : {
162 27329 : describe_node (std::string ("Attribute"), [this, &attrib] () {
163 27329 : push (Rust::Token::make (HASH, attrib.get_locus ()));
164 27329 : if (attrib.is_inner_attribute ())
165 22626 : push (Rust::Token::make (EXCLAM, UNDEF_LOCATION));
166 27329 : push (Rust::Token::make (LEFT_SQUARE, UNDEF_LOCATION));
167 27329 : visit (attrib.get_path ());
168 :
169 27329 : if (attrib.has_attr_input ())
170 : {
171 21191 : switch (attrib.get_attr_input ().get_attr_input_type ())
172 : {
173 11472 : case AST::AttrInput::AttrInputType::LITERAL:
174 11472 : {
175 11472 : visit (
176 11472 : static_cast<AttrInputLiteral &> (attrib.get_attr_input ()));
177 11472 : 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 422 : case AST::AttrInput::AttrInputType::META_ITEM:
185 422 : {
186 422 : visit (static_cast<AttrInputMetaItemContainer &> (
187 422 : attrib.get_attr_input ()));
188 422 : break;
189 : }
190 9296 : case AST::AttrInput::AttrInputType::TOKEN_TREE:
191 9296 : {
192 9296 : visit (static_cast<DelimTokenTree &> (attrib.get_attr_input ()));
193 9296 : break;
194 : }
195 0 : default:
196 0 : rust_unreachable ();
197 : }
198 : }
199 27329 : push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION));
200 27329 : });
201 27329 : }
202 :
203 : void
204 28842 : TokenCollector::visit (SimplePath &path)
205 : {
206 28842 : describe_node (std::string ("SimplePath"), [this, &path] () {
207 28842 : if (path.has_opening_scope_resolution ())
208 : {
209 0 : push (Rust::Token::make (SCOPE_RESOLUTION, path.get_locus ()));
210 : }
211 28842 : visit_items_joined_by_separator (path.get_segments (), SCOPE_RESOLUTION);
212 28842 : });
213 28842 : }
214 :
215 : void
216 29844 : TokenCollector::visit (SimplePathSegment &segment)
217 : {
218 29844 : describe_node (std::string ("SimplePathSegment"), [this, &segment] () {
219 29844 : auto name = segment.get_segment_name ();
220 29844 : if (segment.is_crate_path_seg ())
221 : {
222 268 : push (Rust::Token::make (CRATE, segment.get_locus ()));
223 : }
224 29710 : else if (segment.is_super_path_seg ())
225 : {
226 604 : push (Rust::Token::make (SUPER, segment.get_locus ()));
227 : }
228 29408 : else if (segment.is_lower_self_seg ())
229 : {
230 150 : push (Rust::Token::make (SELF, segment.get_locus ()));
231 : }
232 29333 : else if (segment.is_big_self ())
233 : {
234 0 : push (Rust::Token::make (SELF_ALIAS, segment.get_locus ()));
235 : }
236 : else
237 : {
238 58666 : push (Rust::Token::make_identifier (segment.get_locus (),
239 : std::move (name)));
240 : }
241 29844 : });
242 29844 : }
243 :
244 : void
245 29545 : TokenCollector::visit (Visibility &vis)
246 : {
247 29545 : describe_node (std::string ("Visibility"), [this, &vis] () {
248 29545 : switch (vis.get_vis_type ())
249 : {
250 8991 : case Visibility::PUB:
251 8991 : push (Rust::Token::make (PUB, vis.get_locus ()));
252 8991 : break;
253 47 : case Visibility::PUB_CRATE:
254 47 : push (Rust::Token::make (PUB, vis.get_locus ()));
255 47 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
256 47 : push (Rust::Token::make (CRATE, UNDEF_LOCATION));
257 47 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
258 47 : 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 29545 : });
282 29545 : }
283 :
284 : void
285 9621 : TokenCollector::visit (std::vector<std::unique_ptr<GenericParam>> ¶ms)
286 : {
287 9621 : describe_node (std::string ("GenericParam"), [this, ¶ms] () {
288 9621 : push (Rust::Token::make (LEFT_ANGLE, UNDEF_LOCATION));
289 9621 : visit_items_joined_by_separator (params, COMMA);
290 9621 : push (Rust::Token::make (RIGHT_ANGLE, UNDEF_LOCATION));
291 9621 : });
292 9621 : }
293 :
294 : void
295 2112 : TokenCollector::visit (TupleField &field)
296 : {
297 2112 : describe_node (std::string ("TupleField"), [this, &field] () {
298 2169 : for (auto attr : field.get_outer_attrs ())
299 : {
300 57 : visit (attr);
301 57 : }
302 2112 : visit (field.get_visibility ());
303 2112 : visit (field.get_field_type ());
304 2112 : });
305 2112 : }
306 :
307 : void
308 2284 : TokenCollector::visit (StructField &field)
309 : {
310 2284 : describe_node (std::string ("StructField"), [this, &field] () {
311 2285 : for (auto attr : field.get_outer_attrs ())
312 : {
313 1 : visit (attr);
314 1 : }
315 2284 : visit (field.get_visibility ());
316 4568 : auto name = field.get_field_name ().as_string ();
317 4568 : push (Rust::Token::make_identifier (field.get_locus (), std::move (name)));
318 2284 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
319 2284 : visit (field.get_field_type ());
320 2284 : });
321 2284 : }
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 19437 : TokenCollector::visit (FunctionQualifiers &qualifiers)
336 : {
337 : // Syntax:
338 : // `const`? `async`? `unsafe`? (`extern` Abi?)?
339 : // unsafe? (extern Abi?)?
340 19437 : describe_node (std::string ("FunctionQualifiers"), [this, &qualifiers] () {
341 19437 : if (qualifiers.is_async ())
342 2 : push (Rust::Token::make (ASYNC, qualifiers.get_locus ()));
343 19437 : if (qualifiers.is_const ())
344 1988 : push (Rust::Token::make (CONST, qualifiers.get_locus ()));
345 19437 : if (qualifiers.is_unsafe ())
346 1118 : push (Rust::Token::make (UNSAFE, qualifiers.get_locus ()));
347 19437 : if (qualifiers.is_extern ())
348 : {
349 71 : push (Rust::Token::make (EXTERN_KW, qualifiers.get_locus ()));
350 71 : if (qualifiers.has_abi ())
351 : {
352 142 : push (Rust::Token::make_string (UNDEF_LOCATION,
353 213 : qualifiers.get_extern_abi ()));
354 : }
355 : }
356 19437 : });
357 19437 : }
358 :
359 : void
360 65 : TokenCollector::visit (MaybeNamedParam ¶m)
361 : {
362 : // Syntax:
363 : // OuterAttribute* ( ( IDENTIFIER | _ ) : )? Type
364 :
365 65 : describe_node (std::string ("MaybeNamedParam"), [this, ¶m] () {
366 65 : for (auto attr : param.get_outer_attrs ())
367 : {
368 0 : visit (attr);
369 0 : }
370 130 : auto param_name = param.get_name ().as_string ();
371 65 : 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 65 : visit (param.get_type ());
386 65 : });
387 65 : }
388 :
389 : void
390 80963 : TokenCollector::visit (Token &tok)
391 : {
392 80963 : std::string data
393 105981 : = tok.get_tok_ptr ()->should_have_str () ? tok.get_str () : "";
394 80963 : switch (tok.get_id ())
395 : {
396 20376 : case IDENTIFIER:
397 40752 : push (Rust::Token::make_identifier (tok.get_locus (), std::move (data)));
398 20376 : break;
399 393 : case INT_LITERAL:
400 393 : {
401 393 : auto suffix_start = data.length ();
402 786 : push (Rust::Token::make_int (tok.get_locus (), std::move (data),
403 : suffix_start, IntegerLiteralBase::Decimal,
404 : tok.get_type_hint ()));
405 393 : 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 4239 : case STRING_LITERAL:
415 8478 : push (Rust::Token::make_string (tok.get_locus (), std::move (data)));
416 4239 : 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 55945 : default:
447 111890 : push (Rust::Token::make (tok.get_id (), tok.get_locus ()));
448 : }
449 80963 : }
450 :
451 : void
452 10579 : TokenCollector::visit (DelimTokenTree &delim_tok_tree)
453 : {
454 10579 : describe_node (std::string ("DelimTokenTree"), [this, &delim_tok_tree] () {
455 91063 : for (auto &token : delim_tok_tree.to_token_stream ())
456 : {
457 80484 : visit (token);
458 10579 : }
459 10579 : });
460 10579 : }
461 :
462 : void
463 422 : TokenCollector::visit (AttrInputMetaItemContainer &container)
464 : {
465 422 : describe_node (std::string ("AttrInputMetaItemContainer"),
466 422 : [this, &container] () {
467 844 : for (auto &item : container.get_items ())
468 : {
469 422 : visit (item);
470 : }
471 422 : });
472 422 : }
473 :
474 : void
475 26158 : TokenCollector::visit (IdentifierExpr &ident_expr)
476 : {
477 26158 : describe_node (std::string ("IdentifierExpr"), [this, &ident_expr] () {
478 52316 : auto ident = ident_expr.get_ident ().as_string ();
479 52316 : push (Rust::Token::make_identifier (ident_expr.get_locus (),
480 : std::move (ident)));
481 26158 : });
482 26158 : }
483 :
484 : void
485 10129 : TokenCollector::visit (Lifetime &lifetime)
486 : {
487 : // Syntax:
488 : // Lifetime :
489 : // LIFETIME_OR_LABEL
490 : // | 'static
491 : // | '_
492 :
493 10129 : describe_node (std::string ("Lifetime"), [this, &lifetime] () {
494 10129 : auto name = lifetime.get_lifetime_name ();
495 10129 : switch (lifetime.get_lifetime_type ())
496 : {
497 510 : case Lifetime::LifetimeType::NAMED:
498 510 : push (
499 1020 : Rust::Token::make_lifetime (lifetime.get_locus (), std::move (name)));
500 510 : break;
501 113 : case Lifetime::LifetimeType::STATIC:
502 226 : push (Rust::Token::make_lifetime (lifetime.get_locus (),
503 113 : Values::Keywords::STATIC_KW));
504 113 : break;
505 9506 : case Lifetime::LifetimeType::WILDCARD:
506 19012 : push (Rust::Token::make_lifetime (lifetime.get_locus (),
507 9506 : Values::Keywords::UNDERSCORE));
508 9506 : break;
509 : }
510 10129 : });
511 10129 : }
512 :
513 : void
514 164 : 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 164 : describe_node (std::string ("LifetimeParam"), [this, &lifetime_param] () {
523 164 : visit_items_as_lines (lifetime_param.get_outer_attrs ());
524 164 : auto lifetime = lifetime_param.get_lifetime ();
525 164 : visit (lifetime);
526 :
527 164 : 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 164 : });
536 164 : }
537 :
538 : void
539 76 : TokenCollector::visit (ConstGenericParam ¶m)
540 : {
541 : // Syntax:
542 : // const IDENTIFIER : Type ( = Block | IDENTIFIER | -?LITERAL )?
543 76 : describe_node (std::string ("ConstGenericParam"), [this, ¶m] () {
544 76 : visit_items_as_lines (param.get_outer_attrs ());
545 76 : push (Rust::Token::make (CONST, param.get_locus ()));
546 76 : auto id = param.get_name ().as_string ();
547 152 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
548 76 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
549 76 : if (param.has_type ())
550 76 : visit (param.get_type ());
551 76 : if (param.has_default_value ())
552 : {
553 6 : push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
554 6 : visit (param.get_default_value_unchecked ());
555 : }
556 76 : });
557 76 : }
558 :
559 : void
560 40536 : TokenCollector::visit (PathExprSegment &segment)
561 : {
562 40536 : describe_node (std::string ("PathExprSegment"), [this, &segment] () {
563 40536 : visit (segment.get_ident_segment ());
564 40536 : if (segment.has_generic_args ())
565 : {
566 998 : auto generics = segment.get_generic_args ();
567 998 : push (Rust::Token::make (SCOPE_RESOLUTION, segment.get_locus ()));
568 998 : push (Rust::Token::make (LEFT_ANGLE, generics.get_locus ()));
569 :
570 998 : auto &lifetime_args = generics.get_lifetime_args ();
571 998 : auto &generic_args = generics.get_generic_args ();
572 998 : auto &binding_args = generics.get_binding_args ();
573 :
574 998 : visit_items_joined_by_separator (generic_args, COMMA);
575 :
576 998 : if (!lifetime_args.empty ()
577 998 : && (!generic_args.empty () || !binding_args.empty ()))
578 : {
579 0 : push (Rust::Token::make (COMMA, UNDEF_LOCATION));
580 : }
581 :
582 998 : visit_items_joined_by_separator (binding_args, COMMA);
583 :
584 998 : if (!generic_args.empty () && !binding_args.empty ())
585 : {
586 0 : push (Rust::Token::make (COMMA, UNDEF_LOCATION));
587 : }
588 :
589 998 : visit_items_joined_by_separator (lifetime_args, COMMA);
590 :
591 998 : push (Rust::Token::make (RIGHT_ANGLE, UNDEF_LOCATION));
592 998 : }
593 40536 : });
594 40536 : }
595 :
596 : void
597 27232 : TokenCollector::visit (PathInExpression &path)
598 : {
599 27232 : describe_node (std::string ("PathInExpression"), [this, &path] () {
600 27232 : if (path.is_lang_item ())
601 : {
602 167 : push (Rust::Token::make (TokenId::HASH, path.get_locus ()));
603 167 : push (Rust::Token::make (TokenId::LEFT_SQUARE, path.get_locus ()));
604 334 : push (Rust::Token::make_identifier (path.get_locus (), "lang"));
605 167 : push (Rust::Token::make (TokenId::EQUAL, path.get_locus ()));
606 334 : push (Rust::Token::make_string (
607 167 : path.get_locus (), LangItem::ToString (path.get_lang_item ())));
608 167 : push (Rust::Token::make (TokenId::RIGHT_SQUARE, path.get_locus ()));
609 :
610 167 : return;
611 : }
612 :
613 27065 : if (path.opening_scope_resolution ())
614 766 : push (Rust::Token::make (SCOPE_RESOLUTION, path.get_locus ()));
615 :
616 27065 : visit_items_joined_by_separator (path.get_segments (), SCOPE_RESOLUTION);
617 : });
618 27232 : }
619 :
620 : void
621 59723 : TokenCollector::visit (TypePathSegment &segment)
622 : {
623 : // Syntax:
624 : // PathIdentSegment
625 59723 : describe_node (std::string ("TypePathSegment"), [this, &segment] () {
626 59723 : auto locus = segment.is_lang_item ()
627 59723 : ? segment.get_locus ()
628 59388 : : segment.get_ident_segment ().get_locus ();
629 59723 : auto segment_string = segment.is_lang_item ()
630 59723 : ? LangItem::PrettyString (segment.get_lang_item ())
631 59723 : : segment.get_ident_segment ().as_string ();
632 119446 : push (Rust::Token::make_identifier (locus, std::move (segment_string)));
633 59723 : });
634 59723 : }
635 :
636 : void
637 3302 : TokenCollector::visit (TypePathSegmentGeneric &segment)
638 : {
639 : // Syntax:
640 : // PathIdentSegment `::`? (GenericArgs)?
641 : // GenericArgs :
642 : // `<` `>`
643 : // | `<` ( GenericArg `,` )* GenericArg `,`? `>`
644 3302 : describe_node (std::string ("TypePathSegmentGeneric"), [this, &segment] () {
645 3302 : auto locus = segment.is_lang_item ()
646 3302 : ? segment.get_locus ()
647 3254 : : segment.get_ident_segment ().get_locus ();
648 3302 : auto segment_string = segment.is_lang_item ()
649 3302 : ? LangItem::PrettyString (segment.get_lang_item ())
650 3302 : : segment.get_ident_segment ().as_string ();
651 6604 : push (Rust::Token::make_identifier (locus, std::move (segment_string)));
652 :
653 3302 : push (Rust::Token::make (LEFT_ANGLE, UNDEF_LOCATION));
654 :
655 3302 : {
656 3302 : auto &lifetime_args = segment.get_generic_args ().get_lifetime_args ();
657 3302 : auto &generic_args = segment.get_generic_args ().get_generic_args ();
658 3302 : auto &binding_args = segment.get_generic_args ().get_binding_args ();
659 :
660 3302 : visit_items_joined_by_separator (lifetime_args, COMMA);
661 3302 : if (!lifetime_args.empty ()
662 3302 : && (!generic_args.empty () || !binding_args.empty ()))
663 4 : push (Rust::Token::make (COMMA, UNDEF_LOCATION));
664 3302 : visit_items_joined_by_separator (generic_args, COMMA);
665 3302 : if (!generic_args.empty () && !binding_args.empty ())
666 2 : push (Rust::Token::make (COMMA, UNDEF_LOCATION));
667 3302 : visit_items_joined_by_separator (binding_args, COMMA);
668 : }
669 :
670 6604 : push (Rust::Token::make (RIGHT_ANGLE, UNDEF_LOCATION));
671 3302 : });
672 3302 : }
673 :
674 : void
675 52 : TokenCollector::visit (GenericArgsBinding &binding)
676 : {
677 : // Syntax:
678 : // IDENTIFIER `=` Type
679 52 : describe_node (std::string ("GenericArgsBinding"), [this, &binding] () {
680 104 : auto identifier = binding.get_identifier ().as_string ();
681 104 : push (Rust::Token::make_identifier (binding.get_locus (),
682 : std::move (identifier)));
683 :
684 52 : push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
685 52 : visit (binding.get_type ());
686 52 : });
687 52 : }
688 :
689 : void
690 4528 : 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 4528 : describe_node (std::string ("GenericArg"), [this, &arg] () {
695 4528 : switch (arg.get_kind ())
696 : {
697 110 : case GenericArg::Kind::Const:
698 110 : visit (arg.get_expression ());
699 110 : break;
700 4411 : case GenericArg::Kind::Type:
701 4411 : visit (arg.get_type ());
702 4411 : 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 4528 : });
712 4528 : }
713 :
714 : void
715 28 : TokenCollector::visit (TypePathSegmentFunction &segment)
716 : {
717 : // Syntax:
718 : // PathIdentSegment `::`? (TypePathFn)?
719 28 : describe_node (std::string ("TypePathSegmentFunction"), [this, &segment] () {
720 28 : auto ident_segment = segment.get_ident_segment ();
721 28 : auto id = ident_segment.as_string ();
722 56 : push (Rust::Token::make_identifier (ident_segment.get_locus (),
723 : std::move (id)));
724 :
725 28 : if (segment.get_separating_scope_resolution ())
726 0 : push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
727 :
728 28 : if (!segment.is_ident_only ())
729 28 : visit (segment.get_type_path_function ());
730 28 : });
731 28 : }
732 :
733 : void
734 28 : TokenCollector::visit (TypePathFunction &type_path_fn)
735 : {
736 : // Syntax:
737 : // `(` TypePathFnInputs? `)` (`->` Type)?
738 : // TypePathFnInputs :
739 : // Type (`,` Type)* `,`?
740 28 : describe_node (std::string ("TypePathFunction"), [this, &type_path_fn] () {
741 28 : push (Rust::Token::make (LEFT_PAREN, type_path_fn.get_locus ()));
742 28 : if (type_path_fn.has_inputs ())
743 27 : visit_items_joined_by_separator (type_path_fn.get_params (), COMMA);
744 28 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
745 :
746 28 : if (type_path_fn.has_return_type ())
747 : {
748 28 : push (Rust::Token::make (RETURN_TYPE, UNDEF_LOCATION));
749 28 : visit (type_path_fn.get_return_type ());
750 : }
751 28 : });
752 28 : }
753 :
754 : void
755 60889 : TokenCollector::visit (TypePath &path)
756 : {
757 : // Syntax:
758 : // `::`? TypePathSegment (`::` TypePathSegment)*
759 60889 : describe_node (std::string ("TypePath"), [this, &path] () {
760 60889 : if (path.has_opening_scope_resolution_op ())
761 728 : push (Rust::Token::make (SCOPE_RESOLUTION, path.get_locus ()));
762 :
763 60889 : visit_items_joined_by_separator (path.get_segments (), SCOPE_RESOLUTION);
764 60889 : });
765 60889 : }
766 :
767 : void
768 40536 : TokenCollector::visit (PathIdentSegment &segment)
769 : {
770 40536 : describe_node (std::string ("PathIdentSegment"), [this, &segment] () {
771 40536 : if (segment.is_super_path_seg ())
772 : {
773 2 : push (Rust::Token::make (SUPER, segment.get_locus ()));
774 : }
775 40535 : else if (segment.is_crate_path_seg ())
776 : {
777 3070 : push (Rust::Token::make (CRATE, segment.get_locus ()));
778 : }
779 39000 : else if (segment.is_lower_self_seg ())
780 : {
781 14870 : push (Rust::Token::make (SELF, segment.get_locus ()));
782 : }
783 31565 : else if (segment.is_big_self_seg ())
784 : {
785 980 : push (Rust::Token::make (SELF_ALIAS, segment.get_locus ()));
786 : }
787 : else
788 : {
789 31075 : auto id = segment.as_string ();
790 31075 : push (
791 62150 : Rust::Token::make_identifier (segment.get_locus (), std::move (id)));
792 31075 : }
793 40536 : });
794 40536 : }
795 :
796 : void
797 119 : TokenCollector::visit (QualifiedPathInExpression &path)
798 : {
799 119 : describe_node (std::string ("QualifiedPathInExpression"), [this, &path] () {
800 119 : visit (path.get_qualified_path_type ());
801 238 : for (auto &segment : path.get_segments ())
802 : {
803 119 : push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
804 119 : visit (segment);
805 : }
806 119 : });
807 119 : }
808 :
809 : void
810 401 : TokenCollector::visit (QualifiedPathType &path)
811 : {
812 401 : describe_node (std::string ("QualifiedPathType"), [this, &path] () {
813 401 : push (Rust::Token::make (LEFT_ANGLE, path.get_locus ()));
814 401 : visit (path.get_type ());
815 401 : if (path.has_as_clause ())
816 : {
817 361 : push (Rust::Token::make (AS, UNDEF_LOCATION));
818 361 : visit (path.get_as_type_path ());
819 : }
820 401 : push (Rust::Token::make (RIGHT_ANGLE, UNDEF_LOCATION));
821 401 : });
822 401 : }
823 :
824 : void
825 282 : TokenCollector::visit (QualifiedPathInType &path)
826 : {
827 282 : describe_node (std::string ("QualifiedPathInType"), [this, &path] () {
828 282 : visit (path.get_qualified_path_type ());
829 :
830 282 : push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
831 282 : visit (path.get_associated_segment ());
832 282 : for (auto &segment : path.get_segments ())
833 : {
834 0 : push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
835 0 : visit (segment);
836 : }
837 282 : });
838 282 : }
839 :
840 : void
841 33045 : TokenCollector::visit (Literal &lit, location_t locus)
842 : {
843 33045 : auto value = lit.as_string ();
844 33045 : 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 13927 : case Literal::LitType::STRING:
853 27854 : push (Rust::Token::make_string (locus, std::move (value)));
854 13927 : 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 16853 : case Literal::LitType::INT:
868 16853 : {
869 16853 : auto val_len = value.length ();
870 33706 : push (Rust::Token::make_int (locus, std::move (value), val_len,
871 : IntegerLiteralBase::Decimal,
872 : lit.get_type_hint ()));
873 16853 : break;
874 : }
875 330 : case Literal::LitType::FLOAT:
876 330 : {
877 330 : auto val_len = value.length ();
878 660 : push (Rust::Token::make_float (locus, std::move (value), val_len,
879 : lit.get_type_hint ()));
880 330 : break;
881 : }
882 1291 : case Literal::LitType::BOOL:
883 1291 : {
884 1291 : if (value == Values::Keywords::FALSE_LITERAL)
885 1104 : push (Rust::Token::make (FALSE_LITERAL, locus));
886 739 : else if (value == Values::Keywords::TRUE_LITERAL)
887 1478 : 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 33045 : break;
895 : }
896 33045 : }
897 :
898 : void
899 32565 : TokenCollector::visit (LiteralExpr &expr)
900 : {
901 32565 : describe_node (std::string ("LiteralExpr"), [this, &expr] () {
902 32565 : auto lit = expr.get_literal ();
903 32565 : visit (lit, expr.get_locus ());
904 32565 : });
905 32565 : }
906 :
907 : void
908 11472 : TokenCollector::visit (AttrInputLiteral &literal)
909 : {
910 11472 : describe_node (std::string ("AttrInputLiteral"), [this, &literal] () {
911 11472 : push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
912 11472 : visit (literal.get_literal ());
913 11472 : });
914 11472 : }
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 2033 : TokenCollector::visit (BorrowExpr &expr)
946 : {
947 2033 : describe_node (std::string ("BorrowExpr"), [this, &expr] () {
948 2033 : push (Rust::Token::make (AMP, expr.get_locus ()));
949 2033 : if (expr.get_is_double_borrow ())
950 46 : push (Rust::Token::make (AMP, UNDEF_LOCATION));
951 :
952 2033 : 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 2029 : if (expr.get_is_mut ())
964 886 : push (Rust::Token::make (MUT, UNDEF_LOCATION));
965 : }
966 :
967 2033 : 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 2029 : if (expr.get_is_mut ())
979 886 : push (Rust::Token::make (MUT, UNDEF_LOCATION));
980 : }
981 :
982 2033 : if (expr.has_borrow_expr ())
983 2033 : visit (expr.get_borrowed_expr ());
984 2033 : });
985 2033 : }
986 :
987 : void
988 4129 : TokenCollector::visit (DereferenceExpr &expr)
989 : {
990 4129 : describe_node (std::string ("DereferenceExpr"), [this, &expr] () {
991 4129 : push (Rust::Token::make (ASTERISK, expr.get_locus ()));
992 4129 : visit (expr.get_dereferenced_expr ());
993 4129 : });
994 4129 : }
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 875 : TokenCollector::visit (NegationExpr &expr)
1007 : {
1008 875 : describe_node (std::string ("NegationExpr"), [this, &expr] () {
1009 875 : switch (expr.get_expr_type ())
1010 : {
1011 410 : case NegationOperator::NEGATE:
1012 410 : push (Rust::Token::make (MINUS, expr.get_locus ()));
1013 410 : break;
1014 465 : case NegationOperator::NOT:
1015 465 : push (Rust::Token::make (EXCLAM, expr.get_locus ()));
1016 465 : break;
1017 : }
1018 875 : visit (expr.get_negated_expr ());
1019 875 : });
1020 875 : }
1021 :
1022 : void
1023 3696 : TokenCollector::visit (ArithmeticOrLogicalExpr &expr)
1024 : {
1025 3696 : describe_node (std::string ("ArithmeticOrLogicalExpr"), [this, &expr] () {
1026 3696 : visit (expr.get_left_expr ());
1027 3696 : switch (expr.get_expr_type ())
1028 : {
1029 2005 : case ArithmeticOrLogicalOperator::ADD:
1030 2005 : push (Rust::Token::make (PLUS, expr.get_locus ()));
1031 2005 : break;
1032 :
1033 1141 : case ArithmeticOrLogicalOperator::SUBTRACT:
1034 1141 : push (Rust::Token::make (MINUS, expr.get_locus ()));
1035 1141 : break;
1036 :
1037 249 : case ArithmeticOrLogicalOperator::MULTIPLY:
1038 249 : push (Rust::Token::make (ASTERISK, expr.get_locus ()));
1039 249 : break;
1040 :
1041 34 : case ArithmeticOrLogicalOperator::DIVIDE:
1042 34 : push (Rust::Token::make (DIV, expr.get_locus ()));
1043 34 : break;
1044 :
1045 40 : case ArithmeticOrLogicalOperator::MODULUS:
1046 40 : push (Rust::Token::make (PERCENT, expr.get_locus ()));
1047 40 : break;
1048 :
1049 52 : case ArithmeticOrLogicalOperator::BITWISE_AND:
1050 52 : push (Rust::Token::make (AMP, expr.get_locus ()));
1051 52 : break;
1052 :
1053 39 : case ArithmeticOrLogicalOperator::BITWISE_OR:
1054 39 : push (Rust::Token::make (PIPE, expr.get_locus ()));
1055 39 : 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 3696 : visit (expr.get_right_expr ());
1071 3696 : });
1072 3696 : }
1073 :
1074 : void
1075 3912 : TokenCollector::visit (ComparisonExpr &expr)
1076 : {
1077 3912 : describe_node (std::string ("ComparisonExpr"), [this, &expr] () {
1078 3912 : visit (expr.get_left_expr ());
1079 :
1080 3912 : switch (expr.get_expr_type ())
1081 : {
1082 906 : case ComparisonOperator::EQUAL:
1083 906 : push (Rust::Token::make (EQUAL_EQUAL, expr.get_locus ()));
1084 906 : break;
1085 1011 : case ComparisonOperator::NOT_EQUAL:
1086 1011 : push (Rust::Token::make (NOT_EQUAL, expr.get_locus ()));
1087 1011 : break;
1088 663 : case ComparisonOperator::GREATER_THAN:
1089 663 : push (Rust::Token::make (RIGHT_ANGLE, expr.get_locus ()));
1090 663 : break;
1091 803 : case ComparisonOperator::LESS_THAN:
1092 803 : push (Rust::Token::make (LEFT_ANGLE, expr.get_locus ()));
1093 803 : 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 293 : case ComparisonOperator::LESS_OR_EQUAL:
1099 293 : push (Rust::Token::make (LESS_OR_EQUAL, expr.get_locus ()));
1100 293 : break;
1101 : }
1102 3912 : visit (expr.get_right_expr ());
1103 3912 : });
1104 3912 : }
1105 :
1106 : void
1107 466 : TokenCollector::visit (LazyBooleanExpr &expr)
1108 : {
1109 466 : describe_node (std::string ("LazyBooleanExpr"), [this, &expr] () {
1110 466 : visit (expr.get_left_expr ());
1111 :
1112 466 : switch (expr.get_expr_type ())
1113 : {
1114 378 : case LazyBooleanOperator::LOGICAL_AND:
1115 378 : push (Rust::Token::make (LOGICAL_AND, expr.get_locus ()));
1116 378 : break;
1117 88 : case LazyBooleanOperator::LOGICAL_OR:
1118 88 : push (Rust::Token::make (OR, expr.get_locus ()));
1119 88 : break;
1120 : }
1121 :
1122 466 : visit (expr.get_right_expr ());
1123 466 : });
1124 466 : }
1125 :
1126 : void
1127 5613 : TokenCollector::visit (TypeCastExpr &expr)
1128 : {
1129 5613 : describe_node (std::string ("TypeCastExpr"), [this, &expr] () {
1130 5613 : visit (expr.get_casted_expr ());
1131 5613 : push (Rust::Token::make (AS, expr.get_locus ()));
1132 5613 : visit (expr.get_type_to_cast_to ());
1133 5613 : });
1134 5613 : }
1135 :
1136 : void
1137 2505 : TokenCollector::visit (AssignmentExpr &expr)
1138 : {
1139 2505 : describe_node (std::string ("AssignementExpr"), [this, &expr] () {
1140 2505 : expr.visit_lhs (*this);
1141 2505 : push (Rust::Token::make (EQUAL, expr.get_locus ()));
1142 2505 : expr.visit_rhs (*this);
1143 2505 : });
1144 2505 : }
1145 :
1146 : void
1147 703 : TokenCollector::visit (CompoundAssignmentExpr &expr)
1148 : {
1149 703 : describe_node (std::string ("CompoundAssignmentExpr"), [this, &expr] () {
1150 703 : visit (expr.get_left_expr ());
1151 :
1152 703 : switch (expr.get_expr_type ())
1153 : {
1154 177 : case CompoundAssignmentOperator::ADD:
1155 177 : push (Rust::Token::make (PLUS_EQ, expr.get_locus ()));
1156 177 : 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 703 : visit (expr.get_right_expr ());
1186 703 : });
1187 703 : }
1188 :
1189 : void
1190 360 : TokenCollector::visit (GroupedExpr &expr)
1191 : {
1192 360 : describe_node (std::string ("GroupedExpr"), [this, &expr] () {
1193 360 : push (Rust::Token::make (LEFT_PAREN, expr.get_locus ()));
1194 360 : visit (expr.get_expr_in_parens ());
1195 360 : push (Rust::Token::make (RIGHT_PAREN, expr.get_locus ()));
1196 360 : });
1197 360 : }
1198 :
1199 : void
1200 295 : TokenCollector::visit (ArrayElemsValues &elems)
1201 : {
1202 295 : describe_node (std::string ("ArraysElemValues"), [this, &elems] () {
1203 295 : visit_items_joined_by_separator (elems.get_values (), COMMA);
1204 295 : });
1205 295 : }
1206 :
1207 : void
1208 115 : TokenCollector::visit (ArrayElemsCopied &elems)
1209 : {
1210 115 : describe_node (std::string ("ArrayElemsCopied"), [this, &elems] () {
1211 115 : visit (elems.get_elem_to_copy ());
1212 115 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
1213 115 : visit (elems.get_num_copies ());
1214 115 : });
1215 115 : }
1216 :
1217 : void
1218 410 : TokenCollector::visit (ArrayExpr &expr)
1219 : {
1220 410 : describe_node (std::string ("ArrayExpr"), [this, &expr] () {
1221 410 : push (Rust::Token::make (LEFT_SQUARE, expr.get_locus ()));
1222 410 : visit (expr.get_array_elems ());
1223 410 : push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION));
1224 410 : });
1225 410 : }
1226 :
1227 : void
1228 302 : TokenCollector::visit (ArrayIndexExpr &expr)
1229 : {
1230 302 : describe_node (std::string ("ArrayIndexExpr"), [this, &expr] () {
1231 302 : visit (expr.get_array_expr ());
1232 302 : push (Rust::Token::make (LEFT_SQUARE, expr.get_locus ()));
1233 302 : visit (expr.get_index_expr ());
1234 302 : push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION));
1235 302 : });
1236 302 : }
1237 :
1238 : void
1239 580 : TokenCollector::visit (TupleExpr &expr)
1240 : {
1241 580 : describe_node (std::string ("TupleExpr"), [this, &expr] () {
1242 580 : visit_items_as_lines (expr.get_outer_attrs ());
1243 580 : push (Rust::Token::make (LEFT_PAREN, expr.get_locus ()));
1244 580 : visit_items_joined_by_separator (expr.get_tuple_elems (), COMMA);
1245 580 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
1246 580 : });
1247 580 : }
1248 :
1249 : void
1250 900 : TokenCollector::visit (TupleIndexExpr &expr)
1251 : {
1252 900 : describe_node (std::string ("TupleIndexExpr"), [this, &expr] () {
1253 900 : visit (expr.get_tuple_expr ());
1254 900 : push (Rust::Token::make (DOT, expr.get_locus ()));
1255 900 : auto str = std::to_string (expr.get_tuple_index ());
1256 900 : auto suffix_start = str.length ();
1257 1800 : push (Rust::Token::make_int (UNDEF_LOCATION, str, suffix_start,
1258 : IntegerLiteralBase::Decimal));
1259 900 : });
1260 900 : }
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 229 : TokenCollector::visit (StructExprFieldIdentifier &expr)
1271 : {
1272 229 : describe_node (std::string ("StructExprFieldIdentifier"), [this, &expr] () {
1273 229 : visit_items_as_lines (expr.get_outer_attrs ());
1274 458 : auto id = expr.get_field_name ().as_string ();
1275 458 : push (Rust::Token::make_identifier (expr.get_locus (), std::move (id)));
1276 229 : });
1277 229 : }
1278 :
1279 : void
1280 2071 : TokenCollector::visit (StructExprFieldIdentifierValue &expr)
1281 : {
1282 2071 : describe_node (std::string ("StructExprFieldIdentifierValue"), [this,
1283 : &expr] () {
1284 2071 : visit_items_as_lines (expr.get_outer_attrs ());
1285 2071 : auto id = expr.get_field_name ();
1286 4142 : push (Rust::Token::make_identifier (expr.get_locus (), std::move (id)));
1287 2071 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
1288 2071 : visit (expr.get_value ());
1289 2071 : });
1290 2071 : }
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 1381 : TokenCollector::visit (StructExprStructFields &expr)
1317 : {
1318 1381 : describe_node (std::string ("StructExprStructFields"), [this, &expr] () {
1319 1381 : visit (expr.get_struct_name ());
1320 1381 : push (Rust::Token::make (LEFT_CURLY, expr.get_locus ()));
1321 1381 : visit_items_joined_by_separator (expr.get_fields (), COMMA);
1322 1381 : 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 1318 : trailing_comma ();
1330 : }
1331 1381 : push (Rust::Token::make (RIGHT_CURLY, expr.get_locus ()));
1332 1381 : });
1333 1381 : }
1334 :
1335 : void
1336 0 : TokenCollector::visit (StructExprStructBase &)
1337 : {
1338 : // FIXME: Implement this node
1339 0 : rust_unreachable ();
1340 : }
1341 :
1342 : void
1343 13255 : TokenCollector::visit (CallExpr &expr)
1344 : {
1345 13255 : describe_node (std::string ("CallExpr"), [this, &expr] () {
1346 13255 : visit (expr.get_function_expr ());
1347 :
1348 13255 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
1349 :
1350 13255 : visit_items_joined_by_separator (expr.get_params (), COMMA);
1351 :
1352 13255 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
1353 13255 : });
1354 13255 : }
1355 :
1356 : void
1357 3185 : TokenCollector::visit (MethodCallExpr &expr)
1358 : {
1359 3185 : describe_node (std::string ("MethodCallExpr"), [this, &expr] () {
1360 3185 : visit (expr.get_receiver_expr ());
1361 3185 : push (Rust::Token::make (DOT, expr.get_locus ()));
1362 3185 : visit (expr.get_method_name ());
1363 3185 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
1364 3185 : visit_items_joined_by_separator (expr.get_params (), COMMA);
1365 3185 : trailing_comma ();
1366 3185 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
1367 3185 : });
1368 3185 : }
1369 :
1370 : void
1371 5134 : TokenCollector::visit (FieldAccessExpr &expr)
1372 : {
1373 5134 : describe_node (std::string ("FieldAccessExpr"), [this, &expr] () {
1374 5134 : visit (expr.get_receiver_expr ());
1375 5134 : push (Rust::Token::make (DOT, expr.get_locus ()));
1376 10268 : auto field_name = expr.get_field_name ().as_string ();
1377 5134 : push (
1378 10268 : Rust::Token::make_identifier (UNDEF_LOCATION, std::move (field_name)));
1379 5134 : });
1380 5134 : }
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 24433 : TokenCollector::visit (BlockExpr &expr)
1421 : {
1422 24433 : describe_node (std::string ("BlockExpr"), [this, &expr] () {
1423 24433 : visit_items_as_lines (expr.get_outer_attrs ());
1424 24433 : push (Rust::Token::make (LEFT_CURLY, expr.get_locus ()));
1425 24433 : newline ();
1426 24433 : increment_indentation ();
1427 24433 : visit_items_as_lines (expr.get_inner_attrs ());
1428 :
1429 24433 : visit_items_as_lines (expr.get_statements (), {});
1430 :
1431 24433 : if (expr.has_tail_expr ())
1432 : {
1433 17557 : indentation ();
1434 17557 : visit (expr.get_tail_expr ());
1435 17557 : newline ();
1436 : }
1437 :
1438 24433 : decrement_indentation ();
1439 24433 : indentation ();
1440 24433 : push (Rust::Token::make (RIGHT_CURLY, expr.get_locus ()));
1441 24433 : newline ();
1442 24433 : });
1443 24433 : }
1444 :
1445 : void
1446 935 : TokenCollector::visit (AnonConst &expr)
1447 : {
1448 935 : if (!expr.is_deferred ())
1449 : {
1450 915 : visit (expr.get_inner_expr ());
1451 915 : 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 25 : TokenCollector::visit (ContinueExpr &expr)
1481 : {
1482 25 : describe_node (std::string ("ContinueExpr"), [this, &expr] () {
1483 25 : push (Rust::Token::make (CONTINUE, expr.get_locus ()));
1484 25 : if (expr.has_label ())
1485 6 : visit (expr.get_label_unchecked ());
1486 25 : });
1487 25 : }
1488 :
1489 : void
1490 113 : TokenCollector::visit (BreakExpr &expr)
1491 : {
1492 113 : describe_node (std::string ("BreakExpr"), [this, &expr] () {
1493 113 : push (Rust::Token::make (BREAK, expr.get_locus ()));
1494 113 : if (expr.has_label ())
1495 33 : visit (expr.get_label_unchecked ());
1496 113 : if (expr.has_break_expr ())
1497 21 : visit (expr.get_break_expr_unchecked ());
1498 113 : });
1499 113 : }
1500 :
1501 : void
1502 73 : TokenCollector::visit (RangeFromToExpr &expr)
1503 : {
1504 73 : describe_node (std::string ("RangeFromToExpr"), [this, &expr] () {
1505 73 : visit (expr.get_from_expr ());
1506 73 : push (Rust::Token::make (DOT_DOT, expr.get_locus ()));
1507 73 : visit (expr.get_to_expr ());
1508 73 : });
1509 73 : }
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 4 : TokenCollector::visit (BoxExpr &expr)
1558 : {
1559 4 : describe_node (std::string ("BoxExpr"), [this, &expr] () {
1560 4 : push (Rust::Token::make (BOX, expr.get_locus ()));
1561 4 : visit (expr.get_boxed_expr ());
1562 4 : });
1563 4 : }
1564 :
1565 : void
1566 561 : TokenCollector::visit (ReturnExpr &expr)
1567 : {
1568 561 : describe_node (std::string ("ReturnExpr"), [this, &expr] () {
1569 561 : push (Rust::Token::make (RETURN_KW, expr.get_locus ()));
1570 561 : if (expr.has_returned_expr ())
1571 524 : visit (expr.get_returned_expr ());
1572 561 : });
1573 561 : }
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 3908 : TokenCollector::visit (UnsafeBlockExpr &expr)
1584 : {
1585 3908 : describe_node (std::string ("UnsafeBlockExpr"), [this, &expr] () {
1586 3908 : push (Rust::Token::make (UNSAFE, expr.get_locus ()));
1587 3908 : visit (expr.get_block_expr ());
1588 3908 : });
1589 3908 : }
1590 :
1591 : void
1592 84 : TokenCollector::visit (LoopLabel &label)
1593 : {
1594 84 : describe_node (std::string ("LoopLabel"), [this, &label] () {
1595 84 : visit (label.get_lifetime ());
1596 84 : push (Rust::Token::make (COLON, label.get_locus ()));
1597 84 : });
1598 84 : }
1599 :
1600 : void
1601 236 : TokenCollector::visit_loop_common (BaseLoopExpr &expr)
1602 : {
1603 236 : describe_node (std::string ("BaseLoopExpr"), [this, &expr] () {
1604 236 : if (expr.has_loop_label ())
1605 51 : visit (expr.get_loop_label ());
1606 236 : });
1607 236 : }
1608 :
1609 : void
1610 147 : TokenCollector::visit (LoopExpr &expr)
1611 : {
1612 147 : describe_node (std::string ("LoopExpr"), [this, &expr] () {
1613 147 : visit_loop_common (expr);
1614 147 : push (Rust::Token::make (LOOP, expr.get_locus ()));
1615 147 : visit (expr.get_loop_block ());
1616 147 : });
1617 147 : }
1618 :
1619 : void
1620 89 : TokenCollector::visit (WhileLoopExpr &expr)
1621 : {
1622 89 : describe_node (std::string ("WhileLoopExpr"), [this, &expr] () {
1623 89 : visit_loop_common (expr);
1624 89 : push (Rust::Token::make (WHILE, expr.get_locus ()));
1625 89 : visit (expr.get_predicate_expr ());
1626 89 : visit (expr.get_loop_block ());
1627 89 : });
1628 89 : }
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 2768 : TokenCollector::visit (IfExpr &expr)
1659 : {
1660 2768 : describe_node (std::string ("IfExpr"), [this, &expr] () {
1661 2768 : push (Rust::Token::make (IF, expr.get_locus ()));
1662 :
1663 2768 : visit (expr.get_condition_expr ());
1664 2768 : visit (expr.get_if_block ());
1665 2768 : });
1666 2768 : }
1667 :
1668 : void
1669 1323 : TokenCollector::visit (IfExprConseqElse &expr)
1670 : {
1671 1323 : describe_node (std::string ("IfExprConseqElse"), [this, &expr] () {
1672 1323 : visit (static_cast<IfExpr &> (expr));
1673 1323 : indentation ();
1674 1323 : push (Rust::Token::make (ELSE, expr.get_locus ()));
1675 1323 : visit (expr.get_else_block ());
1676 1323 : });
1677 1323 : }
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 2473 : TokenCollector::visit (MatchArm &arm)
1705 : {
1706 2473 : describe_node (std::string ("MatchArm"), [this, &arm] () {
1707 2473 : visit_items_as_lines (arm.get_outer_attrs ());
1708 2473 : visit (arm.get_pattern ());
1709 2473 : 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 2473 : });
1715 2473 : }
1716 :
1717 : void
1718 2473 : TokenCollector::visit (MatchCase &match_case)
1719 : {
1720 2473 : describe_node (std::string ("MatchCase"), [this, &match_case] () {
1721 2473 : indentation ();
1722 2473 : visit (match_case.get_arm ());
1723 2473 : push (Rust::Token::make (MATCH_ARROW, UNDEF_LOCATION));
1724 2473 : visit (match_case.get_expr ());
1725 2473 : indentation ();
1726 2473 : push (Rust::Token::make (COMMA, UNDEF_LOCATION));
1727 2473 : newline ();
1728 2473 : });
1729 2473 : }
1730 :
1731 : void
1732 1075 : TokenCollector::visit (MatchExpr &expr)
1733 : {
1734 1075 : describe_node (std::string ("MatchExpr"), [this, &expr] () {
1735 1075 : push (Rust::Token::make (MATCH_KW, expr.get_locus ()));
1736 1075 : visit (expr.get_scrutinee_expr ());
1737 1075 : push (Rust::Token::make (LEFT_CURLY, UNDEF_LOCATION));
1738 1075 : newline ();
1739 1075 : increment_indentation ();
1740 1075 : visit_items_as_lines (expr.get_inner_attrs ());
1741 3548 : for (auto &arm : expr.get_match_cases ())
1742 : {
1743 2473 : visit (arm);
1744 : }
1745 1075 : decrement_indentation ();
1746 1075 : indentation ();
1747 1075 : push (Rust::Token::make (RIGHT_CURLY, UNDEF_LOCATION));
1748 1075 : });
1749 1075 : }
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 : push (Rust::Token::make_string (expr.get_template ().get_locus (),
1873 2 : std::move (expr.get_template ().symbol)));
1874 :
1875 2 : push (Rust::Token::make (COLON, expr.get_locus ()));
1876 :
1877 2 : bool needs_comma = false;
1878 :
1879 2 : for (auto output : expr.get_outputs ())
1880 : {
1881 0 : if (needs_comma)
1882 0 : push (Rust::Token::make (COMMA, expr.get_locus ()));
1883 0 : needs_comma = true;
1884 0 : push (Rust::Token::make_string (expr.get_locus (),
1885 : std::move (output.constraint)));
1886 0 : push (Rust::Token::make (LEFT_PAREN, expr.get_locus ()));
1887 0 : visit (output.expr);
1888 0 : push (Rust::Token::make (RIGHT_PAREN, expr.get_locus ()));
1889 0 : }
1890 :
1891 2 : push (Rust::Token::make (COLON, expr.get_locus ()));
1892 2 : needs_comma = false;
1893 4 : for (auto input : expr.get_inputs ())
1894 : {
1895 2 : if (needs_comma)
1896 0 : push (Rust::Token::make (COMMA, expr.get_locus ()));
1897 2 : needs_comma = true;
1898 4 : push (Rust::Token::make_string (expr.get_locus (),
1899 : std::move (input.constraint)));
1900 2 : push (Rust::Token::make (LEFT_PAREN, expr.get_locus ()));
1901 2 : visit (input.expr);
1902 4 : push (Rust::Token::make (RIGHT_PAREN, expr.get_locus ()));
1903 2 : }
1904 :
1905 2 : push (Rust::Token::make (COLON, expr.get_locus ()));
1906 2 : needs_comma = false;
1907 4 : for (auto &clobber : expr.get_clobbers ())
1908 : {
1909 2 : if (needs_comma)
1910 0 : push (Rust::Token::make (COMMA, expr.get_locus ()));
1911 2 : needs_comma = true;
1912 4 : push (Rust::Token::make_string (expr.get_locus (),
1913 2 : std::move (clobber.symbol)));
1914 : }
1915 2 : push (Rust::Token::make (COLON, expr.get_locus ()));
1916 :
1917 : #define X(code, s) \
1918 : if (expr.code) \
1919 : { \
1920 : if (needs_comma) \
1921 : push (Rust::Token::make (COMMA, expr.get_locus ())); \
1922 : needs_comma = true; \
1923 : push (Rust::Token::make_string (expr.get_locus (), s)); \
1924 : }
1925 :
1926 2 : needs_comma = false;
1927 4 : X (is_volatile (), "volatile")
1928 2 : X (is_stack_aligned (), "alignstack")
1929 2 : X (get_dialect () == LlvmInlineAsm::Dialect::Intel, "intel")
1930 :
1931 : #undef X
1932 :
1933 2 : push (Rust::Token::make (RIGHT_PAREN, expr.get_locus ()));
1934 2 : }
1935 :
1936 : // rust-item.h
1937 :
1938 : void
1939 4831 : TokenCollector::visit (TypeParam ¶m)
1940 : {
1941 : // Syntax:
1942 : // IDENTIFIER( : TypeParamBounds? )? ( = Type )?
1943 : // TypeParamBounds :
1944 : // TypeParamBound ( + TypeParamBound )* +?
1945 4831 : describe_node (std::string ("TypeParam"), [this, ¶m] () {
1946 4831 : visit_items_as_lines (param.get_outer_attrs ());
1947 9662 : auto id = param.get_type_representation ().as_string ();
1948 9662 : push (Rust::Token::make_identifier (param.get_locus (), std::move (id)));
1949 4831 : if (param.has_type_param_bounds ())
1950 : {
1951 864 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
1952 864 : visit_items_joined_by_separator (param.get_type_param_bounds (), PLUS);
1953 : }
1954 4831 : if (param.has_type ())
1955 : {
1956 385 : push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
1957 385 : visit (param.get_type ());
1958 : }
1959 4831 : });
1960 4831 : }
1961 :
1962 : void
1963 312 : TokenCollector::visit (WhereClause &rule)
1964 : {
1965 : // Syntax:
1966 : // where ( WhereClauseItem , )* WhereClauseItem ?
1967 : // WhereClauseItem :
1968 : // LifetimeWhereClauseItem
1969 : // | TypeBoundWhereClauseItem
1970 312 : describe_node (std::string ("WhereClause"), [this, &rule] () {
1971 312 : push (Rust::Token::make (WHERE, UNDEF_LOCATION));
1972 312 : newline ();
1973 312 : increment_indentation ();
1974 312 : visit_items_joined_by_separator (rule.get_items (), COMMA);
1975 312 : decrement_indentation ();
1976 312 : });
1977 312 : }
1978 :
1979 : void
1980 0 : TokenCollector::visit (LifetimeWhereClauseItem &item)
1981 : {
1982 : // Syntax:
1983 : // Lifetime : LifetimeBounds
1984 : // LifetimeBounds :
1985 : // ( Lifetime + )* Lifetime?
1986 :
1987 0 : describe_node (std::string ("LifetimeWhereClauseItem"), [this, &item] () {
1988 0 : visit (item.get_lifetime ());
1989 0 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
1990 0 : visit_items_joined_by_separator (item.get_lifetime_bounds (), PLUS);
1991 0 : });
1992 0 : }
1993 :
1994 : void
1995 336 : TokenCollector::visit (TypeBoundWhereClauseItem &item)
1996 : {
1997 : // Syntax:
1998 : // ForLifetimes? Type : TypeParamBounds?
1999 : // TypeParamBounds :
2000 : // TypeParamBound ( + TypeParamBound )* +?
2001 : // TypeParamBound :
2002 : // Lifetime | TraitBound
2003 :
2004 336 : describe_node (std::string ("TypeBoundWhereClauseItem"), [this, &item] () {
2005 336 : if (item.has_for_lifetimes ())
2006 7 : visit (item.get_for_lifetimes ());
2007 :
2008 336 : visit (item.get_type ());
2009 :
2010 336 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
2011 336 : visit_items_joined_by_separator (item.get_type_param_bounds (), PLUS);
2012 336 : });
2013 336 : }
2014 :
2015 : void
2016 1201 : TokenCollector::visit (Module &module)
2017 : {
2018 : // Syntax:
2019 : // mod IDENTIFIER ;
2020 : // | mod IDENTIFIER {
2021 : // InnerAttribute*
2022 : // Item*
2023 : // }
2024 1201 : describe_node (std::string ("Module"), [this, &module] () {
2025 1201 : visit_items_as_lines (module.get_outer_attrs ());
2026 1201 : visit (module.get_visibility ());
2027 2402 : auto name = module.get_name ().as_string ();
2028 1201 : push (Rust::Token::make (MOD, module.get_locus ()));
2029 2402 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (name)));
2030 :
2031 1201 : if (module.get_kind () == Module::UNLOADED)
2032 : {
2033 0 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2034 0 : newline ();
2035 : }
2036 : else /* Module::LOADED */
2037 : {
2038 1201 : push (Rust::Token::make (LEFT_CURLY, UNDEF_LOCATION));
2039 1201 : newline ();
2040 1201 : increment_indentation ();
2041 :
2042 1201 : visit_items_as_lines (module.get_inner_attrs ());
2043 1201 : visit_items_as_lines (module.get_items ());
2044 :
2045 1201 : decrement_indentation ();
2046 :
2047 1201 : push (Rust::Token::make (RIGHT_CURLY, UNDEF_LOCATION));
2048 1201 : newline ();
2049 : }
2050 1201 : });
2051 1201 : }
2052 :
2053 : void
2054 25 : TokenCollector::visit (ExternCrate &crate)
2055 : {
2056 25 : describe_node (std::string ("ExternCrate"), [this, &crate] () {
2057 25 : visit_items_as_lines (crate.get_outer_attrs ());
2058 25 : push (Rust::Token::make (EXTERN_KW, crate.get_locus ()));
2059 25 : push (Rust::Token::make (CRATE, UNDEF_LOCATION));
2060 25 : auto ref = crate.get_referenced_crate ();
2061 50 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (ref)));
2062 25 : if (crate.has_as_clause ())
2063 : {
2064 1 : auto as_clause = crate.get_as_clause ();
2065 1 : push (Rust::Token::make (AS, UNDEF_LOCATION));
2066 1 : push (
2067 2 : Rust::Token::make_identifier (UNDEF_LOCATION, std::move (as_clause)));
2068 1 : }
2069 25 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2070 25 : newline ();
2071 25 : });
2072 25 : }
2073 :
2074 : void
2075 18 : TokenCollector::visit (UseTreeGlob &use_tree)
2076 : {
2077 18 : describe_node (std::string ("UseTreeGlob"), [this, &use_tree] () {
2078 18 : switch (use_tree.get_glob_type ())
2079 : {
2080 15 : case UseTreeGlob::PathType::PATH_PREFIXED:
2081 15 : {
2082 15 : auto path = use_tree.get_path ();
2083 15 : visit (path);
2084 30 : push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
2085 15 : }
2086 15 : break;
2087 2 : case UseTreeGlob::PathType::NO_PATH:
2088 2 : push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
2089 2 : break;
2090 : case UseTreeGlob::PathType::GLOBAL:
2091 : break;
2092 : }
2093 18 : push (Rust::Token::make (ASTERISK, UNDEF_LOCATION));
2094 18 : });
2095 18 : }
2096 :
2097 : void
2098 171 : TokenCollector::visit (UseTreeList &use_tree)
2099 : {
2100 171 : describe_node (std::string ("UseTreeList"), [this, &use_tree] () {
2101 171 : switch (use_tree.get_path_type ())
2102 : {
2103 171 : case UseTreeList::PathType::PATH_PREFIXED:
2104 171 : {
2105 171 : auto path = use_tree.get_path ();
2106 171 : visit (path);
2107 :
2108 342 : push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
2109 171 : }
2110 171 : break;
2111 0 : case UseTreeList::PathType::NO_PATH:
2112 0 : push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
2113 0 : break;
2114 : case UseTreeList::PathType::GLOBAL:
2115 : break;
2116 : }
2117 :
2118 171 : push (Rust::Token::make (LEFT_CURLY, UNDEF_LOCATION));
2119 171 : if (use_tree.has_trees ())
2120 : {
2121 171 : visit_items_joined_by_separator (use_tree.get_trees (), COMMA);
2122 : }
2123 171 : push (Rust::Token::make (RIGHT_CURLY, UNDEF_LOCATION));
2124 171 : });
2125 171 : }
2126 :
2127 : void
2128 1135 : TokenCollector::visit (UseTreeRebind &use_tree)
2129 : {
2130 1135 : describe_node (std::string ("UseTreeRebind"), [this, &use_tree] () {
2131 1135 : auto path = use_tree.get_path ();
2132 1135 : visit (path);
2133 1135 : switch (use_tree.get_new_bind_type ())
2134 : {
2135 2 : case UseTreeRebind::NewBindType::IDENTIFIER:
2136 2 : {
2137 2 : push (Rust::Token::make (AS, UNDEF_LOCATION));
2138 2 : auto id = use_tree.get_identifier ().as_string ();
2139 4 : push (Rust::Token::make_identifier (use_tree.get_locus (),
2140 : std::move (id)));
2141 2 : }
2142 2 : break;
2143 2 : case UseTreeRebind::NewBindType::WILDCARD:
2144 2 : push (Rust::Token::make (AS, UNDEF_LOCATION));
2145 2 : push (Rust::Token::make (UNDERSCORE, use_tree.get_locus ()));
2146 2 : break;
2147 : case UseTreeRebind::NewBindType::NONE:
2148 : break;
2149 : }
2150 1135 : });
2151 1135 : }
2152 :
2153 : void
2154 691 : TokenCollector::visit (UseDeclaration &decl)
2155 : {
2156 691 : describe_node (std::string ("UseDeclaration"), [this, &decl] () {
2157 691 : visit_items_as_lines (decl.get_outer_attrs ());
2158 691 : push (Rust::Token::make (USE, decl.get_locus ()));
2159 691 : visit (*decl.get_tree ());
2160 691 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2161 691 : newline ();
2162 691 : });
2163 691 : }
2164 :
2165 : void
2166 19356 : TokenCollector::visit (Function &function)
2167 : {
2168 : // Syntax:
2169 : // FunctionQualifiers fn IDENTIFIER GenericParams?
2170 : // ( FunctionParameters? )
2171 : // FunctionReturnType? WhereClause?
2172 : // ( BlockExpression | ; )
2173 19356 : describe_node (std::string ("Function"), [this, &function] () {
2174 19356 : visit_items_as_lines (function.get_outer_attrs ());
2175 :
2176 19356 : visit (function.get_visibility ());
2177 19356 : auto qualifiers = function.get_qualifiers ();
2178 19356 : visit (qualifiers);
2179 :
2180 19356 : push (Rust::Token::make (FN_KW, function.get_locus ()));
2181 38712 : auto name = function.get_function_name ().as_string ();
2182 38712 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (name)));
2183 19356 : if (function.has_generics ())
2184 1793 : visit (function.get_generic_params ());
2185 :
2186 19356 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
2187 :
2188 19356 : visit_items_joined_by_separator (function.get_function_params ());
2189 19356 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
2190 :
2191 19356 : if (function.has_return_type ())
2192 : {
2193 14097 : push (Rust::Token::make (RETURN_TYPE, UNDEF_LOCATION));
2194 14097 : visit (function.get_return_type ());
2195 : }
2196 :
2197 19356 : if (function.has_where_clause ())
2198 211 : visit (function.get_where_clause ());
2199 :
2200 19356 : if (function.has_body ())
2201 14944 : visit (*function.get_definition ());
2202 : else
2203 8824 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2204 19356 : newline ();
2205 19356 : });
2206 19356 : }
2207 :
2208 : void
2209 1450 : TokenCollector::visit (TypeAlias &type_alias)
2210 : {
2211 : // Syntax:
2212 : // Visibility? type IDENTIFIER GenericParams? WhereClause? = Type;
2213 :
2214 : // Note: Associated types are handled by `AST::TraitItemType`.
2215 1450 : describe_node (std::string ("TypeAlias"), [this, &type_alias] () {
2216 1450 : visit_items_as_lines (type_alias.get_outer_attrs ());
2217 1450 : if (type_alias.has_visibility ())
2218 16 : visit (type_alias.get_visibility ());
2219 2900 : auto alias_name = type_alias.get_new_type_name ().as_string ();
2220 1450 : push (Rust::Token::make (TYPE, type_alias.get_locus ()));
2221 1450 : push (
2222 2900 : Rust::Token::make_identifier (UNDEF_LOCATION, std::move (alias_name)));
2223 :
2224 1450 : if (type_alias.has_generics ())
2225 22 : visit (type_alias.get_generic_params ());
2226 :
2227 1450 : if (type_alias.has_where_clause ())
2228 0 : visit (type_alias.get_where_clause ());
2229 :
2230 1450 : push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
2231 1450 : visit (type_alias.get_type_aliased ());
2232 2900 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2233 1450 : });
2234 1450 : }
2235 :
2236 : void
2237 1561 : TokenCollector::visit (StructStruct &struct_item)
2238 : {
2239 1561 : describe_node (std::string ("StructStruct"), [this, &struct_item] () {
2240 1561 : visit_items_as_lines (struct_item.get_outer_attrs ());
2241 1561 : if (struct_item.has_visibility ())
2242 372 : visit (struct_item.get_visibility ());
2243 3122 : auto struct_name = struct_item.get_identifier ().as_string ();
2244 1561 : push (Rust::Token::make (STRUCT_KW, struct_item.get_locus ()));
2245 1561 : push (
2246 3122 : Rust::Token::make_identifier (UNDEF_LOCATION, std::move (struct_name)));
2247 :
2248 1561 : if (struct_item.has_generics ())
2249 502 : visit (struct_item.get_generic_params ());
2250 1561 : if (struct_item.has_where_clause ())
2251 3 : visit (struct_item.get_where_clause ());
2252 1561 : if (struct_item.is_unit_struct ())
2253 : {
2254 548 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2255 548 : newline ();
2256 : }
2257 : else
2258 2026 : visit_items_as_block (struct_item.get_fields (),
2259 : {Rust::Token::make (COMMA, UNDEF_LOCATION)});
2260 1561 : });
2261 1561 : }
2262 :
2263 : void
2264 967 : TokenCollector::visit (TupleStruct &tuple_struct)
2265 : {
2266 967 : describe_node (std::string ("TupleStruct"), [this, &tuple_struct] () {
2267 967 : visit_items_as_lines (tuple_struct.get_outer_attrs ());
2268 1934 : auto struct_name = tuple_struct.get_identifier ().as_string ();
2269 967 : push (Rust::Token::make (STRUCT_KW, tuple_struct.get_locus ()));
2270 967 : push (
2271 1934 : Rust::Token::make_identifier (UNDEF_LOCATION, std::move (struct_name)));
2272 967 : if (tuple_struct.has_generics ())
2273 292 : visit (tuple_struct.get_generic_params ());
2274 967 : if (tuple_struct.has_where_clause ())
2275 0 : visit (tuple_struct.get_where_clause ());
2276 :
2277 967 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
2278 967 : visit_items_joined_by_separator (tuple_struct.get_fields (), COMMA);
2279 967 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
2280 967 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2281 967 : newline ();
2282 967 : });
2283 967 : }
2284 :
2285 : void
2286 436 : TokenCollector::visit (EnumItem &item)
2287 : {
2288 436 : describe_node (std::string ("EnumItem"), [this, &item] () {
2289 436 : visit_items_as_lines (item.get_outer_attrs ());
2290 872 : auto id = item.get_identifier ().as_string ();
2291 872 : push (Rust::Token::make_identifier (item.get_locus (), std::move (id)));
2292 436 : });
2293 436 : }
2294 :
2295 : void
2296 413 : TokenCollector::visit (EnumItemTuple &item)
2297 : {
2298 413 : describe_node (std::string ("EnumItemTuple"), [this, &item] () {
2299 826 : auto id = item.get_identifier ().as_string ();
2300 826 : push (Rust::Token::make_identifier (item.get_locus (), std::move (id)));
2301 413 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
2302 413 : visit_items_joined_by_separator (item.get_tuple_fields (), COMMA);
2303 826 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
2304 413 : });
2305 413 : }
2306 :
2307 : void
2308 79 : TokenCollector::visit (EnumItemStruct &item)
2309 : {
2310 79 : describe_node (std::string ("EnumItemStruct"), [this, &item] () {
2311 158 : auto id = item.get_identifier ().as_string ();
2312 158 : push (Rust::Token::make_identifier (item.get_locus (), std::move (id)));
2313 158 : visit_items_as_block (item.get_struct_fields (),
2314 : {Rust::Token::make (COMMA, UNDEF_LOCATION)});
2315 79 : });
2316 79 : }
2317 :
2318 : void
2319 279 : TokenCollector::visit (EnumItemDiscriminant &item)
2320 : {
2321 279 : describe_node (std::string ("EnumItemDiscriminant"), [this, &item] () {
2322 558 : auto id = item.get_identifier ().as_string ();
2323 558 : push (Rust::Token::make_identifier (item.get_locus (), std::move (id)));
2324 279 : push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
2325 279 : visit (item.get_expr ());
2326 279 : });
2327 279 : }
2328 :
2329 : void
2330 516 : TokenCollector::visit (Enum &enumeration)
2331 : {
2332 516 : describe_node (std::string ("Enum"), [this, &enumeration] () {
2333 516 : visit_items_as_lines (enumeration.get_outer_attrs ());
2334 516 : if (enumeration.has_visibility ())
2335 276 : visit (enumeration.get_visibility ());
2336 1032 : push (Rust::Token::make (ENUM_KW, enumeration.get_locus ()));
2337 1032 : auto id = enumeration.get_identifier ().as_string ();
2338 516 : push (
2339 1032 : Rust::Token::make_identifier (enumeration.get_locus (), std::move (id)));
2340 516 : if (enumeration.has_generics ())
2341 241 : visit (enumeration.get_generic_params ());
2342 516 : if (enumeration.has_where_clause ())
2343 0 : visit (enumeration.get_where_clause ());
2344 :
2345 1032 : visit_items_as_block (enumeration.get_variants (),
2346 : {Rust::Token::make (COMMA, UNDEF_LOCATION)});
2347 516 : });
2348 516 : }
2349 :
2350 : void
2351 101 : TokenCollector::visit (Union &union_item)
2352 : {
2353 101 : describe_node (std::string ("Union"), [this, &union_item] () {
2354 101 : visit_items_as_lines (union_item.get_outer_attrs ());
2355 202 : auto id = union_item.get_identifier ().as_string ();
2356 202 : push (Rust::Token::make_identifier (union_item.get_locus (),
2357 101 : Values::WeakKeywords::UNION));
2358 202 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2359 :
2360 101 : if (union_item.has_generics ())
2361 74 : visit (union_item.get_generic_params ());
2362 :
2363 101 : if (union_item.has_where_clause ())
2364 0 : visit (union_item.get_where_clause ());
2365 :
2366 202 : visit_items_as_block (union_item.get_variants (),
2367 : {Rust::Token::make (COMMA, UNDEF_LOCATION)});
2368 101 : });
2369 101 : }
2370 :
2371 : void
2372 550 : TokenCollector::visit (ConstantItem &item)
2373 : {
2374 550 : describe_node (std::string ("ConstantItem"), [this, &item] () {
2375 550 : visit_items_as_lines (item.get_outer_attrs ());
2376 550 : push (Rust::Token::make (CONST, item.get_locus ()));
2377 550 : if (item.is_unnamed ())
2378 : {
2379 10 : push (Rust::Token::make (UNDERSCORE, UNDEF_LOCATION));
2380 : }
2381 : else
2382 : {
2383 1090 : push (Rust::Token::make_identifier (item.get_identifier ()));
2384 : }
2385 550 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
2386 550 : visit (item.get_type ());
2387 550 : if (item.has_expr ())
2388 : {
2389 526 : push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
2390 526 : visit (item.get_expr ());
2391 : }
2392 550 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2393 550 : });
2394 550 : }
2395 :
2396 : void
2397 52 : TokenCollector::visit (StaticItem &item)
2398 : {
2399 52 : describe_node (std::string ("StaticItem"), [this, &item] () {
2400 52 : visit_items_as_lines (item.get_outer_attrs ());
2401 52 : push (Rust::Token::make (STATIC_KW, item.get_locus ()));
2402 52 : if (item.is_mutable ())
2403 6 : push (Rust::Token::make (MUT, UNDEF_LOCATION));
2404 :
2405 104 : auto id = item.get_identifier ().as_string ();
2406 104 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2407 52 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
2408 :
2409 52 : visit (item.get_type ());
2410 :
2411 52 : if (item.has_expr ())
2412 : {
2413 52 : push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
2414 52 : visit (item.get_expr ());
2415 : }
2416 104 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2417 52 : });
2418 52 : }
2419 :
2420 : void
2421 0 : TokenCollector::visit_function_common (std::unique_ptr<Type> &return_type,
2422 : std::unique_ptr<BlockExpr> &block)
2423 : {
2424 : // FIXME: This should format the `<vis> fn <name> ( [args] )` as well
2425 0 : if (return_type)
2426 : {
2427 0 : push (Rust::Token::make (RETURN_TYPE, UNDEF_LOCATION));
2428 0 : visit (return_type);
2429 : }
2430 :
2431 0 : if (block)
2432 : {
2433 0 : visit (block);
2434 : }
2435 : else
2436 : {
2437 0 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2438 0 : newline ();
2439 : }
2440 0 : }
2441 :
2442 : void
2443 8720 : TokenCollector::visit (SelfParam ¶m)
2444 : {
2445 8720 : describe_node (std::string ("SelfParam"), [this, ¶m] () {
2446 8720 : if (param.get_has_ref ())
2447 : {
2448 5167 : push (Rust::Token::make (AMP, UNDEF_LOCATION));
2449 5167 : if (param.has_lifetime ())
2450 : {
2451 4908 : auto lifetime = param.get_lifetime ();
2452 4908 : visit (lifetime);
2453 4908 : }
2454 5167 : if (param.get_is_mut ())
2455 888 : push (Rust::Token::make (MUT, UNDEF_LOCATION));
2456 : }
2457 8720 : push (Rust::Token::make (SELF, UNDEF_LOCATION));
2458 8720 : if (param.has_type ())
2459 : {
2460 3 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
2461 3 : visit (param.get_type ());
2462 : }
2463 8720 : });
2464 8720 : }
2465 :
2466 : void
2467 779 : TokenCollector::visit (TraitItemType &item)
2468 : {
2469 779 : describe_node (std::string ("TraitItemType"), [this, &item] () {
2470 779 : visit_items_as_lines (item.get_outer_attrs ());
2471 1558 : auto id = item.get_identifier ().as_string ();
2472 779 : indentation ();
2473 :
2474 779 : push (Rust::Token::make (TYPE, item.get_locus ()));
2475 1558 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2476 779 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2477 779 : newline ();
2478 779 : });
2479 779 : }
2480 :
2481 : void
2482 3926 : TokenCollector::visit (Trait &trait)
2483 : {
2484 3926 : describe_node (std::string ("Trait"), [this, &trait] () {
2485 7841 : for (auto &attr : trait.get_outer_attrs ())
2486 : {
2487 3915 : visit (attr);
2488 3915 : newline ();
2489 3915 : indentation ();
2490 : }
2491 :
2492 3926 : visit (trait.get_visibility ());
2493 :
2494 7852 : auto id = trait.get_identifier ().as_string ();
2495 3926 : push (Rust::Token::make (TRAIT, trait.get_locus ()));
2496 7852 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2497 :
2498 3926 : if (trait.has_generics ())
2499 667 : visit (trait.get_generic_params ());
2500 3926 : if (!trait.get_type_param_bounds ().empty ())
2501 1078 : push (Rust::Token::make ((COLON), trait.get_locus ()));
2502 3926 : visit_items_joined_by_separator (trait.get_type_param_bounds (), PLUS);
2503 :
2504 3926 : visit_items_as_block (trait.get_trait_items (), {});
2505 3926 : });
2506 3926 : }
2507 :
2508 : void
2509 1002 : TokenCollector::visit (InherentImpl &impl)
2510 : {
2511 1002 : describe_node (std::string ("InherentImpl"), [this, &impl] () {
2512 1002 : visit_items_as_lines (impl.get_outer_attrs ());
2513 1002 : push (Rust::Token::make (IMPL, impl.get_locus ()));
2514 1002 : visit (impl.get_generic_params ());
2515 :
2516 1002 : visit (impl.get_type ());
2517 :
2518 1002 : if (impl.has_where_clause ())
2519 0 : visit (impl.get_where_clause ());
2520 :
2521 : // FIXME: Handle inner attributes
2522 :
2523 1002 : visit_items_as_block (impl.get_impl_items (), {});
2524 1002 : });
2525 1002 : }
2526 :
2527 : void
2528 5028 : TokenCollector::visit (TraitImpl &impl)
2529 : {
2530 5028 : describe_node (std::string ("TraitImpl"), [this, &impl] () {
2531 5028 : visit_items_as_lines (impl.get_outer_attrs ());
2532 5028 : push (Rust::Token::make (IMPL, impl.get_locus ()));
2533 5028 : visit (impl.get_generic_params ());
2534 5028 : if (impl.is_exclam ())
2535 12 : push (Rust::Token::make (EXCLAM, UNDEF_LOCATION));
2536 5028 : visit (impl.get_trait_path ());
2537 5028 : push (Rust::Token::make (FOR, UNDEF_LOCATION));
2538 5028 : visit (impl.get_type ());
2539 :
2540 5028 : if (impl.has_where_clause ())
2541 98 : visit (impl.get_where_clause ());
2542 5028 : });
2543 5028 : visit_items_as_block (impl.get_impl_items ());
2544 5028 : }
2545 :
2546 : void
2547 2 : TokenCollector::visit (ExternalTypeItem &type)
2548 : {
2549 2 : describe_node (std::string ("ExternalTypeItem"), [this, &type] () {
2550 2 : visit (type.get_visibility ());
2551 :
2552 4 : auto id = type.get_identifier ().as_string ();
2553 :
2554 2 : push (Rust::Token::make (TYPE, UNDEF_LOCATION));
2555 4 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2556 4 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2557 2 : });
2558 2 : }
2559 :
2560 : void
2561 0 : TokenCollector::visit (ExternalStaticItem &item)
2562 : {
2563 0 : describe_node (std::string ("ExternalStaticItem"), [this, &item] () {
2564 0 : auto id = item.get_identifier ().as_string ();
2565 0 : visit_items_as_lines (item.get_outer_attrs ());
2566 0 : if (item.has_visibility ())
2567 0 : visit (item.get_visibility ());
2568 0 : push (Rust::Token::make (STATIC_KW, item.get_locus ()));
2569 0 : if (item.is_mut ())
2570 0 : push (Rust::Token::make (MUT, UNDEF_LOCATION));
2571 0 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2572 0 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
2573 0 : visit (item.get_type ());
2574 : // TODO: No expr ? The "(= Expression)?" part from the reference seems
2575 : // missing in the ast.
2576 0 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2577 0 : });
2578 0 : }
2579 :
2580 : void
2581 1667 : TokenCollector::visit (ExternBlock &block)
2582 : {
2583 1667 : describe_node (std::string ("ExternBlock"), [this, &block] () {
2584 1667 : visit_items_as_lines (block.get_outer_attrs ());
2585 1667 : push (Rust::Token::make (EXTERN_KW, block.get_locus ()));
2586 :
2587 1667 : if (block.has_abi ())
2588 : {
2589 1666 : auto abi = block.get_abi ();
2590 3332 : push (Rust::Token::make_string (UNDEF_LOCATION, std::move (abi)));
2591 1666 : }
2592 :
2593 1667 : visit_items_as_block (block.get_extern_items (), {});
2594 1667 : });
2595 1667 : }
2596 :
2597 : static std::pair<TokenId, TokenId>
2598 1175 : get_delimiters (DelimType delim)
2599 : {
2600 1175 : switch (delim)
2601 : {
2602 1118 : case PARENS:
2603 1118 : return {LEFT_PAREN, RIGHT_PAREN};
2604 43 : case SQUARE:
2605 43 : return {LEFT_SQUARE, RIGHT_SQUARE};
2606 14 : case CURLY:
2607 14 : return {LEFT_CURLY, RIGHT_CURLY};
2608 0 : default:
2609 0 : rust_unreachable ();
2610 : }
2611 : }
2612 :
2613 : void
2614 974 : TokenCollector::visit (MacroMatchFragment &match)
2615 : {
2616 974 : describe_node (std::string ("MacroMatchFragment"), [this, &match] () {
2617 1948 : auto id = match.get_ident ().as_string ();
2618 974 : auto frag_spec = match.get_frag_spec ().as_string ();
2619 974 : push (Rust::Token::make (DOLLAR_SIGN, UNDEF_LOCATION));
2620 1948 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2621 974 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
2622 1948 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (frag_spec)));
2623 974 : });
2624 974 : }
2625 :
2626 : void
2627 542 : TokenCollector::visit (MacroMatchRepetition &repetition)
2628 : {
2629 542 : describe_node (std::string ("MacroMatchRepetition"), [this, &repetition] () {
2630 542 : push (Rust::Token::make (DOLLAR_SIGN, UNDEF_LOCATION));
2631 542 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
2632 :
2633 1196 : for (auto &match : repetition.get_matches ())
2634 : {
2635 654 : visit (match);
2636 : }
2637 :
2638 542 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
2639 :
2640 542 : if (repetition.has_sep ())
2641 : {
2642 262 : push (Rust::Token::make (repetition.get_sep ()->get_id (),
2643 131 : repetition.get_sep ()->get_locus ()));
2644 : }
2645 542 : switch (repetition.get_op ())
2646 : {
2647 476 : case MacroMatchRepetition::ANY:
2648 476 : push (Rust::Token::make (ASTERISK, UNDEF_LOCATION));
2649 476 : break;
2650 33 : case MacroMatchRepetition::ONE_OR_MORE:
2651 33 : push (Rust::Token::make (PLUS, UNDEF_LOCATION));
2652 33 : break;
2653 33 : case MacroMatchRepetition::ZERO_OR_ONE:
2654 33 : push (Rust::Token::make (QUESTION_MARK, UNDEF_LOCATION));
2655 33 : break;
2656 : case MacroMatchRepetition::NONE:
2657 : break;
2658 : }
2659 542 : });
2660 542 : }
2661 :
2662 : void
2663 1175 : TokenCollector::visit (MacroMatcher &matcher)
2664 : {
2665 1175 : describe_node (std::string ("MacroMatcher"), [this, &matcher] () {
2666 1175 : auto delimiters = get_delimiters (matcher.get_delim_type ());
2667 :
2668 1175 : push (Rust::Token::make (delimiters.first, UNDEF_LOCATION));
2669 :
2670 2583 : for (auto &item : matcher.get_matches ())
2671 : {
2672 1408 : visit (item);
2673 : }
2674 :
2675 1175 : push (Rust::Token::make (delimiters.second, UNDEF_LOCATION));
2676 1175 : });
2677 1175 : }
2678 :
2679 : void
2680 1108 : TokenCollector::visit (MacroRule &rule)
2681 : {
2682 1108 : describe_node (std::string ("MacroRule"), [this, &rule] () {
2683 1108 : visit (rule.get_matcher ());
2684 1108 : push (Rust::Token::make (MATCH_ARROW, rule.get_locus ()));
2685 1108 : visit (rule.get_transcriber ().get_token_tree ());
2686 1108 : });
2687 1108 : }
2688 :
2689 : void
2690 970 : TokenCollector::visit (MacroRulesDefinition &rules_def)
2691 : {
2692 970 : describe_node (std::string ("MacroRulesDefinition"), [this, &rules_def] () {
2693 1113 : for (auto &outer_attr : rules_def.get_outer_attrs ())
2694 143 : visit (outer_attr);
2695 :
2696 1940 : auto rule_name = rules_def.get_rule_name ().as_string ();
2697 :
2698 1940 : push (Rust::Token::make_identifier (rules_def.get_locus (),
2699 970 : Values::WeakKeywords::MACRO_RULES));
2700 970 : push (Rust::Token::make (EXCLAM, UNDEF_LOCATION));
2701 :
2702 1940 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (rule_name)));
2703 :
2704 1940 : visit_items_as_block (rules_def.get_rules (),
2705 : {Rust::Token::make (SEMICOLON, UNDEF_LOCATION)});
2706 970 : });
2707 970 : }
2708 :
2709 : void
2710 175 : TokenCollector::visit (MacroInvocation &invocation)
2711 : {
2712 175 : describe_node (std::string ("MacroInvocation"), [this, &invocation] () {
2713 175 : auto data = invocation.get_invoc_data ();
2714 175 : visit (data.get_path ());
2715 175 : push (Rust::Token::make (EXCLAM, UNDEF_LOCATION));
2716 175 : visit (data.get_delim_tok_tree ());
2717 175 : if (invocation.has_semicolon ())
2718 348 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2719 175 : });
2720 175 : }
2721 :
2722 : void
2723 0 : TokenCollector::visit (MetaItemPath &item)
2724 : {
2725 0 : describe_node (std::string ("MetaItemPath"), [this, &item] () {
2726 0 : auto path = item.to_path_item ();
2727 0 : visit (path);
2728 0 : });
2729 0 : }
2730 :
2731 : void
2732 14 : TokenCollector::visit (MetaItemSeq &item)
2733 : {
2734 14 : describe_node (std::string ("MetaItemSeq"), [this, &item] () {
2735 14 : visit (item.get_path ());
2736 : // TODO: Double check this, there is probably a mistake.
2737 14 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
2738 14 : visit_items_joined_by_separator (item.get_seq (), COMMA);
2739 14 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
2740 14 : });
2741 14 : }
2742 :
2743 : void
2744 42 : TokenCollector::visit (MetaWord &word)
2745 : {
2746 42 : describe_node (std::string ("MetaWord"), [this, &word] () {
2747 42 : auto id = word.get_ident ().as_string ();
2748 :
2749 84 : push (Rust::Token::make_identifier (word.get_locus (), std::move (id)));
2750 42 : });
2751 42 : }
2752 :
2753 : void
2754 388 : TokenCollector::visit (MetaNameValueStr &name)
2755 : {
2756 388 : describe_node (std::string ("MetaNameValueStr"), [this, &name] () {
2757 388 : auto pair = name.get_name_value_pair ();
2758 388 : auto id = std::get<0> (pair).as_string ();
2759 388 : auto value = std::get<1> (pair);
2760 :
2761 776 : push (Rust::Token::make_identifier (name.get_locus (), std::move (id)));
2762 388 : push (Rust::Token::make (EQUAL, name.get_locus ()));
2763 388 : push (Rust::Token::make (DOUBLE_QUOTE, UNDEF_LOCATION));
2764 776 : push (Rust::Token::make_identifier (name.get_locus (), std::move (value)));
2765 776 : push (Rust::Token::make (DOUBLE_QUOTE, UNDEF_LOCATION));
2766 388 : });
2767 388 : }
2768 :
2769 : void
2770 0 : TokenCollector::visit (MetaListPaths &list)
2771 : {
2772 0 : describe_node (std::string ("MetaListPath"), [this, &list] () {
2773 0 : auto id = list.get_ident ().as_string ();
2774 :
2775 0 : push (Rust::Token::make_identifier (list.get_locus (), std::move (id)));
2776 0 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
2777 :
2778 0 : visit_items_joined_by_separator (list.get_paths (), COMMA);
2779 :
2780 0 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
2781 0 : });
2782 0 : }
2783 :
2784 : void
2785 0 : TokenCollector::visit (MetaListNameValueStr &list)
2786 : {
2787 0 : describe_node (std::string ("MetaListNameValueStr"), [this, &list] () {
2788 0 : auto id = list.get_ident ().as_string ();
2789 :
2790 0 : push (Rust::Token::make_identifier (list.get_locus (), std::move (id)));
2791 0 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
2792 :
2793 0 : visit_items_joined_by_separator (list.get_values (), COMMA);
2794 :
2795 0 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
2796 0 : });
2797 0 : }
2798 :
2799 : // rust-pattern.h
2800 : void
2801 419 : TokenCollector::visit (LiteralPattern &pattern)
2802 : {
2803 419 : describe_node (std::string ("LiteralPattern"), [this, &pattern] () {
2804 419 : visit (pattern.get_literal (), pattern.get_locus ());
2805 419 : });
2806 419 : }
2807 :
2808 : void
2809 25561 : TokenCollector::visit (IdentifierPattern &pattern)
2810 : {
2811 25561 : describe_node (std::string ("IdentifierPattern"), [this, &pattern] () {
2812 25561 : if (pattern.get_is_ref ())
2813 : {
2814 4 : push (Rust::Token::make (REF, pattern.get_locus ()));
2815 : }
2816 25561 : if (pattern.get_is_mut ())
2817 : {
2818 2028 : push (Rust::Token::make (MUT, UNDEF_LOCATION));
2819 : }
2820 :
2821 51122 : auto id = pattern.get_ident ().as_string ();
2822 51122 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2823 :
2824 25561 : if (pattern.has_subpattern ())
2825 : {
2826 27 : push (Rust::Token::make (PATTERN_BIND, UNDEF_LOCATION));
2827 27 : visit (pattern.get_subpattern ());
2828 : }
2829 25561 : });
2830 25561 : }
2831 :
2832 : void
2833 1128 : TokenCollector::visit (WildcardPattern &pattern)
2834 : {
2835 1128 : describe_node (std::string ("WildcardPattern"), [this, &pattern] () {
2836 1128 : push (Rust::Token::make (UNDERSCORE, pattern.get_locus ()));
2837 1128 : });
2838 1128 : }
2839 :
2840 : void
2841 44 : TokenCollector::visit (RestPattern &pattern)
2842 : {
2843 44 : describe_node (std::string ("RestPattern"), [this, &pattern] () {
2844 44 : push (Rust::Token::make (DOT_DOT, pattern.get_locus ()));
2845 44 : });
2846 44 : }
2847 :
2848 : // void TokenCollector::visit(RangePatternBound& ){}
2849 :
2850 : void
2851 61 : TokenCollector::visit (RangePatternBoundLiteral &pattern)
2852 : {
2853 61 : describe_node (std::string ("RangePatternBoundLiteral"), [this, &pattern] () {
2854 61 : if (pattern.get_has_minus ())
2855 : {
2856 48 : push (Rust::Token::make (MINUS, pattern.get_locus ()));
2857 : }
2858 61 : auto literal = pattern.get_literal ();
2859 61 : visit (literal);
2860 61 : });
2861 61 : }
2862 :
2863 : void
2864 21 : TokenCollector::visit (RangePatternBoundPath &pattern)
2865 : {
2866 21 : describe_node (std::string ("RangePatternBoundPath"),
2867 42 : [this, &pattern] () { visit (pattern.get_path ()); });
2868 21 : }
2869 :
2870 : void
2871 0 : TokenCollector::visit (RangePatternBoundQualPath &pattern)
2872 : {
2873 0 : describe_node (std::string ("RangePatternBoundQualPath"),
2874 0 : [this, &pattern] () {
2875 0 : visit (pattern.get_qualified_path ());
2876 : });
2877 0 : }
2878 :
2879 : void
2880 41 : TokenCollector::visit (RangePattern &pattern)
2881 : {
2882 41 : describe_node (std::string ("RangePattern"), [this, &pattern] () {
2883 41 : if (pattern.get_has_lower_bound () && pattern.get_has_upper_bound ())
2884 : {
2885 41 : visit (pattern.get_lower_bound ());
2886 41 : if (pattern.get_has_ellipsis_syntax ())
2887 0 : push (Rust::Token::make (ELLIPSIS, pattern.get_locus ()));
2888 : else
2889 82 : push (Rust::Token::make (DOT_DOT_EQ, pattern.get_locus ()));
2890 41 : visit (pattern.get_upper_bound ());
2891 : }
2892 0 : else if (pattern.get_has_lower_bound ())
2893 : {
2894 0 : visit (pattern.get_lower_bound ());
2895 0 : push (Rust::Token::make (DOT_DOT, pattern.get_locus ()));
2896 : }
2897 : else
2898 : {
2899 0 : push (Rust::Token::make (DOT_DOT_EQ, pattern.get_locus ()));
2900 0 : visit (pattern.get_upper_bound ());
2901 : }
2902 41 : });
2903 41 : }
2904 :
2905 : void
2906 198 : TokenCollector::visit (ReferencePattern &pattern)
2907 :
2908 : {
2909 198 : describe_node (std::string ("ReferencePattern"), [this, &pattern] () {
2910 198 : if (pattern.is_double_reference ())
2911 : {
2912 20 : push (Rust::Token::make (LOGICAL_AND, pattern.get_locus ()));
2913 : }
2914 : else
2915 : {
2916 376 : push (Rust::Token::make (AMP, pattern.get_locus ()));
2917 : }
2918 :
2919 198 : if (pattern.get_is_mut ())
2920 : {
2921 0 : push (Rust::Token::make (MUT, UNDEF_LOCATION));
2922 : }
2923 :
2924 198 : visit (pattern.get_referenced_pattern ());
2925 198 : });
2926 198 : }
2927 :
2928 : // void TokenCollector::visit(StructPatternField& ){}
2929 :
2930 : void
2931 26 : TokenCollector::visit (StructPatternFieldTuplePat &pattern)
2932 : {
2933 26 : describe_node (std::string ("StructPatternFieldTuplePat"), [this,
2934 : &pattern] () {
2935 26 : visit_items_as_lines (pattern.get_outer_attrs ());
2936 26 : auto str = std::to_string (pattern.get_index ());
2937 26 : auto suffix_start = str.length ();
2938 52 : push (Rust::Token::make_int (pattern.get_locus (), str, suffix_start,
2939 : IntegerLiteralBase::Decimal));
2940 26 : push (Rust::Token::make (COLON, pattern.get_locus ()));
2941 26 : visit (pattern.get_index_pattern ());
2942 26 : });
2943 26 : }
2944 :
2945 : void
2946 148 : TokenCollector::visit (StructPatternFieldIdentPat &pattern)
2947 : {
2948 148 : describe_node (std::string ("StructPatternFieldIdentPat"), [this,
2949 : &pattern] () {
2950 148 : visit_items_as_lines (pattern.get_outer_attrs ());
2951 :
2952 148 : auto id = pattern.get_identifier ().as_string ();
2953 296 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2954 :
2955 148 : push (Rust::Token::make (COLON, pattern.get_locus ()));
2956 :
2957 148 : visit (pattern.get_ident_pattern ());
2958 148 : });
2959 148 : }
2960 :
2961 : void
2962 99 : TokenCollector::visit (StructPatternFieldIdent &pattern)
2963 : {
2964 99 : describe_node (std::string ("StructPatternFieldIdent"), [this, &pattern] () {
2965 99 : visit_items_as_lines (pattern.get_outer_attrs ());
2966 99 : if (pattern.is_ref ())
2967 0 : push (Rust::Token::make (REF, UNDEF_LOCATION));
2968 99 : if (pattern.is_mut ())
2969 4 : push (Rust::Token::make (MUT, UNDEF_LOCATION));
2970 :
2971 99 : auto id = pattern.get_identifier ().as_string ();
2972 198 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2973 99 : });
2974 99 : }
2975 :
2976 : void
2977 173 : TokenCollector::visit (StructPattern &pattern)
2978 : {
2979 173 : describe_node (std::string ("StructPattern"), [this, &pattern] () {
2980 173 : visit (pattern.get_path ());
2981 173 : push (Rust::Token::make (LEFT_CURLY, pattern.get_locus ()));
2982 173 : auto elems = pattern.get_struct_pattern_elems ();
2983 173 : if (elems.has_struct_pattern_fields ())
2984 : {
2985 172 : visit_items_joined_by_separator (elems.get_struct_pattern_fields ());
2986 172 : if (elems.has_rest ())
2987 : {
2988 13 : push (Rust::Token::make (COMMA, UNDEF_LOCATION));
2989 13 : visit_items_as_lines (elems.get_etc_outer_attrs ());
2990 : }
2991 : }
2992 : else
2993 : {
2994 1 : visit_items_as_lines (elems.get_etc_outer_attrs ());
2995 : }
2996 :
2997 346 : push (Rust::Token::make (RIGHT_CURLY, UNDEF_LOCATION));
2998 173 : });
2999 173 : }
3000 :
3001 : // void TokenCollector::visit(TupleStructItems& ){}
3002 :
3003 : void
3004 964 : TokenCollector::visit (TupleStructItemsNoRest &pattern)
3005 : {
3006 964 : describe_node (std::string ("TupleStructItemsNoRange"), [this, &pattern] () {
3007 964 : visit_items_joined_by_separator (pattern.get_patterns ());
3008 964 : });
3009 964 : }
3010 :
3011 : void
3012 36 : TokenCollector::visit (TupleStructItemsHasRest &pattern)
3013 : {
3014 36 : describe_node (std::string ("TupleStructItemsRange"), [this, &pattern] () {
3015 65 : for (auto &lower : pattern.get_lower_patterns ())
3016 : {
3017 29 : visit (lower);
3018 : }
3019 36 : push (Rust::Token::make (DOT_DOT, UNDEF_LOCATION));
3020 65 : for (auto &upper : pattern.get_lower_patterns ())
3021 : {
3022 29 : visit (upper);
3023 : }
3024 36 : });
3025 36 : }
3026 :
3027 : void
3028 1000 : TokenCollector::visit (TupleStructPattern &pattern)
3029 : {
3030 1000 : describe_node (std::string ("TupleStructPattern"), [this, &pattern] () {
3031 1000 : visit (pattern.get_path ());
3032 1000 : push (Rust::Token::make (LEFT_PAREN, pattern.get_locus ()));
3033 1000 : visit (pattern.get_items ());
3034 1000 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
3035 1000 : });
3036 1000 : }
3037 :
3038 : // void
3039 : // TokenCollector::visit (TuplePatternItems &)
3040 : // {}
3041 :
3042 : void
3043 490 : TokenCollector::visit (TuplePatternItemsNoRest &pattern)
3044 : {
3045 490 : describe_node (std::string ("TuplePatternItemsMultiple"), [this,
3046 : &pattern] () {
3047 490 : visit_items_joined_by_separator (pattern.get_patterns (), COMMA);
3048 490 : });
3049 490 : }
3050 :
3051 : void
3052 31 : TokenCollector::visit (TuplePatternItemsHasRest &pattern)
3053 : {
3054 31 : describe_node (std::string ("TuplePatternItemsRanged"), [this, &pattern] () {
3055 58 : for (auto &lower : pattern.get_lower_patterns ())
3056 : {
3057 27 : visit (lower);
3058 : }
3059 31 : push (Rust::Token::make (DOT_DOT, UNDEF_LOCATION));
3060 58 : for (auto &upper : pattern.get_lower_patterns ())
3061 : {
3062 27 : visit (upper);
3063 : }
3064 31 : });
3065 31 : }
3066 :
3067 : void
3068 521 : TokenCollector::visit (TuplePattern &pattern)
3069 : {
3070 521 : describe_node (std::string ("TuplePattern"), [this, &pattern] () {
3071 521 : push (Rust::Token::make (LEFT_PAREN, pattern.get_locus ()));
3072 521 : visit (pattern.get_items ());
3073 521 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
3074 521 : });
3075 521 : }
3076 :
3077 : void
3078 1 : TokenCollector::visit (GroupedPattern &pattern)
3079 : {
3080 1 : describe_node (std::string ("GroupedPattern"), [this, &pattern] () {
3081 1 : push (Rust::Token::make (LEFT_PAREN, pattern.get_locus ()));
3082 1 : visit (pattern.get_pattern_in_parens ());
3083 1 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
3084 1 : });
3085 1 : }
3086 :
3087 : void
3088 75 : TokenCollector::visit (SlicePattern &pattern)
3089 : {
3090 75 : describe_node (std::string ("SlicePattern"), [this, &pattern] () {
3091 75 : push (Rust::Token::make (LEFT_SQUARE, pattern.get_locus ()));
3092 75 : visit_items_joined_by_separator (pattern.get_patterns (), COMMA);
3093 75 : push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION));
3094 75 : });
3095 75 : }
3096 :
3097 : void
3098 145 : TokenCollector::visit (AltPattern &pattern)
3099 : {
3100 145 : describe_node (std::string ("AltPattern"), [this, &pattern] () {
3101 145 : visit_items_joined_by_separator (pattern.get_alts (), PIPE);
3102 145 : });
3103 145 : }
3104 :
3105 : // rust-stmt.h
3106 : void
3107 45 : TokenCollector::visit (EmptyStmt &)
3108 45 : {}
3109 :
3110 : void
3111 13065 : TokenCollector::visit (LetStmt &stmt)
3112 : {
3113 13065 : describe_node (std::string ("LetStmt"), [this, &stmt] () {
3114 13065 : push (Rust::Token::make (LET, stmt.get_locus ()));
3115 13065 : auto &pattern = stmt.get_pattern ();
3116 13065 : visit (pattern);
3117 :
3118 13065 : if (stmt.has_type ())
3119 : {
3120 2159 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
3121 2159 : visit (stmt.get_type ());
3122 : }
3123 :
3124 13065 : if (stmt.has_type ())
3125 : {
3126 2159 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
3127 2159 : visit (stmt.get_type ());
3128 : }
3129 :
3130 13065 : if (stmt.has_init_expr ())
3131 : {
3132 11934 : push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
3133 11934 : visit (stmt.get_init_expr ());
3134 : }
3135 :
3136 13065 : if (stmt.has_else_expr ())
3137 : {
3138 5 : push (Rust::Token::make (ELSE, UNDEF_LOCATION));
3139 5 : visit (stmt.get_else_expr ());
3140 : }
3141 :
3142 13065 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
3143 13065 : });
3144 13065 : }
3145 :
3146 : void
3147 11305 : TokenCollector::visit (ExprStmt &stmt)
3148 : {
3149 11305 : describe_node (std::string ("ExprStmt"), [this, &stmt] () {
3150 11305 : visit (stmt.get_expr ());
3151 :
3152 11305 : if (stmt.is_semicolon_followed ())
3153 18022 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
3154 11305 : });
3155 11305 : }
3156 :
3157 : // rust-type.h
3158 : void
3159 2239 : TokenCollector::visit (TraitBound &bound)
3160 : {
3161 : // Syntax:
3162 : // ?? ForLifetimes? TypePath
3163 : // | ( ?? ForLifetimes? TypePath )
3164 2239 : describe_node (std::string ("TraitBound"), [this, &bound] () {
3165 2239 : if (bound.has_opening_question_mark ())
3166 858 : push (Rust::Token::make (QUESTION_MARK, bound.get_locus ()));
3167 :
3168 2239 : if (bound.has_for_lifetimes ())
3169 7 : visit (bound.get_for_lifetimes ());
3170 :
3171 2239 : visit (bound.get_type_path ());
3172 2239 : });
3173 2239 : }
3174 :
3175 : void
3176 8 : TokenCollector::visit (ImplTraitType &type)
3177 : {
3178 : // Syntax:
3179 : // impl TypeParamBounds
3180 : // TypeParamBounds :
3181 : // TypeParamBound ( + TypeParamBound )* +?
3182 8 : describe_node (std::string ("ImplTraitType"), [this, &type] () {
3183 8 : push (Rust::Token::make (IMPL, type.get_locus ()));
3184 8 : visit_items_joined_by_separator (type.get_type_param_bounds (), PLUS);
3185 8 : });
3186 8 : }
3187 :
3188 : void
3189 11 : TokenCollector::visit (TraitObjectType &type)
3190 : {
3191 : // Syntax:
3192 : // dyn? TypeParamBounds
3193 : // TypeParamBounds :
3194 : // TypeParamBound ( + TypeParamBound )* +?
3195 11 : describe_node (std::string ("TraiObjectType"), [this, &type] () {
3196 11 : if (type.is_dyn ())
3197 22 : push (Rust::Token::make (DYN, type.get_locus ()));
3198 11 : visit_items_joined_by_separator (type.get_type_param_bounds (), PLUS);
3199 11 : });
3200 11 : }
3201 :
3202 : void
3203 5 : TokenCollector::visit (ParenthesisedType &type)
3204 : {
3205 : // Syntax:
3206 : // ( Type )
3207 5 : describe_node (std::string ("ParenthesisedType"), [this, &type] () {
3208 5 : push (Rust::Token::make (LEFT_PAREN, type.get_locus ()));
3209 5 : visit (type.get_type_in_parens ());
3210 5 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
3211 5 : });
3212 5 : }
3213 :
3214 : void
3215 28 : TokenCollector::visit (ImplTraitTypeOneBound &type)
3216 : {
3217 : // Syntax:
3218 : // impl TraitBound
3219 :
3220 28 : describe_node (std::string ("ImplTraitTypeOneBound"), [this, &type] () {
3221 28 : push (Rust::Token::make (IMPL, type.get_locus ()));
3222 28 : visit (type.get_trait_bound ());
3223 28 : });
3224 28 : }
3225 :
3226 : void
3227 326 : TokenCollector::visit (TraitObjectTypeOneBound &type)
3228 : {
3229 : // Syntax:
3230 : // dyn? TraitBound
3231 326 : describe_node (std::string ("TraitObjectTypeOneBound"), [this, &type] () {
3232 326 : if (type.is_dyn ())
3233 652 : push (Rust::Token::make (DYN, type.get_locus ()));
3234 326 : visit (type.get_trait_bound ());
3235 326 : });
3236 326 : }
3237 :
3238 : void
3239 461 : TokenCollector::visit (TupleType &type)
3240 : {
3241 : // Syntax:
3242 : // ( )
3243 : // | ( ( Type , )+ Type? )
3244 :
3245 461 : describe_node (std::string ("TupleType"), [this, &type] () {
3246 461 : push (Rust::Token::make (LEFT_PAREN, type.get_locus ()));
3247 461 : visit_items_joined_by_separator (type.get_elems (), COMMA);
3248 461 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
3249 461 : });
3250 461 : }
3251 :
3252 : void
3253 192 : TokenCollector::visit (NeverType &type)
3254 : {
3255 : // Syntax:
3256 : // !
3257 :
3258 192 : describe_node (std::string ("NeverType"), [this, &type] () {
3259 192 : push (Rust::Token::make (EXCLAM, type.get_locus ()));
3260 192 : });
3261 192 : }
3262 :
3263 : void
3264 7189 : TokenCollector::visit (RawPointerType &type)
3265 : {
3266 : // Syntax:
3267 : // * ( mut | const ) TypeNoBounds
3268 7189 : describe_node (std::string ("RawPointerType"), [this, &type] () {
3269 7189 : push (Rust::Token::make (ASTERISK, type.get_locus ()));
3270 7189 : if (type.get_pointer_type () == RawPointerType::MUT)
3271 1776 : push (Rust::Token::make (MUT, UNDEF_LOCATION));
3272 : else /* RawPointerType::CONST */
3273 12602 : push (Rust::Token::make (CONST, UNDEF_LOCATION));
3274 :
3275 7189 : visit (type.get_type_pointed_to ());
3276 7189 : });
3277 7189 : }
3278 :
3279 : void
3280 4934 : TokenCollector::visit (ReferenceType &type)
3281 : {
3282 : // Syntax:
3283 : // & Lifetime? mut? TypeNoBounds
3284 4934 : describe_node (std::string ("ReferenceType"), [this, &type] () {
3285 4934 : push (Rust::Token::make (AMP, type.get_locus ()));
3286 :
3287 4934 : if (type.has_lifetime ())
3288 : {
3289 4934 : visit (type.get_lifetime ());
3290 : }
3291 :
3292 4934 : if (type.get_has_mut ())
3293 686 : push (Rust::Token::make (MUT, UNDEF_LOCATION));
3294 :
3295 4934 : visit (type.get_type_referenced ());
3296 4934 : });
3297 4934 : }
3298 :
3299 : void
3300 921 : TokenCollector::visit (ArrayType &type)
3301 : {
3302 : // Syntax:
3303 : // [type Type ; Expression ]
3304 921 : describe_node (std::string ("ArrayType"), [this, &type] () {
3305 921 : push (Rust::Token::make (LEFT_SQUARE, type.get_locus ()));
3306 921 : visit (type.get_elem_type ());
3307 921 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
3308 921 : visit (type.get_size_expr ());
3309 921 : push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION));
3310 921 : });
3311 921 : }
3312 :
3313 : void
3314 931 : TokenCollector::visit (SliceType &type)
3315 : {
3316 : // Syntax:
3317 : // [type Type ]
3318 :
3319 931 : describe_node (std::string ("SliceType"), [this, &type] () {
3320 931 : push (Rust::Token::make (LEFT_SQUARE, type.get_locus ()));
3321 931 : visit (type.get_elem_type ());
3322 931 : push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION));
3323 931 : });
3324 931 : }
3325 :
3326 : void
3327 275 : TokenCollector::visit (InferredType &type)
3328 : {
3329 : // Syntax:
3330 : // _
3331 275 : describe_node (std::string ("InferredType"), [this, &type] () {
3332 275 : push (Rust::Token::make (UNDERSCORE, type.get_locus ()));
3333 275 : });
3334 275 : }
3335 :
3336 : void
3337 81 : TokenCollector::visit (BareFunctionType &type)
3338 : {
3339 : // Syntax:
3340 : // ForLifetimes? FunctionTypeQualifiers fn
3341 : // ( FunctionParametersMaybeNamedVariadic? )
3342 : // BareFunctionReturnType?
3343 : //
3344 : // BareFunctionReturnType:
3345 : // -> TypeNoBounds
3346 : //
3347 : // FunctionParametersMaybeNamedVariadic :
3348 : // MaybeNamedFunctionParameters |
3349 : // MaybeNamedFunctionParametersVariadic
3350 : //
3351 : // MaybeNamedFunctionParameters :
3352 : // MaybeNamedParam ( , MaybeNamedParam )* ,?
3353 : //
3354 : // MaybeNamedFunctionParametersVariadic :
3355 : // ( MaybeNamedParam , )* MaybeNamedParam , OuterAttribute* ...
3356 81 : describe_node (std::string ("BareFunctionType"), [this, &type] () {
3357 81 : if (type.has_for_lifetimes ())
3358 0 : visit (type.get_for_lifetimes ());
3359 :
3360 81 : visit (type.get_function_qualifiers ());
3361 :
3362 81 : push (Rust::Token::make (FN_KW, type.get_locus ()));
3363 81 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
3364 :
3365 81 : visit_items_joined_by_separator (type.get_function_params (), COMMA);
3366 :
3367 81 : if (type.is_variadic ())
3368 : {
3369 0 : push (Rust::Token::make (COMMA, UNDEF_LOCATION));
3370 0 : for (auto &item : type.get_variadic_attr ())
3371 : {
3372 0 : visit (item);
3373 : }
3374 0 : push (Rust::Token::make (ELLIPSIS, UNDEF_LOCATION));
3375 : }
3376 :
3377 81 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
3378 :
3379 81 : if (type.has_return_type ())
3380 : {
3381 65 : push (Rust::Token::make (RETURN_TYPE, UNDEF_LOCATION));
3382 65 : visit (type.get_return_type ());
3383 : }
3384 81 : });
3385 81 : }
3386 :
3387 : void
3388 0 : TokenCollector::visit (AST::FormatArgs &fmt)
3389 : {
3390 0 : push (Rust::Token::make_identifier (fmt.get_locus (), "format_args"));
3391 0 : push (Rust::Token::make (EXCLAM, fmt.get_locus ()));
3392 0 : push (Rust::Token::make (LEFT_PAREN, fmt.get_locus ()));
3393 :
3394 0 : std::string reconstructed_template = "\"";
3395 0 : const auto &template_pieces = fmt.get_template ();
3396 :
3397 0 : for (const auto &piece : template_pieces.get_pieces ())
3398 : {
3399 0 : if (piece.tag == Fmt::ffi::Piece::Tag::String)
3400 : {
3401 0 : std::string literal = piece.string._0.to_string ();
3402 0 : for (char c : literal)
3403 : {
3404 0 : if (c == '"' || c == '\\')
3405 : {
3406 0 : reconstructed_template += '\\';
3407 : }
3408 0 : else if (c == '\n')
3409 : {
3410 0 : reconstructed_template += "\\n";
3411 0 : continue;
3412 : }
3413 0 : else if (c == '\r')
3414 : {
3415 0 : reconstructed_template += "\\r";
3416 0 : continue;
3417 : }
3418 0 : else if (c == '\t')
3419 : {
3420 0 : reconstructed_template += "\\t";
3421 0 : continue;
3422 : }
3423 0 : reconstructed_template += c;
3424 : }
3425 0 : }
3426 0 : else if (piece.tag == Fmt::ffi::Piece::Tag::NextArgument)
3427 : {
3428 0 : reconstructed_template += "{";
3429 :
3430 0 : const auto &argument = piece.next_argument._0;
3431 0 : const auto &position = argument.position;
3432 :
3433 0 : switch (position.tag)
3434 : {
3435 : case Fmt::ffi::Position::Tag::ArgumentImplicitlyIs:
3436 : break;
3437 0 : case Fmt::ffi::Position::Tag::ArgumentIs:
3438 0 : reconstructed_template
3439 0 : += std::to_string (position.argument_is._0);
3440 0 : break;
3441 0 : case Fmt::ffi::Position::Tag::ArgumentNamed:
3442 0 : reconstructed_template += position.argument_named._0.to_string ();
3443 0 : break;
3444 : }
3445 :
3446 : // Add format specifiers if any (like :?, :x, etc.)
3447 0 : const auto &format_spec = argument.format;
3448 :
3449 0 : bool has_format_spec = false;
3450 0 : std::string format_part;
3451 :
3452 : // For now, skipping the complex format specifications that
3453 : // use FFIOpt since FFIOpt::get_opt() has a bug.
3454 :
3455 : // Alignment
3456 0 : if (format_spec.align != Fmt::ffi::Alignment::AlignUnknown)
3457 : {
3458 0 : has_format_spec = true;
3459 0 : switch (format_spec.align)
3460 : {
3461 0 : case Fmt::ffi::Alignment::AlignLeft:
3462 0 : format_part += "<";
3463 0 : break;
3464 0 : case Fmt::ffi::Alignment::AlignRight:
3465 0 : format_part += ">";
3466 0 : break;
3467 0 : case Fmt::ffi::Alignment::AlignCenter:
3468 0 : format_part += "^";
3469 0 : break;
3470 : case Fmt::ffi::Alignment::AlignUnknown:
3471 : break;
3472 : }
3473 : }
3474 :
3475 : // Alternate flag
3476 0 : if (format_spec.alternate)
3477 : {
3478 0 : has_format_spec = true;
3479 0 : format_part += "#";
3480 : }
3481 :
3482 : // Zero pad flag
3483 0 : if (format_spec.zero_pad)
3484 : {
3485 0 : has_format_spec = true;
3486 0 : format_part += "0";
3487 : }
3488 :
3489 : // Width
3490 0 : if (format_spec.width.tag != Fmt::ffi::Count::Tag::CountImplied)
3491 : {
3492 0 : has_format_spec = true;
3493 0 : switch (format_spec.width.tag)
3494 : {
3495 0 : case Fmt::ffi::Count::Tag::CountIs:
3496 0 : format_part += std::to_string (format_spec.width.count_is._0);
3497 0 : break;
3498 0 : case Fmt::ffi::Count::Tag::CountIsParam:
3499 0 : format_part
3500 0 : += std::to_string (format_spec.width.count_is_param._0)
3501 0 : + "$";
3502 0 : break;
3503 0 : case Fmt::ffi::Count::Tag::CountIsName:
3504 0 : format_part
3505 0 : += format_spec.width.count_is_name._0.to_string () + "$";
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 : // Precision
3516 0 : if (format_spec.precision.tag != Fmt::ffi::Count::Tag::CountImplied)
3517 : {
3518 0 : has_format_spec = true;
3519 0 : format_part += ".";
3520 0 : switch (format_spec.precision.tag)
3521 : {
3522 0 : case Fmt::ffi::Count::Tag::CountIs:
3523 0 : format_part
3524 0 : += std::to_string (format_spec.precision.count_is._0);
3525 0 : break;
3526 0 : case Fmt::ffi::Count::Tag::CountIsParam:
3527 0 : format_part
3528 0 : += std::to_string (format_spec.precision.count_is_param._0)
3529 0 : + "$";
3530 0 : break;
3531 0 : case Fmt::ffi::Count::Tag::CountIsName:
3532 0 : format_part
3533 0 : += format_spec.precision.count_is_name._0.to_string ()
3534 0 : + "$";
3535 0 : break;
3536 0 : case Fmt::ffi::Count::Tag::CountIsStar:
3537 0 : format_part += "*";
3538 0 : break;
3539 : case Fmt::ffi::Count::Tag::CountImplied:
3540 : break;
3541 : }
3542 : }
3543 :
3544 : // Type/trait (like ?, x, X, etc.)
3545 0 : std::string type_str = format_spec.ty.to_string ();
3546 0 : if (!type_str.empty ())
3547 : {
3548 0 : has_format_spec = true;
3549 0 : format_part += type_str;
3550 : }
3551 :
3552 : // Add the format specification if any
3553 0 : if (has_format_spec)
3554 : {
3555 0 : reconstructed_template += ":";
3556 0 : reconstructed_template += format_part;
3557 : }
3558 :
3559 0 : reconstructed_template += "}";
3560 : }
3561 : }
3562 0 : reconstructed_template += "\"";
3563 :
3564 0 : push (Rust::Token::make_string (fmt.get_locus (), reconstructed_template));
3565 :
3566 : // Visit format arguments if any exist
3567 0 : auto &arguments = fmt.get_arguments ();
3568 0 : if (!arguments.empty ())
3569 : {
3570 0 : push (Rust::Token::make (COMMA, fmt.get_locus ()));
3571 :
3572 0 : auto &args = arguments.get_args ();
3573 0 : for (size_t i = 0; i < args.size (); ++i)
3574 : {
3575 0 : if (i > 0)
3576 : {
3577 0 : push (Rust::Token::make (COMMA, fmt.get_locus ()));
3578 : }
3579 :
3580 0 : auto kind = args[i].get_kind ();
3581 :
3582 : // Handle named arguments: name = expr
3583 0 : if (kind.kind == FormatArgumentKind::Kind::Named)
3584 : {
3585 0 : auto ident = kind.get_ident ().as_string ();
3586 0 : push (Rust::Token::make_identifier (fmt.get_locus (),
3587 : std::move (ident)));
3588 0 : push (Rust::Token::make (EQUAL, fmt.get_locus ()));
3589 0 : }
3590 : // Note: Captured arguments are handled implicitly in the
3591 : // template reconstruction They don't need explicit "name ="
3592 : // syntax in the reconstructed macro call
3593 :
3594 0 : auto &expr = args[i].get_expr ();
3595 0 : expr.accept_vis (*this);
3596 0 : }
3597 : }
3598 :
3599 0 : push (Rust::Token::make (RIGHT_PAREN, fmt.get_locus ()));
3600 0 : }
3601 :
3602 : void
3603 14 : TokenCollector::visit (AST::OffsetOf &offset_of)
3604 : {
3605 14 : auto loc = offset_of.get_locus ();
3606 :
3607 28 : push (Rust::Token::make_identifier (loc, "offset_of"));
3608 14 : push (Rust::Token::make (EXCLAM, loc));
3609 14 : push (Rust::Token::make (LEFT_PAREN, loc));
3610 :
3611 14 : visit (offset_of.get_type ());
3612 :
3613 14 : push (Rust::Token::make (COMMA, loc));
3614 :
3615 14 : push (Rust::Token::make_identifier (offset_of.get_field ()));
3616 :
3617 14 : push (Rust::Token::make (RIGHT_PAREN, loc));
3618 14 : }
3619 :
3620 : } // namespace AST
3621 : } // namespace Rust
|