libcpp, c, middle-end: Optimize initializers using #embed in C
[official-gcc.git] / gcc / rust / ast / rust-ast-collector.cc
bloba2cb506805bec3559020ec604946425fc1e15821
1 // Copyright (C) 2020-2024 Free Software Foundation, Inc.
3 // This file is part of GCC.
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.
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.
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 #include "rust-ast-collector.h"
19 #include "rust-ast.h"
20 #include "rust-diagnostics.h"
21 #include "rust-item.h"
22 #include "rust-keyword-values.h"
24 namespace Rust {
25 namespace AST {
27 std::vector<TokenPtr>
28 TokenCollector::collect_tokens () const
30 std::vector<TokenPtr> result;
31 for (auto item : tokens)
33 if (item.get_kind () == CollectItem::Kind::Token)
35 result.emplace_back (item.get_token ());
38 return result;
41 std::vector<CollectItem>
42 TokenCollector::collect () const
44 return tokens;
47 void
48 TokenCollector::visit (AST::Crate &crate)
50 visit_items_as_lines (crate.inner_attrs);
51 visit_items_as_lines (crate.items);
54 void
55 TokenCollector::visit (AST::Item &item)
57 item.accept_vis (*this);
60 void
61 TokenCollector::trailing_comma ()
63 if (output_trailing_commas)
65 push (Rust::Token::make (COMMA, UNDEF_LOCATION));
69 void
70 TokenCollector::newline ()
72 tokens.push_back ({CollectItem::Kind::Newline});
75 void
76 TokenCollector::indentation ()
78 tokens.push_back ({indent_level});
81 void
82 TokenCollector::increment_indentation ()
84 indent_level++;
87 void
88 TokenCollector::decrement_indentation ()
90 rust_assert (indent_level != 0);
91 indent_level--;
94 void
95 TokenCollector::comment (std::string comment)
97 tokens.push_back ({comment});
100 void
101 TokenCollector::visit (Visitable &v)
103 v.accept_vis (*this);
106 void
107 TokenCollector::visit (FunctionParam &param)
109 visit_items_as_lines (param.get_outer_attrs ());
110 if (!param.is_variadic ())
112 visit (param.get_pattern ());
113 push (Rust::Token::make (COLON, UNDEF_LOCATION));
114 visit (param.get_type ());
116 else
118 if (param.has_name ())
120 visit (param.get_pattern ());
121 push (Rust::Token::make (COLON, UNDEF_LOCATION));
123 push (Rust::Token::make (ELLIPSIS, UNDEF_LOCATION));
127 void
128 TokenCollector::visit (VariadicParam &param)
130 if (param.has_pattern ())
132 visit (param.get_pattern ());
133 push (Rust::Token::make (COLON, UNDEF_LOCATION));
135 push (Rust::Token::make (ELLIPSIS, UNDEF_LOCATION));
138 void
139 TokenCollector::visit (Attribute &attrib)
141 push (Rust::Token::make (HASH, attrib.get_locus ()));
142 if (attrib.is_inner_attribute ())
143 push (Rust::Token::make (EXCLAM, UNDEF_LOCATION));
144 push (Rust::Token::make (LEFT_SQUARE, UNDEF_LOCATION));
145 visit (attrib.get_path ());
147 if (attrib.has_attr_input ())
149 switch (attrib.get_attr_input ().get_attr_input_type ())
151 case AST::AttrInput::AttrInputType::LITERAL: {
152 visit (static_cast<AttrInputLiteral &> (attrib.get_attr_input ()));
153 break;
155 case AST::AttrInput::AttrInputType::MACRO: {
156 visit (static_cast<AttrInputMacro &> (attrib.get_attr_input ()));
157 break;
159 case AST::AttrInput::AttrInputType::META_ITEM: {
160 visit (static_cast<AttrInputMetaItemContainer &> (
161 attrib.get_attr_input ()));
162 break;
164 case AST::AttrInput::AttrInputType::TOKEN_TREE: {
165 visit (static_cast<DelimTokenTree &> (attrib.get_attr_input ()));
166 break;
168 default:
169 rust_unreachable ();
172 push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION));
175 void
176 TokenCollector::visit (SimplePath &path)
178 if (path.has_opening_scope_resolution ())
180 push (Rust::Token::make (SCOPE_RESOLUTION, path.get_locus ()));
182 visit_items_joined_by_separator (path.get_segments (), SCOPE_RESOLUTION);
185 void
186 TokenCollector::visit (SimplePathSegment &segment)
188 auto name = segment.get_segment_name ();
189 if (segment.is_crate_path_seg ())
191 push (Rust::Token::make (CRATE, segment.get_locus ()));
193 else if (segment.is_super_path_seg ())
195 push (Rust::Token::make (SUPER, segment.get_locus ()));
197 else if (segment.is_lower_self_seg ())
199 push (Rust::Token::make (SELF, segment.get_locus ()));
201 else if (segment.is_big_self ())
203 push (Rust::Token::make (SELF_ALIAS, segment.get_locus ()));
205 else
207 push (
208 Rust::Token::make_identifier (segment.get_locus (), std::move (name)));
212 void
213 TokenCollector::visit (Visibility &vis)
215 switch (vis.get_vis_type ())
217 case Visibility::PUB:
218 push (Rust::Token::make (PUB, vis.get_locus ()));
219 break;
220 case Visibility::PUB_CRATE:
221 push (Rust::Token::make (PUB, vis.get_locus ()));
222 push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
223 push (Rust::Token::make (CRATE, UNDEF_LOCATION));
224 push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
225 break;
226 case Visibility::PUB_SELF:
227 push (Rust::Token::make (PUB, vis.get_locus ()));
228 push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
229 push (Rust::Token::make (SELF, UNDEF_LOCATION));
230 push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
231 break;
232 case Visibility::PUB_SUPER:
233 push (Rust::Token::make (PUB, vis.get_locus ()));
234 push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
235 push (Rust::Token::make (SUPER, UNDEF_LOCATION));
236 push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
237 break;
238 case Visibility::PUB_IN_PATH:
239 push (Rust::Token::make (PUB, vis.get_locus ()));
240 push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
241 push (Rust::Token::make (IN, UNDEF_LOCATION));
242 visit (vis.get_path ());
243 push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
244 break;
245 case Visibility::PRIV:
246 break;
250 void
251 TokenCollector::visit (NamedFunctionParam &param)
253 auto name = param.get_name ();
254 if (!param.is_variadic ())
256 push (
257 Rust::Token::make_identifier (param.get_locus (), std::move (name)));
258 push (Rust::Token::make (COLON, UNDEF_LOCATION));
259 visit (param.get_type ());
261 else
263 if (name != "")
265 push (Rust::Token::make_identifier (param.get_locus (),
266 std::move (name)));
267 push (Rust::Token::make (COLON, UNDEF_LOCATION));
269 push (Rust::Token::make (ELLIPSIS, UNDEF_LOCATION));
273 void
274 TokenCollector::visit (std::vector<std::unique_ptr<GenericParam>> &params)
276 push (Rust::Token::make (LEFT_ANGLE, UNDEF_LOCATION));
277 visit_items_joined_by_separator (params, COMMA);
278 push (Rust::Token::make (RIGHT_ANGLE, UNDEF_LOCATION));
281 void
282 TokenCollector::visit (TupleField &field)
284 for (auto attr : field.get_outer_attrs ())
286 visit (attr);
288 visit (field.get_visibility ());
289 visit (field.get_field_type ());
292 void
293 TokenCollector::visit (StructField &field)
295 for (auto attr : field.get_outer_attrs ())
297 visit (attr);
299 visit (field.get_visibility ());
300 auto name = field.get_field_name ().as_string ();
301 push (Rust::Token::make_identifier (field.get_locus (), std::move (name)));
302 push (Rust::Token::make (COLON, UNDEF_LOCATION));
303 visit (field.get_field_type ());
306 void
307 TokenCollector::visit (std::vector<LifetimeParam> &for_lifetimes)
309 push (Rust::Token::make (FOR, UNDEF_LOCATION));
310 push (Rust::Token::make (LEFT_ANGLE, UNDEF_LOCATION));
311 visit_items_joined_by_separator (for_lifetimes, COMMA);
312 push (Rust::Token::make (RIGHT_ANGLE, UNDEF_LOCATION));
315 void
316 TokenCollector::visit (FunctionQualifiers &qualifiers)
318 // Syntax:
319 // `const`? `async`? `unsafe`? (`extern` Abi?)?
320 // unsafe? (extern Abi?)?
322 if (qualifiers.is_async ())
323 push (Rust::Token::make (ASYNC, qualifiers.get_locus ()));
324 if (qualifiers.is_const ())
325 push (Rust::Token::make (CONST, qualifiers.get_locus ()));
326 if (qualifiers.is_unsafe ())
327 push (Rust::Token::make (UNSAFE, qualifiers.get_locus ()));
328 if (qualifiers.is_extern ())
330 push (Rust::Token::make (EXTERN_KW, qualifiers.get_locus ()));
331 if (qualifiers.has_abi ())
333 push (Rust::Token::make_string (UNDEF_LOCATION,
334 qualifiers.get_extern_abi ()));
339 void
340 TokenCollector::visit (MaybeNamedParam &param)
342 // Syntax:
343 // OuterAttribute* ( ( IDENTIFIER | _ ) : )? Type
345 for (auto attr : param.get_outer_attrs ())
347 visit (attr);
349 auto param_name = param.get_name ().as_string ();
350 switch (param.get_param_kind ())
352 case MaybeNamedParam::UNNAMED:
353 break;
354 case MaybeNamedParam::IDENTIFIER:
355 push (
356 Rust::Token::make_identifier (UNDEF_LOCATION, std::move (param_name)));
357 push (Rust::Token::make (COLON, UNDEF_LOCATION));
358 break;
359 case MaybeNamedParam::WILDCARD:
360 push (Rust::Token::make (UNDERSCORE, UNDEF_LOCATION));
361 push (Rust::Token::make (COLON, UNDEF_LOCATION));
362 break;
364 visit (param.get_type ());
367 void
368 TokenCollector::visit (Token &tok)
370 std::string data = tok.get_tok_ptr ()->has_str () ? tok.get_str () : "";
371 switch (tok.get_id ())
373 case IDENTIFIER:
374 push (Rust::Token::make_identifier (tok.get_locus (), std::move (data)));
375 break;
376 case INT_LITERAL:
377 push (Rust::Token::make_int (tok.get_locus (), std::move (data),
378 tok.get_type_hint ()));
379 break;
380 case FLOAT_LITERAL:
381 push (Rust::Token::make_float (tok.get_locus (), std::move (data),
382 tok.get_type_hint ()));
383 break;
384 case STRING_LITERAL:
385 push (Rust::Token::make_string (tok.get_locus (), std::move (data)));
386 break;
387 case CHAR_LITERAL:
388 push (Rust::Token::make_char (
389 tok.get_locus (),
390 // FIXME: This need to be fixed to properly support UTF-8
391 static_cast<uint32_t> (data[0])));
392 break;
393 case BYTE_CHAR_LITERAL:
394 push (Rust::Token::make_byte_char (tok.get_locus (), data[0]));
395 break;
396 case BYTE_STRING_LITERAL:
397 push (Rust::Token::make_byte_string (tok.get_locus (), std::move (data)));
398 break;
399 case INNER_DOC_COMMENT:
400 push (Rust::Token::make_inner_doc_comment (tok.get_locus (),
401 std::move (data)));
402 break;
403 case OUTER_DOC_COMMENT:
404 push (Rust::Token::make_outer_doc_comment (tok.get_locus (),
405 std::move (data)));
406 break;
407 case LIFETIME:
408 push (Rust::Token::make_lifetime (tok.get_locus (), std::move (data)));
409 break;
410 default:
411 push (Rust::Token::make (tok.get_id (), tok.get_locus ()));
415 void
416 TokenCollector::visit (DelimTokenTree &delim_tok_tree)
418 for (auto &token : delim_tok_tree.to_token_stream ())
420 visit (token);
424 void
425 TokenCollector::visit (AttrInputMetaItemContainer &container)
427 for (auto &item : container.get_items ())
429 visit (item);
433 void
434 TokenCollector::visit (IdentifierExpr &ident_expr)
436 auto ident = ident_expr.get_ident ().as_string ();
437 push (
438 Rust::Token::make_identifier (ident_expr.get_locus (), std::move (ident)));
441 void
442 TokenCollector::visit (Lifetime &lifetime)
444 // Syntax:
445 // Lifetime :
446 // LIFETIME_OR_LABEL
447 // | 'static
448 // | '_
450 auto name = lifetime.get_lifetime_name ();
451 switch (lifetime.get_lifetime_type ())
453 case Lifetime::LifetimeType::NAMED:
454 push (
455 Rust::Token::make_lifetime (lifetime.get_locus (), std::move (name)));
456 break;
457 case Lifetime::LifetimeType::STATIC:
458 push (Rust::Token::make_lifetime (lifetime.get_locus (),
459 Values::Keywords::STATIC_KW));
460 break;
461 case Lifetime::LifetimeType::WILDCARD:
462 push (Rust::Token::make_lifetime (lifetime.get_locus (),
463 Values::Keywords::UNDERSCORE));
464 break;
468 void
469 TokenCollector::visit (LifetimeParam &lifetime_param)
471 // Syntax:
472 // LIFETIME_OR_LABEL ( : LifetimeBounds )?
473 // LifetimeBounds :
474 // ( Lifetime + )* Lifetime?
476 // TODO what to do with outer attr? They are not mentioned in the reference.
478 auto lifetime = lifetime_param.get_lifetime ();
479 visit (lifetime);
481 if (lifetime_param.has_lifetime_bounds ())
483 push (Rust::Token::make (COLON, UNDEF_LOCATION));
484 for (auto &bound : lifetime_param.get_lifetime_bounds ())
486 visit (bound);
491 void
492 TokenCollector::visit (ConstGenericParam &param)
494 // Syntax:
495 // const IDENTIFIER : Type ( = Block | IDENTIFIER | -?LITERAL )?
497 push (Rust::Token::make (CONST, param.get_locus ()));
498 auto id = param.get_name ().as_string ();
499 push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
500 push (Rust::Token::make (COLON, UNDEF_LOCATION));
501 if (param.has_type ())
502 visit (param.get_type ());
503 if (param.has_default_value ())
505 push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
506 visit (param.get_default_value ());
510 void
511 TokenCollector::visit (PathExprSegment &segment)
513 visit (segment.get_ident_segment ());
514 if (segment.has_generic_args ())
516 auto generics = segment.get_generic_args ();
517 push (Rust::Token::make (SCOPE_RESOLUTION, segment.get_locus ()));
518 push (Rust::Token::make (LEFT_ANGLE, generics.get_locus ()));
520 auto &lifetime_args = generics.get_lifetime_args ();
521 auto &generic_args = generics.get_generic_args ();
522 auto &binding_args = generics.get_binding_args ();
524 visit_items_joined_by_separator (generic_args, COMMA);
526 if (!lifetime_args.empty ()
527 && (!generic_args.empty () || !binding_args.empty ()))
529 push (Rust::Token::make (COMMA, UNDEF_LOCATION));
532 visit_items_joined_by_separator (binding_args, COMMA);
534 if (!generic_args.empty () && !binding_args.empty ())
536 push (Rust::Token::make (COMMA, UNDEF_LOCATION));
539 visit_items_joined_by_separator (lifetime_args, COMMA);
541 push (Rust::Token::make (RIGHT_ANGLE, UNDEF_LOCATION));
545 void
546 TokenCollector::visit (PathInExpression &path)
548 if (path.opening_scope_resolution ())
550 push (Rust::Token::make (SCOPE_RESOLUTION, path.get_locus ()));
553 visit_items_joined_by_separator (path.get_segments (), SCOPE_RESOLUTION);
556 void
557 TokenCollector::visit (TypePathSegment &segment)
559 // Syntax:
560 // PathIdentSegment
561 auto ident_segment = segment.get_ident_segment ();
562 auto id = ident_segment.as_string ();
563 push (
564 Rust::Token::make_identifier (ident_segment.get_locus (), std::move (id)));
567 void
568 TokenCollector::visit (TypePathSegmentGeneric &segment)
570 // Syntax:
571 // PathIdentSegment `::`? (GenericArgs)?
572 // GenericArgs :
573 // `<` `>`
574 // | `<` ( GenericArg `,` )* GenericArg `,`? `>`
576 auto ident_segment = segment.get_ident_segment ();
577 auto id = ident_segment.as_string ();
578 push (
579 Rust::Token::make_identifier (ident_segment.get_locus (), std::move (id)));
581 if (segment.get_separating_scope_resolution ())
582 push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
584 push (Rust::Token::make (LEFT_ANGLE, UNDEF_LOCATION));
587 auto &lifetime_args = segment.get_generic_args ().get_lifetime_args ();
588 auto &generic_args = segment.get_generic_args ().get_generic_args ();
589 auto &binding_args = segment.get_generic_args ().get_binding_args ();
591 visit_items_joined_by_separator (lifetime_args, COMMA);
592 if (!lifetime_args.empty ()
593 && (!generic_args.empty () || !binding_args.empty ()))
594 push (Rust::Token::make (COMMA, UNDEF_LOCATION));
595 visit_items_joined_by_separator (generic_args, COMMA);
596 if (!generic_args.empty () && !binding_args.empty ())
597 push (Rust::Token::make (COMMA, UNDEF_LOCATION));
598 visit_items_joined_by_separator (binding_args, COMMA);
601 push (Rust::Token::make (RIGHT_ANGLE, UNDEF_LOCATION));
604 void
605 TokenCollector::visit (GenericArgsBinding &binding)
607 // Syntax:
608 // IDENTIFIER `=` Type
609 auto identifier = binding.get_identifier ().as_string ();
610 push (Rust::Token::make_identifier (binding.get_locus (),
611 std::move (identifier)));
613 push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
614 visit (binding.get_type ());
617 void
618 TokenCollector::visit (GenericArg &arg)
620 // `GenericArg` implements `accept_vis` but it is not useful for this case as
621 // it ignores unresolved cases (`Kind::Either`).
622 switch (arg.get_kind ())
624 case GenericArg::Kind::Const:
625 visit (arg.get_expression ());
626 break;
627 case GenericArg::Kind::Type:
628 visit (arg.get_type ());
629 break;
630 case GenericArg::Kind::Either: {
631 auto path = arg.get_path ();
632 push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (path)));
634 break;
635 case GenericArg::Kind::Error:
636 rust_unreachable ();
640 void
641 TokenCollector::visit (TypePathSegmentFunction &segment)
643 // Syntax:
644 // PathIdentSegment `::`? (TypePathFn)?
646 auto ident_segment = segment.get_ident_segment ();
647 auto id = ident_segment.as_string ();
648 push (
649 Rust::Token::make_identifier (ident_segment.get_locus (), std::move (id)));
651 if (segment.get_separating_scope_resolution ())
652 push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
654 if (!segment.is_ident_only ())
655 visit (segment.get_type_path_function ());
658 void
659 TokenCollector::visit (TypePathFunction &type_path_fn)
661 // Syntax:
662 // `(` TypePathFnInputs? `)` (`->` Type)?
663 // TypePathFnInputs :
664 // Type (`,` Type)* `,`?
666 push (Rust::Token::make (LEFT_PAREN, type_path_fn.get_locus ()));
667 if (type_path_fn.has_inputs ())
668 visit_items_joined_by_separator (type_path_fn.get_params (), COMMA);
669 push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
671 if (type_path_fn.has_return_type ())
673 push (Rust::Token::make (RETURN_TYPE, UNDEF_LOCATION));
674 visit (type_path_fn.get_return_type ());
678 void
679 TokenCollector::visit (TypePath &path)
681 // Syntax:
682 // `::`? TypePathSegment (`::` TypePathSegment)*
684 if (path.has_opening_scope_resolution_op ())
685 push (Rust::Token::make (SCOPE_RESOLUTION, path.get_locus ()));
687 visit_items_joined_by_separator (path.get_segments (), SCOPE_RESOLUTION);
690 void
691 TokenCollector::visit (PathIdentSegment &segment)
693 if (segment.is_super_segment ())
695 push (Rust::Token::make (SUPER, segment.get_locus ()));
697 else if (segment.is_crate_segment ())
699 push (Rust::Token::make (CRATE, segment.get_locus ()));
701 else if (segment.is_lower_self ())
703 push (Rust::Token::make (SELF, segment.get_locus ()));
705 else if (segment.is_big_self ())
707 push (Rust::Token::make (SELF_ALIAS, segment.get_locus ()));
709 else
711 auto id = segment.as_string ();
712 push (
713 Rust::Token::make_identifier (segment.get_locus (), std::move (id)));
717 void
718 TokenCollector::visit (QualifiedPathInExpression &path)
720 visit (path.get_qualified_path_type ());
721 for (auto &segment : path.get_segments ())
723 push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
724 visit (segment);
728 void
729 TokenCollector::visit (QualifiedPathType &path)
731 push (Rust::Token::make (LEFT_ANGLE, path.get_locus ()));
732 visit (path.get_type ());
733 if (path.has_as_clause ())
735 push (Rust::Token::make (AS, UNDEF_LOCATION));
736 visit (path.get_as_type_path ());
738 push (Rust::Token::make (RIGHT_ANGLE, UNDEF_LOCATION));
741 void
742 TokenCollector::visit (QualifiedPathInType &path)
744 visit (path.get_qualified_path_type ());
746 push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
747 visit (path.get_associated_segment ());
748 for (auto &segment : path.get_segments ())
750 push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
751 visit (segment);
755 void
756 TokenCollector::visit (Literal &lit, location_t locus)
758 auto value = lit.as_string ();
759 switch (lit.get_lit_type ())
761 case Literal::LitType::CHAR:
762 push (
763 Rust::Token::make_char (locus,
764 // TODO: Change this to support utf-8 properly
765 Codepoint (static_cast<uint32_t> (value[0]))));
766 break;
767 case Literal::LitType::STRING:
768 push (Rust::Token::make_string (locus, std::move (value)));
769 break;
770 case Literal::LitType::BYTE:
771 push (Rust::Token::make_byte_char (locus, value[0]));
772 break;
773 case Literal::LitType::BYTE_STRING:
774 push (Rust::Token::make_byte_string (locus, std::move (value)));
775 break;
776 case Literal::LitType::INT:
777 push (
778 Rust::Token::make_int (locus, std::move (value), lit.get_type_hint ()));
779 break;
780 case Literal::LitType::FLOAT:
781 push (Rust::Token::make_float (locus, std::move (value),
782 lit.get_type_hint ()));
783 break;
784 case Literal::LitType::BOOL: {
785 if (value == Values::Keywords::FALSE_LITERAL)
786 push (Rust::Token::make (FALSE_LITERAL, locus));
787 else if (value == Values::Keywords::TRUE_LITERAL)
788 push (Rust::Token::make (TRUE_LITERAL, locus));
789 else
790 rust_unreachable (); // Not a boolean
791 break;
793 case Literal::LitType::ERROR:
794 rust_unreachable ();
795 break;
799 void
800 TokenCollector::visit (LiteralExpr &expr)
802 auto lit = expr.get_literal ();
803 visit (lit, expr.get_locus ());
806 void
807 TokenCollector::visit (AttrInputLiteral &literal)
809 push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
810 visit (literal.get_literal ());
813 void
814 TokenCollector::visit (AttrInputMacro &macro)
816 push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
817 visit (macro.get_macro ());
820 void
821 TokenCollector::visit (MetaItemLitExpr &item)
823 auto lit = item.get_literal ();
824 visit (lit);
827 void
828 TokenCollector::visit (MetaItemPathLit &item)
830 auto path = item.get_path ();
831 auto lit = item.get_literal ();
832 visit (path);
833 push (Rust::Token::make (COLON, item.get_locus ()));
834 visit (lit);
837 void
838 TokenCollector::visit (BorrowExpr &expr)
840 push (Rust::Token::make (AMP, expr.get_locus ()));
841 if (expr.get_is_double_borrow ())
842 push (Rust::Token::make (AMP, UNDEF_LOCATION));
843 if (expr.get_is_mut ())
844 push (Rust::Token::make (MUT, UNDEF_LOCATION));
846 visit (expr.get_borrowed_expr ());
849 void
850 TokenCollector::visit (DereferenceExpr &expr)
852 push (Rust::Token::make (ASTERISK, expr.get_locus ()));
853 visit (expr.get_dereferenced_expr ());
856 void
857 TokenCollector::visit (ErrorPropagationExpr &expr)
859 visit (expr.get_propagating_expr ());
860 push (Rust::Token::make (QUESTION_MARK, expr.get_locus ()));
863 void
864 TokenCollector::visit (NegationExpr &expr)
866 switch (expr.get_expr_type ())
868 case NegationOperator::NEGATE:
869 push (Rust::Token::make (MINUS, expr.get_locus ()));
870 break;
871 case NegationOperator::NOT:
872 push (Rust::Token::make (EXCLAM, expr.get_locus ()));
873 break;
875 visit (expr.get_negated_expr ());
878 void
879 TokenCollector::visit (ArithmeticOrLogicalExpr &expr)
881 visit (expr.get_left_expr ());
882 switch (expr.get_expr_type ())
884 case ArithmeticOrLogicalOperator::ADD:
885 push (Rust::Token::make (PLUS, expr.get_locus ()));
886 break;
888 case ArithmeticOrLogicalOperator::SUBTRACT:
889 push (Rust::Token::make (MINUS, expr.get_locus ()));
890 break;
892 case ArithmeticOrLogicalOperator::MULTIPLY:
893 push (Rust::Token::make (ASTERISK, expr.get_locus ()));
894 break;
896 case ArithmeticOrLogicalOperator::DIVIDE:
897 push (Rust::Token::make (DIV, expr.get_locus ()));
898 break;
900 case ArithmeticOrLogicalOperator::MODULUS:
901 push (Rust::Token::make (PERCENT, expr.get_locus ()));
902 break;
904 case ArithmeticOrLogicalOperator::BITWISE_AND:
905 push (Rust::Token::make (AMP, expr.get_locus ()));
906 break;
908 case ArithmeticOrLogicalOperator::BITWISE_OR:
909 push (Rust::Token::make (PIPE, expr.get_locus ()));
910 break;
912 case ArithmeticOrLogicalOperator::BITWISE_XOR:
913 push (Rust::Token::make (CARET, expr.get_locus ()));
914 break;
916 case ArithmeticOrLogicalOperator::LEFT_SHIFT:
917 push (Rust::Token::make (LEFT_SHIFT, expr.get_locus ()));
918 break;
920 case ArithmeticOrLogicalOperator::RIGHT_SHIFT:
921 push (Rust::Token::make (RIGHT_SHIFT, expr.get_locus ()));
922 break;
925 visit (expr.get_right_expr ());
928 void
929 TokenCollector::visit (ComparisonExpr &expr)
931 visit (expr.get_left_expr ());
933 switch (expr.get_expr_type ())
935 case ComparisonOperator::EQUAL:
936 push (Rust::Token::make (EQUAL_EQUAL, expr.get_locus ()));
937 break;
938 case ComparisonOperator::NOT_EQUAL:
939 push (Rust::Token::make (NOT_EQUAL, expr.get_locus ()));
940 break;
941 case ComparisonOperator::GREATER_THAN:
942 push (Rust::Token::make (RIGHT_ANGLE, expr.get_locus ()));
943 break;
944 case ComparisonOperator::LESS_THAN:
945 push (Rust::Token::make (LEFT_ANGLE, expr.get_locus ()));
946 break;
947 case ComparisonOperator::GREATER_OR_EQUAL:
948 push (Rust::Token::make (GREATER_OR_EQUAL, expr.get_locus ()));
949 break;
951 case ComparisonOperator::LESS_OR_EQUAL:
952 push (Rust::Token::make (LESS_OR_EQUAL, expr.get_locus ()));
953 break;
955 visit (expr.get_right_expr ());
958 void
959 TokenCollector::visit (LazyBooleanExpr &expr)
961 visit (expr.get_left_expr ());
963 switch (expr.get_expr_type ())
965 case LazyBooleanOperator::LOGICAL_AND:
966 push (Rust::Token::make (LOGICAL_AND, expr.get_locus ()));
967 break;
968 case LazyBooleanOperator::LOGICAL_OR:
969 push (Rust::Token::make (OR, expr.get_locus ()));
970 break;
973 visit (expr.get_right_expr ());
976 void
977 TokenCollector::visit (TypeCastExpr &expr)
979 visit (expr.get_casted_expr ());
980 push (Rust::Token::make (AS, expr.get_locus ()));
981 visit (expr.get_type_to_cast_to ());
984 void
985 TokenCollector::visit (AssignmentExpr &expr)
987 expr.visit_lhs (*this);
988 push (Rust::Token::make (EQUAL, expr.get_locus ()));
989 expr.visit_rhs (*this);
992 void
993 TokenCollector::visit (CompoundAssignmentExpr &expr)
995 visit (expr.get_left_expr ());
997 switch (expr.get_expr_type ())
999 case CompoundAssignmentOperator::ADD:
1000 push (Rust::Token::make (PLUS_EQ, expr.get_locus ()));
1001 break;
1002 case CompoundAssignmentOperator::SUBTRACT:
1003 push (Rust::Token::make (MINUS_EQ, expr.get_locus ()));
1004 break;
1005 case CompoundAssignmentOperator::MULTIPLY:
1006 push (Rust::Token::make (ASTERISK_EQ, expr.get_locus ()));
1007 break;
1008 case CompoundAssignmentOperator::DIVIDE:
1009 push (Rust::Token::make (DIV_EQ, expr.get_locus ()));
1010 break;
1011 case CompoundAssignmentOperator::MODULUS:
1012 push (Rust::Token::make (PERCENT_EQ, expr.get_locus ()));
1013 break;
1014 case CompoundAssignmentOperator::BITWISE_AND:
1015 push (Rust::Token::make (AMP_EQ, expr.get_locus ()));
1016 break;
1017 case CompoundAssignmentOperator::BITWISE_OR:
1018 push (Rust::Token::make (PIPE_EQ, expr.get_locus ()));
1019 break;
1020 case CompoundAssignmentOperator::BITWISE_XOR:
1021 push (Rust::Token::make (CARET_EQ, expr.get_locus ()));
1022 break;
1023 case CompoundAssignmentOperator::LEFT_SHIFT:
1024 push (Rust::Token::make (LEFT_SHIFT_EQ, expr.get_locus ()));
1025 break;
1026 case CompoundAssignmentOperator::RIGHT_SHIFT:
1027 push (Rust::Token::make (RIGHT_SHIFT_EQ, expr.get_locus ()));
1028 break;
1030 visit (expr.get_right_expr ());
1033 void
1034 TokenCollector::visit (GroupedExpr &expr)
1036 push (Rust::Token::make (LEFT_PAREN, expr.get_locus ()));
1037 visit (expr.get_expr_in_parens ());
1038 push (Rust::Token::make (RIGHT_PAREN, expr.get_locus ()));
1041 void
1042 TokenCollector::visit (ArrayElemsValues &elems)
1044 visit_items_joined_by_separator (elems.get_values (), COMMA);
1047 void
1048 TokenCollector::visit (ArrayElemsCopied &elems)
1050 visit (elems.get_elem_to_copy ());
1051 push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
1052 visit (elems.get_num_copies ());
1055 void
1056 TokenCollector::visit (ArrayExpr &expr)
1058 push (Rust::Token::make (LEFT_SQUARE, expr.get_locus ()));
1059 visit (expr.get_array_elems ());
1060 push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION));
1063 void
1064 TokenCollector::visit (ArrayIndexExpr &expr)
1066 visit (expr.get_array_expr ());
1067 push (Rust::Token::make (LEFT_SQUARE, expr.get_locus ()));
1068 visit (expr.get_index_expr ());
1069 push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION));
1072 void
1073 TokenCollector::visit (TupleExpr &expr)
1075 visit_items_as_lines (expr.get_outer_attrs ());
1076 push (Rust::Token::make (LEFT_PAREN, expr.get_locus ()));
1077 visit_items_joined_by_separator (expr.get_tuple_elems (), COMMA);
1078 push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
1081 void
1082 TokenCollector::visit (TupleIndexExpr &expr)
1084 visit (expr.get_tuple_expr ());
1085 push (Rust::Token::make (DOT, expr.get_locus ()));
1086 push (Rust::Token::make_int (UNDEF_LOCATION,
1087 std::to_string (expr.get_tuple_index ())));
1090 void
1091 TokenCollector::visit (StructExprStruct &expr)
1093 visit (expr.get_struct_name ());
1096 void
1097 TokenCollector::visit (StructExprFieldIdentifier &expr)
1099 // TODO: Add attributes
1100 // visit_items_as_lines (expr.get_attrs ());
1101 auto id = expr.get_field_name ().as_string ();
1102 push (Rust::Token::make_identifier (expr.get_locus (), std::move (id)));
1105 void
1106 TokenCollector::visit (StructExprFieldIdentifierValue &expr)
1108 // TODO: Add attributes
1109 // visit_items_as_lines (expr.get_attrs ());
1110 auto id = expr.get_field_name ();
1111 push (Rust::Token::make_identifier (expr.get_locus (), std::move (id)));
1112 push (Rust::Token::make (COLON, UNDEF_LOCATION));
1113 visit (expr.get_value ());
1116 void
1117 TokenCollector::visit (StructExprFieldIndexValue &expr)
1119 // TODO: Add attributes
1120 // visit_items_as_lines (expr.get_attrs ());
1121 push (Rust::Token::make_int (expr.get_locus (),
1122 std::to_string (expr.get_index ())));
1123 push (Rust::Token::make (COLON, UNDEF_LOCATION));
1124 visit (expr.get_value ());
1127 void
1128 TokenCollector::visit (StructBase &base)
1130 push (Rust::Token::make (DOT_DOT, UNDEF_LOCATION));
1131 visit (base.get_base_struct ());
1134 void
1135 TokenCollector::visit (StructExprStructFields &expr)
1137 visit (expr.get_struct_name ());
1138 push (Rust::Token::make (LEFT_CURLY, expr.get_locus ()));
1139 visit_items_joined_by_separator (expr.get_fields (), COMMA);
1140 if (expr.has_struct_base ())
1142 push (Rust::Token::make (COMMA, UNDEF_LOCATION));
1143 visit (expr.get_struct_base ());
1145 else
1147 trailing_comma ();
1149 push (Rust::Token::make (RIGHT_CURLY, expr.get_locus ()));
1152 void
1153 TokenCollector::visit (StructExprStructBase &)
1155 // FIXME: Implement this node
1156 rust_unreachable ();
1159 void
1160 TokenCollector::visit (CallExpr &expr)
1162 visit (expr.get_function_expr ());
1164 push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
1166 visit_items_joined_by_separator (expr.get_params (), COMMA);
1168 push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
1171 void
1172 TokenCollector::visit (MethodCallExpr &expr)
1174 visit (expr.get_receiver_expr ());
1175 push (Rust::Token::make (DOT, expr.get_locus ()));
1176 visit (expr.get_method_name ());
1177 push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
1178 visit_items_joined_by_separator (expr.get_params (), COMMA);
1179 trailing_comma ();
1180 push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
1183 void
1184 TokenCollector::visit (FieldAccessExpr &expr)
1186 visit (expr.get_receiver_expr ());
1187 push (Rust::Token::make (DOT, expr.get_locus ()));
1188 auto field_name = expr.get_field_name ().as_string ();
1189 push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (field_name)));
1192 void
1193 TokenCollector::visit (ClosureParam &param)
1195 visit_items_as_lines (param.get_outer_attrs ());
1196 visit (param.get_pattern ());
1197 if (param.has_type_given ())
1199 push (Rust::Token::make (COLON, param.get_locus ()));
1200 visit (param.get_type ());
1204 void
1205 TokenCollector::visit_closure_common (ClosureExpr &expr)
1207 if (expr.get_has_move ())
1209 push (Rust::Token::make (MOVE, expr.get_locus ()));
1211 push (Rust::Token::make (PIPE, UNDEF_LOCATION));
1212 visit_items_joined_by_separator (expr.get_params (), COMMA);
1213 push (Rust::Token::make (PIPE, UNDEF_LOCATION));
1216 void
1217 TokenCollector::visit (ClosureExprInner &expr)
1219 visit_closure_common (expr);
1220 visit (expr.get_definition_expr ());
1223 void
1224 TokenCollector::visit (BlockExpr &expr)
1226 visit_items_as_lines (expr.get_outer_attrs ());
1227 push (Rust::Token::make (LEFT_CURLY, expr.get_locus ()));
1228 newline ();
1229 increment_indentation ();
1230 visit_items_as_lines (expr.get_inner_attrs ());
1232 visit_items_as_lines (expr.get_statements (), {});
1234 if (expr.has_tail_expr ())
1236 indentation ();
1237 visit (expr.get_tail_expr ());
1238 comment ("tail expr");
1239 newline ();
1242 decrement_indentation ();
1243 indentation ();
1244 push (Rust::Token::make (RIGHT_CURLY, expr.get_locus ()));
1245 newline ();
1248 void
1249 TokenCollector::visit (ClosureExprInnerTyped &expr)
1251 visit_closure_common (expr);
1252 push (Rust::Token::make (RETURN_TYPE, expr.get_locus ()));
1253 visit (expr.get_return_type ());
1254 visit (expr.get_definition_block ());
1257 void
1258 TokenCollector::visit (ContinueExpr &expr)
1260 push (Rust::Token::make (CONTINUE, expr.get_locus ()));
1261 if (expr.has_label ())
1262 visit (expr.get_label ());
1265 void
1266 TokenCollector::visit (BreakExpr &expr)
1268 push (Rust::Token::make (BREAK, expr.get_locus ()));
1269 if (expr.has_label ())
1270 visit (expr.get_label ());
1271 if (expr.has_break_expr ())
1272 visit (expr.get_break_expr ());
1275 void
1276 TokenCollector::visit (RangeFromToExpr &expr)
1278 visit (expr.get_from_expr ());
1279 push (Rust::Token::make (DOT_DOT, expr.get_locus ()));
1280 visit (expr.get_to_expr ());
1283 void
1284 TokenCollector::visit (RangeFromExpr &expr)
1286 visit (expr.get_from_expr ());
1287 push (Rust::Token::make (DOT_DOT, expr.get_locus ()));
1290 void
1291 TokenCollector::visit (RangeToExpr &expr)
1293 push (Rust::Token::make (DOT_DOT, expr.get_locus ()));
1294 visit (expr.get_to_expr ());
1297 void
1298 TokenCollector::visit (RangeFullExpr &expr)
1300 push (Rust::Token::make (DOT_DOT, expr.get_locus ()));
1303 void
1304 TokenCollector::visit (RangeFromToInclExpr &expr)
1306 visit (expr.get_from_expr ());
1307 push (Rust::Token::make (DOT_DOT_EQ, expr.get_locus ()));
1308 visit (expr.get_to_expr ());
1311 void
1312 TokenCollector::visit (RangeToInclExpr &expr)
1314 push (Rust::Token::make (DOT_DOT_EQ, expr.get_locus ()));
1315 visit (expr.get_to_expr ());
1318 void
1319 TokenCollector::visit (ReturnExpr &expr)
1321 push (Rust::Token::make (RETURN_KW, expr.get_locus ()));
1322 if (expr.has_returned_expr ())
1323 visit (expr.get_returned_expr ());
1326 void
1327 TokenCollector::visit (UnsafeBlockExpr &expr)
1329 push (Rust::Token::make (UNSAFE, expr.get_locus ()));
1330 visit (expr.get_block_expr ());
1333 void
1334 TokenCollector::visit (LoopLabel &label)
1336 visit (label.get_lifetime ());
1337 push (Rust::Token::make (COLON, label.get_locus ()));
1340 void
1341 TokenCollector::visit_loop_common (BaseLoopExpr &expr)
1343 if (expr.has_loop_label ())
1344 visit (expr.get_loop_label ());
1347 void
1348 TokenCollector::visit (LoopExpr &expr)
1350 visit_loop_common (expr);
1351 push (Rust::Token::make (LOOP, expr.get_locus ()));
1352 visit (expr.get_loop_block ());
1355 void
1356 TokenCollector::visit (WhileLoopExpr &expr)
1358 visit_loop_common (expr);
1359 push (Rust::Token::make (WHILE, expr.get_locus ()));
1360 visit (expr.get_predicate_expr ());
1361 visit (expr.get_loop_block ());
1364 void
1365 TokenCollector::visit (WhileLetLoopExpr &expr)
1367 visit_loop_common (expr);
1368 push (Rust::Token::make (WHILE, expr.get_locus ()));
1369 push (Rust::Token::make (LET, UNDEF_LOCATION));
1370 // TODO: The reference mention only one Pattern
1371 for (auto &item : expr.get_patterns ())
1373 visit (item);
1375 push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
1376 visit (expr.get_scrutinee_expr ());
1377 visit (expr.get_loop_block ());
1380 void
1381 TokenCollector::visit (ForLoopExpr &expr)
1383 visit_loop_common (expr);
1384 push (Rust::Token::make (FOR, expr.get_locus ()));
1385 visit (expr.get_pattern ());
1386 push (Rust::Token::make (IN, UNDEF_LOCATION));
1387 visit (expr.get_iterator_expr ());
1388 visit (expr.get_loop_block ());
1391 void
1392 TokenCollector::visit (IfExpr &expr)
1394 push (Rust::Token::make (IF, expr.get_locus ()));
1395 visit (expr.get_condition_expr ());
1396 visit (expr.get_if_block ());
1399 void
1400 TokenCollector::visit (IfExprConseqElse &expr)
1402 visit (static_cast<IfExpr &> (expr));
1403 indentation ();
1404 push (Rust::Token::make (ELSE, expr.get_locus ()));
1405 visit (expr.get_else_block ());
1408 void
1409 TokenCollector::visit (IfLetExpr &expr)
1411 push (Rust::Token::make (IF, expr.get_locus ()));
1412 push (Rust::Token::make (LET, UNDEF_LOCATION));
1413 for (auto &pattern : expr.get_patterns ())
1415 visit (pattern);
1417 push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
1418 visit (expr.get_value_expr ());
1419 visit (expr.get_if_block ());
1422 void
1423 TokenCollector::visit (IfLetExprConseqElse &expr)
1425 visit (static_cast<IfLetExpr &> (expr));
1426 indentation ();
1427 push (Rust::Token::make (ELSE, expr.get_locus ()));
1428 visit (expr.get_else_block ());
1431 void
1432 TokenCollector::visit (MatchArm &arm)
1434 visit_items_as_lines (arm.get_outer_attrs ());
1435 for (auto &pattern : arm.get_patterns ())
1437 visit (pattern);
1439 if (arm.has_match_arm_guard ())
1441 push (Rust::Token::make (IF, UNDEF_LOCATION));
1442 visit (arm.get_guard_expr ());
1446 void
1447 TokenCollector::visit (MatchCase &match_case)
1449 indentation ();
1450 visit (match_case.get_arm ());
1451 push (Rust::Token::make (MATCH_ARROW, UNDEF_LOCATION));
1452 visit (match_case.get_expr ());
1453 indentation ();
1454 push (Rust::Token::make (COMMA, UNDEF_LOCATION));
1455 newline ();
1458 void
1459 TokenCollector::visit (MatchExpr &expr)
1461 push (Rust::Token::make (MATCH_KW, expr.get_locus ()));
1462 visit (expr.get_scrutinee_expr ());
1463 push (Rust::Token::make (LEFT_CURLY, UNDEF_LOCATION));
1464 newline ();
1465 increment_indentation ();
1466 visit_items_as_lines (expr.get_inner_attrs ());
1467 for (auto &arm : expr.get_match_cases ())
1469 visit (arm);
1471 decrement_indentation ();
1472 indentation ();
1473 push (Rust::Token::make (RIGHT_CURLY, UNDEF_LOCATION));
1476 void
1477 TokenCollector::visit (AwaitExpr &expr)
1479 visit (expr.get_awaited_expr ());
1480 push (Rust::Token::make (DOT, expr.get_locus ()));
1481 // TODO: Check status of await keyword (Context dependant ?)
1482 push (Rust::Token::make_identifier (UNDEF_LOCATION, Values::Keywords::AWAIT));
1485 void
1486 TokenCollector::visit (AsyncBlockExpr &expr)
1488 push (Rust::Token::make (ASYNC, expr.get_locus ()));
1489 if (expr.get_has_move ())
1490 push (Rust::Token::make (MOVE, UNDEF_LOCATION));
1491 visit (expr.get_block_expr ());
1494 // rust-item.h
1496 void
1497 TokenCollector::visit (TypeParam &param)
1499 // Syntax:
1500 // IDENTIFIER( : TypeParamBounds? )? ( = Type )?
1501 // TypeParamBounds :
1502 // TypeParamBound ( + TypeParamBound )* +?
1504 auto id = param.get_type_representation ().as_string ();
1505 push (Rust::Token::make_identifier (param.get_locus (), std::move (id)));
1506 if (param.has_type_param_bounds ())
1508 push (Rust::Token::make (COLON, UNDEF_LOCATION));
1509 visit_items_joined_by_separator (param.get_type_param_bounds (), PLUS);
1511 if (param.has_type ())
1513 push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
1514 visit (param.get_type ());
1518 void
1519 TokenCollector::visit (WhereClause &rule)
1521 // Syntax:
1522 // where ( WhereClauseItem , )* WhereClauseItem ?
1523 // WhereClauseItem :
1524 // LifetimeWhereClauseItem
1525 // | TypeBoundWhereClauseItem
1527 push (Rust::Token::make (WHERE, UNDEF_LOCATION));
1528 newline ();
1529 increment_indentation ();
1530 visit_items_joined_by_separator (rule.get_items (), COMMA);
1531 decrement_indentation ();
1534 void
1535 TokenCollector::visit (LifetimeWhereClauseItem &item)
1537 // Syntax:
1538 // Lifetime : LifetimeBounds
1539 // LifetimeBounds :
1540 // ( Lifetime + )* Lifetime?
1542 visit (item.get_lifetime ());
1543 push (Rust::Token::make (COLON, UNDEF_LOCATION));
1544 visit_items_joined_by_separator (item.get_lifetime_bounds (), PLUS);
1547 void
1548 TokenCollector::visit (TypeBoundWhereClauseItem &item)
1550 // Syntax:
1551 // ForLifetimes? Type : TypeParamBounds?
1552 // TypeParamBounds :
1553 // TypeParamBound ( + TypeParamBound )* +?
1554 // TypeParamBound :
1555 // Lifetime | TraitBound
1557 if (item.has_for_lifetimes ())
1558 visit (item.get_for_lifetimes ());
1560 visit (item.get_type ());
1562 push (Rust::Token::make (COLON, UNDEF_LOCATION));
1563 visit_items_joined_by_separator (item.get_type_param_bounds (), PLUS);
1566 void
1567 TokenCollector::visit (Module &module)
1569 // Syntax:
1570 // mod IDENTIFIER ;
1571 // | mod IDENTIFIER {
1572 // InnerAttribute*
1573 // Item*
1574 // }
1576 visit_items_as_lines (module.get_outer_attrs ());
1577 visit (module.get_visibility ());
1578 auto name = module.get_name ().as_string ();
1579 push (Rust::Token::make (MOD, module.get_locus ()));
1580 push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (name)));
1582 if (module.get_kind () == Module::UNLOADED)
1584 push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
1585 newline ();
1587 else /* Module::LOADED */
1589 push (Rust::Token::make (LEFT_CURLY, UNDEF_LOCATION));
1590 newline ();
1591 increment_indentation ();
1593 visit_items_as_lines (module.get_inner_attrs ());
1594 visit_items_as_lines (module.get_items ());
1596 decrement_indentation ();
1598 push (Rust::Token::make (RIGHT_CURLY, UNDEF_LOCATION));
1599 newline ();
1603 void
1604 TokenCollector::visit (ExternCrate &crate)
1606 visit_items_as_lines (crate.get_outer_attrs ());
1607 push (Rust::Token::make (EXTERN_KW, crate.get_locus ()));
1608 push (Rust::Token::make (CRATE, UNDEF_LOCATION));
1609 auto ref = crate.get_referenced_crate ();
1610 push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (ref)));
1611 if (crate.has_as_clause ())
1613 auto as_clause = crate.get_as_clause ();
1614 push (Rust::Token::make (AS, UNDEF_LOCATION));
1615 push (
1616 Rust::Token::make_identifier (UNDEF_LOCATION, std::move (as_clause)));
1618 push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
1619 newline ();
1622 void
1623 TokenCollector::visit (UseTreeGlob &use_tree)
1625 switch (use_tree.get_glob_type ())
1627 case UseTreeGlob::PathType::PATH_PREFIXED: {
1628 auto path = use_tree.get_path ();
1629 visit (path);
1630 push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
1632 break;
1633 case UseTreeGlob::PathType::NO_PATH:
1634 push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
1635 break;
1636 case UseTreeGlob::PathType::GLOBAL:
1637 break;
1639 push (Rust::Token::make (ASTERISK, UNDEF_LOCATION));
1642 void
1643 TokenCollector::visit (UseTreeList &use_tree)
1645 switch (use_tree.get_path_type ())
1647 case UseTreeList::PathType::PATH_PREFIXED: {
1648 auto path = use_tree.get_path ();
1649 visit (path);
1650 push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
1652 break;
1653 case UseTreeList::PathType::NO_PATH:
1654 push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
1655 break;
1656 case UseTreeList::PathType::GLOBAL:
1657 break;
1660 push (Rust::Token::make (LEFT_CURLY, UNDEF_LOCATION));
1661 if (use_tree.has_trees ())
1663 visit_items_joined_by_separator (use_tree.get_trees (), COMMA);
1665 push (Rust::Token::make (RIGHT_CURLY, UNDEF_LOCATION));
1668 void
1669 TokenCollector::visit (UseTreeRebind &use_tree)
1671 auto path = use_tree.get_path ();
1672 visit (path);
1673 switch (use_tree.get_new_bind_type ())
1675 case UseTreeRebind::NewBindType::IDENTIFIER: {
1676 push (Rust::Token::make (AS, UNDEF_LOCATION));
1677 auto id = use_tree.get_identifier ().as_string ();
1678 push (
1679 Rust::Token::make_identifier (use_tree.get_locus (), std::move (id)));
1681 break;
1682 case UseTreeRebind::NewBindType::WILDCARD:
1683 push (Rust::Token::make (AS, UNDEF_LOCATION));
1684 push (Rust::Token::make (UNDERSCORE, use_tree.get_locus ()));
1685 break;
1686 case UseTreeRebind::NewBindType::NONE:
1687 break;
1691 void
1692 TokenCollector::visit (UseDeclaration &decl)
1694 visit_items_as_lines (decl.get_outer_attrs ());
1695 push (Rust::Token::make (USE, decl.get_locus ()));
1696 visit (*decl.get_tree ());
1697 push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
1698 newline ();
1701 void
1702 TokenCollector::visit (Function &function)
1704 // Syntax:
1705 // FunctionQualifiers fn IDENTIFIER GenericParams?
1706 // ( FunctionParameters? )
1707 // FunctionReturnType? WhereClause?
1708 // ( BlockExpression | ; )
1709 visit_items_as_lines (function.get_outer_attrs ());
1711 visit (function.get_visibility ());
1712 auto qualifiers = function.get_qualifiers ();
1713 visit (qualifiers);
1715 push (Rust::Token::make (FN_KW, function.get_locus ()));
1716 auto name = function.get_function_name ().as_string ();
1717 push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (name)));
1718 if (function.has_generics ())
1719 visit (function.get_generic_params ());
1721 push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
1723 visit_items_joined_by_separator (function.get_function_params ());
1724 push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
1726 if (function.has_return_type ())
1728 push (Rust::Token::make (RETURN_TYPE, UNDEF_LOCATION));
1729 visit (function.get_return_type ());
1732 if (function.has_where_clause ())
1733 visit (function.get_where_clause ());
1735 if (function.has_body ())
1736 visit (*function.get_definition ());
1737 else
1738 push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
1739 newline ();
1742 void
1743 TokenCollector::visit (TypeAlias &type_alias)
1745 // Syntax:
1746 // Visibility? type IDENTIFIER GenericParams? WhereClause? = Type;
1748 // Note: Associated types are handled by `AST::TraitItemType`.
1750 visit_items_as_lines (type_alias.get_outer_attrs ());
1751 if (type_alias.has_visibility ())
1752 visit (type_alias.get_visibility ());
1753 auto alias_name = type_alias.get_new_type_name ().as_string ();
1754 push (Rust::Token::make (TYPE, type_alias.get_locus ()));
1755 push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (alias_name)));
1757 if (type_alias.has_generics ())
1758 visit (type_alias.get_generic_params ());
1760 if (type_alias.has_where_clause ())
1761 visit (type_alias.get_where_clause ());
1763 push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
1764 visit (type_alias.get_type_aliased ());
1765 push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
1768 void
1769 TokenCollector::visit (StructStruct &struct_item)
1771 visit_items_as_lines (struct_item.get_outer_attrs ());
1772 if (struct_item.has_visibility ())
1773 visit (struct_item.get_visibility ());
1774 auto struct_name = struct_item.get_identifier ().as_string ();
1775 push (Rust::Token::make (STRUCT_KW, struct_item.get_locus ()));
1776 push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (struct_name)));
1778 if (struct_item.has_generics ())
1779 visit (struct_item.get_generic_params ());
1780 if (struct_item.has_where_clause ())
1781 visit (struct_item.get_where_clause ());
1782 if (struct_item.is_unit_struct ())
1784 push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
1785 newline ();
1787 else
1788 visit_items_as_block (struct_item.get_fields (),
1789 {Rust::Token::make (COMMA, UNDEF_LOCATION)});
1792 void
1793 TokenCollector::visit (TupleStruct &tuple_struct)
1795 visit_items_as_lines (tuple_struct.get_outer_attrs ());
1796 auto struct_name = tuple_struct.get_identifier ().as_string ();
1797 push (Rust::Token::make (STRUCT_KW, tuple_struct.get_locus ()));
1798 push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (struct_name)));
1799 if (tuple_struct.has_generics ())
1800 visit (tuple_struct.get_generic_params ());
1801 if (tuple_struct.has_where_clause ())
1802 visit (tuple_struct.get_where_clause ());
1804 push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
1805 visit_items_joined_by_separator (tuple_struct.get_fields (), COMMA);
1806 push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
1807 push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
1808 newline ();
1811 void
1812 TokenCollector::visit (EnumItem &item)
1814 visit_items_as_lines (item.get_outer_attrs ());
1815 auto id = item.get_identifier ().as_string ();
1816 push (Rust::Token::make_identifier (item.get_locus (), std::move (id)));
1819 void
1820 TokenCollector::visit (EnumItemTuple &item)
1822 auto id = item.get_identifier ().as_string ();
1823 push (Rust::Token::make_identifier (item.get_locus (), std::move (id)));
1824 push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
1825 visit_items_joined_by_separator (item.get_tuple_fields (), COMMA);
1826 push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
1829 void
1830 TokenCollector::visit (EnumItemStruct &item)
1832 auto id = item.get_identifier ().as_string ();
1833 push (Rust::Token::make_identifier (item.get_locus (), std::move (id)));
1834 visit_items_as_block (item.get_struct_fields (),
1835 {Rust::Token::make (COMMA, UNDEF_LOCATION)});
1838 void
1839 TokenCollector::visit (EnumItemDiscriminant &item)
1841 auto id = item.get_identifier ().as_string ();
1842 push (Rust::Token::make_identifier (item.get_locus (), std::move (id)));
1843 push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
1844 visit (item.get_expr ());
1847 void
1848 TokenCollector::visit (Enum &enumeration)
1850 visit_items_as_lines (enumeration.get_outer_attrs ());
1851 if (enumeration.has_visibility ())
1852 visit (enumeration.get_visibility ());
1853 push (Rust::Token::make (ENUM_KW, enumeration.get_locus ()));
1854 auto id = enumeration.get_identifier ().as_string ();
1855 push (
1856 Rust::Token::make_identifier (enumeration.get_locus (), std::move (id)));
1857 if (enumeration.has_generics ())
1858 visit (enumeration.get_generic_params ());
1859 if (enumeration.has_where_clause ())
1860 visit (enumeration.get_where_clause ());
1862 visit_items_as_block (enumeration.get_variants (),
1863 {Rust::Token::make (COMMA, UNDEF_LOCATION)});
1866 void
1867 TokenCollector::visit (Union &union_item)
1869 visit_items_as_lines (union_item.get_outer_attrs ());
1870 auto id = union_item.get_identifier ().as_string ();
1871 push (Rust::Token::make_identifier (union_item.get_locus (),
1872 Values::WeakKeywords::UNION));
1873 push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
1875 if (union_item.has_generics ())
1876 visit (union_item.get_generic_params ());
1878 if (union_item.has_where_clause ())
1879 visit (union_item.get_where_clause ());
1881 visit_items_as_block (union_item.get_variants (),
1882 {Rust::Token::make (COMMA, UNDEF_LOCATION)});
1885 void
1886 TokenCollector::visit (ConstantItem &item)
1888 visit_items_as_lines (item.get_outer_attrs ());
1889 push (Rust::Token::make (CONST, item.get_locus ()));
1890 if (item.is_unnamed ())
1892 push (Rust::Token::make (UNDERSCORE, UNDEF_LOCATION));
1894 else
1896 auto id = item.get_identifier ();
1897 push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
1899 push (Rust::Token::make (COLON, UNDEF_LOCATION));
1900 visit (item.get_type ());
1901 if (item.has_expr ())
1903 push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
1904 visit (item.get_expr ());
1906 push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
1909 void
1910 TokenCollector::visit (StaticItem &item)
1912 visit_items_as_lines (item.get_outer_attrs ());
1913 push (Rust::Token::make (STATIC_KW, item.get_locus ()));
1914 if (item.is_mutable ())
1915 push (Rust::Token::make (MUT, UNDEF_LOCATION));
1917 auto id = item.get_identifier ().as_string ();
1918 push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
1919 push (Rust::Token::make (COLON, UNDEF_LOCATION));
1921 visit (item.get_type ());
1923 if (item.has_expr ())
1925 push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
1926 visit (item.get_expr ());
1928 push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
1931 void
1932 TokenCollector::visit_function_common (std::unique_ptr<Type> &return_type,
1933 std::unique_ptr<BlockExpr> &block)
1935 // FIXME: This should format the `<vis> fn <name> ( [args] )` as well
1936 if (return_type)
1938 push (Rust::Token::make (RETURN_TYPE, UNDEF_LOCATION));
1939 visit (return_type);
1942 if (block)
1944 visit (block);
1946 else
1948 push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
1949 newline ();
1953 void
1954 TokenCollector::visit (SelfParam &param)
1956 if (param.get_has_ref ())
1958 push (Rust::Token::make (AMP, UNDEF_LOCATION));
1959 if (param.has_lifetime ())
1961 auto lifetime = param.get_lifetime ();
1962 visit (lifetime);
1964 if (param.get_is_mut ())
1965 push (Rust::Token::make (MUT, UNDEF_LOCATION));
1967 push (Rust::Token::make (SELF, UNDEF_LOCATION));
1968 if (param.has_type ())
1970 push (Rust::Token::make (COLON, UNDEF_LOCATION));
1971 visit (param.get_type ());
1975 void
1976 TokenCollector::visit (TraitItemConst &item)
1978 auto id = item.get_identifier ().as_string ();
1979 indentation ();
1980 push (Rust::Token::make (CONST, item.get_locus ()));
1981 push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
1982 push (Rust::Token::make (COLON, UNDEF_LOCATION));
1983 visit (item.get_type ());
1984 push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
1985 newline ();
1988 void
1989 TokenCollector::visit (TraitItemType &item)
1991 visit_items_as_lines (item.get_outer_attrs ());
1992 auto id = item.get_identifier ().as_string ();
1993 indentation ();
1995 push (Rust::Token::make (TYPE, item.get_locus ()));
1996 push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
1997 push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
1998 newline ();
2001 void
2002 TokenCollector::visit (Trait &trait)
2004 for (auto &attr : trait.get_outer_attrs ())
2006 visit (attr);
2007 newline ();
2008 indentation ();
2011 visit (trait.get_visibility ());
2013 auto id = trait.get_identifier ().as_string ();
2014 push (Rust::Token::make (TRAIT, trait.get_locus ()));
2015 push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2017 visit (trait.get_generic_params ());
2019 visit_items_as_block (trait.get_trait_items (), {});
2022 void
2023 TokenCollector::visit (InherentImpl &impl)
2025 visit_items_as_lines (impl.get_outer_attrs ());
2026 push (Rust::Token::make (IMPL, impl.get_locus ()));
2027 visit (impl.get_generic_params ());
2029 visit (impl.get_type ());
2031 if (impl.has_where_clause ())
2032 visit (impl.get_where_clause ());
2034 // FIXME: Handle inner attributes
2036 visit_items_as_block (impl.get_impl_items (), {});
2039 void
2040 TokenCollector::visit (TraitImpl &impl)
2042 visit_items_as_lines (impl.get_outer_attrs ());
2043 push (Rust::Token::make (IMPL, impl.get_locus ()));
2044 visit (impl.get_generic_params ());
2045 if (impl.is_exclam ())
2046 push (Rust::Token::make (EXCLAM, UNDEF_LOCATION));
2047 visit (impl.get_trait_path ());
2048 push (Rust::Token::make (FOR, UNDEF_LOCATION));
2049 visit (impl.get_type ());
2051 if (impl.has_where_clause ())
2052 visit (impl.get_where_clause ());
2054 visit_items_as_block (impl.get_impl_items ());
2057 void
2058 TokenCollector::visit (ExternalTypeItem &type)
2060 visit (type.get_visibility ());
2062 auto id = type.get_identifier ().as_string ();
2064 push (Rust::Token::make (TYPE, UNDEF_LOCATION));
2065 push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2066 push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2069 void
2070 TokenCollector::visit (ExternalStaticItem &item)
2072 auto id = item.get_identifier ().as_string ();
2073 visit_items_as_lines (item.get_outer_attrs ());
2074 if (item.has_visibility ())
2075 visit (item.get_visibility ());
2076 push (Rust::Token::make (STATIC_KW, item.get_locus ()));
2077 if (item.is_mut ())
2078 push (Rust::Token::make (MUT, UNDEF_LOCATION));
2079 push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2080 push (Rust::Token::make (COLON, UNDEF_LOCATION));
2081 visit (item.get_type ());
2082 // TODO: No expr ? The "(= Expression)?" part from the reference seems missing
2083 // in the ast.
2084 push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2087 void
2088 TokenCollector::visit (ExternBlock &block)
2090 visit_items_as_lines (block.get_outer_attrs ());
2091 push (Rust::Token::make (EXTERN_KW, block.get_locus ()));
2093 if (block.has_abi ())
2095 auto abi = block.get_abi ();
2096 push (Rust::Token::make_string (UNDEF_LOCATION, std::move (abi)));
2099 visit_items_as_block (block.get_extern_items (), {});
2102 static std::pair<TokenId, TokenId>
2103 get_delimiters (DelimType delim)
2105 switch (delim)
2107 case PARENS:
2108 return {LEFT_PAREN, RIGHT_PAREN};
2109 case SQUARE:
2110 return {LEFT_SQUARE, RIGHT_SQUARE};
2111 case CURLY:
2112 return {LEFT_CURLY, RIGHT_CURLY};
2113 default:
2114 rust_unreachable ();
2118 void
2119 TokenCollector::visit (MacroMatchFragment &match)
2121 auto id = match.get_ident ().as_string ();
2122 auto frag_spec = match.get_frag_spec ().as_string ();
2123 push (Rust::Token::make (DOLLAR_SIGN, UNDEF_LOCATION));
2124 push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2125 push (Rust::Token::make (COLON, UNDEF_LOCATION));
2126 push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (frag_spec)));
2129 void
2130 TokenCollector::visit (MacroMatchRepetition &repetition)
2132 push (Rust::Token::make (DOLLAR_SIGN, UNDEF_LOCATION));
2133 push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
2135 for (auto &match : repetition.get_matches ())
2137 visit (match);
2140 push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
2142 if (repetition.has_sep ())
2144 push (Rust::Token::make (repetition.get_sep ()->get_id (),
2145 repetition.get_sep ()->get_locus ()));
2147 switch (repetition.get_op ())
2149 case MacroMatchRepetition::ANY:
2150 push (Rust::Token::make (ASTERISK, UNDEF_LOCATION));
2151 break;
2152 case MacroMatchRepetition::ONE_OR_MORE:
2153 push (Rust::Token::make (PLUS, UNDEF_LOCATION));
2154 break;
2155 case MacroMatchRepetition::ZERO_OR_ONE:
2156 push (Rust::Token::make (QUESTION_MARK, UNDEF_LOCATION));
2157 break;
2158 case MacroMatchRepetition::NONE:
2159 break;
2163 void
2164 TokenCollector::visit (MacroMatcher &matcher)
2166 auto delimiters = get_delimiters (matcher.get_delim_type ());
2168 push (Rust::Token::make (delimiters.first, UNDEF_LOCATION));
2170 for (auto &item : matcher.get_matches ())
2172 visit (item);
2175 push (Rust::Token::make (delimiters.second, UNDEF_LOCATION));
2178 void
2179 TokenCollector::visit (MacroRule &rule)
2181 visit (rule.get_matcher ());
2182 push (Rust::Token::make (MATCH_ARROW, rule.get_locus ()));
2183 visit (rule.get_transcriber ().get_token_tree ());
2186 void
2187 TokenCollector::visit (MacroRulesDefinition &rules_def)
2189 for (auto &outer_attr : rules_def.get_outer_attrs ())
2190 visit (outer_attr);
2192 auto rule_name = rules_def.get_rule_name ().as_string ();
2194 push (Rust::Token::make_identifier (rules_def.get_locus (),
2195 Values::WeakKeywords::MACRO_RULES));
2196 push (Rust::Token::make (EXCLAM, UNDEF_LOCATION));
2198 push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (rule_name)));
2200 visit_items_as_block (rules_def.get_rules (),
2201 {Rust::Token::make (SEMICOLON, UNDEF_LOCATION)});
2204 void
2205 TokenCollector::visit (MacroInvocation &invocation)
2207 auto data = invocation.get_invoc_data ();
2208 visit (data.get_path ());
2209 push (Rust::Token::make (EXCLAM, UNDEF_LOCATION));
2210 visit (data.get_delim_tok_tree ());
2211 if (invocation.has_semicolon ())
2212 push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2215 void
2216 TokenCollector::visit (MetaItemPath &item)
2218 auto path = item.to_path_item ();
2219 visit (path);
2222 void
2223 TokenCollector::visit (MetaItemSeq &item)
2225 visit (item.get_path ());
2226 // TODO: Double check this, there is probably a mistake.
2227 push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
2228 visit_items_joined_by_separator (item.get_seq (), COMMA);
2229 push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
2232 void
2233 TokenCollector::visit (MetaWord &word)
2235 auto id = word.get_ident ().as_string ();
2237 push (Rust::Token::make_identifier (word.get_locus (), std::move (id)));
2240 void
2241 TokenCollector::visit (MetaNameValueStr &name)
2243 auto pair = name.get_name_value_pair ();
2244 auto id = std::get<0> (pair).as_string ();
2245 auto value = std::get<1> (pair);
2247 push (Rust::Token::make_identifier (name.get_locus (), std::move (id)));
2248 push (Rust::Token::make (EQUAL, name.get_locus ()));
2249 push (Rust::Token::make (DOUBLE_QUOTE, UNDEF_LOCATION));
2250 push (Rust::Token::make_identifier (name.get_locus (), std::move (value)));
2251 push (Rust::Token::make (DOUBLE_QUOTE, UNDEF_LOCATION));
2254 void
2255 TokenCollector::visit (MetaListPaths &list)
2257 auto id = list.get_ident ().as_string ();
2259 push (Rust::Token::make_identifier (list.get_locus (), std::move (id)));
2260 push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
2262 visit_items_joined_by_separator (list.get_paths (), COMMA);
2264 push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
2267 void
2268 TokenCollector::visit (MetaListNameValueStr &list)
2270 auto id = list.get_ident ().as_string ();
2272 push (Rust::Token::make_identifier (list.get_locus (), std::move (id)));
2273 push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
2275 visit_items_joined_by_separator (list.get_values (), COMMA);
2277 push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
2280 // rust-pattern.h
2281 void
2282 TokenCollector::visit (LiteralPattern &pattern)
2284 visit (pattern.get_literal (), pattern.get_locus ());
2287 void
2288 TokenCollector::visit (IdentifierPattern &pattern)
2290 if (pattern.get_is_ref ())
2292 push (Rust::Token::make (REF, pattern.get_locus ()));
2294 if (pattern.get_is_mut ())
2296 push (Rust::Token::make (MUT, UNDEF_LOCATION));
2299 auto id = pattern.get_ident ().as_string ();
2300 push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2302 if (pattern.has_pattern_to_bind ())
2304 push (Rust::Token::make (PATTERN_BIND, UNDEF_LOCATION));
2305 visit (pattern.get_pattern_to_bind ());
2309 void
2310 TokenCollector::visit (WildcardPattern &pattern)
2312 push (Rust::Token::make (UNDERSCORE, pattern.get_locus ()));
2315 void
2316 TokenCollector::visit (RestPattern &pattern)
2318 push (Rust::Token::make (DOT_DOT, pattern.get_locus ()));
2321 // void TokenCollector::visit(RangePatternBound& ){}
2323 void
2324 TokenCollector::visit (RangePatternBoundLiteral &pattern)
2326 if (pattern.get_has_minus ())
2328 push (Rust::Token::make (MINUS, pattern.get_locus ()));
2330 auto literal = pattern.get_literal ();
2331 visit (literal);
2334 void
2335 TokenCollector::visit (RangePatternBoundPath &pattern)
2337 visit (pattern.get_path ());
2340 void
2341 TokenCollector::visit (RangePatternBoundQualPath &pattern)
2343 visit (pattern.get_qualified_path ());
2346 void
2347 TokenCollector::visit (RangePattern &pattern)
2349 if (pattern.get_has_lower_bound () && pattern.get_has_upper_bound ())
2351 visit (pattern.get_lower_bound ());
2352 if (pattern.get_has_ellipsis_syntax ())
2353 push (Rust::Token::make (ELLIPSIS, pattern.get_locus ()));
2354 else
2355 push (Rust::Token::make (DOT_DOT_EQ, pattern.get_locus ()));
2356 visit (pattern.get_upper_bound ());
2358 else if (pattern.get_has_lower_bound ())
2360 visit (pattern.get_lower_bound ());
2361 push (Rust::Token::make (DOT_DOT, pattern.get_locus ()));
2363 else
2365 push (Rust::Token::make (DOT_DOT_EQ, pattern.get_locus ()));
2366 visit (pattern.get_upper_bound ());
2370 void
2371 TokenCollector::visit (ReferencePattern &pattern)
2373 if (pattern.is_double_reference ())
2375 push (Rust::Token::make (LOGICAL_AND, pattern.get_locus ()));
2377 else
2379 push (Rust::Token::make (AMP, pattern.get_locus ()));
2382 if (pattern.get_is_mut ())
2384 push (Rust::Token::make (MUT, UNDEF_LOCATION));
2387 visit (pattern.get_referenced_pattern ());
2390 // void TokenCollector::visit(StructPatternField& ){}
2392 void
2393 TokenCollector::visit (StructPatternFieldTuplePat &pattern)
2395 visit_items_as_lines (pattern.get_outer_attrs ());
2396 push (Rust::Token::make_int (pattern.get_locus (),
2397 std::to_string (pattern.get_index ())));
2398 push (Rust::Token::make (COLON, pattern.get_locus ()));
2399 visit (pattern.get_index_pattern ());
2402 void
2403 TokenCollector::visit (StructPatternFieldIdentPat &pattern)
2405 visit_items_as_lines (pattern.get_outer_attrs ());
2407 auto id = pattern.get_identifier ().as_string ();
2408 push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2410 push (Rust::Token::make (COLON, pattern.get_locus ()));
2412 visit (pattern.get_ident_pattern ());
2415 void
2416 TokenCollector::visit (StructPatternFieldIdent &pattern)
2418 visit_items_as_lines (pattern.get_outer_attrs ());
2419 if (pattern.is_ref ())
2420 push (Rust::Token::make (REF, UNDEF_LOCATION));
2421 if (pattern.is_mut ())
2422 push (Rust::Token::make (MUT, UNDEF_LOCATION));
2424 auto id = pattern.get_identifier ().as_string ();
2425 push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
2428 void
2429 TokenCollector::visit (StructPattern &pattern)
2431 visit (pattern.get_path ());
2432 push (Rust::Token::make (LEFT_CURLY, pattern.get_locus ()));
2433 auto elems = pattern.get_struct_pattern_elems ();
2434 if (elems.has_struct_pattern_fields ())
2436 visit_items_joined_by_separator (elems.get_struct_pattern_fields ());
2437 if (elems.has_etc ())
2439 push (Rust::Token::make (COMMA, UNDEF_LOCATION));
2440 visit_items_as_lines (elems.get_etc_outer_attrs ());
2443 else
2445 visit_items_as_lines (elems.get_etc_outer_attrs ());
2448 push (Rust::Token::make (RIGHT_CURLY, UNDEF_LOCATION));
2451 // void TokenCollector::visit(TupleStructItems& ){}
2453 void
2454 TokenCollector::visit (TupleStructItemsNoRange &pattern)
2456 for (auto &pat : pattern.get_patterns ())
2458 visit (pat);
2462 void
2463 TokenCollector::visit (TupleStructItemsRange &pattern)
2465 for (auto &lower : pattern.get_lower_patterns ())
2467 visit (lower);
2469 push (Rust::Token::make (DOT_DOT, UNDEF_LOCATION));
2470 for (auto &upper : pattern.get_lower_patterns ())
2472 visit (upper);
2476 void
2477 TokenCollector::visit (TupleStructPattern &pattern)
2479 visit (pattern.get_path ());
2480 push (Rust::Token::make (LEFT_PAREN, pattern.get_locus ()));
2481 visit (pattern.get_items ());
2482 push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
2485 // void
2486 // TokenCollector::visit (TuplePatternItems &)
2487 // {}
2489 void
2490 TokenCollector::visit (TuplePatternItemsMultiple &pattern)
2492 visit_items_joined_by_separator (pattern.get_patterns (), COMMA);
2495 void
2496 TokenCollector::visit (TuplePatternItemsRanged &pattern)
2498 for (auto &lower : pattern.get_lower_patterns ())
2500 visit (lower);
2502 push (Rust::Token::make (DOT_DOT, UNDEF_LOCATION));
2503 for (auto &upper : pattern.get_lower_patterns ())
2505 visit (upper);
2509 void
2510 TokenCollector::visit (TuplePattern &pattern)
2512 push (Rust::Token::make (LEFT_PAREN, pattern.get_locus ()));
2513 visit (pattern.get_items ());
2514 push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
2517 void
2518 TokenCollector::visit (GroupedPattern &pattern)
2520 push (Rust::Token::make (LEFT_PAREN, pattern.get_locus ()));
2521 visit (pattern.get_pattern_in_parens ());
2522 push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
2525 void
2526 TokenCollector::visit (SlicePattern &pattern)
2528 push (Rust::Token::make (LEFT_SQUARE, pattern.get_locus ()));
2529 visit_items_joined_by_separator (pattern.get_items (), COMMA);
2530 push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION));
2533 void
2534 TokenCollector::visit (AltPattern &pattern)
2536 visit_items_joined_by_separator (pattern.get_alts (), PIPE);
2539 // rust-stmt.h
2540 void
2541 TokenCollector::visit (EmptyStmt &)
2544 void
2545 TokenCollector::visit (LetStmt &stmt)
2547 push (Rust::Token::make (LET, stmt.get_locus ()));
2548 auto &pattern = stmt.get_pattern ();
2549 visit (pattern);
2551 if (stmt.has_type ())
2553 push (Rust::Token::make (COLON, UNDEF_LOCATION));
2554 visit (stmt.get_type ());
2557 if (stmt.has_init_expr ())
2559 push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
2560 visit (stmt.get_init_expr ());
2562 push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2565 void
2566 TokenCollector::visit (ExprStmt &stmt)
2568 visit (stmt.get_expr ());
2569 if (stmt.is_semicolon_followed ())
2570 push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2573 // rust-type.h
2574 void
2575 TokenCollector::visit (TraitBound &bound)
2577 // Syntax:
2578 // ?? ForLifetimes? TypePath
2579 // | ( ?? ForLifetimes? TypePath )
2581 if (bound.has_opening_question_mark ())
2582 push (Rust::Token::make (QUESTION_MARK, bound.get_locus ()));
2584 if (bound.has_for_lifetimes ())
2585 visit (bound.get_for_lifetimes ());
2587 visit (bound.get_type_path ());
2590 void
2591 TokenCollector::visit (ImplTraitType &type)
2593 // Syntax:
2594 // impl TypeParamBounds
2595 // TypeParamBounds :
2596 // TypeParamBound ( + TypeParamBound )* +?
2598 push (Rust::Token::make (IMPL, type.get_locus ()));
2599 visit_items_joined_by_separator (type.get_type_param_bounds (), PLUS);
2602 void
2603 TokenCollector::visit (TraitObjectType &type)
2605 // Syntax:
2606 // dyn? TypeParamBounds
2607 // TypeParamBounds :
2608 // TypeParamBound ( + TypeParamBound )* +?
2610 if (type.is_dyn ())
2611 push (Rust::Token::make (DYN, type.get_locus ()));
2612 visit_items_joined_by_separator (type.get_type_param_bounds (), PLUS);
2615 void
2616 TokenCollector::visit (ParenthesisedType &type)
2618 // Syntax:
2619 // ( Type )
2621 push (Rust::Token::make (LEFT_PAREN, type.get_locus ()));
2622 visit (type.get_type_in_parens ());
2623 push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
2626 void
2627 TokenCollector::visit (ImplTraitTypeOneBound &type)
2629 // Syntax:
2630 // impl TraitBound
2632 push (Rust::Token::make (IMPL, type.get_locus ()));
2633 visit (type.get_trait_bound ());
2636 void
2637 TokenCollector::visit (TraitObjectTypeOneBound &type)
2639 // Syntax:
2640 // dyn? TraitBound
2642 if (type.is_dyn ())
2643 push (Rust::Token::make (DYN, type.get_locus ()));
2644 visit (type.get_trait_bound ());
2647 void
2648 TokenCollector::visit (TupleType &type)
2650 // Syntax:
2651 // ( )
2652 // | ( ( Type , )+ Type? )
2654 push (Rust::Token::make (LEFT_PAREN, type.get_locus ()));
2655 visit_items_joined_by_separator (type.get_elems (), COMMA);
2656 push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
2659 void
2660 TokenCollector::visit (NeverType &type)
2662 // Syntax:
2663 // !
2665 push (Rust::Token::make (EXCLAM, type.get_locus ()));
2668 void
2669 TokenCollector::visit (RawPointerType &type)
2671 // Syntax:
2672 // * ( mut | const ) TypeNoBounds
2674 push (Rust::Token::make (ASTERISK, type.get_locus ()));
2675 if (type.get_pointer_type () == RawPointerType::MUT)
2676 push (Rust::Token::make (MUT, UNDEF_LOCATION));
2677 else /* RawPointerType::CONST */
2678 push (Rust::Token::make (CONST, UNDEF_LOCATION));
2680 visit (type.get_type_pointed_to ());
2683 void
2684 TokenCollector::visit (ReferenceType &type)
2686 // Syntax:
2687 // & Lifetime? mut? TypeNoBounds
2689 push (Rust::Token::make (AMP, type.get_locus ()));
2691 if (type.has_lifetime ())
2693 visit (type.get_lifetime ());
2696 if (type.get_has_mut ())
2697 push (Rust::Token::make (MUT, UNDEF_LOCATION));
2699 visit (type.get_type_referenced ());
2702 void
2703 TokenCollector::visit (ArrayType &type)
2705 // Syntax:
2706 // [ Type ; Expression ]
2708 push (Rust::Token::make (LEFT_SQUARE, type.get_locus ()));
2709 visit (type.get_elem_type ());
2710 push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
2711 visit (type.get_size_expr ());
2712 push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION));
2715 void
2716 TokenCollector::visit (SliceType &type)
2718 // Syntax:
2719 // [ Type ]
2721 push (Rust::Token::make (LEFT_SQUARE, type.get_locus ()));
2722 visit (type.get_elem_type ());
2723 push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION));
2726 void
2727 TokenCollector::visit (InferredType &type)
2729 // Syntax:
2730 // _
2732 push (Rust::Token::make (UNDERSCORE, type.get_locus ()));
2735 void
2736 TokenCollector::visit (BareFunctionType &type)
2738 // Syntax:
2739 // ForLifetimes? FunctionTypeQualifiers fn
2740 // ( FunctionParametersMaybeNamedVariadic? ) BareFunctionReturnType?
2742 // BareFunctionReturnType:
2743 // -> TypeNoBounds
2745 // FunctionParametersMaybeNamedVariadic :
2746 // MaybeNamedFunctionParameters | MaybeNamedFunctionParametersVariadic
2748 // MaybeNamedFunctionParameters :
2749 // MaybeNamedParam ( , MaybeNamedParam )* ,?
2751 // MaybeNamedFunctionParametersVariadic :
2752 // ( MaybeNamedParam , )* MaybeNamedParam , OuterAttribute* ...
2754 if (type.has_for_lifetimes ())
2755 visit (type.get_for_lifetimes ());
2757 visit (type.get_function_qualifiers ());
2759 push (Rust::Token::make (FN_KW, type.get_locus ()));
2760 push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
2762 visit_items_joined_by_separator (type.get_function_params (), COMMA);
2764 if (type.is_variadic ())
2766 push (Rust::Token::make (COMMA, UNDEF_LOCATION));
2767 for (auto &item : type.get_variadic_attr ())
2769 visit (item);
2771 push (Rust::Token::make (ELLIPSIS, UNDEF_LOCATION));
2774 push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
2776 if (type.has_return_type ())
2778 push (Rust::Token::make (RETURN_TYPE, UNDEF_LOCATION));
2779 visit (type.get_return_type ());
2783 void
2784 TokenCollector::visit (AST::FormatArgs &fmt)
2786 rust_sorry_at (fmt.get_locus (), "%s:%u: unimplemented FormatArgs visitor",
2787 __FILE__, __LINE__);
2790 } // namespace AST
2791 } // namespace Rust