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
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
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/>.
19 #include "rust-ast-dump.h"
24 Indent::Indent () : tabs (0) {}
27 operator<< (std::ostream
&stream
, const Indent
&indent
)
29 return stream
<< std::string (indent
.tabs
, '\t');
41 rust_assert (tabs
!= 0);
45 Dump::Dump (std::ostream
&stream
) : stream (stream
), indentation (Indent ()) {}
48 Dump::go (AST::Crate
&crate
)
50 visit_items_as_lines (crate
.items
, "");
54 Dump::go (AST::Item
&item
)
56 item
.accept_vis (*this);
61 Dump::visit (std::unique_ptr
<T
> &node
)
63 node
->accept_vis (*this);
70 node
.accept_vis (*this);
75 Dump::visit_items_joined_by_separator (T
&collection
,
76 const std::string
&separator
,
77 size_t start_offset
, size_t end_offset
)
79 if (collection
.size () > start_offset
)
81 visit (collection
.at (start_offset
));
82 auto size
= collection
.size () - end_offset
;
83 for (size_t i
= start_offset
+ 1; i
< size
; i
++)
86 visit (collection
.at (i
));
93 Dump::visit_as_line (T
&item
, const std::string
&trailing
)
95 stream
<< indentation
;
97 stream
<< trailing
<< '\n';
100 template <typename T
>
102 Dump::visit_items_as_lines (T
&collection
, const std::string
&trailing
)
104 for (auto &item
: collection
)
105 visit_as_line (item
, trailing
);
108 template <typename T
>
110 Dump::visit_items_as_block (T
&collection
, const std::string
&line_trailing
,
111 char left_brace
, char right_brace
)
113 if (collection
.empty ())
115 stream
<< left_brace
<< right_brace
<< '\n';
119 stream
<< left_brace
<< '\n';
121 indentation
.increment ();
122 visit_items_as_lines (collection
, line_trailing
);
123 indentation
.decrement ();
125 stream
<< indentation
<< right_brace
<< '\n';
130 Dump::visit (FunctionParam
¶m
)
132 visit (param
.get_pattern ());
134 visit (param
.get_type ());
138 Dump::visit (Attribute
&attrib
)
141 visit_items_joined_by_separator (attrib
.get_path ().get_segments (), "::");
143 if (attrib
.has_attr_input ())
147 bool is_literal
= attrib
.get_attr_input ().get_attr_input_type ()
148 == AST::AttrInput::AttrInputType::LITERAL
;
152 = static_cast<AST::AttrInputLiteral
&> (attrib
.get_attr_input ());
153 const auto &value
= literal
.get_literal ().as_string ();
155 stream
<< "\"" << value
<< "\"";
167 Dump::visit (SimplePathSegment
&segment
)
169 stream
<< segment
.get_segment_name ();
173 Dump::visit (Visibility
&vis
)
175 switch (vis
.get_vis_type ())
177 case Visibility::PUB
:
180 case Visibility::PUB_CRATE
:
181 stream
<< "pub(crate) ";
183 case Visibility::PUB_SELF
:
184 stream
<< "pub(self) ";
186 case Visibility::PUB_SUPER
:
187 stream
<< "pub(super) ";
189 case Visibility::PUB_IN_PATH
:
190 stream
<< "pub(in " << vis
.get_path ().as_string () << ") ";
192 case Visibility::PRIV
:
198 Dump::visit (NamedFunctionParam
¶m
)
200 stream
<< param
.get_name () << ": ";
201 visit (param
.get_type ());
205 Dump::visit (std::vector
<std::unique_ptr
<GenericParam
>> ¶ms
)
208 visit_items_joined_by_separator (params
, ", ");
213 Dump::visit (TupleField
&field
)
215 // TODO: do we need to emit outer attrs here?
216 visit (field
.get_visibility ());
217 visit (field
.get_field_type ());
221 Dump::visit (StructField
&field
)
223 // TODO: do we need to emit outer attrs here?
224 visit (field
.get_visibility ());
225 stream
<< field
.get_field_name () << ": ";
226 visit (field
.get_field_type ());
229 // TODO is this unique by type?
231 Dump::visit (std::vector
<LifetimeParam
> &for_lifetimes
)
238 // | < (GenericParam ,)* GenericParam ,? >
241 // OuterAttribute* ( LifetimeParam | TypeParam | ConstParam )
244 // LIFETIME_OR_LABEL ( : LifetimeBounds )?
247 visit_items_joined_by_separator (for_lifetimes
, " + ");
252 Dump::visit (FunctionQualifiers
&qualifiers
)
255 // `const`? `async`? `unsafe`? (`extern` Abi?)?
256 // unsafe? (extern Abi?)?
258 switch (qualifiers
.get_const_status ())
270 if (qualifiers
.is_unsafe ())
272 if (qualifiers
.is_extern ())
275 if (qualifiers
.has_abi ())
276 stream
<< "\"" << qualifiers
.get_extern_abi () << "\" ";
281 Dump::visit (MaybeNamedParam
¶m
)
284 // OuterAttribute* ( ( IDENTIFIER | _ ) : )? Type
286 visit_items_joined_by_separator (param
.get_outer_attrs (), " ");
287 switch (param
.get_param_kind ())
289 case MaybeNamedParam::UNNAMED
:
291 case MaybeNamedParam::IDENTIFIER
:
292 stream
<< " " << param
.get_name () << ": ";
294 case MaybeNamedParam::WILDCARD
:
298 visit (param
.get_type ());
302 Dump::visit (Token
&tok
)
304 stream
<< tok
.as_string ();
308 Dump::visit (DelimTokenTree
&delim_tok_tree
)
310 indentation
.increment ();
311 stream
<< '\n' << indentation
;
313 auto tokens
= delim_tok_tree
.to_token_stream ();
314 visit_items_joined_by_separator (tokens
, " ");
316 indentation
.decrement ();
317 stream
<< '\n' << indentation
;
321 Dump::visit (AttrInputMetaItemContainer
&)
325 Dump::visit (IdentifierExpr
&ident_expr
)
327 stream
<< ident_expr
.get_ident ();
331 Dump::visit (Lifetime
&lifetime
)
338 stream
<< lifetime
.as_string ();
342 Dump::visit (LifetimeParam
&lifetime_param
)
345 // LIFETIME_OR_LABEL ( : LifetimeBounds )?
347 // ( Lifetime + )* Lifetime?
349 // TODO what to do with outer attr? They are not mentioned in the reference.
351 auto lifetime
= lifetime_param
.get_lifetime ();
354 if (lifetime_param
.has_lifetime_bounds ())
357 visit_items_joined_by_separator (lifetime_param
.get_lifetime_bounds (),
363 Dump::visit (ConstGenericParam
&)
368 Dump::visit (PathInExpression
&path
)
370 stream
<< path
.as_string ();
374 Dump::visit (TypePathSegment
&segment
)
379 stream
<< segment
.get_ident_segment ().as_string ();
383 Dump::visit (TypePathSegmentGeneric
&segment
)
386 // PathIdentSegment `::`? (GenericArgs)?
389 // | `<` ( GenericArg `,` )* GenericArg `,`? `>`
391 stream
<< segment
.get_ident_segment ().as_string ();
393 if (segment
.get_separating_scope_resolution ())
399 // Here we join 3 lists (each possibly empty) with a separator.
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 ();
405 visit_items_joined_by_separator (lifetime_args
, ", ");
406 if (!lifetime_args
.empty ()
407 && (!generic_args
.empty () || !binding_args
.empty ()))
409 // Insert separator if some items have been already emitted and some
410 // more are to be emitted from any of the following collections.
413 visit_items_joined_by_separator (generic_args
, ", ");
414 if (!generic_args
.empty () && !binding_args
.empty ())
416 // Insert separator if some item vas emitted from the previous
417 // collection and more are to be emitted from the last.
420 visit_items_joined_by_separator (binding_args
, ", ");
427 Dump::visit (GenericArgsBinding
&binding
)
430 // IDENTIFIER `=` Type
432 stream
<< binding
.get_identifier () << " << ";
433 visit (binding
.get_type ());
437 Dump::visit (GenericArg
&arg
)
439 // `GenericArg` implements `accept_vis` but it is not useful for this case as
440 // it ignores unresolved cases (`Kind::Either`).
442 switch (arg
.get_kind ())
444 case GenericArg::Kind::Const
:
445 visit (arg
.get_expression ());
447 case GenericArg::Kind::Type
:
448 visit (arg
.get_type ());
450 case GenericArg::Kind::Either
:
451 stream
<< arg
.get_path ();
453 case GenericArg::Kind::Error
:
459 Dump::visit (TypePathSegmentFunction
&segment
)
462 // PathIdentSegment `::`? (TypePathFn)?
464 stream
<< segment
.get_ident_segment ().as_string ();
466 if (segment
.get_separating_scope_resolution ())
469 if (!segment
.is_ident_only ())
470 visit (segment
.get_type_path_function ());
474 Dump::visit (TypePathFunction
&type_path_fn
)
477 // `(` TypePathFnInputs? `)` (`->` Type)?
478 // TypePathFnInputs :
479 // Type (`,` Type)* `,`?
482 if (type_path_fn
.has_inputs ())
483 visit_items_joined_by_separator (type_path_fn
.get_params (), ", ");
486 if (type_path_fn
.has_return_type ())
489 visit (type_path_fn
.get_return_type ());
494 Dump::visit (TypePath
&path
)
497 // `::`? TypePathSegment (`::` TypePathSegment)*
499 if (path
.has_opening_scope_resolution_op ())
501 visit_items_joined_by_separator (path
.get_segments (), "::");
505 Dump::visit (QualifiedPathInExpression
&path
)
507 stream
<< path
.as_string ();
511 Dump::visit (QualifiedPathInType
&)
516 Dump::visit (LiteralExpr
&expr
)
518 stream
<< expr
.as_string ();
522 Dump::visit (AttrInputLiteral
&)
526 Dump::visit (MetaItemLitExpr
&)
530 Dump::visit (MetaItemPathLit
&)
534 Dump::visit (BorrowExpr
&expr
)
537 if (expr
.get_is_double_borrow ())
539 if (expr
.get_is_mut ())
542 visit (expr
.get_borrowed_expr ());
546 Dump::visit (DereferenceExpr
&expr
)
549 visit (expr
.get_dereferenced_expr ());
553 Dump::visit (ErrorPropagationExpr
&expr
)
555 visit (expr
.get_propagating_expr ());
560 Dump::visit (NegationExpr
&expr
)
562 switch (expr
.get_expr_type ())
564 case NegationOperator::NEGATE
:
567 case NegationOperator::NOT
:
571 visit (expr
.get_negated_expr ());
575 Dump::visit (ArithmeticOrLogicalExpr
&expr
)
578 switch (expr
.get_expr_type ())
580 case ArithmeticOrLogicalOperator::ADD
:
584 case ArithmeticOrLogicalOperator::SUBTRACT
:
588 case ArithmeticOrLogicalOperator::MULTIPLY
:
592 case ArithmeticOrLogicalOperator::DIVIDE
:
596 case ArithmeticOrLogicalOperator::MODULUS
:
600 case ArithmeticOrLogicalOperator::BITWISE_AND
:
604 case ArithmeticOrLogicalOperator::BITWISE_OR
:
608 case ArithmeticOrLogicalOperator::BITWISE_XOR
:
612 case ArithmeticOrLogicalOperator::LEFT_SHIFT
:
616 case ArithmeticOrLogicalOperator::RIGHT_SHIFT
:
621 visit (expr
.get_left_expr ());
622 stream
<< " " << op
<< " ";
623 visit (expr
.get_right_expr ());
627 Dump::visit (ComparisonExpr
&expr
)
630 switch (expr
.get_expr_type ())
632 case ComparisonOperator::EQUAL
:
635 case ComparisonOperator::NOT_EQUAL
:
639 case ComparisonOperator::GREATER_THAN
:
643 case ComparisonOperator::LESS_THAN
:
647 case ComparisonOperator::GREATER_OR_EQUAL
:
651 case ComparisonOperator::LESS_OR_EQUAL
:
656 visit (expr
.get_left_expr ());
657 stream
<< " " << op
<< " ";
658 visit (expr
.get_right_expr ());
662 Dump::visit (LazyBooleanExpr
&expr
)
665 switch (expr
.get_expr_type ())
667 case LazyBooleanOperator::LOGICAL_AND
:
670 case LazyBooleanOperator::LOGICAL_OR
:
675 visit (expr
.get_left_expr ());
676 stream
<< " " << op
<< " ";
677 visit (expr
.get_right_expr ());
681 Dump::visit (TypeCastExpr
&expr
)
683 visit (expr
.get_casted_expr ());
685 visit (expr
.get_type_to_cast_to ());
689 Dump::visit (AssignmentExpr
&expr
)
691 expr
.visit_lhs (*this);
693 expr
.visit_rhs (*this);
697 Dump::visit (CompoundAssignmentExpr
&expr
)
700 switch (expr
.get_expr_type ())
702 case CompoundAssignmentOperator::ADD
:
706 case CompoundAssignmentOperator::SUBTRACT
:
710 case CompoundAssignmentOperator::MULTIPLY
:
714 case CompoundAssignmentOperator::DIVIDE
:
718 case CompoundAssignmentOperator::MODULUS
:
722 case CompoundAssignmentOperator::BITWISE_AND
:
726 case CompoundAssignmentOperator::BITWISE_OR
:
730 case CompoundAssignmentOperator::BITWISE_XOR
:
734 case CompoundAssignmentOperator::LEFT_SHIFT
:
738 case CompoundAssignmentOperator::RIGHT_SHIFT
:
743 visit (expr
.get_left_expr ());
744 stream
<< " " << op
<< "= ";
745 visit (expr
.get_right_expr ());
749 Dump::visit (GroupedExpr
&expr
)
752 visit (expr
.get_expr_in_parens ());
757 Dump::visit (ArrayElemsValues
&elems
)
759 visit_items_joined_by_separator (elems
.get_values (), ", ");
763 Dump::visit (ArrayElemsCopied
&elems
)
765 visit (elems
.get_elem_to_copy ());
767 visit (elems
.get_num_copies ());
771 Dump::visit (ArrayExpr
&expr
)
774 visit (expr
.get_array_elems ());
779 Dump::visit (ArrayIndexExpr
&expr
)
781 visit (expr
.get_array_expr ());
783 visit (expr
.get_index_expr ());
788 Dump::visit (TupleExpr
&)
792 Dump::visit (TupleIndexExpr
&)
796 Dump::visit (StructExprStruct
&)
800 Dump::visit (StructExprFieldIdentifier
&)
804 Dump::visit (StructExprFieldIdentifierValue
&)
808 Dump::visit (StructExprFieldIndexValue
&)
812 Dump::visit (StructExprStructFields
&)
816 Dump::visit (StructExprStructBase
&)
820 Dump::visit (CallExpr
&expr
)
822 visit (expr
.get_function_expr ());
824 stream
<< '(' << '\n';
825 indentation
.increment ();
827 visit_items_as_lines (expr
.get_params (), ",");
829 indentation
.decrement ();
830 stream
<< indentation
<< ')';
834 Dump::visit (MethodCallExpr
&)
838 Dump::visit (FieldAccessExpr
&)
842 Dump::visit (ClosureExprInner
&)
846 Dump::visit (BlockExpr
&expr
)
849 indentation
.increment ();
851 visit_items_as_lines (expr
.get_statements (), ";");
853 if (expr
.has_tail_expr ())
854 visit_as_line (expr
.get_tail_expr (), " /* tail expr */\n");
856 indentation
.decrement ();
857 stream
<< indentation
<< "}\n";
861 Dump::visit (ClosureExprInnerTyped
&)
865 Dump::visit (ContinueExpr
&)
869 Dump::visit (BreakExpr
&)
873 Dump::visit (RangeFromToExpr
&expr
)
875 visit (expr
.get_from_expr ());
877 visit (expr
.get_to_expr ());
881 Dump::visit (RangeFromExpr
&expr
)
883 visit (expr
.get_from_expr ());
888 Dump::visit (RangeToExpr
&expr
)
891 visit (expr
.get_to_expr ());
895 Dump::visit (RangeFullExpr
&)
901 Dump::visit (RangeFromToInclExpr
&expr
)
903 visit (expr
.get_from_expr ());
905 visit (expr
.get_to_expr ());
909 Dump::visit (RangeToInclExpr
&expr
)
912 visit (expr
.get_to_expr ());
916 Dump::visit (ReturnExpr
&)
920 Dump::visit (UnsafeBlockExpr
&)
924 Dump::visit (LoopExpr
&)
928 Dump::visit (WhileLoopExpr
&)
932 Dump::visit (WhileLetLoopExpr
&)
936 Dump::visit (ForLoopExpr
&)
940 Dump::visit (IfExpr
&expr
)
943 visit (expr
.get_condition_expr ());
945 visit (expr
.get_if_block ());
949 Dump::visit (IfExprConseqElse
&expr
)
952 visit (expr
.get_condition_expr ());
954 visit (expr
.get_if_block ());
955 stream
<< indentation
<< "else ";
956 visit (expr
.get_else_block ());
960 Dump::visit (IfExprConseqIf
&expr
)
963 visit (expr
.get_condition_expr ());
965 visit (expr
.get_if_block ());
966 stream
<< indentation
<< "else ";
967 // The "if" part of the "else if" is printed by the next visitor
968 visit (expr
.get_conseq_if_expr ());
972 Dump::visit (IfExprConseqIfLet
&)
976 Dump::visit (IfLetExpr
&)
980 Dump::visit (IfLetExprConseqElse
&)
984 Dump::visit (IfLetExprConseqIf
&)
988 Dump::visit (IfLetExprConseqIfLet
&)
992 Dump::visit (MatchExpr
&)
996 Dump::visit (AwaitExpr
&)
1000 Dump::visit (AsyncBlockExpr
&)
1005 Dump::visit (TypeParam
¶m
)
1008 // IDENTIFIER( : TypeParamBounds? )? ( = Type )?
1009 // TypeParamBounds :
1010 // TypeParamBound ( + TypeParamBound )* +?
1012 stream
<< param
.get_type_representation ();
1013 if (param
.has_type_param_bounds ())
1016 visit_items_joined_by_separator (param
.get_type_param_bounds (), " + ");
1018 if (param
.has_type ())
1021 visit (param
.get_type ());
1026 Dump::visit (WhereClause
&rule
)
1029 // where ( WhereClauseItem , )* WhereClauseItem ?
1030 // WhereClauseItem :
1031 // LifetimeWhereClauseItem
1032 // | TypeBoundWhereClauseItem
1034 stream
<< " where\n";
1035 indentation
.increment ();
1036 visit_items_as_lines (rule
.get_items (), ",");
1037 indentation
.decrement ();
1041 Dump::visit (LifetimeWhereClauseItem
&item
)
1044 // Lifetime : LifetimeBounds
1046 // ( Lifetime + )* Lifetime?
1048 visit (item
.get_lifetime ());
1050 visit_items_joined_by_separator (item
.get_lifetime_bounds (), " + ");
1054 Dump::visit (TypeBoundWhereClauseItem
&item
)
1057 // ForLifetimes? Type : TypeParamBounds?
1058 // TypeParamBounds :
1059 // TypeParamBound ( + TypeParamBound )* +?
1061 // Lifetime | TraitBound
1063 if (item
.has_for_lifetimes ())
1064 visit (item
.get_for_lifetimes ());
1066 visit (item
.get_type ());
1069 visit_items_joined_by_separator (item
.get_type_param_bounds (), " + ");
1073 Dump::visit (Method
&method
)
1075 visit (method
.get_visibility ());
1076 stream
<< "fn " << method
.get_method_name () << '(';
1078 stream
<< method
.get_self_param ().as_string ();
1079 if (!method
.get_function_params ().empty ())
1082 visit_items_joined_by_separator (method
.get_function_params (), ", ");
1087 if (method
.has_return_type ())
1090 visit (method
.get_return_type ());
1094 auto &block
= method
.get_definition ();
1104 Dump::visit (Module
&module
)
1108 // | mod IDENTIFIER {
1113 visit (module
.get_visibility ());
1114 stream
<< "mod " << module
.get_name ();
1116 if (module
.get_kind () == Module::UNLOADED
)
1120 else /* Module::LOADED */
1124 indentation
.increment ();
1126 visit_items_as_lines (module
.get_inner_attrs ());
1127 visit_items_as_lines (module
.get_items ());
1129 indentation
.decrement ();
1131 stream
<< indentation
<< "}\n";
1136 Dump::visit (ExternCrate
&)
1140 Dump::visit (UseTreeGlob
&)
1144 Dump::visit (UseTreeList
&)
1148 Dump::visit (UseTreeRebind
&)
1152 Dump::visit (UseDeclaration
&)
1156 Dump::visit (Function
&function
)
1159 // FunctionQualifiers fn IDENTIFIER GenericParams?
1160 // ( FunctionParameters? )
1161 // FunctionReturnType? WhereClause?
1162 // ( BlockExpression | ; )
1164 visit (function
.get_visibility ());
1166 stream
<< "fn " << function
.get_function_name ();
1167 if (function
.has_generics ())
1168 visit (function
.get_generic_params ());
1171 visit_items_joined_by_separator (function
.get_function_params ());
1174 if (function
.has_return_type ())
1177 visit (function
.get_return_type ());
1181 if (function
.has_where_clause ())
1182 visit (function
.get_where_clause ());
1184 auto &block
= function
.get_definition ();
1194 Dump::visit (TypeAlias
&type_alias
)
1197 // Visibility? type IDENTIFIER GenericParams? WhereClause? = Type;
1199 // Note: Associated types are handled by `AST::TraitItemType`.
1201 if (type_alias
.has_visibility ())
1202 visit (type_alias
.get_visibility ());
1203 stream
<< "type " << type_alias
.get_new_type_name ();
1204 if (type_alias
.has_generics ())
1205 visit (type_alias
.get_generic_params ());
1206 if (type_alias
.has_where_clause ())
1207 visit (type_alias
.get_where_clause ());
1209 visit (type_alias
.get_type_aliased ());
1213 Dump::visit (StructStruct
&struct_item
)
1215 stream
<< "struct " << struct_item
.get_identifier ();
1216 if (struct_item
.has_generics ())
1217 visit (struct_item
.get_generic_params ());
1218 if (struct_item
.has_where_clause ())
1219 visit (struct_item
.get_where_clause ());
1220 if (struct_item
.is_unit_struct ())
1223 visit_items_as_block (struct_item
.get_fields (), ",");
1227 Dump::visit (TupleStruct
&tuple_struct
)
1229 stream
<< "struct " << tuple_struct
.get_identifier ();
1230 if (tuple_struct
.has_generics ())
1231 visit (tuple_struct
.get_generic_params ());
1232 if (tuple_struct
.has_where_clause ())
1233 visit (tuple_struct
.get_where_clause ());
1236 visit_items_joined_by_separator (tuple_struct
.get_fields (), ", ");
1241 Dump::visit (EnumItem
&item
)
1243 stream
<< item
.get_identifier ();
1247 Dump::visit (EnumItemTuple
&item
)
1249 stream
<< item
.get_identifier () << '(';
1250 visit_items_joined_by_separator (item
.get_tuple_fields (), ", ");
1255 Dump::visit (EnumItemStruct
&item
)
1257 stream
<< item
.get_identifier ();
1258 visit_items_as_block (item
.get_struct_fields (), ",");
1262 Dump::visit (EnumItemDiscriminant
&item
)
1264 stream
<< item
.get_identifier () << " = ";
1265 visit (item
.get_expr ());
1269 Dump::visit (Enum
&enum_item
)
1271 stream
<< "enum " << enum_item
.get_identifier ();
1272 if (enum_item
.has_generics ())
1273 visit (enum_item
.get_generic_params ());
1274 if (enum_item
.has_where_clause ())
1275 visit (enum_item
.get_where_clause ());
1277 visit_items_as_block (enum_item
.get_variants (), ",");
1281 Dump::visit (Union
&union_item
)
1283 stream
<< "union " << union_item
.get_identifier ();
1284 if (union_item
.has_generics ())
1285 visit (union_item
.get_generic_params ());
1286 if (union_item
.has_where_clause ())
1287 visit (union_item
.get_where_clause ());
1289 visit_items_as_block (union_item
.get_variants (), ",");
1293 Dump::visit (ConstantItem
&)
1297 Dump::visit (StaticItem
&)
1301 Dump::visit_function_common (std::unique_ptr
<Type
> &return_type
,
1302 std::unique_ptr
<BlockExpr
> &block
)
1304 // FIXME: This should format the `<vis> fn <name> ( [args] )` as well
1308 visit (return_type
);
1324 Dump::visit (TraitItemFunc
&item
)
1326 auto func
= item
.get_trait_function_decl ();
1327 stream
<< "fn " << func
.get_identifier () << '(';
1329 visit_items_joined_by_separator (func
.get_function_params ());
1333 visit_function_common (func
.get_return_type (), item
.get_definition ());
1337 Dump::visit (TraitItemMethod
&item
)
1339 auto method
= item
.get_trait_method_decl ();
1341 // FIXME: Can we have visibility here?
1342 // emit_visibility (method.get_visibility ());
1343 stream
<< "fn " << method
.get_identifier () << '(';
1345 stream
<< method
.get_self_param ().as_string ();
1347 if (!method
.get_function_params ().empty ())
1350 visit_items_joined_by_separator (method
.get_function_params (), ", ");
1355 visit_function_common (method
.get_return_type (), item
.get_definition ());
1359 Dump::visit (TraitItemConst
&item
)
1361 stream
<< indentation
<< "const " << item
.get_identifier () << ": ";
1362 visit (item
.get_type ());
1367 Dump::visit (TraitItemType
&item
)
1369 stream
<< indentation
<< "type " << item
.get_identifier () << ";\n";
1373 Dump::visit (Trait
&trait
)
1375 for (auto &attr
: trait
.get_outer_attrs ())
1378 stream
<< "\n" << indentation
;
1381 visit (trait
.get_visibility ());
1383 stream
<< "trait " << trait
.get_identifier ();
1385 // Traits actually have an implicit Self thrown at the start, so we must
1386 // expect the number of generic params to be > 1
1387 if (trait
.get_generic_params ().size () > 1)
1390 visit_items_joined_by_separator (trait
.get_generic_params (), ", ", 1);
1394 visit_items_as_block (trait
.get_trait_items (), "");
1398 Dump::visit (InherentImpl
&impl
)
1402 // FIXME: Handle generics
1404 visit (impl
.get_type ());
1406 if (impl
.has_where_clause ())
1407 visit (impl
.get_where_clause ());
1409 // FIXME: Handle inner attributes
1411 visit_items_as_block (impl
.get_impl_items (), "");
1415 Dump::visit (TraitImpl
&impl
)
1418 visit (impl
.get_trait_path ());
1420 visit (impl
.get_type ());
1423 indentation
.increment ();
1425 for (auto &item
: impl
.get_impl_items ())
1427 stream
<< indentation
;
1431 indentation
.decrement ();
1436 Dump::visit (ExternalStaticItem
&)
1440 Dump::visit (ExternalFunctionItem
&function
)
1442 visit (function
.get_visibility ());
1444 stream
<< "fn " << function
.get_identifier () << '(';
1446 visit_items_joined_by_separator (function
.get_function_params ());
1449 if (function
.has_return_type ())
1452 visit (function
.get_return_type ());
1457 Dump::visit (ExternBlock
&block
)
1459 stream
<< "extern ";
1461 if (block
.has_abi ())
1462 stream
<< "\"" << block
.get_abi () << "\" ";
1464 visit_items_as_block (block
.get_extern_items (), ";");
1467 static std::pair
<char, char>
1468 get_delimiters (DelimType delim
)
1470 auto start_delim
= '\0';
1471 auto end_delim
= '\0';
1489 return {start_delim
, end_delim
};
1493 Dump::visit (MacroMatchFragment
&match
)
1495 stream
<< '$' << match
.get_ident () << ':'
1496 << match
.get_frag_spec ().as_string ();
1500 Dump::visit (MacroMatchRepetition
&repetition
)
1504 visit_items_joined_by_separator (repetition
.get_matches (), " ");
1506 auto op_char
= '\0';
1507 switch (repetition
.get_op ())
1509 case MacroMatchRepetition::ANY
:
1512 case MacroMatchRepetition::ONE_OR_MORE
:
1515 case MacroMatchRepetition::ZERO_OR_ONE
:
1518 case MacroMatchRepetition::NONE
:
1524 if (repetition
.has_sep ())
1525 stream
<< repetition
.get_sep ()->as_string ();
1531 Dump::visit (MacroMatcher
&matcher
)
1533 auto delimiters
= get_delimiters (matcher
.get_delim_type ());
1535 stream
<< delimiters
.first
;
1537 visit_items_joined_by_separator (matcher
.get_matches (), " ");
1539 stream
<< delimiters
.second
;
1543 Dump::visit (MacroRule
&rule
)
1545 visit (rule
.get_matcher ());
1547 visit (rule
.get_transcriber ().get_token_tree ());
1552 Dump::visit (MacroRulesDefinition
&rules_def
)
1554 for (auto &outer_attr
: rules_def
.get_outer_attrs ())
1557 stream
<< "macro_rules! " << rules_def
.get_rule_name ();
1559 visit_items_as_block (rules_def
.get_rules (), ";");
1563 Dump::visit (MacroInvocation
&)
1567 Dump::visit (MetaItemPath
&)
1571 Dump::visit (MetaItemSeq
&)
1575 Dump::visit (MetaWord
&)
1579 Dump::visit (MetaNameValueStr
&)
1583 Dump::visit (MetaListPaths
&)
1587 Dump::visit (MetaListNameValueStr
&)
1592 Dump::visit (LiteralPattern
&)
1596 Dump::visit (IdentifierPattern
&pattern
)
1598 stream
<< pattern
.get_ident ();
1602 Dump::visit (WildcardPattern
&)
1605 // void Dump::visit(RangePatternBound& ){}
1608 Dump::visit (RangePatternBoundLiteral
&)
1612 Dump::visit (RangePatternBoundPath
&)
1616 Dump::visit (RangePatternBoundQualPath
&)
1620 Dump::visit (RangePattern
&)
1624 Dump::visit (ReferencePattern
&)
1627 // void Dump::visit(StructPatternField& ){}
1630 Dump::visit (StructPatternFieldTuplePat
&)
1634 Dump::visit (StructPatternFieldIdentPat
&)
1638 Dump::visit (StructPatternFieldIdent
&)
1642 Dump::visit (StructPattern
&)
1645 // void Dump::visit(TupleStructItems& ){}
1648 Dump::visit (TupleStructItemsNoRange
&)
1652 Dump::visit (TupleStructItemsRange
&)
1656 Dump::visit (TupleStructPattern
&)
1659 // void Dump::visit(TuplePatternItems& ){}
1662 Dump::visit (TuplePatternItemsMultiple
&)
1666 Dump::visit (TuplePatternItemsRanged
&)
1670 Dump::visit (TuplePattern
&)
1674 Dump::visit (GroupedPattern
&)
1678 Dump::visit (SlicePattern
&)
1682 Dump::visit (AltPattern
&)
1687 Dump::visit (EmptyStmt
&)
1691 Dump::visit (LetStmt
&stmt
)
1694 auto &pattern
= stmt
.get_pattern ();
1698 if (stmt
.has_type ())
1701 visit (stmt
.get_type ());
1704 if (stmt
.has_init_expr ())
1707 visit (stmt
.get_init_expr ());
1712 Dump::visit (ExprStmtWithoutBlock
&stmt
)
1714 visit (stmt
.get_expr ());
1718 Dump::visit (ExprStmtWithBlock
&stmt
)
1720 visit (stmt
.get_expr ());
1725 Dump::visit (TraitBound
&bound
)
1728 // ?? ForLifetimes? TypePath
1729 // | ( ?? ForLifetimes? TypePath )
1731 if (bound
.has_opening_question_mark ())
1734 if (bound
.has_for_lifetimes ())
1735 visit (bound
.get_for_lifetimes ());
1737 visit (bound
.get_type_path ());
1741 Dump::visit (ImplTraitType
&type
)
1744 // impl TypeParamBounds
1745 // TypeParamBounds :
1746 // TypeParamBound ( + TypeParamBound )* +?
1749 visit_items_joined_by_separator (type
.get_type_param_bounds (), " + ");
1753 Dump::visit (TraitObjectType
&type
)
1756 // dyn? TypeParamBounds
1757 // TypeParamBounds :
1758 // TypeParamBound ( + TypeParamBound )* +?
1762 visit_items_joined_by_separator (type
.get_type_param_bounds (), " + ");
1766 Dump::visit (ParenthesisedType
&type
)
1772 visit (type
.get_type_in_parens ());
1777 Dump::visit (ImplTraitTypeOneBound
&type
)
1783 visit (type
.get_trait_bound ());
1787 Dump::visit (TraitObjectTypeOneBound
&type
)
1794 visit (type
.get_trait_bound ());
1798 Dump::visit (TupleType
&type
)
1802 // | ( ( Type , )+ Type? )
1805 visit_items_joined_by_separator (type
.get_elems (), ", ");
1810 Dump::visit (NeverType
&)
1819 Dump::visit (RawPointerType
&type
)
1822 // * ( mut | const ) TypeNoBounds
1824 if (type
.get_pointer_type () == RawPointerType::MUT
)
1826 else /* RawPointerType::CONST */
1827 stream
<< "*const ";
1829 visit (type
.get_type_pointed_to ());
1833 Dump::visit (ReferenceType
&type
)
1836 // & Lifetime? mut? TypeNoBounds
1840 if (type
.has_lifetime ())
1842 visit (type
.get_lifetime ());
1846 if (type
.get_has_mut ())
1849 visit (type
.get_type_referenced ());
1853 Dump::visit (ArrayType
&type
)
1856 // [ Type ; Expression ]
1859 visit (type
.get_elem_type ());
1861 visit (type
.get_size_expr ());
1866 Dump::visit (SliceType
&type
)
1872 visit (type
.get_elem_type ());
1877 Dump::visit (InferredType
&)
1886 Dump::visit (BareFunctionType
&type
)
1889 // ForLifetimes? FunctionTypeQualifiers fn
1890 // ( FunctionParametersMaybeNamedVariadic? ) BareFunctionReturnType?
1892 // BareFunctionReturnType:
1895 // FunctionParametersMaybeNamedVariadic :
1896 // MaybeNamedFunctionParameters | MaybeNamedFunctionParametersVariadic
1898 // MaybeNamedFunctionParameters :
1899 // MaybeNamedParam ( , MaybeNamedParam )* ,?
1901 // MaybeNamedFunctionParametersVariadic :
1902 // ( MaybeNamedParam , )* MaybeNamedParam , OuterAttribute* ...
1904 if (type
.has_for_lifetimes ())
1905 visit (type
.get_for_lifetimes ());
1907 visit (type
.get_function_qualifiers ());
1911 visit_items_joined_by_separator (type
.get_function_params (), ", ");
1913 if (type
.is_variadic ())
1916 visit_items_joined_by_separator (type
.get_variadic_attr (), " ");
1922 if (type
.has_return_type ())
1925 visit (type
.get_return_type ());