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