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