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