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