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