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