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