]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/rust/ast/rust-ast-dump.cc
Update copyright years.
[thirdparty/gcc.git] / gcc / rust / ast / rust-ast-dump.cc
CommitLineData
a945c346 1// Copyright (C) 2020-2024 Free Software Foundation, Inc.
5b981e9c
JP
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-dump.h"
20
21namespace Rust {
22namespace AST {
23
24Indent::Indent () : tabs (0) {}
25
26std::ostream &
27operator<< (std::ostream &stream, const Indent &indent)
28{
29 return stream << std::string (indent.tabs, '\t');
30}
31
32void
33Indent::increment ()
34{
35 tabs++;
36}
37
38void
39Indent::decrement ()
40{
41 rust_assert (tabs != 0);
42 tabs--;
43}
44
45Dump::Dump (std::ostream &stream) : stream (stream), indentation (Indent ()) {}
46
47void
48Dump::go (AST::Crate &crate)
49{
3b5fb3f8 50 visit_items_as_lines (crate.items, "");
5b981e9c
JP
51}
52
53void
54Dump::go (AST::Item &item)
55{
56 item.accept_vis (*this);
57}
58
aedd97a5
JD
59template <typename T>
60void
61Dump::visit (std::unique_ptr<T> &node)
62{
63 node->accept_vis (*this);
64}
65
907d1119
JD
66template <typename T>
67void
68Dump::visit (T &node)
69{
70 node.accept_vis (*this);
71}
72
3b5fb3f8 73template <typename T>
5b981e9c 74void
3b5fb3f8
JD
75Dump::visit_items_joined_by_separator (T &collection,
76 const std::string &separator,
77 size_t start_offset, size_t end_offset)
5b981e9c 78{
3b5fb3f8
JD
79 if (collection.size () > start_offset)
80 {
81 visit (collection.at (start_offset));
82 auto size = collection.size () - end_offset;
83 for (size_t i = start_offset + 1; i < size; i++)
84 {
85 stream << separator;
86 visit (collection.at (i));
87 }
88 }
5b981e9c
JP
89}
90
3b5fb3f8 91template <typename T>
5b981e9c 92void
3b5fb3f8 93Dump::visit_as_line (T &item, const std::string &trailing)
5b981e9c 94{
3b5fb3f8
JD
95 stream << indentation;
96 visit (item);
97 stream << trailing << '\n';
98}
5b981e9c 99
3b5fb3f8
JD
100template <typename T>
101void
102Dump::visit_items_as_lines (T &collection, const std::string &trailing)
103{
104 for (auto &item : collection)
105 visit_as_line (item, trailing);
106}
107
108template <typename T>
109void
110Dump::visit_items_as_block (T &collection, const std::string &line_trailing,
111 char left_brace, char right_brace)
112{
113 if (collection.empty ())
5b981e9c 114 {
3b5fb3f8
JD
115 stream << left_brace << right_brace << '\n';
116 }
117 else
118 {
119 stream << left_brace << '\n';
120
121 indentation.increment ();
122 visit_items_as_lines (collection, line_trailing);
123 indentation.decrement ();
5b981e9c 124
3b5fb3f8 125 stream << indentation << right_brace << '\n';
5b981e9c 126 }
3b5fb3f8
JD
127}
128
129void
130Dump::visit (FunctionParam &param)
131{
132 visit (param.get_pattern ());
133 stream << ": ";
134 visit (param.get_type ());
135}
136
137void
907d1119 138Dump::visit (Attribute &attrib)
3b5fb3f8
JD
139{
140 stream << "#[";
141 visit_items_joined_by_separator (attrib.get_path ().get_segments (), "::");
5b981e9c
JP
142
143 if (attrib.has_attr_input ())
144 {
145 stream << " = ";
146
147 bool is_literal = attrib.get_attr_input ().get_attr_input_type ()
148 == AST::AttrInput::AttrInputType::LITERAL;
149 if (is_literal)
150 {
151 auto &literal
152 = static_cast<AST::AttrInputLiteral &> (attrib.get_attr_input ());
153 const auto &value = literal.get_literal ().as_string ();
154
155 stream << "\"" << value << "\"";
156 }
157 else
158 {
159 stream << "FIXME";
160 }
161 }
162
163 stream << "]";
164}
165
1e8eb102 166void
907d1119 167Dump::visit (SimplePathSegment &segment)
3b5fb3f8
JD
168{
169 stream << segment.get_segment_name ();
170}
171
172void
907d1119 173Dump::visit (Visibility &vis)
1e8eb102
AC
174{
175 switch (vis.get_vis_type ())
176 {
177 case Visibility::PUB:
178 stream << "pub ";
179 break;
180 case Visibility::PUB_CRATE:
181 stream << "pub(crate) ";
182 break;
183 case Visibility::PUB_SELF:
184 stream << "pub(self) ";
185 break;
186 case Visibility::PUB_SUPER:
187 stream << "pub(super) ";
188 break;
189 case Visibility::PUB_IN_PATH:
190 stream << "pub(in " << vis.get_path ().as_string () << ") ";
191 break;
192 case Visibility::PRIV:
193 break;
194 }
195}
196
3b5fb3f8
JD
197void
198Dump::visit (NamedFunctionParam &param)
1e8eb102 199{
3b5fb3f8
JD
200 stream << param.get_name () << ": ";
201 visit (param.get_type ());
1e8eb102
AC
202}
203
8d02ef57 204void
3b5fb3f8 205Dump::visit (std::vector<std::unique_ptr<GenericParam>> &params)
8d02ef57
DF
206{
207 stream << "<";
3b5fb3f8 208 visit_items_joined_by_separator (params, ", ");
8d02ef57
DF
209 stream << ">";
210}
211
4c807ef7 212void
3b5fb3f8 213Dump::visit (TupleField &field)
4c807ef7
DF
214{
215 // TODO: do we need to emit outer attrs here?
3b5fb3f8
JD
216 visit (field.get_visibility ());
217 visit (field.get_field_type ());
4c807ef7
DF
218}
219
220void
3b5fb3f8 221Dump::visit (StructField &field)
4c807ef7
DF
222{
223 // TODO: do we need to emit outer attrs here?
3b5fb3f8 224 visit (field.get_visibility ());
4c807ef7 225 stream << field.get_field_name () << ": ";
3b5fb3f8 226 visit (field.get_field_type ());
4c807ef7
DF
227}
228
bd2240d3
JD
229// TODO is this unique by type?
230void
231Dump::visit (std::vector<LifetimeParam> &for_lifetimes)
232{
233 // ForLifetimes :
234 // for GenericParams
235 //
236 // GenericParams :
237 // < >
238 // | < (GenericParam ,)* GenericParam ,? >
239 //
240 // GenericParam :
241 // OuterAttribute* ( LifetimeParam | TypeParam | ConstParam )
242 //
243 // LifetimeParam :
244 // LIFETIME_OR_LABEL ( : LifetimeBounds )?
245
246 stream << "for <";
247 visit_items_joined_by_separator (for_lifetimes, " + ");
248 stream << "> ";
249}
250
ae1f6b3a
JD
251void
252Dump::visit (FunctionQualifiers &qualifiers)
253{
254 // Syntax:
255 // `const`? `async`? `unsafe`? (`extern` Abi?)?
256 // unsafe? (extern Abi?)?
257
258 switch (qualifiers.get_const_status ())
259 {
260 case NONE:
261 break;
262 case CONST_FN:
263 stream << "const ";
264 break;
265 case ASYNC_FN:
266 stream << "async ";
267 break;
268 }
269
270 if (qualifiers.is_unsafe ())
271 stream << "unsafe ";
272 if (qualifiers.is_extern ())
273 {
274 stream << "extern ";
275 if (qualifiers.has_abi ())
276 stream << "\"" << qualifiers.get_extern_abi () << "\" ";
277 }
278} // namespace AST
279
280void
281Dump::visit (MaybeNamedParam &param)
282{
283 // Syntax:
284 // OuterAttribute* ( ( IDENTIFIER | _ ) : )? Type
285
286 visit_items_joined_by_separator (param.get_outer_attrs (), " ");
287 switch (param.get_param_kind ())
288 {
289 case MaybeNamedParam::UNNAMED:
290 break;
291 case MaybeNamedParam::IDENTIFIER:
292 stream << " " << param.get_name () << ": ";
293 break;
294 case MaybeNamedParam::WILDCARD:
295 stream << " _: ";
296 break;
297 }
298 visit (param.get_type ());
299}
300
5b981e9c
JP
301void
302Dump::visit (Token &tok)
ec28fdb6
AC
303{
304 stream << tok.as_string ();
305}
5b981e9c
JP
306
307void
308Dump::visit (DelimTokenTree &delim_tok_tree)
ec28fdb6 309{
ec28fdb6
AC
310 indentation.increment ();
311 stream << '\n' << indentation;
312
3b5fb3f8
JD
313 auto tokens = delim_tok_tree.to_token_stream ();
314 visit_items_joined_by_separator (tokens, " ");
ec28fdb6
AC
315
316 indentation.decrement ();
317 stream << '\n' << indentation;
318}
5b981e9c
JP
319
320void
971d16cb 321Dump::visit (AttrInputMetaItemContainer &)
5b981e9c
JP
322{}
323
324void
325Dump::visit (IdentifierExpr &ident_expr)
326{
327 stream << ident_expr.get_ident ();
328}
329
330void
331Dump::visit (Lifetime &lifetime)
bd2240d3
JD
332{
333 // Syntax:
334 // Lifetime :
335 // LIFETIME_OR_LABEL
336 // | 'static
337 // | '_
338 stream << lifetime.as_string ();
339}
5b981e9c
JP
340
341void
342Dump::visit (LifetimeParam &lifetime_param)
bd2240d3
JD
343{
344 // Syntax:
345 // LIFETIME_OR_LABEL ( : LifetimeBounds )?
346 // LifetimeBounds :
347 // ( Lifetime + )* Lifetime?
348
349 // TODO what to do with outer attr? They are not mentioned in the reference.
350
351 auto lifetime = lifetime_param.get_lifetime ();
352 visit (lifetime);
353
354 if (lifetime_param.has_lifetime_bounds ())
355 {
356 stream << ": ";
357 visit_items_joined_by_separator (lifetime_param.get_lifetime_bounds (),
358 " + ");
359 }
360}
5b981e9c
JP
361
362void
971d16cb 363Dump::visit (ConstGenericParam &)
5b981e9c
JP
364{}
365
366// rust-path.h
367void
368Dump::visit (PathInExpression &path)
1e8eb102
AC
369{
370 stream << path.as_string ();
371}
5b981e9c
JP
372
373void
b8863414
JD
374Dump::visit (TypePathSegment &segment)
375{
376 // Syntax:
377 // PathIdentSegment
378
379 stream << segment.get_ident_segment ().as_string ();
380}
5b981e9c
JP
381
382void
b8863414
JD
383Dump::visit (TypePathSegmentGeneric &segment)
384{
385 // Syntax:
386 // PathIdentSegment `::`? (GenericArgs)?
387 // GenericArgs :
388 // `<` `>`
389 // | `<` ( GenericArg `,` )* GenericArg `,`? `>`
390
391 stream << segment.get_ident_segment ().as_string ();
392
393 if (segment.get_separating_scope_resolution ())
394 stream << "::";
395
396 stream << "<";
397
398 {
399 // Here we join 3 lists (each possibly empty) with a separator.
400
401 auto &lifetime_args = segment.get_generic_args ().get_lifetime_args ();
402 auto &generic_args = segment.get_generic_args ().get_generic_args ();
403 auto &binding_args = segment.get_generic_args ().get_binding_args ();
404
405 visit_items_joined_by_separator (lifetime_args, ", ");
406 if (!lifetime_args.empty ()
407 && (!generic_args.empty () || !binding_args.empty ()))
408 {
409 // Insert separator if some items have been already emitted and some
410 // more are to be emitted from any of the following collections.
411 stream << ", ";
412 }
413 visit_items_joined_by_separator (generic_args, ", ");
414 if (!generic_args.empty () && !binding_args.empty ())
415 {
416 // Insert separator if some item vas emitted from the previous
417 // collection and more are to be emitted from the last.
418 stream << ", ";
419 }
420 visit_items_joined_by_separator (binding_args, ", ");
421 }
422
423 stream << ">";
424}
5b981e9c
JP
425
426void
b8863414
JD
427Dump::visit (GenericArgsBinding &binding)
428{
429 // Syntax:
430 // IDENTIFIER `=` Type
431
432 stream << binding.get_identifier () << " << ";
433 visit (binding.get_type ());
434}
435
436void
437Dump::visit (GenericArg &arg)
438{
439 // `GenericArg` implements `accept_vis` but it is not useful for this case as
440 // it ignores unresolved cases (`Kind::Either`).
441
442 switch (arg.get_kind ())
443 {
444 case GenericArg::Kind::Const:
445 visit (arg.get_expression ());
446 break;
447 case GenericArg::Kind::Type:
448 visit (arg.get_type ());
449 break;
450 case GenericArg::Kind::Either:
451 stream << arg.get_path ();
452 break;
453 case GenericArg::Kind::Error:
454 gcc_unreachable ();
455 }
456} // namespace AST
457
458void
459Dump::visit (TypePathSegmentFunction &segment)
460{
461 // Syntax:
462 // PathIdentSegment `::`? (TypePathFn)?
463
464 stream << segment.get_ident_segment ().as_string ();
465
466 if (segment.get_separating_scope_resolution ())
467 stream << "::";
468
469 if (!segment.is_ident_only ())
470 visit (segment.get_type_path_function ());
471}
472
473void
474Dump::visit (TypePathFunction &type_path_fn)
475{
476 // Syntax:
477 // `(` TypePathFnInputs? `)` (`->` Type)?
478 // TypePathFnInputs :
479 // Type (`,` Type)* `,`?
480
481 stream << '(';
482 if (type_path_fn.has_inputs ())
483 visit_items_joined_by_separator (type_path_fn.get_params (), ", ");
484 stream << ')';
485
486 if (type_path_fn.has_return_type ())
487 {
488 stream << "->";
489 visit (type_path_fn.get_return_type ());
490 }
491}
5b981e9c
JP
492
493void
494Dump::visit (TypePath &path)
495{
b8863414
JD
496 // Syntax:
497 // `::`? TypePathSegment (`::` TypePathSegment)*
498
499 if (path.has_opening_scope_resolution_op ())
500 stream << "::";
501 visit_items_joined_by_separator (path.get_segments (), "::");
5b981e9c
JP
502}
503
504void
505Dump::visit (QualifiedPathInExpression &path)
1e8eb102
AC
506{
507 stream << path.as_string ();
508}
5b981e9c
JP
509
510void
971d16cb 511Dump::visit (QualifiedPathInType &)
5b981e9c
JP
512{}
513
514// rust-expr.h
515void
516Dump::visit (LiteralExpr &expr)
517{
518 stream << expr.as_string ();
519}
520
521void
971d16cb 522Dump::visit (AttrInputLiteral &)
5b981e9c
JP
523{}
524
525void
971d16cb 526Dump::visit (MetaItemLitExpr &)
5b981e9c
JP
527{}
528
529void
971d16cb 530Dump::visit (MetaItemPathLit &)
5b981e9c
JP
531{}
532
533void
534Dump::visit (BorrowExpr &expr)
d1db4619
DF
535{
536 stream << '&';
537 if (expr.get_is_double_borrow ())
538 stream << '&';
539 if (expr.get_is_mut ())
540 stream << "mut ";
541
3b5fb3f8 542 visit (expr.get_borrowed_expr ());
d1db4619 543}
5b981e9c
JP
544
545void
546Dump::visit (DereferenceExpr &expr)
d1db4619
DF
547{
548 stream << '*';
3b5fb3f8 549 visit (expr.get_dereferenced_expr ());
d1db4619 550}
5b981e9c
JP
551
552void
553Dump::visit (ErrorPropagationExpr &expr)
d1db4619 554{
3b5fb3f8 555 visit (expr.get_propagating_expr ());
d1db4619
DF
556 stream << '?';
557}
5b981e9c
JP
558
559void
560Dump::visit (NegationExpr &expr)
d1db4619
DF
561{
562 switch (expr.get_expr_type ())
563 {
564 case NegationOperator::NEGATE:
565 stream << '-';
566 break;
567 case NegationOperator::NOT:
568 stream << '!';
569 break;
570 }
3b5fb3f8 571 visit (expr.get_negated_expr ());
d1db4619 572}
5b981e9c
JP
573
574void
575Dump::visit (ArithmeticOrLogicalExpr &expr)
576{
1e8eb102 577 auto op = "";
5b981e9c
JP
578 switch (expr.get_expr_type ())
579 {
580 case ArithmeticOrLogicalOperator::ADD:
1e8eb102 581 op = "+";
5b981e9c
JP
582 break;
583
584 case ArithmeticOrLogicalOperator::SUBTRACT:
1e8eb102 585 op = "-";
5b981e9c
JP
586 break;
587
588 case ArithmeticOrLogicalOperator::MULTIPLY:
1e8eb102 589 op = "*";
5b981e9c
JP
590 break;
591
592 case ArithmeticOrLogicalOperator::DIVIDE:
1e8eb102 593 op = "/";
5b981e9c
JP
594 break;
595
596 case ArithmeticOrLogicalOperator::MODULUS:
1e8eb102 597 op = "%";
5b981e9c
JP
598 break;
599
600 case ArithmeticOrLogicalOperator::BITWISE_AND:
1e8eb102 601 op = "&";
5b981e9c
JP
602 break;
603
604 case ArithmeticOrLogicalOperator::BITWISE_OR:
1e8eb102 605 op = "|";
5b981e9c
JP
606 break;
607
608 case ArithmeticOrLogicalOperator::BITWISE_XOR:
1e8eb102 609 op = "^";
5b981e9c
JP
610 break;
611
612 case ArithmeticOrLogicalOperator::LEFT_SHIFT:
1e8eb102 613 op = "<<";
5b981e9c
JP
614 break;
615
616 case ArithmeticOrLogicalOperator::RIGHT_SHIFT:
1e8eb102 617 op = ">>";
5b981e9c
JP
618 break;
619 }
620
3b5fb3f8 621 visit (expr.get_left_expr ());
1e8eb102 622 stream << " " << op << " ";
3b5fb3f8 623 visit (expr.get_right_expr ());
5b981e9c
JP
624}
625
626void
627Dump::visit (ComparisonExpr &expr)
c091fd5f
DF
628{
629 auto op = "";
630 switch (expr.get_expr_type ())
631 {
632 case ComparisonOperator::EQUAL:
633 op = "==";
634 break;
635 case ComparisonOperator::NOT_EQUAL:
636 op = "!=";
637 break;
638
639 case ComparisonOperator::GREATER_THAN:
640 op = ">";
641 break;
642
643 case ComparisonOperator::LESS_THAN:
644 op = "<";
645 break;
646
647 case ComparisonOperator::GREATER_OR_EQUAL:
648 op = ">=";
649 break;
650
651 case ComparisonOperator::LESS_OR_EQUAL:
652 op = "<=";
653 break;
654 }
655
3b5fb3f8 656 visit (expr.get_left_expr ());
c091fd5f 657 stream << " " << op << " ";
3b5fb3f8 658 visit (expr.get_right_expr ());
c091fd5f 659}
5b981e9c
JP
660
661void
662Dump::visit (LazyBooleanExpr &expr)
c091fd5f
DF
663{
664 auto op = "";
665 switch (expr.get_expr_type ())
666 {
667 case LazyBooleanOperator::LOGICAL_AND:
668 op = "&&";
669 break;
670 case LazyBooleanOperator::LOGICAL_OR:
671 op = "||";
672 break;
673 }
674
3b5fb3f8 675 visit (expr.get_left_expr ());
c091fd5f 676 stream << " " << op << " ";
3b5fb3f8 677 visit (expr.get_right_expr ());
c091fd5f 678}
5b981e9c
JP
679
680void
681Dump::visit (TypeCastExpr &expr)
d1db4619 682{
3b5fb3f8 683 visit (expr.get_casted_expr ());
d1db4619 684 stream << " as ";
3b5fb3f8 685 visit (expr.get_type_to_cast_to ());
d1db4619 686}
5b981e9c
JP
687
688void
689Dump::visit (AssignmentExpr &expr)
980bd25e
DF
690{
691 expr.visit_lhs (*this);
692 stream << " = ";
693 expr.visit_rhs (*this);
694}
5b981e9c
JP
695
696void
697Dump::visit (CompoundAssignmentExpr &expr)
980bd25e
DF
698{
699 auto op = "";
700 switch (expr.get_expr_type ())
701 {
702 case CompoundAssignmentOperator::ADD:
703 op = "+";
704 break;
705
706 case CompoundAssignmentOperator::SUBTRACT:
707 op = "-";
708 break;
709
710 case CompoundAssignmentOperator::MULTIPLY:
711 op = "*";
712 break;
713
714 case CompoundAssignmentOperator::DIVIDE:
715 op = "/";
716 break;
717
718 case CompoundAssignmentOperator::MODULUS:
719 op = "%";
720 break;
721
722 case CompoundAssignmentOperator::BITWISE_AND:
723 op = "&";
724 break;
725
726 case CompoundAssignmentOperator::BITWISE_OR:
727 op = "|";
728 break;
729
730 case CompoundAssignmentOperator::BITWISE_XOR:
731 op = "^";
732 break;
733
734 case CompoundAssignmentOperator::LEFT_SHIFT:
735 op = "<<";
736 break;
737
738 case CompoundAssignmentOperator::RIGHT_SHIFT:
739 op = ">>";
740 break;
741 }
742
3b5fb3f8 743 visit (expr.get_left_expr ());
980bd25e 744 stream << " " << op << "= ";
3b5fb3f8 745 visit (expr.get_right_expr ());
980bd25e 746}
5b981e9c
JP
747
748void
749Dump::visit (GroupedExpr &expr)
d1db4619
DF
750{
751 stream << '(';
3b5fb3f8 752 visit (expr.get_expr_in_parens ());
d1db4619
DF
753 stream << ')';
754}
5b981e9c
JP
755
756void
757Dump::visit (ArrayElemsValues &elems)
f26e9ca3 758{
3b5fb3f8 759 visit_items_joined_by_separator (elems.get_values (), ", ");
f26e9ca3 760}
5b981e9c
JP
761
762void
763Dump::visit (ArrayElemsCopied &elems)
f26e9ca3 764{
3b5fb3f8 765 visit (elems.get_elem_to_copy ());
f26e9ca3 766 stream << "; ";
3b5fb3f8 767 visit (elems.get_num_copies ());
f26e9ca3 768}
5b981e9c
JP
769
770void
771Dump::visit (ArrayExpr &expr)
f26e9ca3
DF
772{
773 stream << '[';
3b5fb3f8 774 visit (expr.get_array_elems ());
f26e9ca3
DF
775 stream << ']';
776}
5b981e9c
JP
777
778void
779Dump::visit (ArrayIndexExpr &expr)
f26e9ca3 780{
3b5fb3f8 781 visit (expr.get_array_expr ());
f26e9ca3 782 stream << '[';
3b5fb3f8 783 visit (expr.get_index_expr ());
f26e9ca3
DF
784 stream << ']';
785}
5b981e9c
JP
786
787void
971d16cb 788Dump::visit (TupleExpr &)
5b981e9c
JP
789{}
790
791void
971d16cb 792Dump::visit (TupleIndexExpr &)
5b981e9c
JP
793{}
794
795void
971d16cb 796Dump::visit (StructExprStruct &)
5b981e9c
JP
797{}
798
799void
971d16cb 800Dump::visit (StructExprFieldIdentifier &)
5b981e9c
JP
801{}
802
803void
971d16cb 804Dump::visit (StructExprFieldIdentifierValue &)
5b981e9c
JP
805{}
806
807void
971d16cb 808Dump::visit (StructExprFieldIndexValue &)
5b981e9c
JP
809{}
810
811void
971d16cb 812Dump::visit (StructExprStructFields &)
5b981e9c
JP
813{}
814
815void
971d16cb 816Dump::visit (StructExprStructBase &)
5b981e9c
JP
817{}
818
819void
820Dump::visit (CallExpr &expr)
1e8eb102 821{
3b5fb3f8 822 visit (expr.get_function_expr ());
1e8eb102 823
3b5fb3f8 824 stream << '(' << '\n';
1e8eb102
AC
825 indentation.increment ();
826
3b5fb3f8 827 visit_items_as_lines (expr.get_params (), ",");
1e8eb102
AC
828
829 indentation.decrement ();
3b5fb3f8 830 stream << indentation << ')';
1e8eb102 831}
5b981e9c
JP
832
833void
971d16cb 834Dump::visit (MethodCallExpr &)
5b981e9c
JP
835{}
836
837void
971d16cb 838Dump::visit (FieldAccessExpr &)
5b981e9c
JP
839{}
840
841void
971d16cb 842Dump::visit (ClosureExprInner &)
5b981e9c
JP
843{}
844
845void
846Dump::visit (BlockExpr &expr)
847{
848 stream << "{\n";
849 indentation.increment ();
850
0e44abb1 851 visit_items_as_lines (expr.get_statements (), ";");
5b981e9c
JP
852
853 if (expr.has_tail_expr ())
3b5fb3f8 854 visit_as_line (expr.get_tail_expr (), " /* tail expr */\n");
5b981e9c
JP
855
856 indentation.decrement ();
b1510ce0 857 stream << indentation << "}\n";
5b981e9c
JP
858}
859
860void
971d16cb 861Dump::visit (ClosureExprInnerTyped &)
5b981e9c
JP
862{}
863
864void
971d16cb 865Dump::visit (ContinueExpr &)
5b981e9c
JP
866{}
867
868void
971d16cb 869Dump::visit (BreakExpr &)
5b981e9c
JP
870{}
871
872void
873Dump::visit (RangeFromToExpr &expr)
173f98ae 874{
3b5fb3f8 875 visit (expr.get_from_expr ());
173f98ae 876 stream << "..";
3b5fb3f8 877 visit (expr.get_to_expr ());
173f98ae 878}
5b981e9c
JP
879
880void
881Dump::visit (RangeFromExpr &expr)
173f98ae 882{
3b5fb3f8 883 visit (expr.get_from_expr ());
173f98ae
DF
884 stream << "..";
885}
5b981e9c
JP
886
887void
888Dump::visit (RangeToExpr &expr)
173f98ae
DF
889{
890 stream << "..";
3b5fb3f8 891 visit (expr.get_to_expr ());
173f98ae 892}
5b981e9c
JP
893
894void
971d16cb 895Dump::visit (RangeFullExpr &)
173f98ae
DF
896{
897 stream << "..";
898}
5b981e9c
JP
899
900void
901Dump::visit (RangeFromToInclExpr &expr)
173f98ae 902{
3b5fb3f8 903 visit (expr.get_from_expr ());
173f98ae 904 stream << "..=";
3b5fb3f8 905 visit (expr.get_to_expr ());
173f98ae 906}
5b981e9c
JP
907
908void
909Dump::visit (RangeToInclExpr &expr)
173f98ae
DF
910{
911 stream << "..=";
3b5fb3f8 912 visit (expr.get_to_expr ());
173f98ae 913}
5b981e9c
JP
914
915void
971d16cb 916Dump::visit (ReturnExpr &)
5b981e9c
JP
917{}
918
919void
971d16cb 920Dump::visit (UnsafeBlockExpr &)
5b981e9c
JP
921{}
922
923void
971d16cb 924Dump::visit (LoopExpr &)
5b981e9c
JP
925{}
926
927void
971d16cb 928Dump::visit (WhileLoopExpr &)
5b981e9c
JP
929{}
930
931void
971d16cb 932Dump::visit (WhileLetLoopExpr &)
5b981e9c
JP
933{}
934
935void
971d16cb 936Dump::visit (ForLoopExpr &)
5b981e9c
JP
937{}
938
939void
940Dump::visit (IfExpr &expr)
aeed7470
DF
941{
942 stream << "if ";
3b5fb3f8 943 visit (expr.get_condition_expr ());
0a9114c1 944 stream << " ";
3b5fb3f8 945 visit (expr.get_if_block ());
aeed7470 946}
5b981e9c
JP
947
948void
949Dump::visit (IfExprConseqElse &expr)
aeed7470
DF
950{
951 stream << "if ";
3b5fb3f8 952 visit (expr.get_condition_expr ());
0a9114c1 953 stream << " ";
3b5fb3f8 954 visit (expr.get_if_block ());
aeed7470 955 stream << indentation << "else ";
3b5fb3f8 956 visit (expr.get_else_block ());
aeed7470 957}
5b981e9c
JP
958
959void
960Dump::visit (IfExprConseqIf &expr)
aeed7470
DF
961{
962 stream << "if ";
3b5fb3f8 963 visit (expr.get_condition_expr ());
0a9114c1 964 stream << " ";
3b5fb3f8 965 visit (expr.get_if_block ());
0a9114c1
DF
966 stream << indentation << "else ";
967 // The "if" part of the "else if" is printed by the next visitor
3b5fb3f8 968 visit (expr.get_conseq_if_expr ());
aeed7470 969}
5b981e9c
JP
970
971void
971d16cb 972Dump::visit (IfExprConseqIfLet &)
5b981e9c
JP
973{}
974
975void
971d16cb 976Dump::visit (IfLetExpr &)
5b981e9c
JP
977{}
978
979void
971d16cb 980Dump::visit (IfLetExprConseqElse &)
5b981e9c
JP
981{}
982
983void
971d16cb 984Dump::visit (IfLetExprConseqIf &)
5b981e9c
JP
985{}
986
987void
971d16cb 988Dump::visit (IfLetExprConseqIfLet &)
5b981e9c
JP
989{}
990
991void
971d16cb 992Dump::visit (MatchExpr &)
5b981e9c
JP
993{}
994
995void
971d16cb 996Dump::visit (AwaitExpr &)
5b981e9c
JP
997{}
998
999void
971d16cb 1000Dump::visit (AsyncBlockExpr &)
5b981e9c
JP
1001{}
1002
1003// rust-item.h
1004void
1005Dump::visit (TypeParam &param)
1006{
1acb7e02
JD
1007 // Syntax:
1008 // IDENTIFIER( : TypeParamBounds? )? ( = Type )?
1009 // TypeParamBounds :
1010 // TypeParamBound ( + TypeParamBound )* +?
1011
5b981e9c 1012 stream << param.get_type_representation ();
1acb7e02
JD
1013 if (param.has_type_param_bounds ())
1014 {
1015 stream << ": ";
1016 visit_items_joined_by_separator (param.get_type_param_bounds (), " + ");
1017 }
5b981e9c
JP
1018 if (param.has_type ())
1019 {
1020 stream << " = ";
3b5fb3f8 1021 visit (param.get_type ());
5b981e9c
JP
1022 }
1023}
1024
bd2240d3
JD
1025void
1026Dump::visit (WhereClause &rule)
1027{
1028 // Syntax:
1029 // where ( WhereClauseItem , )* WhereClauseItem ?
1030 // WhereClauseItem :
1031 // LifetimeWhereClauseItem
1032 // | TypeBoundWhereClauseItem
1033
1034 stream << " where\n";
1035 indentation.increment ();
1036 visit_items_as_lines (rule.get_items (), ",");
1037 indentation.decrement ();
1038}
1039
5b981e9c
JP
1040void
1041Dump::visit (LifetimeWhereClauseItem &item)
bd2240d3
JD
1042{
1043 // Syntax:
1044 // Lifetime : LifetimeBounds
1045 // LifetimeBounds :
1046 // ( Lifetime + )* Lifetime?
1047
1048 visit (item.get_lifetime ());
1049 stream << ": ";
1050 visit_items_joined_by_separator (item.get_lifetime_bounds (), " + ");
1051}
5b981e9c
JP
1052
1053void
1054Dump::visit (TypeBoundWhereClauseItem &item)
bd2240d3
JD
1055{
1056 // Syntax:
1057 // ForLifetimes? Type : TypeParamBounds?
1058 // TypeParamBounds :
1059 // TypeParamBound ( + TypeParamBound )* +?
1060 // TypeParamBound :
1061 // Lifetime | TraitBound
1062
1063 if (item.has_for_lifetimes ())
1064 visit (item.get_for_lifetimes ());
1065
1066 visit (item.get_type ());
1067 stream << ": ";
1068
1069 visit_items_joined_by_separator (item.get_type_param_bounds (), " + ");
1070}
5b981e9c
JP
1071
1072void
1073Dump::visit (Method &method)
1074{
3b5fb3f8 1075 visit (method.get_visibility ());
1e8eb102 1076 stream << "fn " << method.get_method_name () << '(';
5b981e9c 1077
567494f7
JD
1078 stream << method.get_self_param ().as_string ();
1079 if (!method.get_function_params ().empty ())
1080 {
1081 stream << ", ";
1082 visit_items_joined_by_separator (method.get_function_params (), ", ");
1083 }
5b981e9c
JP
1084
1085 stream << ") ";
1086
1087 if (method.has_return_type ())
1088 {
1089 stream << "-> ";
3b5fb3f8 1090 visit (method.get_return_type ());
5b981e9c
JP
1091 stream << " ";
1092 }
1093
1094 auto &block = method.get_definition ();
1095 if (!block)
1096 stream << ';';
1097 else
3b5fb3f8 1098 visit (block);
5b981e9c
JP
1099
1100 stream << '\n';
1101}
1102
1103void
1104Dump::visit (Module &module)
31150a63 1105{
e535b7b3
JD
1106 // Syntax:
1107 // mod IDENTIFIER ;
1108 // | mod IDENTIFIER {
1109 // InnerAttribute*
1110 // Item*
1111 // }
2f16df1b 1112
3b5fb3f8 1113 visit (module.get_visibility ());
e535b7b3 1114 stream << "mod " << module.get_name ();
31150a63 1115
e535b7b3 1116 if (module.get_kind () == Module::UNLOADED)
31150a63 1117 {
e535b7b3 1118 stream << ";\n";
31150a63 1119 }
e535b7b3
JD
1120 else /* Module::LOADED */
1121 {
1122 stream << " {\n";
31150a63 1123
e535b7b3 1124 indentation.increment ();
2f16df1b 1125
3b5fb3f8
JD
1126 visit_items_as_lines (module.get_inner_attrs ());
1127 visit_items_as_lines (module.get_items ());
e535b7b3
JD
1128
1129 indentation.decrement ();
1130
1131 stream << indentation << "}\n";
1132 }
31150a63 1133}
5b981e9c
JP
1134
1135void
971d16cb 1136Dump::visit (ExternCrate &)
5b981e9c
JP
1137{}
1138
1139void
971d16cb 1140Dump::visit (UseTreeGlob &)
5b981e9c
JP
1141{}
1142
1143void
971d16cb 1144Dump::visit (UseTreeList &)
5b981e9c
JP
1145{}
1146
1147void
971d16cb 1148Dump::visit (UseTreeRebind &)
5b981e9c
JP
1149{}
1150
1151void
971d16cb 1152Dump::visit (UseDeclaration &)
5b981e9c
JP
1153{}
1154
1155void
1156Dump::visit (Function &function)
1157{
bd2240d3
JD
1158 // Syntax:
1159 // FunctionQualifiers fn IDENTIFIER GenericParams?
1160 // ( FunctionParameters? )
1161 // FunctionReturnType? WhereClause?
1162 // ( BlockExpression | ; )
1163
3b5fb3f8 1164 visit (function.get_visibility ());
421494b5 1165
5b981e9c 1166 stream << "fn " << function.get_function_name ();
5b981e9c 1167 if (function.has_generics ())
3b5fb3f8 1168 visit (function.get_generic_params ());
5b981e9c
JP
1169
1170 stream << '(';
3b5fb3f8 1171 visit_items_joined_by_separator (function.get_function_params ());
5b981e9c
JP
1172 stream << ") ";
1173
1174 if (function.has_return_type ())
1175 {
1176 stream << "-> ";
3b5fb3f8 1177 visit (function.get_return_type ());
5b981e9c
JP
1178 stream << " ";
1179 }
1180
bd2240d3
JD
1181 if (function.has_where_clause ())
1182 visit (function.get_where_clause ());
1183
5b981e9c
JP
1184 auto &block = function.get_definition ();
1185 if (!block)
1186 stream << ';';
1187 else
3b5fb3f8 1188 visit (block);
5b981e9c
JP
1189
1190 stream << '\n';
1191}
1192
1193void
1194Dump::visit (TypeAlias &type_alias)
acbaadfa
JD
1195{
1196 // Syntax:
1197 // Visibility? type IDENTIFIER GenericParams? WhereClause? = Type;
1198
1199 // Note: Associated types are handled by `AST::TraitItemType`.
1200
1201 if (type_alias.has_visibility ())
3b5fb3f8 1202 visit (type_alias.get_visibility ());
acbaadfa
JD
1203 stream << "type " << type_alias.get_new_type_name ();
1204 if (type_alias.has_generics ())
3b5fb3f8 1205 visit (type_alias.get_generic_params ());
acbaadfa 1206 if (type_alias.has_where_clause ())
bd2240d3 1207 visit (type_alias.get_where_clause ());
acbaadfa 1208 stream << " = ";
3b5fb3f8 1209 visit (type_alias.get_type_aliased ());
acbaadfa 1210}
5b981e9c
JP
1211
1212void
1213Dump::visit (StructStruct &struct_item)
0a762d20
DF
1214{
1215 stream << "struct " << struct_item.get_identifier ();
1216 if (struct_item.has_generics ())
3b5fb3f8 1217 visit (struct_item.get_generic_params ());
bd2240d3
JD
1218 if (struct_item.has_where_clause ())
1219 visit (struct_item.get_where_clause ());
04a16c58
JD
1220 if (struct_item.is_unit_struct ())
1221 stream << ";\n";
1222 else
1223 visit_items_as_block (struct_item.get_fields (), ",");
0a762d20 1224}
5b981e9c
JP
1225
1226void
1227Dump::visit (TupleStruct &tuple_struct)
0a762d20
DF
1228{
1229 stream << "struct " << tuple_struct.get_identifier ();
1230 if (tuple_struct.has_generics ())
3b5fb3f8 1231 visit (tuple_struct.get_generic_params ());
bd2240d3
JD
1232 if (tuple_struct.has_where_clause ())
1233 visit (tuple_struct.get_where_clause ());
0a762d20
DF
1234
1235 stream << '(';
3b5fb3f8 1236 visit_items_joined_by_separator (tuple_struct.get_fields (), ", ");
0a762d20
DF
1237 stream << ");\n";
1238}
5b981e9c
JP
1239
1240void
1241Dump::visit (EnumItem &item)
0a762d20
DF
1242{
1243 stream << item.get_identifier ();
1244}
5b981e9c
JP
1245
1246void
1247Dump::visit (EnumItemTuple &item)
0a762d20
DF
1248{
1249 stream << item.get_identifier () << '(';
3b5fb3f8 1250 visit_items_joined_by_separator (item.get_tuple_fields (), ", ");
0a762d20
DF
1251 stream << ')';
1252}
5b981e9c
JP
1253
1254void
1255Dump::visit (EnumItemStruct &item)
0a762d20 1256{
3b5fb3f8
JD
1257 stream << item.get_identifier ();
1258 visit_items_as_block (item.get_struct_fields (), ",");
0a762d20 1259}
5b981e9c
JP
1260
1261void
1262Dump::visit (EnumItemDiscriminant &item)
0a762d20
DF
1263{
1264 stream << item.get_identifier () << " = ";
3b5fb3f8 1265 visit (item.get_expr ());
0a762d20 1266}
5b981e9c
JP
1267
1268void
1269Dump::visit (Enum &enum_item)
0a762d20
DF
1270{
1271 stream << "enum " << enum_item.get_identifier ();
1272 if (enum_item.has_generics ())
3b5fb3f8 1273 visit (enum_item.get_generic_params ());
bd2240d3
JD
1274 if (enum_item.has_where_clause ())
1275 visit (enum_item.get_where_clause ());
0a762d20 1276
3b5fb3f8 1277 visit_items_as_block (enum_item.get_variants (), ",");
0a762d20 1278}
5b981e9c
JP
1279
1280void
1281Dump::visit (Union &union_item)
0a762d20
DF
1282{
1283 stream << "union " << union_item.get_identifier ();
1284 if (union_item.has_generics ())
3b5fb3f8 1285 visit (union_item.get_generic_params ());
bd2240d3
JD
1286 if (union_item.has_where_clause ())
1287 visit (union_item.get_where_clause ());
0a762d20 1288
3b5fb3f8 1289 visit_items_as_block (union_item.get_variants (), ",");
0a762d20 1290}
5b981e9c
JP
1291
1292void
971d16cb 1293Dump::visit (ConstantItem &)
5b981e9c
JP
1294{}
1295
1296void
971d16cb 1297Dump::visit (StaticItem &)
5b981e9c
JP
1298{}
1299
1300void
3b5fb3f8
JD
1301Dump::visit_function_common (std::unique_ptr<Type> &return_type,
1302 std::unique_ptr<BlockExpr> &block)
5b981e9c 1303{
1e8eb102 1304 // FIXME: This should format the `<vis> fn <name> ( [args] )` as well
5b981e9c
JP
1305 if (return_type)
1306 {
1307 stream << "-> ";
3b5fb3f8 1308 visit (return_type);
5b981e9c
JP
1309 }
1310
1311 if (block)
1312 {
1313 if (return_type)
1e8eb102
AC
1314 {
1315 stream << ' ';
3b5fb3f8 1316 visit (block);
1e8eb102 1317 }
5b981e9c
JP
1318 }
1319 else
1320 stream << ";\n";
1321}
1322
1323void
1324Dump::visit (TraitItemFunc &item)
1325{
1326 auto func = item.get_trait_function_decl ();
8e7e682a 1327 stream << "fn " << func.get_identifier () << '(';
5b981e9c 1328
3b5fb3f8 1329 visit_items_joined_by_separator (func.get_function_params ());
5b981e9c
JP
1330
1331 stream << ") ";
1332
3b5fb3f8 1333 visit_function_common (func.get_return_type (), item.get_definition ());
5b981e9c
JP
1334}
1335
1336void
1337Dump::visit (TraitItemMethod &item)
1338{
1339 auto method = item.get_trait_method_decl ();
1e8eb102 1340
1e8eb102
AC
1341 // FIXME: Can we have visibility here?
1342 // emit_visibility (method.get_visibility ());
1343 stream << "fn " << method.get_identifier () << '(';
5b981e9c 1344
567494f7 1345 stream << method.get_self_param ().as_string ();
5b981e9c 1346
567494f7
JD
1347 if (!method.get_function_params ().empty ())
1348 {
1349 stream << ", ";
1350 visit_items_joined_by_separator (method.get_function_params (), ", ");
1351 }
5b981e9c
JP
1352
1353 stream << ") ";
1354
3b5fb3f8 1355 visit_function_common (method.get_return_type (), item.get_definition ());
5b981e9c
JP
1356}
1357
1358void
1359Dump::visit (TraitItemConst &item)
1360{
1361 stream << indentation << "const " << item.get_identifier () << ": ";
3b5fb3f8 1362 visit (item.get_type ());
5b981e9c
JP
1363 stream << ";\n";
1364}
1365
1366void
1367Dump::visit (TraitItemType &item)
1368{
1369 stream << indentation << "type " << item.get_identifier () << ";\n";
1370}
1371
1372void
1373Dump::visit (Trait &trait)
1374{
907d1119 1375 for (auto &attr : trait.get_outer_attrs ())
5b981e9c 1376 {
3b5fb3f8 1377 visit (attr);
5b981e9c
JP
1378 stream << "\n" << indentation;
1379 }
1380
3b5fb3f8 1381 visit (trait.get_visibility ());
1e8eb102 1382
5b981e9c
JP
1383 stream << "trait " << trait.get_identifier ();
1384
3b5fb3f8
JD
1385 // Traits actually have an implicit Self thrown at the start, so we must
1386 // expect the number of generic params to be > 1
5b981e9c
JP
1387 if (trait.get_generic_params ().size () > 1)
1388 {
1389 stream << "<";
3b5fb3f8 1390 visit_items_joined_by_separator (trait.get_generic_params (), ", ", 1);
5b981e9c
JP
1391 stream << ">";
1392 }
1393
3b5fb3f8 1394 visit_items_as_block (trait.get_trait_items (), "");
5b981e9c
JP
1395}
1396
1397void
1398Dump::visit (InherentImpl &impl)
1399{
1400 stream << "impl ";
1401
1402 // FIXME: Handle generics
1403
3b5fb3f8 1404 visit (impl.get_type ());
5b981e9c 1405
bd2240d3
JD
1406 if (impl.has_where_clause ())
1407 visit (impl.get_where_clause ());
1408
5b981e9c
JP
1409 // FIXME: Handle inner attributes
1410
3b5fb3f8 1411 visit_items_as_block (impl.get_impl_items (), "");
5b981e9c
JP
1412}
1413
1414void
1415Dump::visit (TraitImpl &impl)
1416{
1417 stream << "impl ";
3b5fb3f8 1418 visit (impl.get_trait_path ());
5b981e9c 1419 stream << " for ";
3b5fb3f8 1420 visit (impl.get_type ());
5b981e9c 1421 stream << " {\n";
1e8eb102 1422
5b981e9c
JP
1423 indentation.increment ();
1424
1425 for (auto &item : impl.get_impl_items ())
1e8eb102
AC
1426 {
1427 stream << indentation;
3b5fb3f8 1428 visit (item);
1e8eb102 1429 }
5b981e9c
JP
1430
1431 indentation.decrement ();
1432 stream << "\n}\n";
1433}
1434
1435void
971d16cb 1436Dump::visit (ExternalStaticItem &)
5b981e9c
JP
1437{}
1438
1439void
1440Dump::visit (ExternalFunctionItem &function)
1441{
3b5fb3f8 1442 visit (function.get_visibility ());
1e8eb102 1443
5b981e9c
JP
1444 stream << "fn " << function.get_identifier () << '(';
1445
3b5fb3f8 1446 visit_items_joined_by_separator (function.get_function_params ());
5b981e9c
JP
1447
1448 stream << ')';
1449 if (function.has_return_type ())
1450 {
1451 stream << "-> ";
3b5fb3f8 1452 visit (function.get_return_type ());
5b981e9c
JP
1453 }
1454}
1455
1456void
1457Dump::visit (ExternBlock &block)
1458{
1459 stream << "extern ";
1460
1461 if (block.has_abi ())
1e8eb102 1462 stream << "\"" << block.get_abi () << "\" ";
5b981e9c 1463
3b5fb3f8 1464 visit_items_as_block (block.get_extern_items (), ";");
5b981e9c
JP
1465}
1466
ec28fdb6
AC
1467static std::pair<char, char>
1468get_delimiters (DelimType delim)
1469{
1470 auto start_delim = '\0';
1471 auto end_delim = '\0';
1472
1473 switch (delim)
1474 {
1475 case PARENS:
1476 start_delim = '(';
1477 end_delim = ')';
1478 break;
1479 case SQUARE:
1480 start_delim = '[';
1481 end_delim = ']';
1482 break;
1483 case CURLY:
1484 start_delim = '{';
1485 end_delim = '}';
1486 break;
1487 }
1488
1489 return {start_delim, end_delim};
1490}
1491
5b981e9c
JP
1492void
1493Dump::visit (MacroMatchFragment &match)
ec28fdb6
AC
1494{
1495 stream << '$' << match.get_ident () << ':'
1496 << match.get_frag_spec ().as_string ();
1497}
5b981e9c
JP
1498
1499void
ec28fdb6
AC
1500Dump::visit (MacroMatchRepetition &repetition)
1501{
1502 stream << "$(";
1503
3b5fb3f8 1504 visit_items_joined_by_separator (repetition.get_matches (), " ");
ec28fdb6
AC
1505
1506 auto op_char = '\0';
1507 switch (repetition.get_op ())
1508 {
1509 case MacroMatchRepetition::ANY:
1510 op_char = '*';
1511 break;
1512 case MacroMatchRepetition::ONE_OR_MORE:
1513 op_char = '+';
1514 break;
1515 case MacroMatchRepetition::ZERO_OR_ONE:
1516 op_char = '?';
1517 break;
1518 case MacroMatchRepetition::NONE:
1519 break;
1520 }
1521
1522 stream << ')';
1523
1524 if (repetition.has_sep ())
1525 stream << repetition.get_sep ()->as_string ();
1526
1527 stream << op_char;
1528}
5b981e9c
JP
1529
1530void
1531Dump::visit (MacroMatcher &matcher)
ec28fdb6
AC
1532{
1533 auto delimiters = get_delimiters (matcher.get_delim_type ());
1534
1535 stream << delimiters.first;
1536
3b5fb3f8 1537 visit_items_joined_by_separator (matcher.get_matches (), " ");
ec28fdb6
AC
1538
1539 stream << delimiters.second;
1540}
5b981e9c 1541
3b5fb3f8
JD
1542void
1543Dump::visit (MacroRule &rule)
1544{
1545 visit (rule.get_matcher ());
1546 stream << " => ";
1547 visit (rule.get_transcriber ().get_token_tree ());
1548 stream << ";";
1549}
1550
5b981e9c
JP
1551void
1552Dump::visit (MacroRulesDefinition &rules_def)
ec28fdb6
AC
1553{
1554 for (auto &outer_attr : rules_def.get_outer_attrs ())
3b5fb3f8 1555 visit (outer_attr);
ec28fdb6 1556
3b5fb3f8 1557 stream << "macro_rules! " << rules_def.get_rule_name ();
ec28fdb6 1558
3b5fb3f8 1559 visit_items_as_block (rules_def.get_rules (), ";");
ec28fdb6 1560}
5b981e9c
JP
1561
1562void
971d16cb 1563Dump::visit (MacroInvocation &)
5b981e9c
JP
1564{}
1565
1566void
971d16cb 1567Dump::visit (MetaItemPath &)
5b981e9c
JP
1568{}
1569
1570void
971d16cb 1571Dump::visit (MetaItemSeq &)
5b981e9c
JP
1572{}
1573
1574void
971d16cb 1575Dump::visit (MetaWord &)
5b981e9c
JP
1576{}
1577
1578void
971d16cb 1579Dump::visit (MetaNameValueStr &)
5b981e9c
JP
1580{}
1581
1582void
971d16cb 1583Dump::visit (MetaListPaths &)
5b981e9c
JP
1584{}
1585
1586void
971d16cb 1587Dump::visit (MetaListNameValueStr &)
5b981e9c
JP
1588{}
1589
1590// rust-pattern.h
1591void
971d16cb 1592Dump::visit (LiteralPattern &)
5b981e9c
JP
1593{}
1594
1595void
1596Dump::visit (IdentifierPattern &pattern)
1597{
1598 stream << pattern.get_ident ();
1599}
1600
1601void
971d16cb 1602Dump::visit (WildcardPattern &)
5b981e9c
JP
1603{}
1604
971d16cb 1605// void Dump::visit(RangePatternBound& ){}
5b981e9c
JP
1606
1607void
971d16cb 1608Dump::visit (RangePatternBoundLiteral &)
5b981e9c
JP
1609{}
1610
1611void
971d16cb 1612Dump::visit (RangePatternBoundPath &)
5b981e9c
JP
1613{}
1614
1615void
971d16cb 1616Dump::visit (RangePatternBoundQualPath &)
5b981e9c
JP
1617{}
1618
1619void
971d16cb 1620Dump::visit (RangePattern &)
5b981e9c
JP
1621{}
1622
1623void
971d16cb 1624Dump::visit (ReferencePattern &)
5b981e9c
JP
1625{}
1626
971d16cb 1627// void Dump::visit(StructPatternField& ){}
5b981e9c
JP
1628
1629void
971d16cb 1630Dump::visit (StructPatternFieldTuplePat &)
5b981e9c
JP
1631{}
1632
1633void
971d16cb 1634Dump::visit (StructPatternFieldIdentPat &)
5b981e9c
JP
1635{}
1636
1637void
971d16cb 1638Dump::visit (StructPatternFieldIdent &)
5b981e9c
JP
1639{}
1640
1641void
971d16cb 1642Dump::visit (StructPattern &)
5b981e9c
JP
1643{}
1644
971d16cb 1645// void Dump::visit(TupleStructItems& ){}
5b981e9c
JP
1646
1647void
971d16cb 1648Dump::visit (TupleStructItemsNoRange &)
5b981e9c
JP
1649{}
1650
1651void
971d16cb 1652Dump::visit (TupleStructItemsRange &)
5b981e9c
JP
1653{}
1654
1655void
971d16cb 1656Dump::visit (TupleStructPattern &)
5b981e9c
JP
1657{}
1658
971d16cb 1659// void Dump::visit(TuplePatternItems& ){}
5b981e9c
JP
1660
1661void
971d16cb 1662Dump::visit (TuplePatternItemsMultiple &)
5b981e9c
JP
1663{}
1664
1665void
971d16cb 1666Dump::visit (TuplePatternItemsRanged &)
5b981e9c
JP
1667{}
1668
1669void
971d16cb 1670Dump::visit (TuplePattern &)
5b981e9c
JP
1671{}
1672
1673void
971d16cb 1674Dump::visit (GroupedPattern &)
5b981e9c
JP
1675{}
1676
1677void
971d16cb 1678Dump::visit (SlicePattern &)
5b981e9c
JP
1679{}
1680
8628486f
OA
1681void
1682Dump::visit (AltPattern &)
1683{}
1684
5b981e9c
JP
1685// rust-stmt.h
1686void
971d16cb 1687Dump::visit (EmptyStmt &)
5b981e9c
JP
1688{}
1689
1690void
1691Dump::visit (LetStmt &stmt)
1692{
1693 stream << "let ";
1694 auto &pattern = stmt.get_pattern ();
1695 if (pattern)
3b5fb3f8 1696 visit (pattern);
5b981e9c
JP
1697
1698 if (stmt.has_type ())
1699 {
1700 stream << ": ";
3b5fb3f8 1701 visit (stmt.get_type ());
5b981e9c
JP
1702 }
1703
1704 if (stmt.has_init_expr ())
1705 {
1706 stream << " = ";
3b5fb3f8 1707 visit (stmt.get_init_expr ());
5b981e9c
JP
1708 }
1709}
1710
1711void
1712Dump::visit (ExprStmtWithoutBlock &stmt)
1e8eb102 1713{
3b5fb3f8 1714 visit (stmt.get_expr ());
1e8eb102 1715}
5b981e9c
JP
1716
1717void
1718Dump::visit (ExprStmtWithBlock &stmt)
1e8eb102 1719{
3b5fb3f8 1720 visit (stmt.get_expr ());
1e8eb102 1721}
5b981e9c
JP
1722
1723// rust-type.h
1724void
1725Dump::visit (TraitBound &bound)
bd2240d3
JD
1726{
1727 // Syntax:
1728 // ?? ForLifetimes? TypePath
1729 // | ( ?? ForLifetimes? TypePath )
1730
1731 if (bound.has_opening_question_mark ())
1732 stream << "? ";
1733
1734 if (bound.has_for_lifetimes ())
1735 visit (bound.get_for_lifetimes ());
1736
1737 visit (bound.get_type_path ());
1738}
5b981e9c
JP
1739
1740void
638f65b2
JD
1741Dump::visit (ImplTraitType &type)
1742{
1743 // Syntax:
1744 // impl TypeParamBounds
1745 // TypeParamBounds :
1746 // TypeParamBound ( + TypeParamBound )* +?
1747
1748 stream << "impl ";
7ed4a0eb 1749 visit_items_joined_by_separator (type.get_type_param_bounds (), " + ");
638f65b2 1750}
5b981e9c
JP
1751
1752void
7ed4a0eb
JD
1753Dump::visit (TraitObjectType &type)
1754{
1755 // Syntax:
1756 // dyn? TypeParamBounds
1757 // TypeParamBounds :
1758 // TypeParamBound ( + TypeParamBound )* +?
1759
1760 if (type.is_dyn ())
1761 stream << "dyn ";
1762 visit_items_joined_by_separator (type.get_type_param_bounds (), " + ");
1763}
5b981e9c
JP
1764
1765void
e311e9b7
JD
1766Dump::visit (ParenthesisedType &type)
1767{
1768 // Syntax:
1769 // ( Type )
1770
1771 stream << "(";
1772 visit (type.get_type_in_parens ());
1773 stream << ")";
1774}
5b981e9c
JP
1775
1776void
ca06115e
JD
1777Dump::visit (ImplTraitTypeOneBound &type)
1778{
1779 // Syntax:
1780 // impl TraitBound
1781
1782 stream << "impl ";
7ed4a0eb 1783 visit (type.get_trait_bound ());
ca06115e 1784}
5b981e9c
JP
1785
1786void
0bb33cb5
JD
1787Dump::visit (TraitObjectTypeOneBound &type)
1788{
1789 // Syntax:
1790 // dyn? TraitBound
1791
1792 if (type.is_dyn ())
1793 stream << "dyn ";
1acb7e02 1794 visit (type.get_trait_bound ());
0bb33cb5 1795}
5b981e9c
JP
1796
1797void
91409d27
JD
1798Dump::visit (TupleType &type)
1799{
1800 // Syntax:
1801 // ( )
1802 // | ( ( Type , )+ Type? )
1803
1804 stream << '(';
1805 visit_items_joined_by_separator (type.get_elems (), ", ");
1806 stream << ')';
1807}
5b981e9c
JP
1808
1809void
971d16cb 1810Dump::visit (NeverType &)
c4c859bf 1811{
91409d27
JD
1812 // Syntax:
1813 // !
c4c859bf 1814
91409d27 1815 stream << '!';
c4c859bf 1816}
5b981e9c
JP
1817
1818void
1819Dump::visit (RawPointerType &type)
971d16cb
JD
1820{
1821 // Syntax:
1822 // * ( mut | const ) TypeNoBounds
1823
1824 if (type.get_pointer_type () == RawPointerType::MUT)
1825 stream << "*mut ";
1826 else /* RawPointerType::CONST */
1827 stream << "*const ";
1828
1829 visit (type.get_type_pointed_to ());
1830}
5b981e9c
JP
1831
1832void
1833Dump::visit (ReferenceType &type)
1834{
971d16cb
JD
1835 // Syntax:
1836 // & Lifetime? mut? TypeNoBounds
1837
1838 stream << '&';
1839
1840 if (type.has_lifetime ())
1841 {
1842 visit (type.get_lifetime ());
1843 stream << ' ';
1844 }
1845
1846 if (type.get_has_mut ())
1847 stream << "mut ";
1848
3b5fb3f8 1849 visit (type.get_type_referenced ());
5b981e9c
JP
1850}
1851
1852void
1853Dump::visit (ArrayType &type)
1854{
140a2aed
JD
1855 // Syntax:
1856 // [ Type ; Expression ]
1857
1858 stream << '[';
3b5fb3f8 1859 visit (type.get_elem_type ());
140a2aed 1860 stream << "; ";
971d16cb 1861 visit (type.get_size_expr ());
140a2aed 1862 stream << ']';
5b981e9c
JP
1863}
1864
1865void
1866Dump::visit (SliceType &type)
1867{
59fb0747
JD
1868 // Syntax:
1869 // [ Type ]
1870
1871 stream << '[';
3b5fb3f8 1872 visit (type.get_elem_type ());
59fb0747 1873 stream << ']';
5b981e9c
JP
1874}
1875
1876void
971d16cb 1877Dump::visit (InferredType &)
5b981e9c 1878{
ee0166fa
JD
1879 // Syntax:
1880 // _
1881
5b981e9c
JP
1882 stream << "_";
1883}
1884
1885void
ae1f6b3a
JD
1886Dump::visit (BareFunctionType &type)
1887{
1888 // Syntax:
1889 // ForLifetimes? FunctionTypeQualifiers fn
1890 // ( FunctionParametersMaybeNamedVariadic? ) BareFunctionReturnType?
1891 //
1892 // BareFunctionReturnType:
1893 // -> TypeNoBounds
1894 //
1895 // FunctionParametersMaybeNamedVariadic :
1896 // MaybeNamedFunctionParameters | MaybeNamedFunctionParametersVariadic
1897 //
1898 // MaybeNamedFunctionParameters :
1899 // MaybeNamedParam ( , MaybeNamedParam )* ,?
1900 //
1901 // MaybeNamedFunctionParametersVariadic :
1902 // ( MaybeNamedParam , )* MaybeNamedParam , OuterAttribute* ...
1903
1904 if (type.has_for_lifetimes ())
1905 visit (type.get_for_lifetimes ());
1906
1907 visit (type.get_function_qualifiers ());
1908
1909 stream << "fn (";
1910
1911 visit_items_joined_by_separator (type.get_function_params (), ", ");
1912
1913 if (type.is_variadic ())
1914 {
1915 stream << ", ";
1916 visit_items_joined_by_separator (type.get_variadic_attr (), " ");
1917 stream << "...";
1918 }
1919
1920 stream << ')';
1921
1922 if (type.has_return_type ())
1923 {
1924 stream << " -> ";
1925 visit (type.get_return_type ());
1926 }
1927}
5b981e9c
JP
1928
1929} // namespace AST
1930} // namespace Rust