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 4449 : TokenCollector::collect () const
49 : {
50 4449 : return tokens;
51 : }
52 :
53 : void
54 4446 : TokenCollector::visit (AST::Crate &crate)
55 : {
56 4446 : visit_items_as_lines (crate.inner_attrs);
57 4446 : visit_items_as_lines (crate.items);
58 4446 : }
59 :
60 : void
61 3 : TokenCollector::visit (AST::Item &item)
62 : {
63 3 : item.accept_vis (*this);
64 3 : }
65 :
66 : void
67 4520 : TokenCollector::trailing_comma ()
68 : {
69 4520 : if (output_trailing_commas)
70 : {
71 0 : push (Rust::Token::make (COMMA, UNDEF_LOCATION));
72 : }
73 4520 : }
74 :
75 : void
76 218399 : TokenCollector::newline ()
77 : {
78 218399 : tokens.emplace_back (CollectItem::Kind::Newline);
79 218399 : }
80 :
81 : void
82 158715 : TokenCollector::indentation ()
83 : {
84 158715 : tokens.emplace_back (indent_level);
85 158715 : }
86 :
87 : void
88 38351 : TokenCollector::increment_indentation ()
89 : {
90 38351 : indent_level++;
91 38351 : }
92 :
93 : void
94 38351 : TokenCollector::decrement_indentation ()
95 : {
96 38351 : rust_assert (indent_level != 0);
97 38351 : indent_level--;
98 38351 : }
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 725136 : TokenCollector::describe_node (const std::string &node_name,
108 : std::function<void ()> visitor)
109 : {
110 725136 : tokens.emplace_back (CollectItem::make_begin_node_description (node_name));
111 :
112 725136 : visitor ();
113 :
114 725136 : tokens.push_back (CollectItem::make_end_node_description (node_name));
115 725136 : }
116 :
117 : void
118 0 : TokenCollector::visit (Visitable &v)
119 : {
120 0 : v.accept_vis (*this);
121 0 : }
122 :
123 : void
124 11850 : TokenCollector::visit (FunctionParam ¶m)
125 : {
126 11850 : describe_node (std::string ("FunctionParam"), [this, ¶m] () {
127 11850 : visit_items_as_lines (param.get_outer_attrs ());
128 11850 : if (!param.is_variadic ())
129 : {
130 11850 : visit (param.get_pattern ());
131 11850 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
132 11850 : 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 11850 : });
144 11850 : }
145 :
146 : void
147 883 : TokenCollector::visit (VariadicParam ¶m)
148 : {
149 883 : describe_node (std::string ("VariadicParam"), [this, ¶m] () {
150 883 : if (param.has_pattern ())
151 : {
152 9 : visit (param.get_pattern ());
153 18 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
154 : }
155 883 : push (Rust::Token::make (ELLIPSIS, UNDEF_LOCATION));
156 883 : });
157 883 : }
158 :
159 : void
160 27516 : TokenCollector::visit (Attribute &attrib)
161 : {
162 27516 : describe_node (std::string ("Attribute"), [this, &attrib] () {
163 27516 : push (Rust::Token::make (HASH, attrib.get_locus ()));
164 27516 : if (attrib.is_inner_attribute ())
165 22878 : push (Rust::Token::make (EXCLAM, UNDEF_LOCATION));
166 27516 : push (Rust::Token::make (LEFT_SQUARE, UNDEF_LOCATION));
167 27516 : visit (attrib.get_path ());
168 :
169 27516 : if (attrib.has_attr_input ())
170 : {
171 21320 : switch (attrib.get_attr_input ().get_attr_input_type ())
172 : {
173 11524 : case AST::AttrInput::AttrInputType::LITERAL:
174 11524 : {
175 11524 : visit (
176 11524 : static_cast<AttrInputLiteral &> (attrib.get_attr_input ()));
177 11524 : 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 422 : case AST::AttrInput::AttrInputType::META_ITEM:
185 422 : {
186 422 : visit (static_cast<AttrInputMetaItemContainer &> (
187 422 : attrib.get_attr_input ()));
188 422 : break;
189 : }
190 9373 : case AST::AttrInput::AttrInputType::TOKEN_TREE:
191 9373 : {
192 9373 : visit (static_cast<DelimTokenTree &> (attrib.get_attr_input ()));
193 9373 : break;
194 : }
195 0 : default:
196 0 : rust_unreachable ();
197 : }
198 : }
199 27516 : push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION));
200 27516 : });
201 27516 : }
202 :
203 : void
204 29029 : TokenCollector::visit (SimplePath &path)
205 : {
206 29029 : describe_node (std::string ("SimplePath"), [this, &path] () {
207 29029 : if (path.has_opening_scope_resolution ())
208 : {
209 0 : push (Rust::Token::make (SCOPE_RESOLUTION, path.get_locus ()));
210 : }
211 29029 : visit_items_joined_by_separator (path.get_segments (), SCOPE_RESOLUTION);
212 29029 : });
213 29029 : }
214 :
215 : void
216 30031 : TokenCollector::visit (SimplePathSegment &segment)
217 : {
218 30031 : describe_node (std::string ("SimplePathSegment"), [this, &segment] () {
219 30031 : auto name = segment.get_segment_name ();
220 30031 : if (segment.is_crate_path_seg ())
221 : {
222 268 : push (Rust::Token::make (CRATE, segment.get_locus ()));
223 : }
224 29897 : else if (segment.is_super_path_seg ())
225 : {
226 604 : push (Rust::Token::make (SUPER, segment.get_locus ()));
227 : }
228 29595 : else if (segment.is_lower_self_seg ())
229 : {
230 150 : push (Rust::Token::make (SELF, segment.get_locus ()));
231 : }
232 29520 : else if (segment.is_big_self ())
233 : {
234 0 : push (Rust::Token::make (SELF_ALIAS, segment.get_locus ()));
235 : }
236 : else
237 : {
238 59040 : push (Rust::Token::make_identifier (segment.get_locus (),
239 : std::move (name)));
240 : }
241 30031 : });
242 30031 : }
243 :
244 : void
245 29852 : TokenCollector::visit (Visibility &vis)
246 : {
247 29852 : describe_node (std::string ("Visibility"), [this, &vis] () {
248 29852 : switch (vis.get_vis_type ())
249 : {
250 9029 : case Visibility::PUB:
251 9029 : push (Rust::Token::make (PUB, vis.get_locus ()));
252 9029 : 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 29852 : });
282 29852 : }
283 :
284 : void
285 9702 : TokenCollector::visit (std::vector<std::unique_ptr<GenericParam>> ¶ms)
286 : {
287 9702 : describe_node (std::string ("GenericParam"), [this, ¶ms] () {
288 9702 : push (Rust::Token::make (LEFT_ANGLE, UNDEF_LOCATION));
289 9702 : visit_items_joined_by_separator (params, COMMA);
290 9702 : push (Rust::Token::make (RIGHT_ANGLE, UNDEF_LOCATION));
291 9702 : });
292 9702 : }
293 :
294 : void
295 2155 : TokenCollector::visit (TupleField &field)
296 : {
297 2155 : describe_node (std::string ("TupleField"), [this, &field] () {
298 2212 : for (auto attr : field.get_outer_attrs ())
299 : {
300 57 : visit (attr);
301 57 : }
302 2155 : visit (field.get_visibility ());
303 2155 : visit (field.get_field_type ());
304 2155 : });
305 2155 : }
306 :
307 : void
308 2316 : TokenCollector::visit (StructField &field)
309 : {
310 2316 : describe_node (std::string ("StructField"), [this, &field] () {
311 2317 : for (auto attr : field.get_outer_attrs ())
312 : {
313 1 : visit (attr);
314 1 : }
315 2316 : visit (field.get_visibility ());
316 4632 : auto name = field.get_field_name ().as_string ();
317 4632 : push (Rust::Token::make_identifier (field.get_locus (), std::move (name)));
318 2316 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
319 2316 : visit (field.get_field_type ());
320 2316 : });
321 2316 : }
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 19598 : TokenCollector::visit (FunctionQualifiers &qualifiers)
336 : {
337 : // Syntax:
338 : // `const`? `async`? `unsafe`? (`extern` Abi?)?
339 : // unsafe? (extern Abi?)?
340 19598 : describe_node (std::string ("FunctionQualifiers"), [this, &qualifiers] () {
341 19598 : if (qualifiers.is_async ())
342 2 : push (Rust::Token::make (ASYNC, qualifiers.get_locus ()));
343 19598 : if (qualifiers.is_const ())
344 1990 : push (Rust::Token::make (CONST, qualifiers.get_locus ()));
345 19598 : if (qualifiers.is_unsafe ())
346 1118 : push (Rust::Token::make (UNSAFE, qualifiers.get_locus ()));
347 19598 : if (qualifiers.is_extern ())
348 : {
349 75 : push (Rust::Token::make (EXTERN_KW, qualifiers.get_locus ()));
350 75 : if (qualifiers.has_abi ())
351 : {
352 150 : push (Rust::Token::make_string (UNDEF_LOCATION,
353 225 : qualifiers.get_extern_abi ()));
354 : }
355 : }
356 19598 : });
357 19598 : }
358 :
359 : void
360 66 : TokenCollector::visit (MaybeNamedParam ¶m)
361 : {
362 : // Syntax:
363 : // OuterAttribute* ( ( IDENTIFIER | _ ) : )? Type
364 :
365 66 : describe_node (std::string ("MaybeNamedParam"), [this, ¶m] () {
366 66 : for (auto attr : param.get_outer_attrs ())
367 : {
368 0 : visit (attr);
369 0 : }
370 132 : auto param_name = param.get_name ().as_string ();
371 66 : 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 66 : visit (param.get_type ());
386 66 : });
387 66 : }
388 :
389 : void
390 81246 : TokenCollector::visit (Token &tok)
391 : {
392 81246 : std::string data
393 106367 : = tok.get_tok_ptr ()->should_have_str () ? tok.get_str () : "";
394 81246 : switch (tok.get_id ())
395 : {
396 20478 : case IDENTIFIER:
397 40956 : push (Rust::Token::make_identifier (tok.get_locus (), std::move (data)));
398 20478 : break;
399 394 : case INT_LITERAL:
400 394 : {
401 394 : auto suffix_start = data.length ();
402 788 : push (Rust::Token::make_int (tok.get_locus (), std::move (data),
403 : suffix_start, IntegerLiteralBase::Decimal,
404 : tok.get_type_hint ()));
405 394 : 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 4239 : case STRING_LITERAL:
415 8478 : push (Rust::Token::make_string (tok.get_locus (), std::move (data)));
416 4239 : 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 56125 : default:
447 112250 : push (Rust::Token::make (tok.get_id (), tok.get_locus ()));
448 : }
449 81246 : }
450 :
451 : void
452 10656 : TokenCollector::visit (DelimTokenTree &delim_tok_tree)
453 : {
454 10656 : describe_node (std::string ("DelimTokenTree"), [this, &delim_tok_tree] () {
455 91423 : for (auto &token : delim_tok_tree.to_token_stream ())
456 : {
457 80767 : visit (token);
458 10656 : }
459 10656 : });
460 10656 : }
461 :
462 : void
463 422 : TokenCollector::visit (AttrInputMetaItemContainer &container)
464 : {
465 422 : describe_node (std::string ("AttrInputMetaItemContainer"),
466 422 : [this, &container] () {
467 844 : for (auto &item : container.get_items ())
468 : {
469 422 : visit (item);
470 : }
471 422 : });
472 422 : }
473 :
474 : void
475 26395 : TokenCollector::visit (IdentifierExpr &ident_expr)
476 : {
477 26395 : describe_node (std::string ("IdentifierExpr"), [this, &ident_expr] () {
478 52790 : auto ident = ident_expr.get_ident ().as_string ();
479 52790 : push (Rust::Token::make_identifier (ident_expr.get_locus (),
480 : std::move (ident)));
481 26395 : });
482 26395 : }
483 :
484 : void
485 10217 : TokenCollector::visit (Lifetime &lifetime)
486 : {
487 : // Syntax:
488 : // Lifetime :
489 : // LIFETIME_OR_LABEL
490 : // | 'static
491 : // | '_
492 :
493 10217 : describe_node (std::string ("Lifetime"), [this, &lifetime] () {
494 10217 : auto name = lifetime.get_lifetime_name ();
495 10217 : switch (lifetime.get_lifetime_type ())
496 : {
497 555 : case Lifetime::LifetimeType::NAMED:
498 555 : push (
499 1110 : Rust::Token::make_lifetime (lifetime.get_locus (), std::move (name)));
500 555 : break;
501 120 : case Lifetime::LifetimeType::STATIC:
502 240 : push (Rust::Token::make_lifetime (lifetime.get_locus (),
503 120 : Values::Keywords::STATIC_KW));
504 120 : break;
505 9542 : case Lifetime::LifetimeType::WILDCARD:
506 19084 : push (Rust::Token::make_lifetime (lifetime.get_locus (),
507 9542 : Values::Keywords::UNDERSCORE));
508 9542 : break;
509 : }
510 10217 : });
511 10217 : }
512 :
513 : void
514 182 : 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 182 : describe_node (std::string ("LifetimeParam"), [this, &lifetime_param] () {
523 182 : visit_items_as_lines (lifetime_param.get_outer_attrs ());
524 182 : auto lifetime = lifetime_param.get_lifetime ();
525 182 : visit (lifetime);
526 :
527 182 : 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 182 : });
536 182 : }
537 :
538 : void
539 78 : TokenCollector::visit (ConstGenericParam ¶m)
540 : {
541 : // Syntax:
542 : // const IDENTIFIER : Type ( = Block | IDENTIFIER | -?LITERAL )?
543 78 : describe_node (std::string ("ConstGenericParam"), [this, ¶m] () {
544 78 : visit_items_as_lines (param.get_outer_attrs ());
545 78 : push (Rust::Token::make (CONST, param.get_locus ()));
546 78 : auto id = param.get_name ().as_string ();
547 156 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
548 78 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
549 78 : if (param.has_type ())
550 78 : visit (param.get_type ());
551 78 : 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 78 : });
557 78 : }
558 :
559 : void
560 41000 : TokenCollector::visit (PathExprSegment &segment)
561 : {
562 41000 : describe_node (std::string ("PathExprSegment"), [this, &segment] () {
563 41000 : visit (segment.get_ident_segment ());
564 41000 : if (segment.has_generic_args ())
565 : {
566 1000 : auto generics = segment.get_generic_args ();
567 1000 : push (Rust::Token::make (SCOPE_RESOLUTION, segment.get_locus ()));
568 1000 : push (Rust::Token::make (LEFT_ANGLE, generics.get_locus ()));
569 :
570 1000 : auto &lifetime_args = generics.get_lifetime_args ();
571 1000 : auto &generic_args = generics.get_generic_args ();
572 1000 : auto &binding_args = generics.get_binding_args ();
573 :
574 1000 : visit_items_joined_by_separator (generic_args, COMMA);
575 :
576 1000 : if (!lifetime_args.empty ()
577 1000 : && (!generic_args.empty () || !binding_args.empty ()))
578 : {
579 0 : push (Rust::Token::make (COMMA, UNDEF_LOCATION));
580 : }
581 :
582 1000 : visit_items_joined_by_separator (binding_args, COMMA);
583 :
584 1000 : if (!generic_args.empty () && !binding_args.empty ())
585 : {
586 0 : push (Rust::Token::make (COMMA, UNDEF_LOCATION));
587 : }
588 :
589 1000 : visit_items_joined_by_separator (lifetime_args, COMMA);
590 :
591 1000 : push (Rust::Token::make (RIGHT_ANGLE, UNDEF_LOCATION));
592 1000 : }
593 41000 : });
594 41000 : }
595 :
596 : void
597 27573 : TokenCollector::visit (PathInExpression &path)
598 : {
599 27573 : describe_node (std::string ("PathInExpression"), [this, &path] () {
600 27573 : if (path.is_lang_item ())
601 : {
602 167 : push (Rust::Token::make (TokenId::HASH, path.get_locus ()));
603 167 : push (Rust::Token::make (TokenId::LEFT_SQUARE, path.get_locus ()));
604 334 : push (Rust::Token::make_identifier (path.get_locus (), "lang"));
605 167 : push (Rust::Token::make (TokenId::EQUAL, path.get_locus ()));
606 334 : push (Rust::Token::make_string (
607 167 : path.get_locus (), LangItem::ToString (path.get_lang_item ())));
608 167 : push (Rust::Token::make (TokenId::RIGHT_SQUARE, path.get_locus ()));
609 :
610 167 : return;
611 : }
612 :
613 27406 : if (path.opening_scope_resolution ())
614 766 : push (Rust::Token::make (SCOPE_RESOLUTION, path.get_locus ()));
615 :
616 27406 : visit_items_joined_by_separator (path.get_segments (), SCOPE_RESOLUTION);
617 : });
618 27573 : }
619 :
620 : void
621 60275 : TokenCollector::visit (TypePathSegment &segment)
622 : {
623 : // Syntax:
624 : // PathIdentSegment
625 60275 : describe_node (std::string ("TypePathSegment"), [this, &segment] () {
626 60275 : auto locus = segment.is_lang_item ()
627 60275 : ? segment.get_locus ()
628 59937 : : segment.get_ident_segment ().get_locus ();
629 60275 : auto segment_string = segment.is_lang_item ()
630 60275 : ? LangItem::PrettyString (segment.get_lang_item ())
631 60275 : : segment.get_ident_segment ().as_string ();
632 120550 : push (Rust::Token::make_identifier (locus, std::move (segment_string)));
633 60275 : });
634 60275 : }
635 :
636 : void
637 3342 : TokenCollector::visit (TypePathSegmentGeneric &segment)
638 : {
639 : // Syntax:
640 : // PathIdentSegment `::`? (GenericArgs)?
641 : // GenericArgs :
642 : // `<` `>`
643 : // | `<` ( GenericArg `,` )* GenericArg `,`? `>`
644 3342 : describe_node (std::string ("TypePathSegmentGeneric"), [this, &segment] () {
645 3342 : auto locus = segment.is_lang_item ()
646 3342 : ? segment.get_locus ()
647 3294 : : segment.get_ident_segment ().get_locus ();
648 3342 : auto segment_string = segment.is_lang_item ()
649 3342 : ? LangItem::PrettyString (segment.get_lang_item ())
650 3342 : : segment.get_ident_segment ().as_string ();
651 6684 : push (Rust::Token::make_identifier (locus, std::move (segment_string)));
652 :
653 3342 : push (Rust::Token::make (LEFT_ANGLE, UNDEF_LOCATION));
654 :
655 3342 : {
656 3342 : auto &lifetime_args = segment.get_generic_args ().get_lifetime_args ();
657 3342 : auto &generic_args = segment.get_generic_args ().get_generic_args ();
658 3342 : auto &binding_args = segment.get_generic_args ().get_binding_args ();
659 :
660 3342 : visit_items_joined_by_separator (lifetime_args, COMMA);
661 3342 : if (!lifetime_args.empty ()
662 3342 : && (!generic_args.empty () || !binding_args.empty ()))
663 16 : push (Rust::Token::make (COMMA, UNDEF_LOCATION));
664 3342 : visit_items_joined_by_separator (generic_args, COMMA);
665 3342 : if (!generic_args.empty () && !binding_args.empty ())
666 2 : push (Rust::Token::make (COMMA, UNDEF_LOCATION));
667 3342 : visit_items_joined_by_separator (binding_args, COMMA);
668 : }
669 :
670 6684 : push (Rust::Token::make (RIGHT_ANGLE, UNDEF_LOCATION));
671 3342 : });
672 3342 : }
673 :
674 : void
675 57 : TokenCollector::visit (GenericArgsBinding &binding)
676 : {
677 : // Syntax:
678 : // IDENTIFIER `=` Type
679 57 : describe_node (std::string ("GenericArgsBinding"), [this, &binding] () {
680 114 : auto identifier = binding.get_identifier ().as_string ();
681 114 : push (Rust::Token::make_identifier (binding.get_locus (),
682 : std::move (identifier)));
683 :
684 57 : push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
685 57 : visit (binding.get_type ());
686 57 : });
687 57 : }
688 :
689 : void
690 4566 : 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 4566 : describe_node (std::string ("GenericArg"), [this, &arg] () {
695 4566 : switch (arg.get_kind ())
696 : {
697 110 : case GenericArg::Kind::Const:
698 110 : visit (arg.get_expression ());
699 110 : break;
700 4449 : case GenericArg::Kind::Type:
701 4449 : visit (arg.get_type ());
702 4449 : 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 4566 : });
712 4566 : }
713 :
714 : void
715 36 : TokenCollector::visit (TypePathSegmentFunction &segment)
716 : {
717 : // Syntax:
718 : // PathIdentSegment `::`? (TypePathFn)?
719 36 : describe_node (std::string ("TypePathSegmentFunction"), [this, &segment] () {
720 36 : auto ident_segment = segment.get_ident_segment ();
721 36 : auto id = ident_segment.as_string ();
722 72 : push (Rust::Token::make_identifier (ident_segment.get_locus (),
723 : std::move (id)));
724 :
725 36 : if (segment.get_separating_scope_resolution ())
726 0 : push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
727 :
728 36 : if (!segment.is_ident_only ())
729 36 : visit (segment.get_type_path_function ());
730 36 : });
731 36 : }
732 :
733 : void
734 36 : TokenCollector::visit (TypePathFunction &type_path_fn)
735 : {
736 : // Syntax:
737 : // `(` TypePathFnInputs? `)` (`->` Type)?
738 : // TypePathFnInputs :
739 : // Type (`,` Type)* `,`?
740 36 : describe_node (std::string ("TypePathFunction"), [this, &type_path_fn] () {
741 36 : push (Rust::Token::make (LEFT_PAREN, type_path_fn.get_locus ()));
742 36 : if (type_path_fn.has_inputs ())
743 35 : visit_items_joined_by_separator (type_path_fn.get_params (), COMMA);
744 36 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
745 :
746 36 : if (type_path_fn.has_return_type ())
747 : {
748 36 : push (Rust::Token::make (RETURN_TYPE, UNDEF_LOCATION));
749 36 : visit (type_path_fn.get_return_type ());
750 : }
751 36 : });
752 36 : }
753 :
754 : void
755 61466 : TokenCollector::visit (TypePath &path)
756 : {
757 : // Syntax:
758 : // `::`? TypePathSegment (`::` TypePathSegment)*
759 61466 : describe_node (std::string ("TypePath"), [this, &path] () {
760 61466 : if (path.has_opening_scope_resolution_op ())
761 728 : push (Rust::Token::make (SCOPE_RESOLUTION, path.get_locus ()));
762 :
763 61466 : visit_items_joined_by_separator (path.get_segments (), SCOPE_RESOLUTION);
764 61466 : });
765 61466 : }
766 :
767 : void
768 41000 : TokenCollector::visit (PathIdentSegment &segment)
769 : {
770 41000 : describe_node (std::string ("PathIdentSegment"), [this, &segment] () {
771 41000 : if (segment.is_super_path_seg ())
772 : {
773 2 : push (Rust::Token::make (SUPER, segment.get_locus ()));
774 : }
775 40999 : else if (segment.is_crate_path_seg ())
776 : {
777 3102 : push (Rust::Token::make (CRATE, segment.get_locus ()));
778 : }
779 39448 : else if (segment.is_lower_self_seg ())
780 : {
781 14894 : push (Rust::Token::make (SELF, segment.get_locus ()));
782 : }
783 32001 : else if (segment.is_big_self_seg ())
784 : {
785 980 : push (Rust::Token::make (SELF_ALIAS, segment.get_locus ()));
786 : }
787 : else
788 : {
789 31511 : auto id = segment.as_string ();
790 31511 : push (
791 63022 : Rust::Token::make_identifier (segment.get_locus (), std::move (id)));
792 31511 : }
793 41000 : });
794 41000 : }
795 :
796 : void
797 119 : TokenCollector::visit (QualifiedPathInExpression &path)
798 : {
799 119 : describe_node (std::string ("QualifiedPathInExpression"), [this, &path] () {
800 119 : visit (path.get_qualified_path_type ());
801 238 : for (auto &segment : path.get_segments ())
802 : {
803 119 : push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
804 119 : visit (segment);
805 : }
806 119 : });
807 119 : }
808 :
809 : void
810 403 : TokenCollector::visit (QualifiedPathType &path)
811 : {
812 403 : describe_node (std::string ("QualifiedPathType"), [this, &path] () {
813 403 : push (Rust::Token::make (LEFT_ANGLE, path.get_locus ()));
814 403 : visit (path.get_type ());
815 403 : if (path.has_as_clause ())
816 : {
817 363 : push (Rust::Token::make (AS, UNDEF_LOCATION));
818 363 : visit (path.get_as_type_path ());
819 : }
820 403 : push (Rust::Token::make (RIGHT_ANGLE, UNDEF_LOCATION));
821 403 : });
822 403 : }
823 :
824 : void
825 284 : TokenCollector::visit (QualifiedPathInType &path)
826 : {
827 284 : describe_node (std::string ("QualifiedPathInType"), [this, &path] () {
828 284 : visit (path.get_qualified_path_type ());
829 :
830 284 : push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
831 284 : visit (path.get_associated_segment ());
832 284 : for (auto &segment : path.get_segments ())
833 : {
834 0 : push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
835 0 : visit (segment);
836 : }
837 284 : });
838 284 : }
839 :
840 : void
841 33749 : TokenCollector::visit (Literal &lit, location_t locus)
842 : {
843 33749 : auto value = lit.as_string ();
844 33749 : 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 13979 : case Literal::LitType::STRING:
853 27958 : push (Rust::Token::make_string (locus, std::move (value)));
854 13979 : 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 17426 : case Literal::LitType::INT:
868 17426 : {
869 17426 : auto val_len = value.length ();
870 34852 : push (Rust::Token::make_int (locus, std::move (value), val_len,
871 : IntegerLiteralBase::Decimal,
872 : lit.get_type_hint ()));
873 17426 : break;
874 : }
875 351 : case Literal::LitType::FLOAT:
876 351 : {
877 351 : auto val_len = value.length ();
878 702 : push (Rust::Token::make_float (locus, std::move (value), val_len,
879 : lit.get_type_hint ()));
880 351 : break;
881 : }
882 1349 : case Literal::LitType::BOOL:
883 1349 : {
884 1349 : if (value == Values::Keywords::FALSE_LITERAL)
885 1164 : push (Rust::Token::make (FALSE_LITERAL, locus));
886 767 : else if (value == Values::Keywords::TRUE_LITERAL)
887 1534 : 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 33749 : break;
895 : }
896 33749 : }
897 :
898 : void
899 33211 : TokenCollector::visit (LiteralExpr &expr)
900 : {
901 33211 : describe_node (std::string ("LiteralExpr"), [this, &expr] () {
902 33211 : auto lit = expr.get_literal ();
903 33211 : visit (lit, expr.get_locus ());
904 33211 : });
905 33211 : }
906 :
907 : void
908 11524 : TokenCollector::visit (AttrInputLiteral &literal)
909 : {
910 11524 : describe_node (std::string ("AttrInputLiteral"), [this, &literal] () {
911 11524 : push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
912 11524 : visit (literal.get_literal ());
913 11524 : });
914 11524 : }
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 2039 : TokenCollector::visit (BorrowExpr &expr)
946 : {
947 2039 : describe_node (std::string ("BorrowExpr"), [this, &expr] () {
948 2039 : push (Rust::Token::make (AMP, expr.get_locus ()));
949 2039 : if (expr.get_is_double_borrow ())
950 46 : push (Rust::Token::make (AMP, UNDEF_LOCATION));
951 :
952 2039 : 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 2035 : if (expr.get_is_mut ())
964 886 : push (Rust::Token::make (MUT, UNDEF_LOCATION));
965 : }
966 :
967 2039 : 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 2035 : if (expr.get_is_mut ())
979 886 : push (Rust::Token::make (MUT, UNDEF_LOCATION));
980 : }
981 :
982 2039 : if (expr.has_borrow_expr ())
983 2039 : visit (expr.get_borrowed_expr ());
984 2039 : });
985 2039 : }
986 :
987 : void
988 4130 : TokenCollector::visit (DereferenceExpr &expr)
989 : {
990 4130 : describe_node (std::string ("DereferenceExpr"), [this, &expr] () {
991 4130 : push (Rust::Token::make (ASTERISK, expr.get_locus ()));
992 4130 : visit (expr.get_dereferenced_expr ());
993 4130 : });
994 4130 : }
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 882 : TokenCollector::visit (NegationExpr &expr)
1007 : {
1008 882 : describe_node (std::string ("NegationExpr"), [this, &expr] () {
1009 882 : switch (expr.get_expr_type ())
1010 : {
1011 417 : case NegationOperator::NEGATE:
1012 417 : push (Rust::Token::make (MINUS, expr.get_locus ()));
1013 417 : break;
1014 465 : case NegationOperator::NOT:
1015 465 : push (Rust::Token::make (EXCLAM, expr.get_locus ()));
1016 465 : break;
1017 : }
1018 882 : visit (expr.get_negated_expr ());
1019 882 : });
1020 882 : }
1021 :
1022 : void
1023 3775 : TokenCollector::visit (ArithmeticOrLogicalExpr &expr)
1024 : {
1025 3775 : describe_node (std::string ("ArithmeticOrLogicalExpr"), [this, &expr] () {
1026 3775 : visit (expr.get_left_expr ());
1027 3775 : switch (expr.get_expr_type ())
1028 : {
1029 2041 : case ArithmeticOrLogicalOperator::ADD:
1030 2041 : push (Rust::Token::make (PLUS, expr.get_locus ()));
1031 2041 : break;
1032 :
1033 1148 : case ArithmeticOrLogicalOperator::SUBTRACT:
1034 1148 : push (Rust::Token::make (MINUS, expr.get_locus ()));
1035 1148 : break;
1036 :
1037 277 : case ArithmeticOrLogicalOperator::MULTIPLY:
1038 277 : push (Rust::Token::make (ASTERISK, expr.get_locus ()));
1039 277 : break;
1040 :
1041 34 : case ArithmeticOrLogicalOperator::DIVIDE:
1042 34 : push (Rust::Token::make (DIV, expr.get_locus ()));
1043 34 : break;
1044 :
1045 48 : case ArithmeticOrLogicalOperator::MODULUS:
1046 48 : push (Rust::Token::make (PERCENT, expr.get_locus ()));
1047 48 : break;
1048 :
1049 52 : case ArithmeticOrLogicalOperator::BITWISE_AND:
1050 52 : push (Rust::Token::make (AMP, expr.get_locus ()));
1051 52 : break;
1052 :
1053 39 : case ArithmeticOrLogicalOperator::BITWISE_OR:
1054 39 : push (Rust::Token::make (PIPE, expr.get_locus ()));
1055 39 : 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 3775 : visit (expr.get_right_expr ());
1071 3775 : });
1072 3775 : }
1073 :
1074 : void
1075 4073 : TokenCollector::visit (ComparisonExpr &expr)
1076 : {
1077 4073 : describe_node (std::string ("ComparisonExpr"), [this, &expr] () {
1078 4073 : visit (expr.get_left_expr ());
1079 :
1080 4073 : switch (expr.get_expr_type ())
1081 : {
1082 927 : case ComparisonOperator::EQUAL:
1083 927 : push (Rust::Token::make (EQUAL_EQUAL, expr.get_locus ()));
1084 927 : break;
1085 1130 : case ComparisonOperator::NOT_EQUAL:
1086 1130 : push (Rust::Token::make (NOT_EQUAL, expr.get_locus ()));
1087 1130 : break;
1088 677 : case ComparisonOperator::GREATER_THAN:
1089 677 : push (Rust::Token::make (RIGHT_ANGLE, expr.get_locus ()));
1090 677 : break;
1091 810 : case ComparisonOperator::LESS_THAN:
1092 810 : push (Rust::Token::make (LEFT_ANGLE, expr.get_locus ()));
1093 810 : 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 293 : case ComparisonOperator::LESS_OR_EQUAL:
1099 293 : push (Rust::Token::make (LESS_OR_EQUAL, expr.get_locus ()));
1100 293 : break;
1101 : }
1102 4073 : visit (expr.get_right_expr ());
1103 4073 : });
1104 4073 : }
1105 :
1106 : void
1107 522 : TokenCollector::visit (LazyBooleanExpr &expr)
1108 : {
1109 522 : describe_node (std::string ("LazyBooleanExpr"), [this, &expr] () {
1110 522 : visit (expr.get_left_expr ());
1111 :
1112 522 : 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 144 : case LazyBooleanOperator::LOGICAL_OR:
1118 144 : push (Rust::Token::make (OR, expr.get_locus ()));
1119 144 : break;
1120 : }
1121 :
1122 522 : visit (expr.get_right_expr ());
1123 522 : });
1124 522 : }
1125 :
1126 : void
1127 5624 : TokenCollector::visit (TypeCastExpr &expr)
1128 : {
1129 5624 : describe_node (std::string ("TypeCastExpr"), [this, &expr] () {
1130 5624 : visit (expr.get_casted_expr ());
1131 5624 : push (Rust::Token::make (AS, expr.get_locus ()));
1132 5624 : visit (expr.get_type_to_cast_to ());
1133 5624 : });
1134 5624 : }
1135 :
1136 : void
1137 2537 : TokenCollector::visit (AssignmentExpr &expr)
1138 : {
1139 2537 : describe_node (std::string ("AssignementExpr"), [this, &expr] () {
1140 2537 : expr.visit_lhs (*this);
1141 2537 : push (Rust::Token::make (EQUAL, expr.get_locus ()));
1142 2537 : expr.visit_rhs (*this);
1143 2537 : });
1144 2537 : }
1145 :
1146 : void
1147 718 : TokenCollector::visit (CompoundAssignmentExpr &expr)
1148 : {
1149 718 : describe_node (std::string ("CompoundAssignmentExpr"), [this, &expr] () {
1150 718 : visit (expr.get_left_expr ());
1151 :
1152 718 : switch (expr.get_expr_type ())
1153 : {
1154 191 : case CompoundAssignmentOperator::ADD:
1155 191 : push (Rust::Token::make (PLUS_EQ, expr.get_locus ()));
1156 191 : break;
1157 107 : case CompoundAssignmentOperator::SUBTRACT:
1158 107 : push (Rust::Token::make (MINUS_EQ, expr.get_locus ()));
1159 107 : 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 718 : visit (expr.get_right_expr ());
1186 718 : });
1187 718 : }
1188 :
1189 : void
1190 360 : TokenCollector::visit (GroupedExpr &expr)
1191 : {
1192 360 : describe_node (std::string ("GroupedExpr"), [this, &expr] () {
1193 360 : push (Rust::Token::make (LEFT_PAREN, expr.get_locus ()));
1194 360 : visit (expr.get_expr_in_parens ());
1195 360 : push (Rust::Token::make (RIGHT_PAREN, expr.get_locus ()));
1196 360 : });
1197 360 : }
1198 :
1199 : void
1200 295 : TokenCollector::visit (ArrayElemsValues &elems)
1201 : {
1202 295 : describe_node (std::string ("ArraysElemValues"), [this, &elems] () {
1203 295 : visit_items_joined_by_separator (elems.get_values (), COMMA);
1204 295 : });
1205 295 : }
1206 :
1207 : void
1208 116 : TokenCollector::visit (ArrayElemsCopied &elems)
1209 : {
1210 116 : describe_node (std::string ("ArrayElemsCopied"), [this, &elems] () {
1211 116 : visit (elems.get_elem_to_copy ());
1212 116 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
1213 116 : visit (elems.get_num_copies ());
1214 116 : });
1215 116 : }
1216 :
1217 : void
1218 411 : TokenCollector::visit (ArrayExpr &expr)
1219 : {
1220 411 : describe_node (std::string ("ArrayExpr"), [this, &expr] () {
1221 411 : push (Rust::Token::make (LEFT_SQUARE, expr.get_locus ()));
1222 411 : visit (expr.get_array_elems ());
1223 411 : push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION));
1224 411 : });
1225 411 : }
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 601 : TokenCollector::visit (TupleExpr &expr)
1240 : {
1241 601 : describe_node (std::string ("TupleExpr"), [this, &expr] () {
1242 601 : visit_items_as_lines (expr.get_outer_attrs ());
1243 601 : push (Rust::Token::make (LEFT_PAREN, expr.get_locus ()));
1244 601 : visit_items_joined_by_separator (expr.get_tuple_elems (), COMMA);
1245 601 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
1246 601 : });
1247 601 : }
1248 :
1249 : void
1250 914 : TokenCollector::visit (TupleIndexExpr &expr)
1251 : {
1252 914 : describe_node (std::string ("TupleIndexExpr"), [this, &expr] () {
1253 914 : visit (expr.get_tuple_expr ());
1254 914 : push (Rust::Token::make (DOT, expr.get_locus ()));
1255 914 : auto str = std::to_string (expr.get_tuple_index ());
1256 914 : auto suffix_start = str.length ();
1257 1828 : push (Rust::Token::make_int (UNDEF_LOCATION, str, suffix_start,
1258 : IntegerLiteralBase::Decimal));
1259 914 : });
1260 914 : }
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 229 : TokenCollector::visit (StructExprFieldIdentifier &expr)
1271 : {
1272 229 : describe_node (std::string ("StructExprFieldIdentifier"), [this, &expr] () {
1273 229 : visit_items_as_lines (expr.get_outer_attrs ());
1274 458 : auto id = expr.get_field_name ().as_string ();
1275 458 : push (Rust::Token::make_identifier (expr.get_locus (), std::move (id)));
1276 229 : });
1277 229 : }
1278 :
1279 : void
1280 2082 : TokenCollector::visit (StructExprFieldIdentifierValue &expr)
1281 : {
1282 2082 : describe_node (std::string ("StructExprFieldIdentifierValue"), [this,
1283 : &expr] () {
1284 2082 : visit_items_as_lines (expr.get_outer_attrs ());
1285 2082 : auto id = expr.get_field_name ();
1286 4164 : push (Rust::Token::make_identifier (expr.get_locus (), std::move (id)));
1287 2082 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
1288 2082 : visit (expr.get_value ());
1289 2082 : });
1290 2082 : }
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 1387 : TokenCollector::visit (StructExprStructFields &expr)
1317 : {
1318 1387 : describe_node (std::string ("StructExprStructFields"), [this, &expr] () {
1319 1387 : visit (expr.get_struct_name ());
1320 1387 : push (Rust::Token::make (LEFT_CURLY, expr.get_locus ()));
1321 1387 : visit_items_joined_by_separator (expr.get_fields (), COMMA);
1322 1387 : 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 1324 : trailing_comma ();
1330 : }
1331 1387 : push (Rust::Token::make (RIGHT_CURLY, expr.get_locus ()));
1332 1387 : });
1333 1387 : }
1334 :
1335 : void
1336 0 : TokenCollector::visit (StructExprStructBase &)
1337 : {
1338 : // FIXME: Implement this node
1339 0 : rust_unreachable ();
1340 : }
1341 :
1342 : void
1343 13485 : TokenCollector::visit (CallExpr &expr)
1344 : {
1345 13485 : describe_node (std::string ("CallExpr"), [this, &expr] () {
1346 13485 : visit (expr.get_function_expr ());
1347 :
1348 13485 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
1349 :
1350 13485 : visit_items_joined_by_separator (expr.get_params (), COMMA);
1351 :
1352 13485 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
1353 13485 : });
1354 13485 : }
1355 :
1356 : void
1357 3196 : TokenCollector::visit (MethodCallExpr &expr)
1358 : {
1359 3196 : describe_node (std::string ("MethodCallExpr"), [this, &expr] () {
1360 3196 : visit (expr.get_receiver_expr ());
1361 3196 : push (Rust::Token::make (DOT, expr.get_locus ()));
1362 3196 : visit (expr.get_method_name ());
1363 3196 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
1364 3196 : visit_items_joined_by_separator (expr.get_params (), COMMA);
1365 3196 : trailing_comma ();
1366 3196 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
1367 3196 : });
1368 3196 : }
1369 :
1370 : void
1371 5148 : TokenCollector::visit (FieldAccessExpr &expr)
1372 : {
1373 5148 : describe_node (std::string ("FieldAccessExpr"), [this, &expr] () {
1374 5148 : visit (expr.get_receiver_expr ());
1375 5148 : push (Rust::Token::make (DOT, expr.get_locus ()));
1376 10296 : auto field_name = expr.get_field_name ().as_string ();
1377 5148 : push (
1378 10296 : Rust::Token::make_identifier (UNDEF_LOCATION, std::move (field_name)));
1379 5148 : });
1380 5148 : }
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 24685 : TokenCollector::visit (BlockExpr &expr)
1421 : {
1422 24685 : describe_node (std::string ("BlockExpr"), [this, &expr] () {
1423 24685 : visit_items_as_lines (expr.get_outer_attrs ());
1424 24685 : push (Rust::Token::make (LEFT_CURLY, expr.get_locus ()));
1425 24685 : newline ();
1426 24685 : increment_indentation ();
1427 24685 : visit_items_as_lines (expr.get_inner_attrs ());
1428 :
1429 24685 : visit_items_as_lines (expr.get_statements (), {});
1430 :
1431 24685 : if (expr.has_tail_expr ())
1432 : {
1433 17719 : indentation ();
1434 17719 : visit (expr.get_tail_expr ());
1435 17719 : newline ();
1436 : }
1437 :
1438 24685 : decrement_indentation ();
1439 24685 : indentation ();
1440 24685 : push (Rust::Token::make (RIGHT_CURLY, expr.get_locus ()));
1441 24685 : newline ();
1442 24685 : });
1443 24685 : }
1444 :
1445 : void
1446 937 : TokenCollector::visit (AnonConst &expr)
1447 : {
1448 937 : if (!expr.is_deferred ())
1449 : {
1450 917 : visit (expr.get_inner_expr ());
1451 917 : 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 113 : TokenCollector::visit (BreakExpr &expr)
1491 : {
1492 113 : describe_node (std::string ("BreakExpr"), [this, &expr] () {
1493 113 : push (Rust::Token::make (BREAK, expr.get_locus ()));
1494 113 : if (expr.has_label ())
1495 33 : visit (expr.get_label_unchecked ());
1496 113 : if (expr.has_break_expr ())
1497 21 : visit (expr.get_break_expr_unchecked ());
1498 113 : });
1499 113 : }
1500 :
1501 : void
1502 73 : TokenCollector::visit (RangeFromToExpr &expr)
1503 : {
1504 73 : describe_node (std::string ("RangeFromToExpr"), [this, &expr] () {
1505 73 : visit (expr.get_from_expr ());
1506 73 : push (Rust::Token::make (DOT_DOT, expr.get_locus ()));
1507 73 : visit (expr.get_to_expr ());
1508 73 : });
1509 73 : }
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 631 : TokenCollector::visit (ReturnExpr &expr)
1567 : {
1568 631 : describe_node (std::string ("ReturnExpr"), [this, &expr] () {
1569 631 : push (Rust::Token::make (RETURN_KW, expr.get_locus ()));
1570 631 : if (expr.has_returned_expr ())
1571 594 : visit (expr.get_returned_expr ());
1572 631 : });
1573 631 : }
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 3951 : TokenCollector::visit (UnsafeBlockExpr &expr)
1584 : {
1585 3951 : describe_node (std::string ("UnsafeBlockExpr"), [this, &expr] () {
1586 3951 : push (Rust::Token::make (UNSAFE, expr.get_locus ()));
1587 3951 : visit (expr.get_block_expr ());
1588 3951 : });
1589 3951 : }
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 236 : TokenCollector::visit_loop_common (BaseLoopExpr &expr)
1602 : {
1603 236 : describe_node (std::string ("BaseLoopExpr"), [this, &expr] () {
1604 236 : if (expr.has_loop_label ())
1605 51 : visit (expr.get_loop_label ());
1606 236 : });
1607 236 : }
1608 :
1609 : void
1610 147 : TokenCollector::visit (LoopExpr &expr)
1611 : {
1612 147 : describe_node (std::string ("LoopExpr"), [this, &expr] () {
1613 147 : visit_loop_common (expr);
1614 147 : push (Rust::Token::make (LOOP, expr.get_locus ()));
1615 147 : visit (expr.get_loop_block ());
1616 147 : });
1617 147 : }
1618 :
1619 : void
1620 89 : TokenCollector::visit (WhileLoopExpr &expr)
1621 : {
1622 89 : describe_node (std::string ("WhileLoopExpr"), [this, &expr] () {
1623 89 : visit_loop_common (expr);
1624 89 : push (Rust::Token::make (WHILE, expr.get_locus ()));
1625 89 : visit (expr.get_predicate_expr ());
1626 89 : visit (expr.get_loop_block ());
1627 89 : });
1628 89 : }
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 2831 : TokenCollector::visit (IfExpr &expr)
1659 : {
1660 2831 : describe_node (std::string ("IfExpr"), [this, &expr] () {
1661 2831 : push (Rust::Token::make (IF, expr.get_locus ()));
1662 :
1663 2831 : visit (expr.get_condition_expr ());
1664 2831 : visit (expr.get_if_block ());
1665 2831 : });
1666 2831 : }
1667 :
1668 : void
1669 1323 : TokenCollector::visit (IfExprConseqElse &expr)
1670 : {
1671 1323 : describe_node (std::string ("IfExprConseqElse"), [this, &expr] () {
1672 1323 : visit (static_cast<IfExpr &> (expr));
1673 1323 : indentation ();
1674 1323 : push (Rust::Token::make (ELSE, expr.get_locus ()));
1675 1323 : visit (expr.get_else_block ());
1676 1323 : });
1677 1323 : }
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 2597 : TokenCollector::visit (MatchArm &arm)
1705 : {
1706 2597 : describe_node (std::string ("MatchArm"), [this, &arm] () {
1707 2597 : visit_items_as_lines (arm.get_outer_attrs ());
1708 2597 : visit (arm.get_pattern ());
1709 2597 : if (arm.has_match_arm_guard ())
1710 : {
1711 59 : push (Rust::Token::make (IF, UNDEF_LOCATION));
1712 59 : visit (arm.get_guard_expr ());
1713 : }
1714 2597 : });
1715 2597 : }
1716 :
1717 : void
1718 2597 : TokenCollector::visit (MatchCase &match_case)
1719 : {
1720 2597 : describe_node (std::string ("MatchCase"), [this, &match_case] () {
1721 2597 : indentation ();
1722 2597 : visit (match_case.get_arm ());
1723 2597 : push (Rust::Token::make (MATCH_ARROW, UNDEF_LOCATION));
1724 2597 : visit (match_case.get_expr ());
1725 2597 : indentation ();
1726 2597 : push (Rust::Token::make (COMMA, UNDEF_LOCATION));
1727 2597 : newline ();
1728 2597 : });
1729 2597 : }
1730 :
1731 : void
1732 1113 : TokenCollector::visit (MatchExpr &expr)
1733 : {
1734 1113 : describe_node (std::string ("MatchExpr"), [this, &expr] () {
1735 1113 : push (Rust::Token::make (MATCH_KW, expr.get_locus ()));
1736 1113 : visit (expr.get_scrutinee_expr ());
1737 1113 : push (Rust::Token::make (LEFT_CURLY, UNDEF_LOCATION));
1738 1113 : newline ();
1739 1113 : increment_indentation ();
1740 1113 : visit_items_as_lines (expr.get_inner_attrs ());
1741 3710 : for (auto &arm : expr.get_match_cases ())
1742 : {
1743 2597 : visit (arm);
1744 : }
1745 1113 : decrement_indentation ();
1746 1113 : indentation ();
1747 1113 : push (Rust::Token::make (RIGHT_CURLY, UNDEF_LOCATION));
1748 1113 : });
1749 1113 : }
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 4904 : TokenCollector::visit (TypeParam ¶m)
1940 : {
1941 : // Syntax:
1942 : // IDENTIFIER( : TypeParamBounds? )? ( = Type )?
1943 : // TypeParamBounds :
1944 : // TypeParamBound ( + TypeParamBound )* +?
1945 4904 : describe_node (std::string ("TypeParam"), [this, ¶m] () {
1946 4904 : visit_items_as_lines (param.get_outer_attrs ());
1947 9808 : auto id = param.get_type_representation ().as_string ();
1948 9808 : push (Rust::Token::make_identifier (param.get_locus (), std::move (id)));
1949 4904 : if (param.has_type_param_bounds ())
1950 : {
1951 877 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
1952 877 : visit_items_joined_by_separator (param.get_type_param_bounds (), PLUS);
1953 : }
1954 4904 : if (param.has_type ())
1955 : {
1956 393 : push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
1957 393 : visit (param.get_type ());
1958 : }
1959 4904 : });
1960 4904 : }
1961 :
1962 : void
1963 320 : TokenCollector::visit (WhereClause &rule)
1964 : {
1965 : // Syntax:
1966 : // where ( WhereClauseItem , )* WhereClauseItem ?
1967 : // WhereClauseItem :
1968 : // LifetimeWhereClauseItem
1969 : // | TypeBoundWhereClauseItem
1970 320 : describe_node (std::string ("WhereClause"), [this, &rule] () {
1971 320 : push (Rust::Token::make (WHERE, UNDEF_LOCATION));
1972 320 : newline ();
1973 320 : increment_indentation ();
1974 320 : visit_items_joined_by_separator (rule.get_items (), COMMA);
1975 320 : decrement_indentation ();
1976 320 : });
1977 320 : }
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 345 : TokenCollector::visit (TypeBoundWhereClauseItem &item)
1996 : {
1997 : // Syntax:
1998 : // ForLifetimes? Type : TypeParamBounds?
1999 : // TypeParamBounds :
2000 : // TypeParamBound ( + TypeParamBound )* +?
2001 : // TypeParamBound :
2002 : // Lifetime | TraitBound
2003 :
2004 345 : describe_node (std::string ("TypeBoundWhereClauseItem"), [this, &item] () {
2005 345 : if (item.has_for_lifetimes ())
2006 7 : visit (item.get_for_lifetimes ());
2007 :
2008 345 : visit (item.get_type ());
2009 :
2010 345 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
2011 345 : visit_items_joined_by_separator (item.get_type_param_bounds (), PLUS);
2012 345 : });
2013 345 : }
2014 :
2015 : void
2016 1201 : TokenCollector::visit (Module &module)
2017 : {
2018 : // Syntax:
2019 : // mod IDENTIFIER ;
2020 : // | mod IDENTIFIER {
2021 : // InnerAttribute*
2022 : // Item*
2023 : // }
2024 1201 : describe_node (std::string ("Module"), [this, &module] () {
2025 1201 : visit_items_as_lines (module.get_outer_attrs ());
2026 1201 : visit (module.get_visibility ());
2027 2402 : auto name = module.get_name ().as_string ();
2028 1201 : push (Rust::Token::make (MOD, module.get_locus ()));
2029 2402 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (name)));
2030 :
2031 1201 : 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 1201 : push (Rust::Token::make (LEFT_CURLY, UNDEF_LOCATION));
2039 1201 : newline ();
2040 1201 : increment_indentation ();
2041 :
2042 1201 : visit_items_as_lines (module.get_inner_attrs ());
2043 1201 : visit_items_as_lines (module.get_items ());
2044 :
2045 1201 : decrement_indentation ();
2046 :
2047 1201 : push (Rust::Token::make (RIGHT_CURLY, UNDEF_LOCATION));
2048 1201 : newline ();
2049 : }
2050 1201 : });
2051 1201 : }
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 18 : TokenCollector::visit (UseTreeGlob &use_tree)
2076 : {
2077 18 : describe_node (std::string ("UseTreeGlob"), [this, &use_tree] () {
2078 18 : switch (use_tree.get_glob_type ())
2079 : {
2080 15 : case UseTreeGlob::PathType::PATH_PREFIXED:
2081 15 : {
2082 15 : auto path = use_tree.get_path ();
2083 15 : visit (path);
2084 30 : push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
2085 15 : }
2086 15 : 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 18 : push (Rust::Token::make (ASTERISK, UNDEF_LOCATION));
2094 18 : });
2095 18 : }
2096 :
2097 : void
2098 171 : TokenCollector::visit (UseTreeList &use_tree)
2099 : {
2100 171 : describe_node (std::string ("UseTreeList"), [this, &use_tree] () {
2101 171 : switch (use_tree.get_path_type ())
2102 : {
2103 171 : case UseTreeList::PathType::PATH_PREFIXED:
2104 171 : {
2105 171 : auto path = use_tree.get_path ();
2106 171 : visit (path);
2107 :
2108 342 : push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
2109 171 : }
2110 171 : 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 171 : push (Rust::Token::make (LEFT_CURLY, UNDEF_LOCATION));
2119 171 : if (use_tree.has_trees ())
2120 : {
2121 171 : visit_items_joined_by_separator (use_tree.get_trees (), COMMA);
2122 : }
2123 171 : push (Rust::Token::make (RIGHT_CURLY, UNDEF_LOCATION));
2124 171 : });
2125 171 : }
2126 :
2127 : void
2128 1135 : TokenCollector::visit (UseTreeRebind &use_tree)
2129 : {
2130 1135 : describe_node (std::string ("UseTreeRebind"), [this, &use_tree] () {
2131 1135 : auto path = use_tree.get_path ();
2132 1135 : visit (path);
2133 1135 : 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 1135 : });
2151 1135 : }
2152 :
2153 : void
2154 691 : TokenCollector::visit (UseDeclaration &decl)
2155 : {
2156 691 : describe_node (std::string ("UseDeclaration"), [this, &decl] () {
2157 691 : visit_items_as_lines (decl.get_outer_attrs ());
2158 691 : push (Rust::Token::make (USE, decl.get_locus ()));
2159 691 : visit (*decl.get_tree ());
2160 691 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2161 691 : newline ();
2162 691 : });
2163 691 : }
2164 :
2165 : void
2166 19516 : TokenCollector::visit (Function &function)
2167 : {
2168 : // Syntax:
2169 : // FunctionQualifiers fn IDENTIFIER GenericParams?
2170 : // ( FunctionParameters? )
2171 : // FunctionReturnType? WhereClause?
2172 : // ( BlockExpression | ; )
2173 19516 : describe_node (std::string ("Function"), [this, &function] () {
2174 19516 : visit_items_as_lines (function.get_outer_attrs ());
2175 :
2176 19516 : visit (function.get_visibility ());
2177 19516 : auto qualifiers = function.get_qualifiers ();
2178 19516 : visit (qualifiers);
2179 :
2180 19516 : push (Rust::Token::make (FN_KW, function.get_locus ()));
2181 39032 : auto name = function.get_function_name ().as_string ();
2182 39032 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (name)));
2183 19516 : if (function.has_generics ())
2184 1808 : visit (function.get_generic_params ());
2185 :
2186 19516 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
2187 :
2188 19516 : visit_items_joined_by_separator (function.get_function_params ());
2189 19516 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
2190 :
2191 19516 : if (function.has_return_type ())
2192 : {
2193 14244 : push (Rust::Token::make (RETURN_TYPE, UNDEF_LOCATION));
2194 14244 : visit (function.get_return_type ());
2195 : }
2196 :
2197 19516 : if (function.has_where_clause ())
2198 212 : visit (function.get_where_clause ());
2199 :
2200 19516 : if (function.has_body ())
2201 15071 : visit (*function.get_definition ());
2202 : else
2203 8890 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2204 19516 : newline ();
2205 19516 : });
2206 19516 : }
2207 :
2208 : void
2209 1465 : 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 1465 : describe_node (std::string ("TypeAlias"), [this, &type_alias] () {
2216 1465 : visit_items_as_lines (type_alias.get_outer_attrs ());
2217 1465 : if (type_alias.has_visibility ())
2218 16 : visit (type_alias.get_visibility ());
2219 2930 : auto alias_name = type_alias.get_new_type_name ().as_string ();
2220 1465 : push (Rust::Token::make (TYPE, type_alias.get_locus ()));
2221 1465 : push (
2222 2930 : Rust::Token::make_identifier (UNDEF_LOCATION, std::move (alias_name)));
2223 :
2224 1465 : if (type_alias.has_generics ())
2225 23 : visit (type_alias.get_generic_params ());
2226 :
2227 1465 : if (type_alias.has_where_clause ())
2228 0 : visit (type_alias.get_where_clause ());
2229 :
2230 1465 : push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
2231 1465 : visit (type_alias.get_type_aliased ());
2232 2930 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2233 1465 : });
2234 1465 : }
2235 :
2236 : void
2237 0 : TokenCollector::visit (TraitAlias &trait_alias)
2238 : {
2239 : // Syntax:
2240 : // Visibility? trait IDENTIFIER GenericParams? = TypeBounds? WhereClause?;
2241 : // https://github.com/rust-lang/rfcs/blob/main/text/1733-trait-alias.md
2242 0 : describe_node (std::string ("TraitAlias"), [this, &trait_alias] () {
2243 0 : visit_items_as_lines (trait_alias.get_outer_attrs ());
2244 0 : if (trait_alias.has_visibility ())
2245 0 : visit (trait_alias.get_visibility ());
2246 0 : auto alias_name = trait_alias.get_alias_name ().as_string ();
2247 0 : push (Rust::Token::make (TRAIT, trait_alias.get_locus ()));
2248 0 : push (
2249 0 : Rust::Token::make_identifier (UNDEF_LOCATION, std::move (alias_name)));
2250 :
2251 0 : if (trait_alias.has_generics ())
2252 0 : visit (trait_alias.get_generic_params ());
2253 :
2254 0 : push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
2255 :
2256 0 : visit_items_joined_by_separator (trait_alias.get_alias_bounds (), PLUS);
2257 :
2258 0 : if (trait_alias.has_where_clause ())
2259 0 : visit (trait_alias.get_where_clause ());
2260 :
2261 0 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2262 0 : });
2263 0 : }
2264 :
2265 : void
2266 1592 : TokenCollector::visit (StructStruct &struct_item)
2267 : {
2268 1592 : describe_node (std::string ("StructStruct"), [this, &struct_item] () {
2269 1592 : visit_items_as_lines (struct_item.get_outer_attrs ());
2270 1592 : if (struct_item.has_visibility ())
2271 377 : visit (struct_item.get_visibility ());
2272 3184 : auto struct_name = struct_item.get_identifier ().as_string ();
2273 1592 : push (Rust::Token::make (STRUCT_KW, struct_item.get_locus ()));
2274 1592 : push (
2275 3184 : Rust::Token::make_identifier (UNDEF_LOCATION, std::move (struct_name)));
2276 :
2277 1592 : if (struct_item.has_generics ())
2278 513 : visit (struct_item.get_generic_params ());
2279 1592 : if (struct_item.has_where_clause ())
2280 5 : visit (struct_item.get_where_clause ());
2281 1592 : if (struct_item.is_unit_struct ())
2282 : {
2283 556 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2284 556 : newline ();
2285 : }
2286 : else
2287 2072 : visit_items_as_block (struct_item.get_fields (),
2288 : {Rust::Token::make (COMMA, UNDEF_LOCATION)});
2289 1592 : });
2290 1592 : }
2291 :
2292 : void
2293 982 : TokenCollector::visit (TupleStruct &tuple_struct)
2294 : {
2295 982 : describe_node (std::string ("TupleStruct"), [this, &tuple_struct] () {
2296 982 : visit_items_as_lines (tuple_struct.get_outer_attrs ());
2297 1964 : auto struct_name = tuple_struct.get_identifier ().as_string ();
2298 982 : push (Rust::Token::make (STRUCT_KW, tuple_struct.get_locus ()));
2299 982 : push (
2300 1964 : Rust::Token::make_identifier (UNDEF_LOCATION, std::move (struct_name)));
2301 982 : if (tuple_struct.has_generics ())
2302 296 : visit (tuple_struct.get_generic_params ());
2303 982 : if (tuple_struct.has_where_clause ())
2304 0 : visit (tuple_struct.get_where_clause ());
2305 :
2306 982 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
2307 982 : visit_items_joined_by_separator (tuple_struct.get_fields (), COMMA);
2308 982 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
2309 982 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2310 982 : newline ();
2311 982 : });
2312 982 : }
2313 :
2314 : void
2315 449 : TokenCollector::visit (EnumItem &item)
2316 : {
2317 449 : describe_node (std::string ("EnumItem"), [this, &item] () {
2318 449 : visit_items_as_lines (item.get_outer_attrs ());
2319 898 : auto id = item.get_identifier ().as_string ();
2320 898 : push (Rust::Token::make_identifier (item.get_locus (), std::move (id)));
2321 449 : });
2322 449 : }
2323 :
2324 : void
2325 432 : TokenCollector::visit (EnumItemTuple &item)
2326 : {
2327 432 : describe_node (std::string ("EnumItemTuple"), [this, &item] () {
2328 864 : auto id = item.get_identifier ().as_string ();
2329 864 : push (Rust::Token::make_identifier (item.get_locus (), std::move (id)));
2330 432 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
2331 432 : visit_items_joined_by_separator (item.get_tuple_fields (), COMMA);
2332 864 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
2333 432 : });
2334 432 : }
2335 :
2336 : void
2337 79 : TokenCollector::visit (EnumItemStruct &item)
2338 : {
2339 79 : describe_node (std::string ("EnumItemStruct"), [this, &item] () {
2340 158 : auto id = item.get_identifier ().as_string ();
2341 158 : push (Rust::Token::make_identifier (item.get_locus (), std::move (id)));
2342 158 : visit_items_as_block (item.get_struct_fields (),
2343 : {Rust::Token::make (COMMA, UNDEF_LOCATION)});
2344 79 : });
2345 79 : }
2346 :
2347 : void
2348 279 : TokenCollector::visit (EnumItemDiscriminant &item)
2349 : {
2350 279 : describe_node (std::string ("EnumItemDiscriminant"), [this, &item] () {
2351 558 : auto id = item.get_identifier ().as_string ();
2352 558 : push (Rust::Token::make_identifier (item.get_locus (), std::move (id)));
2353 279 : push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
2354 279 : visit (item.get_expr ());
2355 279 : });
2356 279 : }
2357 :
2358 : void
2359 528 : TokenCollector::visit (Enum &enumeration)
2360 : {
2361 528 : describe_node (std::string ("Enum"), [this, &enumeration] () {
2362 528 : visit_items_as_lines (enumeration.get_outer_attrs ());
2363 528 : if (enumeration.has_visibility ())
2364 279 : visit (enumeration.get_visibility ());
2365 528 : push (Rust::Token::make (ENUM_KW, enumeration.get_locus ()));
2366 1056 : auto id = enumeration.get_identifier ().as_string ();
2367 528 : push (
2368 1056 : Rust::Token::make_identifier (enumeration.get_locus (), std::move (id)));
2369 528 : if (enumeration.has_generics ())
2370 243 : visit (enumeration.get_generic_params ());
2371 528 : if (enumeration.has_where_clause ())
2372 0 : visit (enumeration.get_where_clause ());
2373 :
2374 1056 : visit_items_as_block (enumeration.get_variants (),
2375 : {Rust::Token::make (COMMA, UNDEF_LOCATION)});
2376 528 : });
2377 528 : }
2378 :
2379 : void
2380 101 : TokenCollector::visit (Union &union_item)
2381 : {
2382 101 : describe_node (std::string ("Union"), [this, &union_item] () {
2383 101 : visit_items_as_lines (union_item.get_outer_attrs ());
2384 202 : auto id = union_item.get_identifier ().as_string ();
2385 202 : push (Rust::Token::make_identifier (union_item.get_locus (),
2386 101 : Values::WeakKeywords::UNION));
2387 202 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2388 :
2389 101 : if (union_item.has_generics ())
2390 74 : visit (union_item.get_generic_params ());
2391 :
2392 101 : if (union_item.has_where_clause ())
2393 0 : visit (union_item.get_where_clause ());
2394 :
2395 202 : visit_items_as_block (union_item.get_variants (),
2396 : {Rust::Token::make (COMMA, UNDEF_LOCATION)});
2397 101 : });
2398 101 : }
2399 :
2400 : void
2401 552 : TokenCollector::visit (ConstantItem &item)
2402 : {
2403 552 : describe_node (std::string ("ConstantItem"), [this, &item] () {
2404 552 : visit_items_as_lines (item.get_outer_attrs ());
2405 552 : push (Rust::Token::make (CONST, item.get_locus ()));
2406 552 : if (item.is_unnamed ())
2407 : {
2408 12 : push (Rust::Token::make (UNDERSCORE, UNDEF_LOCATION));
2409 : }
2410 : else
2411 : {
2412 1092 : push (Rust::Token::make_identifier (item.get_identifier ()));
2413 : }
2414 552 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
2415 552 : visit (item.get_type ());
2416 552 : if (item.has_expr ())
2417 : {
2418 528 : push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
2419 528 : visit (item.get_expr ());
2420 : }
2421 552 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2422 552 : });
2423 552 : }
2424 :
2425 : void
2426 70 : TokenCollector::visit (StaticItem &item)
2427 : {
2428 70 : describe_node (std::string ("StaticItem"), [this, &item] () {
2429 70 : visit_items_as_lines (item.get_outer_attrs ());
2430 70 : push (Rust::Token::make (STATIC_KW, item.get_locus ()));
2431 70 : if (item.is_mutable ())
2432 34 : push (Rust::Token::make (MUT, UNDEF_LOCATION));
2433 :
2434 140 : auto id = item.get_identifier ().as_string ();
2435 140 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2436 70 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
2437 :
2438 70 : visit (item.get_type ());
2439 :
2440 70 : if (item.has_expr ())
2441 : {
2442 70 : push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
2443 70 : visit (item.get_expr ());
2444 : }
2445 140 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2446 70 : });
2447 70 : }
2448 :
2449 : void
2450 0 : TokenCollector::visit_function_common (std::unique_ptr<Type> &return_type,
2451 : std::unique_ptr<BlockExpr> &block)
2452 : {
2453 : // FIXME: This should format the `<vis> fn <name> ( [args] )` as well
2454 0 : if (return_type)
2455 : {
2456 0 : push (Rust::Token::make (RETURN_TYPE, UNDEF_LOCATION));
2457 0 : visit (return_type);
2458 : }
2459 :
2460 0 : if (block)
2461 : {
2462 0 : visit (block);
2463 : }
2464 : else
2465 : {
2466 0 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2467 0 : newline ();
2468 : }
2469 0 : }
2470 :
2471 : void
2472 8761 : TokenCollector::visit (SelfParam ¶m)
2473 : {
2474 8761 : describe_node (std::string ("SelfParam"), [this, ¶m] () {
2475 8761 : if (param.get_has_ref ())
2476 : {
2477 5190 : push (Rust::Token::make (AMP, UNDEF_LOCATION));
2478 5190 : if (param.has_lifetime ())
2479 : {
2480 4931 : auto lifetime = param.get_lifetime ();
2481 4931 : visit (lifetime);
2482 4931 : }
2483 5190 : if (param.get_is_mut ())
2484 906 : push (Rust::Token::make (MUT, UNDEF_LOCATION));
2485 : }
2486 8761 : push (Rust::Token::make (SELF, UNDEF_LOCATION));
2487 8761 : if (param.has_type ())
2488 : {
2489 3 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
2490 3 : visit (param.get_type ());
2491 : }
2492 8761 : });
2493 8761 : }
2494 :
2495 : void
2496 797 : TokenCollector::visit (TraitItemType &item)
2497 : {
2498 797 : describe_node (std::string ("TraitItemType"), [this, &item] () {
2499 797 : visit_items_as_lines (item.get_outer_attrs ());
2500 1594 : auto id = item.get_identifier ().as_string ();
2501 797 : indentation ();
2502 :
2503 797 : push (Rust::Token::make (TYPE, item.get_locus ()));
2504 1594 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2505 797 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2506 797 : newline ();
2507 797 : });
2508 797 : }
2509 :
2510 : void
2511 3990 : TokenCollector::visit (Trait &trait)
2512 : {
2513 3990 : describe_node (std::string ("Trait"), [this, &trait] () {
2514 7958 : for (auto &attr : trait.get_outer_attrs ())
2515 : {
2516 3968 : visit (attr);
2517 3968 : newline ();
2518 3968 : indentation ();
2519 : }
2520 :
2521 3990 : visit (trait.get_visibility ());
2522 :
2523 7980 : auto id = trait.get_identifier ().as_string ();
2524 3990 : push (Rust::Token::make (TRAIT, trait.get_locus ()));
2525 7980 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2526 :
2527 3990 : if (trait.has_generics ())
2528 686 : visit (trait.get_generic_params ());
2529 3990 : if (!trait.get_type_param_bounds ().empty ())
2530 1092 : push (Rust::Token::make ((COLON), trait.get_locus ()));
2531 3990 : visit_items_joined_by_separator (trait.get_type_param_bounds (), PLUS);
2532 :
2533 3990 : visit_items_as_block (trait.get_trait_items (), {});
2534 3990 : });
2535 3990 : }
2536 :
2537 : void
2538 1011 : TokenCollector::visit (InherentImpl &impl)
2539 : {
2540 1011 : describe_node (std::string ("InherentImpl"), [this, &impl] () {
2541 1011 : visit_items_as_lines (impl.get_outer_attrs ());
2542 1011 : push (Rust::Token::make (IMPL, impl.get_locus ()));
2543 1011 : visit (impl.get_generic_params ());
2544 :
2545 1011 : visit (impl.get_type ());
2546 :
2547 1011 : if (impl.has_where_clause ())
2548 0 : visit (impl.get_where_clause ());
2549 :
2550 : // FIXME: Handle inner attributes
2551 :
2552 1011 : visit_items_as_block (impl.get_impl_items (), {});
2553 1011 : });
2554 1011 : }
2555 :
2556 : void
2557 5048 : TokenCollector::visit (TraitImpl &impl)
2558 : {
2559 5048 : describe_node (std::string ("TraitImpl"), [this, &impl] () {
2560 5048 : visit_items_as_lines (impl.get_outer_attrs ());
2561 5048 : push (Rust::Token::make (IMPL, impl.get_locus ()));
2562 5048 : visit (impl.get_generic_params ());
2563 5048 : if (impl.is_exclam ())
2564 12 : push (Rust::Token::make (EXCLAM, UNDEF_LOCATION));
2565 5048 : visit (impl.get_trait_path ());
2566 5048 : push (Rust::Token::make (FOR, UNDEF_LOCATION));
2567 5048 : visit (impl.get_type ());
2568 :
2569 5048 : if (impl.has_where_clause ())
2570 103 : visit (impl.get_where_clause ());
2571 5048 : });
2572 5048 : visit_items_as_block (impl.get_impl_items ());
2573 5048 : }
2574 :
2575 : void
2576 2 : TokenCollector::visit (ExternalTypeItem &type)
2577 : {
2578 2 : describe_node (std::string ("ExternalTypeItem"), [this, &type] () {
2579 2 : visit (type.get_visibility ());
2580 :
2581 4 : auto id = type.get_identifier ().as_string ();
2582 :
2583 2 : push (Rust::Token::make (TYPE, UNDEF_LOCATION));
2584 4 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2585 4 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2586 2 : });
2587 2 : }
2588 :
2589 : void
2590 0 : TokenCollector::visit (ExternalStaticItem &item)
2591 : {
2592 0 : describe_node (std::string ("ExternalStaticItem"), [this, &item] () {
2593 0 : auto id = item.get_identifier ().as_string ();
2594 0 : visit_items_as_lines (item.get_outer_attrs ());
2595 0 : if (item.has_visibility ())
2596 0 : visit (item.get_visibility ());
2597 0 : push (Rust::Token::make (STATIC_KW, item.get_locus ()));
2598 0 : if (item.is_mut ())
2599 0 : push (Rust::Token::make (MUT, UNDEF_LOCATION));
2600 0 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2601 0 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
2602 0 : visit (item.get_type ());
2603 : // TODO: No expr ? The "(= Expression)?" part from the reference seems
2604 : // missing in the ast.
2605 0 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2606 0 : });
2607 0 : }
2608 :
2609 : void
2610 1676 : TokenCollector::visit (ExternBlock &block)
2611 : {
2612 1676 : describe_node (std::string ("ExternBlock"), [this, &block] () {
2613 1676 : visit_items_as_lines (block.get_outer_attrs ());
2614 1676 : push (Rust::Token::make (EXTERN_KW, block.get_locus ()));
2615 :
2616 1676 : if (block.has_abi ())
2617 : {
2618 1675 : auto abi = block.get_abi ();
2619 3350 : push (Rust::Token::make_string (UNDEF_LOCATION, std::move (abi)));
2620 1675 : }
2621 :
2622 1676 : visit_items_as_block (block.get_extern_items (), {});
2623 1676 : });
2624 1676 : }
2625 :
2626 : static std::pair<TokenId, TokenId>
2627 1175 : get_delimiters (DelimType delim)
2628 : {
2629 1175 : switch (delim)
2630 : {
2631 1118 : case PARENS:
2632 1118 : return {LEFT_PAREN, RIGHT_PAREN};
2633 43 : case SQUARE:
2634 43 : return {LEFT_SQUARE, RIGHT_SQUARE};
2635 14 : case CURLY:
2636 14 : return {LEFT_CURLY, RIGHT_CURLY};
2637 0 : default:
2638 0 : rust_unreachable ();
2639 : }
2640 : }
2641 :
2642 : void
2643 974 : TokenCollector::visit (MacroMatchFragment &match)
2644 : {
2645 974 : describe_node (std::string ("MacroMatchFragment"), [this, &match] () {
2646 1948 : auto id = match.get_ident ().as_string ();
2647 974 : auto frag_spec = match.get_frag_spec ().as_string ();
2648 974 : push (Rust::Token::make (DOLLAR_SIGN, UNDEF_LOCATION));
2649 1948 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2650 974 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
2651 1948 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (frag_spec)));
2652 974 : });
2653 974 : }
2654 :
2655 : void
2656 542 : TokenCollector::visit (MacroMatchRepetition &repetition)
2657 : {
2658 542 : describe_node (std::string ("MacroMatchRepetition"), [this, &repetition] () {
2659 542 : push (Rust::Token::make (DOLLAR_SIGN, UNDEF_LOCATION));
2660 542 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
2661 :
2662 1196 : for (auto &match : repetition.get_matches ())
2663 : {
2664 654 : visit (match);
2665 : }
2666 :
2667 542 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
2668 :
2669 542 : if (repetition.has_sep ())
2670 : {
2671 262 : push (Rust::Token::make (repetition.get_sep ()->get_id (),
2672 131 : repetition.get_sep ()->get_locus ()));
2673 : }
2674 542 : switch (repetition.get_op ())
2675 : {
2676 476 : case MacroMatchRepetition::ANY:
2677 476 : push (Rust::Token::make (ASTERISK, UNDEF_LOCATION));
2678 476 : break;
2679 33 : case MacroMatchRepetition::ONE_OR_MORE:
2680 33 : push (Rust::Token::make (PLUS, UNDEF_LOCATION));
2681 33 : break;
2682 33 : case MacroMatchRepetition::ZERO_OR_ONE:
2683 33 : push (Rust::Token::make (QUESTION_MARK, UNDEF_LOCATION));
2684 33 : break;
2685 : case MacroMatchRepetition::NONE:
2686 : break;
2687 : }
2688 542 : });
2689 542 : }
2690 :
2691 : void
2692 1175 : TokenCollector::visit (MacroMatcher &matcher)
2693 : {
2694 1175 : describe_node (std::string ("MacroMatcher"), [this, &matcher] () {
2695 1175 : auto delimiters = get_delimiters (matcher.get_delim_type ());
2696 :
2697 1175 : push (Rust::Token::make (delimiters.first, UNDEF_LOCATION));
2698 :
2699 2583 : for (auto &item : matcher.get_matches ())
2700 : {
2701 1408 : visit (item);
2702 : }
2703 :
2704 1175 : push (Rust::Token::make (delimiters.second, UNDEF_LOCATION));
2705 1175 : });
2706 1175 : }
2707 :
2708 : void
2709 1108 : TokenCollector::visit (MacroRule &rule)
2710 : {
2711 1108 : describe_node (std::string ("MacroRule"), [this, &rule] () {
2712 1108 : visit (rule.get_matcher ());
2713 1108 : push (Rust::Token::make (MATCH_ARROW, rule.get_locus ()));
2714 1108 : visit (rule.get_transcriber ().get_token_tree ());
2715 1108 : });
2716 1108 : }
2717 :
2718 : void
2719 970 : TokenCollector::visit (MacroRulesDefinition &rules_def)
2720 : {
2721 970 : describe_node (std::string ("MacroRulesDefinition"), [this, &rules_def] () {
2722 1113 : for (auto &outer_attr : rules_def.get_outer_attrs ())
2723 143 : visit (outer_attr);
2724 :
2725 1940 : auto rule_name = rules_def.get_rule_name ().as_string ();
2726 :
2727 1940 : push (Rust::Token::make_identifier (rules_def.get_locus (),
2728 970 : Values::WeakKeywords::MACRO_RULES));
2729 970 : push (Rust::Token::make (EXCLAM, UNDEF_LOCATION));
2730 :
2731 1940 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (rule_name)));
2732 :
2733 1940 : visit_items_as_block (rules_def.get_rules (),
2734 : {Rust::Token::make (SEMICOLON, UNDEF_LOCATION)});
2735 970 : });
2736 970 : }
2737 :
2738 : void
2739 175 : TokenCollector::visit (MacroInvocation &invocation)
2740 : {
2741 175 : describe_node (std::string ("MacroInvocation"), [this, &invocation] () {
2742 175 : auto data = invocation.get_invoc_data ();
2743 175 : visit (data.get_path ());
2744 175 : push (Rust::Token::make (EXCLAM, UNDEF_LOCATION));
2745 175 : visit (data.get_delim_tok_tree ());
2746 175 : if (invocation.has_semicolon ())
2747 348 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2748 175 : });
2749 175 : }
2750 :
2751 : void
2752 0 : TokenCollector::visit (MetaItemPath &item)
2753 : {
2754 0 : describe_node (std::string ("MetaItemPath"), [this, &item] () {
2755 0 : auto path = item.to_path_item ();
2756 0 : visit (path);
2757 0 : });
2758 0 : }
2759 :
2760 : void
2761 14 : TokenCollector::visit (MetaItemSeq &item)
2762 : {
2763 14 : describe_node (std::string ("MetaItemSeq"), [this, &item] () {
2764 14 : visit (item.get_path ());
2765 : // TODO: Double check this, there is probably a mistake.
2766 14 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
2767 14 : visit_items_joined_by_separator (item.get_seq (), COMMA);
2768 14 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
2769 14 : });
2770 14 : }
2771 :
2772 : void
2773 42 : TokenCollector::visit (MetaWord &word)
2774 : {
2775 42 : describe_node (std::string ("MetaWord"), [this, &word] () {
2776 42 : auto id = word.get_ident ().as_string ();
2777 :
2778 84 : push (Rust::Token::make_identifier (word.get_locus (), std::move (id)));
2779 42 : });
2780 42 : }
2781 :
2782 : void
2783 388 : TokenCollector::visit (MetaNameValueStr &name)
2784 : {
2785 388 : describe_node (std::string ("MetaNameValueStr"), [this, &name] () {
2786 388 : auto pair = name.get_name_value_pair ();
2787 388 : auto id = std::get<0> (pair).as_string ();
2788 388 : auto value = std::get<1> (pair);
2789 :
2790 776 : push (Rust::Token::make_identifier (name.get_locus (), std::move (id)));
2791 388 : push (Rust::Token::make (EQUAL, name.get_locus ()));
2792 388 : push (Rust::Token::make (DOUBLE_QUOTE, UNDEF_LOCATION));
2793 776 : push (Rust::Token::make_identifier (name.get_locus (), std::move (value)));
2794 776 : push (Rust::Token::make (DOUBLE_QUOTE, UNDEF_LOCATION));
2795 388 : });
2796 388 : }
2797 :
2798 : void
2799 0 : TokenCollector::visit (MetaListPaths &list)
2800 : {
2801 0 : describe_node (std::string ("MetaListPath"), [this, &list] () {
2802 0 : auto id = list.get_ident ().as_string ();
2803 :
2804 0 : push (Rust::Token::make_identifier (list.get_locus (), std::move (id)));
2805 0 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
2806 :
2807 0 : visit_items_joined_by_separator (list.get_paths (), COMMA);
2808 :
2809 0 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
2810 0 : });
2811 0 : }
2812 :
2813 : void
2814 0 : TokenCollector::visit (MetaListNameValueStr &list)
2815 : {
2816 0 : describe_node (std::string ("MetaListNameValueStr"), [this, &list] () {
2817 0 : auto id = list.get_ident ().as_string ();
2818 :
2819 0 : push (Rust::Token::make_identifier (list.get_locus (), std::move (id)));
2820 0 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
2821 :
2822 0 : visit_items_joined_by_separator (list.get_values (), COMMA);
2823 :
2824 0 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
2825 0 : });
2826 0 : }
2827 :
2828 : // rust-pattern.h
2829 : void
2830 477 : TokenCollector::visit (LiteralPattern &pattern)
2831 : {
2832 477 : describe_node (std::string ("LiteralPattern"), [this, &pattern] () {
2833 477 : visit (pattern.get_literal (), pattern.get_locus ());
2834 477 : });
2835 477 : }
2836 :
2837 : void
2838 25784 : TokenCollector::visit (IdentifierPattern &pattern)
2839 : {
2840 25784 : describe_node (std::string ("IdentifierPattern"), [this, &pattern] () {
2841 25784 : if (pattern.get_is_ref ())
2842 : {
2843 4 : push (Rust::Token::make (REF, pattern.get_locus ()));
2844 : }
2845 25784 : if (pattern.get_is_mut ())
2846 : {
2847 2044 : push (Rust::Token::make (MUT, UNDEF_LOCATION));
2848 : }
2849 :
2850 51568 : auto id = pattern.get_ident ().as_string ();
2851 51568 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2852 :
2853 25784 : if (pattern.has_subpattern ())
2854 : {
2855 27 : push (Rust::Token::make (PATTERN_BIND, UNDEF_LOCATION));
2856 27 : visit (pattern.get_subpattern ());
2857 : }
2858 25784 : });
2859 25784 : }
2860 :
2861 : void
2862 1187 : TokenCollector::visit (WildcardPattern &pattern)
2863 : {
2864 1187 : describe_node (std::string ("WildcardPattern"), [this, &pattern] () {
2865 1187 : push (Rust::Token::make (UNDERSCORE, pattern.get_locus ()));
2866 1187 : });
2867 1187 : }
2868 :
2869 : void
2870 44 : TokenCollector::visit (RestPattern &pattern)
2871 : {
2872 44 : describe_node (std::string ("RestPattern"), [this, &pattern] () {
2873 44 : push (Rust::Token::make (DOT_DOT, pattern.get_locus ()));
2874 44 : });
2875 44 : }
2876 :
2877 : // void TokenCollector::visit(RangePatternBound& ){}
2878 :
2879 : void
2880 61 : TokenCollector::visit (RangePatternBoundLiteral &pattern)
2881 : {
2882 61 : describe_node (std::string ("RangePatternBoundLiteral"), [this, &pattern] () {
2883 61 : if (pattern.get_has_minus ())
2884 : {
2885 48 : push (Rust::Token::make (MINUS, pattern.get_locus ()));
2886 : }
2887 61 : auto literal = pattern.get_literal ();
2888 61 : visit (literal);
2889 61 : });
2890 61 : }
2891 :
2892 : void
2893 21 : TokenCollector::visit (RangePatternBoundPath &pattern)
2894 : {
2895 21 : describe_node (std::string ("RangePatternBoundPath"),
2896 42 : [this, &pattern] () { visit (pattern.get_path ()); });
2897 21 : }
2898 :
2899 : void
2900 0 : TokenCollector::visit (RangePatternBoundQualPath &pattern)
2901 : {
2902 0 : describe_node (std::string ("RangePatternBoundQualPath"),
2903 0 : [this, &pattern] () {
2904 0 : visit (pattern.get_qualified_path ());
2905 : });
2906 0 : }
2907 :
2908 : void
2909 41 : TokenCollector::visit (RangePattern &pattern)
2910 : {
2911 41 : describe_node (std::string ("RangePattern"), [this, &pattern] () {
2912 41 : if (pattern.get_has_lower_bound () && pattern.get_has_upper_bound ())
2913 : {
2914 41 : visit (pattern.get_lower_bound ());
2915 41 : if (pattern.get_has_ellipsis_syntax ())
2916 0 : push (Rust::Token::make (ELLIPSIS, pattern.get_locus ()));
2917 : else
2918 82 : push (Rust::Token::make (DOT_DOT_EQ, pattern.get_locus ()));
2919 41 : visit (pattern.get_upper_bound ());
2920 : }
2921 0 : else if (pattern.get_has_lower_bound ())
2922 : {
2923 0 : visit (pattern.get_lower_bound ());
2924 0 : push (Rust::Token::make (DOT_DOT, pattern.get_locus ()));
2925 : }
2926 : else
2927 : {
2928 0 : push (Rust::Token::make (DOT_DOT_EQ, pattern.get_locus ()));
2929 0 : visit (pattern.get_upper_bound ());
2930 : }
2931 41 : });
2932 41 : }
2933 :
2934 : void
2935 198 : TokenCollector::visit (ReferencePattern &pattern)
2936 :
2937 : {
2938 198 : describe_node (std::string ("ReferencePattern"), [this, &pattern] () {
2939 198 : if (pattern.is_double_reference ())
2940 : {
2941 20 : push (Rust::Token::make (LOGICAL_AND, pattern.get_locus ()));
2942 : }
2943 : else
2944 : {
2945 376 : push (Rust::Token::make (AMP, pattern.get_locus ()));
2946 : }
2947 :
2948 198 : if (pattern.get_is_mut ())
2949 : {
2950 0 : push (Rust::Token::make (MUT, UNDEF_LOCATION));
2951 : }
2952 :
2953 198 : visit (pattern.get_referenced_pattern ());
2954 198 : });
2955 198 : }
2956 :
2957 : // void TokenCollector::visit(StructPatternField& ){}
2958 :
2959 : void
2960 26 : TokenCollector::visit (StructPatternFieldTuplePat &pattern)
2961 : {
2962 26 : describe_node (std::string ("StructPatternFieldTuplePat"), [this,
2963 : &pattern] () {
2964 26 : visit_items_as_lines (pattern.get_outer_attrs ());
2965 26 : auto str = std::to_string (pattern.get_index ());
2966 26 : auto suffix_start = str.length ();
2967 52 : push (Rust::Token::make_int (pattern.get_locus (), str, suffix_start,
2968 : IntegerLiteralBase::Decimal));
2969 26 : push (Rust::Token::make (COLON, pattern.get_locus ()));
2970 26 : visit (pattern.get_index_pattern ());
2971 26 : });
2972 26 : }
2973 :
2974 : void
2975 148 : TokenCollector::visit (StructPatternFieldIdentPat &pattern)
2976 : {
2977 148 : describe_node (std::string ("StructPatternFieldIdentPat"), [this,
2978 : &pattern] () {
2979 148 : visit_items_as_lines (pattern.get_outer_attrs ());
2980 :
2981 148 : auto id = pattern.get_identifier ().as_string ();
2982 296 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2983 :
2984 148 : push (Rust::Token::make (COLON, pattern.get_locus ()));
2985 :
2986 148 : visit (pattern.get_ident_pattern ());
2987 148 : });
2988 148 : }
2989 :
2990 : void
2991 99 : TokenCollector::visit (StructPatternFieldIdent &pattern)
2992 : {
2993 99 : describe_node (std::string ("StructPatternFieldIdent"), [this, &pattern] () {
2994 99 : visit_items_as_lines (pattern.get_outer_attrs ());
2995 99 : if (pattern.is_ref ())
2996 0 : push (Rust::Token::make (REF, UNDEF_LOCATION));
2997 99 : if (pattern.is_mut ())
2998 4 : push (Rust::Token::make (MUT, UNDEF_LOCATION));
2999 :
3000 99 : auto id = pattern.get_identifier ().as_string ();
3001 198 : push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
3002 99 : });
3003 99 : }
3004 :
3005 : void
3006 173 : TokenCollector::visit (StructPattern &pattern)
3007 : {
3008 173 : describe_node (std::string ("StructPattern"), [this, &pattern] () {
3009 173 : visit (pattern.get_path ());
3010 173 : push (Rust::Token::make (LEFT_CURLY, pattern.get_locus ()));
3011 173 : auto elems = pattern.get_struct_pattern_elems ();
3012 173 : if (elems.has_struct_pattern_fields ())
3013 : {
3014 172 : visit_items_joined_by_separator (elems.get_struct_pattern_fields ());
3015 172 : if (elems.has_rest ())
3016 : {
3017 13 : push (Rust::Token::make (COMMA, UNDEF_LOCATION));
3018 13 : visit_items_as_lines (elems.get_etc_outer_attrs ());
3019 : }
3020 : }
3021 : else
3022 : {
3023 1 : visit_items_as_lines (elems.get_etc_outer_attrs ());
3024 : }
3025 :
3026 346 : push (Rust::Token::make (RIGHT_CURLY, UNDEF_LOCATION));
3027 173 : });
3028 173 : }
3029 :
3030 : // void TokenCollector::visit(TupleStructItems& ){}
3031 :
3032 : void
3033 1004 : TokenCollector::visit (TupleStructItemsNoRest &pattern)
3034 : {
3035 1004 : describe_node (std::string ("TupleStructItemsNoRange"), [this, &pattern] () {
3036 1004 : visit_items_joined_by_separator (pattern.get_patterns ());
3037 1004 : });
3038 1004 : }
3039 :
3040 : void
3041 36 : TokenCollector::visit (TupleStructItemsHasRest &pattern)
3042 : {
3043 36 : describe_node (std::string ("TupleStructItemsRange"), [this, &pattern] () {
3044 65 : for (auto &lower : pattern.get_lower_patterns ())
3045 : {
3046 29 : visit (lower);
3047 : }
3048 36 : push (Rust::Token::make (DOT_DOT, UNDEF_LOCATION));
3049 65 : for (auto &upper : pattern.get_lower_patterns ())
3050 : {
3051 29 : visit (upper);
3052 : }
3053 36 : });
3054 36 : }
3055 :
3056 : void
3057 1040 : TokenCollector::visit (TupleStructPattern &pattern)
3058 : {
3059 1040 : describe_node (std::string ("TupleStructPattern"), [this, &pattern] () {
3060 1040 : visit (pattern.get_path ());
3061 1040 : push (Rust::Token::make (LEFT_PAREN, pattern.get_locus ()));
3062 1040 : visit (pattern.get_items ());
3063 1040 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
3064 1040 : });
3065 1040 : }
3066 :
3067 : // void
3068 : // TokenCollector::visit (TuplePatternItems &)
3069 : // {}
3070 :
3071 : void
3072 519 : TokenCollector::visit (TuplePatternItemsNoRest &pattern)
3073 : {
3074 519 : describe_node (std::string ("TuplePatternItemsMultiple"), [this,
3075 : &pattern] () {
3076 519 : visit_items_joined_by_separator (pattern.get_patterns (), COMMA);
3077 519 : });
3078 519 : }
3079 :
3080 : void
3081 31 : TokenCollector::visit (TuplePatternItemsHasRest &pattern)
3082 : {
3083 31 : describe_node (std::string ("TuplePatternItemsRanged"), [this, &pattern] () {
3084 58 : for (auto &lower : pattern.get_lower_patterns ())
3085 : {
3086 27 : visit (lower);
3087 : }
3088 31 : push (Rust::Token::make (DOT_DOT, UNDEF_LOCATION));
3089 58 : for (auto &upper : pattern.get_lower_patterns ())
3090 : {
3091 27 : visit (upper);
3092 : }
3093 31 : });
3094 31 : }
3095 :
3096 : void
3097 550 : TokenCollector::visit (TuplePattern &pattern)
3098 : {
3099 550 : describe_node (std::string ("TuplePattern"), [this, &pattern] () {
3100 550 : push (Rust::Token::make (LEFT_PAREN, pattern.get_locus ()));
3101 550 : visit (pattern.get_items ());
3102 550 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
3103 550 : });
3104 550 : }
3105 :
3106 : void
3107 1 : TokenCollector::visit (GroupedPattern &pattern)
3108 : {
3109 1 : describe_node (std::string ("GroupedPattern"), [this, &pattern] () {
3110 1 : push (Rust::Token::make (LEFT_PAREN, pattern.get_locus ()));
3111 1 : visit (pattern.get_pattern_in_parens ());
3112 1 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
3113 1 : });
3114 1 : }
3115 :
3116 : void
3117 75 : TokenCollector::visit (SlicePattern &pattern)
3118 : {
3119 75 : describe_node (std::string ("SlicePattern"), [this, &pattern] () {
3120 75 : push (Rust::Token::make (LEFT_SQUARE, pattern.get_locus ()));
3121 75 : visit_items_joined_by_separator (pattern.get_patterns (), COMMA);
3122 75 : push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION));
3123 75 : });
3124 75 : }
3125 :
3126 : void
3127 152 : TokenCollector::visit (AltPattern &pattern)
3128 : {
3129 152 : describe_node (std::string ("AltPattern"), [this, &pattern] () {
3130 152 : visit_items_joined_by_separator (pattern.get_alts (), PIPE);
3131 152 : });
3132 152 : }
3133 :
3134 : // rust-stmt.h
3135 : void
3136 45 : TokenCollector::visit (EmptyStmt &)
3137 45 : {}
3138 :
3139 : void
3140 13117 : TokenCollector::visit (LetStmt &stmt)
3141 : {
3142 13117 : describe_node (std::string ("LetStmt"), [this, &stmt] () {
3143 13117 : push (Rust::Token::make (LET, stmt.get_locus ()));
3144 13117 : auto &pattern = stmt.get_pattern ();
3145 13117 : visit (pattern);
3146 :
3147 13117 : if (stmt.has_type ())
3148 : {
3149 2170 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
3150 2170 : visit (stmt.get_type ());
3151 : }
3152 :
3153 13117 : if (stmt.has_type ())
3154 : {
3155 2170 : push (Rust::Token::make (COLON, UNDEF_LOCATION));
3156 2170 : visit (stmt.get_type ());
3157 : }
3158 :
3159 13117 : if (stmt.has_init_expr ())
3160 : {
3161 11985 : push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
3162 11985 : visit (stmt.get_init_expr ());
3163 : }
3164 :
3165 13117 : if (stmt.has_else_expr ())
3166 : {
3167 5 : push (Rust::Token::make (ELSE, UNDEF_LOCATION));
3168 5 : visit (stmt.get_else_expr ());
3169 : }
3170 :
3171 13117 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
3172 13117 : });
3173 13117 : }
3174 :
3175 : void
3176 11486 : TokenCollector::visit (ExprStmt &stmt)
3177 : {
3178 11486 : describe_node (std::string ("ExprStmt"), [this, &stmt] () {
3179 11486 : visit (stmt.get_expr ());
3180 :
3181 11486 : if (stmt.is_semicolon_followed ())
3182 18228 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
3183 11486 : });
3184 11486 : }
3185 :
3186 : // rust-type.h
3187 : void
3188 2271 : TokenCollector::visit (TraitBound &bound)
3189 : {
3190 : // Syntax:
3191 : // ?? ForLifetimes? TypePath
3192 : // | ( ?? ForLifetimes? TypePath )
3193 2271 : describe_node (std::string ("TraitBound"), [this, &bound] () {
3194 2271 : if (bound.has_opening_question_mark ())
3195 860 : push (Rust::Token::make (QUESTION_MARK, bound.get_locus ()));
3196 :
3197 2271 : if (bound.has_for_lifetimes ())
3198 7 : visit (bound.get_for_lifetimes ());
3199 :
3200 2271 : visit (bound.get_type_path ());
3201 2271 : });
3202 2271 : }
3203 :
3204 : void
3205 10 : TokenCollector::visit (ImplTraitType &type)
3206 : {
3207 : // Syntax:
3208 : // impl TypeParamBounds
3209 : // TypeParamBounds :
3210 : // TypeParamBound ( + TypeParamBound )* +?
3211 10 : describe_node (std::string ("ImplTraitType"), [this, &type] () {
3212 10 : push (Rust::Token::make (IMPL, type.get_locus ()));
3213 10 : visit_items_joined_by_separator (type.get_type_param_bounds (), PLUS);
3214 10 : });
3215 10 : }
3216 :
3217 : void
3218 11 : TokenCollector::visit (TraitObjectType &type)
3219 : {
3220 : // Syntax:
3221 : // dyn? TypeParamBounds
3222 : // TypeParamBounds :
3223 : // TypeParamBound ( + TypeParamBound )* +?
3224 11 : describe_node (std::string ("TraiObjectType"), [this, &type] () {
3225 11 : if (type.is_dyn ())
3226 22 : push (Rust::Token::make (DYN, type.get_locus ()));
3227 11 : visit_items_joined_by_separator (type.get_type_param_bounds (), PLUS);
3228 11 : });
3229 11 : }
3230 :
3231 : void
3232 5 : TokenCollector::visit (ParenthesisedType &type)
3233 : {
3234 : // Syntax:
3235 : // ( Type )
3236 5 : describe_node (std::string ("ParenthesisedType"), [this, &type] () {
3237 5 : push (Rust::Token::make (LEFT_PAREN, type.get_locus ()));
3238 5 : visit (type.get_type_in_parens ());
3239 5 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
3240 5 : });
3241 5 : }
3242 :
3243 : void
3244 28 : TokenCollector::visit (ImplTraitTypeOneBound &type)
3245 : {
3246 : // Syntax:
3247 : // impl TraitBound
3248 :
3249 28 : describe_node (std::string ("ImplTraitTypeOneBound"), [this, &type] () {
3250 28 : push (Rust::Token::make (IMPL, type.get_locus ()));
3251 28 : visit (type.get_trait_bound ());
3252 28 : });
3253 28 : }
3254 :
3255 : void
3256 326 : TokenCollector::visit (TraitObjectTypeOneBound &type)
3257 : {
3258 : // Syntax:
3259 : // dyn? TraitBound
3260 326 : describe_node (std::string ("TraitObjectTypeOneBound"), [this, &type] () {
3261 326 : if (type.is_dyn ())
3262 652 : push (Rust::Token::make (DYN, type.get_locus ()));
3263 326 : visit (type.get_trait_bound ());
3264 326 : });
3265 326 : }
3266 :
3267 : void
3268 474 : TokenCollector::visit (TupleType &type)
3269 : {
3270 : // Syntax:
3271 : // ( )
3272 : // | ( ( Type , )+ Type? )
3273 :
3274 474 : describe_node (std::string ("TupleType"), [this, &type] () {
3275 474 : push (Rust::Token::make (LEFT_PAREN, type.get_locus ()));
3276 474 : visit_items_joined_by_separator (type.get_elems (), COMMA);
3277 474 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
3278 474 : });
3279 474 : }
3280 :
3281 : void
3282 194 : TokenCollector::visit (NeverType &type)
3283 : {
3284 : // Syntax:
3285 : // !
3286 :
3287 194 : describe_node (std::string ("NeverType"), [this, &type] () {
3288 194 : push (Rust::Token::make (EXCLAM, type.get_locus ()));
3289 194 : });
3290 194 : }
3291 :
3292 : void
3293 7201 : TokenCollector::visit (RawPointerType &type)
3294 : {
3295 : // Syntax:
3296 : // * ( mut | const ) TypeNoBounds
3297 7201 : describe_node (std::string ("RawPointerType"), [this, &type] () {
3298 7201 : push (Rust::Token::make (ASTERISK, type.get_locus ()));
3299 7201 : if (type.get_pointer_type () == RawPointerType::MUT)
3300 1778 : push (Rust::Token::make (MUT, UNDEF_LOCATION));
3301 : else /* RawPointerType::CONST */
3302 12624 : push (Rust::Token::make (CONST, UNDEF_LOCATION));
3303 :
3304 7201 : visit (type.get_type_pointed_to ());
3305 7201 : });
3306 7201 : }
3307 :
3308 : void
3309 4969 : TokenCollector::visit (ReferenceType &type)
3310 : {
3311 : // Syntax:
3312 : // & Lifetime? mut? TypeNoBounds
3313 4969 : describe_node (std::string ("ReferenceType"), [this, &type] () {
3314 4969 : push (Rust::Token::make (AMP, type.get_locus ()));
3315 :
3316 4969 : if (type.has_lifetime ())
3317 : {
3318 4969 : visit (type.get_lifetime ());
3319 : }
3320 :
3321 4969 : if (type.get_has_mut ())
3322 686 : push (Rust::Token::make (MUT, UNDEF_LOCATION));
3323 :
3324 4969 : visit (type.get_type_referenced ());
3325 4969 : });
3326 4969 : }
3327 :
3328 : void
3329 923 : TokenCollector::visit (ArrayType &type)
3330 : {
3331 : // Syntax:
3332 : // [type Type ; Expression ]
3333 923 : describe_node (std::string ("ArrayType"), [this, &type] () {
3334 923 : push (Rust::Token::make (LEFT_SQUARE, type.get_locus ()));
3335 923 : visit (type.get_elem_type ());
3336 923 : push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
3337 923 : visit (type.get_size_expr ());
3338 923 : push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION));
3339 923 : });
3340 923 : }
3341 :
3342 : void
3343 940 : TokenCollector::visit (SliceType &type)
3344 : {
3345 : // Syntax:
3346 : // [type Type ]
3347 :
3348 940 : describe_node (std::string ("SliceType"), [this, &type] () {
3349 940 : push (Rust::Token::make (LEFT_SQUARE, type.get_locus ()));
3350 940 : visit (type.get_elem_type ());
3351 940 : push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION));
3352 940 : });
3353 940 : }
3354 :
3355 : void
3356 275 : TokenCollector::visit (InferredType &type)
3357 : {
3358 : // Syntax:
3359 : // _
3360 275 : describe_node (std::string ("InferredType"), [this, &type] () {
3361 275 : push (Rust::Token::make (UNDERSCORE, type.get_locus ()));
3362 275 : });
3363 275 : }
3364 :
3365 : void
3366 82 : TokenCollector::visit (BareFunctionType &type)
3367 : {
3368 : // Syntax:
3369 : // ForLifetimes? FunctionTypeQualifiers fn
3370 : // ( FunctionParametersMaybeNamedVariadic? )
3371 : // BareFunctionReturnType?
3372 : //
3373 : // BareFunctionReturnType:
3374 : // -> TypeNoBounds
3375 : //
3376 : // FunctionParametersMaybeNamedVariadic :
3377 : // MaybeNamedFunctionParameters |
3378 : // MaybeNamedFunctionParametersVariadic
3379 : //
3380 : // MaybeNamedFunctionParameters :
3381 : // MaybeNamedParam ( , MaybeNamedParam )* ,?
3382 : //
3383 : // MaybeNamedFunctionParametersVariadic :
3384 : // ( MaybeNamedParam , )* MaybeNamedParam , OuterAttribute* ...
3385 82 : describe_node (std::string ("BareFunctionType"), [this, &type] () {
3386 82 : if (type.has_for_lifetimes ())
3387 0 : visit (type.get_for_lifetimes ());
3388 :
3389 82 : visit (type.get_function_qualifiers ());
3390 :
3391 82 : push (Rust::Token::make (FN_KW, type.get_locus ()));
3392 82 : push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
3393 :
3394 82 : visit_items_joined_by_separator (type.get_function_params (), COMMA);
3395 :
3396 82 : if (type.is_variadic ())
3397 : {
3398 0 : push (Rust::Token::make (COMMA, UNDEF_LOCATION));
3399 0 : for (auto &item : type.get_variadic_attr ())
3400 : {
3401 0 : visit (item);
3402 : }
3403 0 : push (Rust::Token::make (ELLIPSIS, UNDEF_LOCATION));
3404 : }
3405 :
3406 82 : push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
3407 :
3408 82 : if (type.has_return_type ())
3409 : {
3410 66 : push (Rust::Token::make (RETURN_TYPE, UNDEF_LOCATION));
3411 66 : visit (type.get_return_type ());
3412 : }
3413 82 : });
3414 82 : }
3415 :
3416 : void
3417 0 : TokenCollector::visit (AST::FormatArgs &fmt)
3418 : {
3419 0 : push (Rust::Token::make_identifier (fmt.get_locus (), "format_args"));
3420 0 : push (Rust::Token::make (EXCLAM, fmt.get_locus ()));
3421 0 : push (Rust::Token::make (LEFT_PAREN, fmt.get_locus ()));
3422 :
3423 0 : std::string reconstructed_template = "\"";
3424 0 : const auto &template_pieces = fmt.get_template ();
3425 :
3426 0 : for (const auto &piece : template_pieces.get_pieces ())
3427 : {
3428 0 : if (piece.tag == Fmt::ffi::Piece::Tag::String)
3429 : {
3430 0 : std::string literal = piece.string._0.to_string ();
3431 0 : for (char c : literal)
3432 : {
3433 0 : if (c == '"' || c == '\\')
3434 : {
3435 0 : reconstructed_template += '\\';
3436 : }
3437 0 : else if (c == '\n')
3438 : {
3439 0 : reconstructed_template += "\\n";
3440 0 : continue;
3441 : }
3442 0 : else if (c == '\r')
3443 : {
3444 0 : reconstructed_template += "\\r";
3445 0 : continue;
3446 : }
3447 0 : else if (c == '\t')
3448 : {
3449 0 : reconstructed_template += "\\t";
3450 0 : continue;
3451 : }
3452 0 : reconstructed_template += c;
3453 : }
3454 0 : }
3455 0 : else if (piece.tag == Fmt::ffi::Piece::Tag::NextArgument)
3456 : {
3457 0 : reconstructed_template += "{";
3458 :
3459 0 : const auto &argument = piece.next_argument._0;
3460 0 : const auto &position = argument.position;
3461 :
3462 0 : switch (position.tag)
3463 : {
3464 : case Fmt::ffi::Position::Tag::ArgumentImplicitlyIs:
3465 : break;
3466 0 : case Fmt::ffi::Position::Tag::ArgumentIs:
3467 0 : reconstructed_template
3468 0 : += std::to_string (position.argument_is._0);
3469 0 : break;
3470 0 : case Fmt::ffi::Position::Tag::ArgumentNamed:
3471 0 : reconstructed_template += position.argument_named._0.to_string ();
3472 0 : break;
3473 : }
3474 :
3475 : // Add format specifiers if any (like :?, :x, etc.)
3476 0 : const auto &format_spec = argument.format;
3477 :
3478 0 : bool has_format_spec = false;
3479 0 : std::string format_part;
3480 :
3481 : // For now, skipping the complex format specifications that
3482 : // use FFIOpt since FFIOpt::get_opt() has a bug.
3483 :
3484 : // Alignment
3485 0 : if (format_spec.align != Fmt::ffi::Alignment::AlignUnknown)
3486 : {
3487 0 : has_format_spec = true;
3488 0 : switch (format_spec.align)
3489 : {
3490 0 : case Fmt::ffi::Alignment::AlignLeft:
3491 0 : format_part += "<";
3492 0 : break;
3493 0 : case Fmt::ffi::Alignment::AlignRight:
3494 0 : format_part += ">";
3495 0 : break;
3496 0 : case Fmt::ffi::Alignment::AlignCenter:
3497 0 : format_part += "^";
3498 0 : break;
3499 : case Fmt::ffi::Alignment::AlignUnknown:
3500 : break;
3501 : }
3502 : }
3503 :
3504 : // Alternate flag
3505 0 : if (format_spec.alternate)
3506 : {
3507 0 : has_format_spec = true;
3508 0 : format_part += "#";
3509 : }
3510 :
3511 : // Zero pad flag
3512 0 : if (format_spec.zero_pad)
3513 : {
3514 0 : has_format_spec = true;
3515 0 : format_part += "0";
3516 : }
3517 :
3518 : // Width
3519 0 : if (format_spec.width.tag != Fmt::ffi::Count::Tag::CountImplied)
3520 : {
3521 0 : has_format_spec = true;
3522 0 : switch (format_spec.width.tag)
3523 : {
3524 0 : case Fmt::ffi::Count::Tag::CountIs:
3525 0 : format_part += std::to_string (format_spec.width.count_is._0);
3526 0 : break;
3527 0 : case Fmt::ffi::Count::Tag::CountIsParam:
3528 0 : format_part
3529 0 : += std::to_string (format_spec.width.count_is_param._0)
3530 0 : + "$";
3531 0 : break;
3532 0 : case Fmt::ffi::Count::Tag::CountIsName:
3533 0 : format_part
3534 0 : += format_spec.width.count_is_name._0.to_string () + "$";
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 : // Precision
3545 0 : if (format_spec.precision.tag != Fmt::ffi::Count::Tag::CountImplied)
3546 : {
3547 0 : has_format_spec = true;
3548 0 : format_part += ".";
3549 0 : switch (format_spec.precision.tag)
3550 : {
3551 0 : case Fmt::ffi::Count::Tag::CountIs:
3552 0 : format_part
3553 0 : += std::to_string (format_spec.precision.count_is._0);
3554 0 : break;
3555 0 : case Fmt::ffi::Count::Tag::CountIsParam:
3556 0 : format_part
3557 0 : += std::to_string (format_spec.precision.count_is_param._0)
3558 0 : + "$";
3559 0 : break;
3560 0 : case Fmt::ffi::Count::Tag::CountIsName:
3561 0 : format_part
3562 0 : += format_spec.precision.count_is_name._0.to_string ()
3563 0 : + "$";
3564 0 : break;
3565 0 : case Fmt::ffi::Count::Tag::CountIsStar:
3566 0 : format_part += "*";
3567 0 : break;
3568 : case Fmt::ffi::Count::Tag::CountImplied:
3569 : break;
3570 : }
3571 : }
3572 :
3573 : // Type/trait (like ?, x, X, etc.)
3574 0 : std::string type_str = format_spec.ty.to_string ();
3575 0 : if (!type_str.empty ())
3576 : {
3577 0 : has_format_spec = true;
3578 0 : format_part += type_str;
3579 : }
3580 :
3581 : // Add the format specification if any
3582 0 : if (has_format_spec)
3583 : {
3584 0 : reconstructed_template += ":";
3585 0 : reconstructed_template += format_part;
3586 : }
3587 :
3588 0 : reconstructed_template += "}";
3589 : }
3590 : }
3591 0 : reconstructed_template += "\"";
3592 :
3593 0 : push (Rust::Token::make_string (fmt.get_locus (), reconstructed_template));
3594 :
3595 : // Visit format arguments if any exist
3596 0 : auto &arguments = fmt.get_arguments ();
3597 0 : if (!arguments.empty ())
3598 : {
3599 0 : push (Rust::Token::make (COMMA, fmt.get_locus ()));
3600 :
3601 0 : auto &args = arguments.get_args ();
3602 0 : for (size_t i = 0; i < args.size (); ++i)
3603 : {
3604 0 : if (i > 0)
3605 : {
3606 0 : push (Rust::Token::make (COMMA, fmt.get_locus ()));
3607 : }
3608 :
3609 0 : auto kind = args[i].get_kind ();
3610 :
3611 : // Handle named arguments: name = expr
3612 0 : if (kind.kind == FormatArgumentKind::Kind::Named)
3613 : {
3614 0 : auto ident = kind.get_ident ().as_string ();
3615 0 : push (Rust::Token::make_identifier (fmt.get_locus (),
3616 : std::move (ident)));
3617 0 : push (Rust::Token::make (EQUAL, fmt.get_locus ()));
3618 0 : }
3619 : // Note: Captured arguments are handled implicitly in the
3620 : // template reconstruction They don't need explicit "name ="
3621 : // syntax in the reconstructed macro call
3622 :
3623 0 : auto &expr = args[i].get_expr ();
3624 0 : expr.accept_vis (*this);
3625 0 : }
3626 : }
3627 :
3628 0 : push (Rust::Token::make (RIGHT_PAREN, fmt.get_locus ()));
3629 0 : }
3630 :
3631 : void
3632 14 : TokenCollector::visit (AST::OffsetOf &offset_of)
3633 : {
3634 14 : auto loc = offset_of.get_locus ();
3635 :
3636 28 : push (Rust::Token::make_identifier (loc, "offset_of"));
3637 14 : push (Rust::Token::make (EXCLAM, loc));
3638 14 : push (Rust::Token::make (LEFT_PAREN, loc));
3639 :
3640 14 : visit (offset_of.get_type ());
3641 :
3642 14 : push (Rust::Token::make (COMMA, loc));
3643 :
3644 14 : push (Rust::Token::make_identifier (offset_of.get_field ()));
3645 :
3646 14 : push (Rust::Token::make (RIGHT_PAREN, loc));
3647 14 : }
3648 :
3649 : } // namespace AST
3650 : } // namespace Rust
|