]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: dump: Replace ast dump internals
authorPierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Wed, 21 Jun 2023 21:47:14 +0000 (23:47 +0200)
committerArthur Cohen <arthur.cohen@embecosm.com>
Tue, 16 Jan 2024 17:46:31 +0000 (18:46 +0100)
Replace ast dump visitor with call to token collector.

gcc/rust/ChangeLog:

* ast/rust-ast-collector.cc (TokenCollector::visit): Add a visit
function for visitable abstract class so we can call a dump on
any visitable item.
* ast/rust-ast-collector.h: Add new visit function prototype.
* ast/rust-ast-dump.cc (Dump::go): Add call to process function.
(Dump::visit): Remove functions.
(Dump::visit_items_joined_by_separator): Likewise.
(Dump::visit_as_line): Likewise.
(Dump::visit_items_as_lines): Likewise.
(Dump::visit_items_as_block): Likewise.
(Dump::visit_function_common): Likewise.
(get_delimiters): Likewise.
(Dump::debug): Update with call to tokencollector.
* ast/rust-ast-dump.h (RUST_AST_DUMP_H): Move include
directives.
(class Dump): Remove multiple prototypes and add generic process
function.

Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
gcc/rust/ast/rust-ast-collector.cc
gcc/rust/ast/rust-ast-collector.h
gcc/rust/ast/rust-ast-dump.cc
gcc/rust/ast/rust-ast-dump.h

index 843ea73281276b78a03383e98ef70f8bfbb0fbb6..f14cb355e9f4074fc3292bddba0a114e1df5bdcc 100644 (file)
@@ -138,6 +138,12 @@ void
 TokenCollector::decrement_indentation ()
 {}
 
+void
+TokenCollector::visit (Visitable &v)
+{
+  v.accept_vis (*this);
+}
+
 void
 TokenCollector::visit (FunctionParam &param)
 {
index feb6c47f4e9899fbb3d17174862b4b881e1d065c..1b314aca8c22bcac87a07a5408985353ee5c57ee 100644 (file)
@@ -108,6 +108,7 @@ public:
    */
   template <typename T> void visit (T &node);
 
+  void visit (Visitable &v);
   void visit (LoopLabel &label);
 
   void visit (Literal &lit, Location locus = {});
index 8cd99fcc17d7a8e4df174426f0b50c6874facbc0..56202a7614b95851ec8ee4925dff1c41db17b3aa 100644 (file)
@@ -25,1926 +25,22 @@ namespace AST {
 Dump::Dump (std::ostream &stream) : stream (stream), indentation (Indent ()) {}
 
 void
-Dump::go (AST::Crate &crate)
-{
-  visit_items_as_lines (crate.items, "");
-}
-
-void
-Dump::go (AST::Item &item)
-{
-  item.accept_vis (*this);
-}
-
-template <typename T>
-void
-Dump::visit (std::unique_ptr<T> &node)
-{
-  node->accept_vis (*this);
-}
-
-template <typename T>
-void
-Dump::visit (T &node)
-{
-  node.accept_vis (*this);
-}
-
-template <typename T>
-void
-Dump::visit_items_joined_by_separator (T &collection,
-                                      const std::string &separator,
-                                      size_t start_offset, size_t end_offset)
-{
-  if (collection.size () > start_offset)
-    {
-      visit (collection.at (start_offset));
-      auto size = collection.size () - end_offset;
-      for (size_t i = start_offset + 1; i < size; i++)
-       {
-         stream << separator;
-         visit (collection.at (i));
-       }
-    }
-}
-
-template <typename T>
-void
-Dump::visit_as_line (T &item, const std::string &trailing)
-{
-  stream << indentation;
-  visit (item);
-  stream << trailing << '\n';
-}
-
-template <typename T>
-void
-Dump::visit_items_as_lines (T &collection, const std::string &trailing)
-{
-  for (auto &item : collection)
-    visit_as_line (item, trailing);
-}
-
-template <typename T>
-void
-Dump::visit_items_as_block (T &collection, const std::string &line_trailing,
-                           char left_brace, char right_brace)
-{
-  if (collection.empty ())
-    {
-      stream << left_brace << right_brace << '\n';
-    }
-  else
-    {
-      stream << left_brace << '\n';
-
-      indentation.increment ();
-      visit_items_as_lines (collection, line_trailing);
-      indentation.decrement ();
-
-      stream << indentation << right_brace << '\n';
-    }
-}
-
-void
-Dump::visit (FunctionParam &param)
-{
-  visit (param.get_pattern ());
-  stream << ": ";
-  visit (param.get_type ());
-}
-
-void
-Dump::visit (Attribute &attrib)
-{
-  stream << "#[";
-  visit_items_joined_by_separator (attrib.get_path ().get_segments (), "::");
-
-  if (attrib.has_attr_input ())
-    {
-      stream << " = ";
-
-      bool is_literal = attrib.get_attr_input ().get_attr_input_type ()
-                       == AST::AttrInput::AttrInputType::LITERAL;
-      if (is_literal)
-       {
-         auto &literal
-           = static_cast<AST::AttrInputLiteral &> (attrib.get_attr_input ());
-         const auto &value = literal.get_literal ().as_string ();
-
-         stream << "\"" << value << "\"";
-       }
-      else
-       {
-         stream << "FIXME";
-       }
-    }
-
-  stream << "]";
-}
-
-void
-Dump::visit (SimplePathSegment &segment)
-{
-  stream << segment.get_segment_name ();
-}
-
-void
-Dump::visit (Visibility &vis)
-{
-  switch (vis.get_vis_type ())
-    {
-    case Visibility::PUB:
-      stream << "pub ";
-      break;
-    case Visibility::PUB_CRATE:
-      stream << "pub(crate) ";
-      break;
-    case Visibility::PUB_SELF:
-      stream << "pub(self) ";
-      break;
-    case Visibility::PUB_SUPER:
-      stream << "pub(super) ";
-      break;
-    case Visibility::PUB_IN_PATH:
-      stream << "pub(in " << vis.get_path ().as_string () << ") ";
-      break;
-    case Visibility::PRIV:
-      break;
-    }
-}
-
-void
-Dump::visit (NamedFunctionParam &param)
-{
-  stream << param.get_name () << ": ";
-  visit (param.get_type ());
-}
-
-void
-Dump::visit (std::vector<std::unique_ptr<GenericParam>> &params)
-{
-  stream << "<";
-  visit_items_joined_by_separator (params, ", ");
-  stream << ">";
-}
-
-void
-Dump::visit (TupleField &field)
-{
-  // TODO: do we need to emit outer attrs here?
-  visit (field.get_visibility ());
-  visit (field.get_field_type ());
-}
-
-void
-Dump::visit (StructField &field)
-{
-  // TODO: do we need to emit outer attrs here?
-  visit (field.get_visibility ());
-  stream << field.get_field_name () << ": ";
-  visit (field.get_field_type ());
-}
-
-// TODO is this unique by type?
-void
-Dump::visit (std::vector<LifetimeParam> &for_lifetimes)
-{
-  // ForLifetimes :
-  //     for GenericParams
-  //
-  // GenericParams :
-  //      < >
-  //   | < (GenericParam ,)* GenericParam ,? >
-  //
-  // GenericParam :
-  //   OuterAttribute* ( LifetimeParam | TypeParam | ConstParam )
-  //
-  // LifetimeParam :
-  //   LIFETIME_OR_LABEL ( : LifetimeBounds )?
-
-  stream << "for <";
-  visit_items_joined_by_separator (for_lifetimes, " + ");
-  stream << "> ";
-}
-
-void
-Dump::visit (FunctionQualifiers &qualifiers)
-{
-  // Syntax:
-  //    `const`? `async`? `unsafe`? (`extern` Abi?)?
-  //    unsafe? (extern Abi?)?
-
-  switch (qualifiers.get_const_status ())
-    {
-    case NONE:
-      break;
-    case CONST_FN:
-      stream << "const ";
-      break;
-    case ASYNC_FN:
-      stream << "async ";
-      break;
-    }
-
-  if (qualifiers.is_unsafe ())
-    stream << "unsafe ";
-  if (qualifiers.is_extern ())
-    {
-      stream << "extern ";
-      if (qualifiers.has_abi ())
-       stream << "\"" << qualifiers.get_extern_abi () << "\" ";
-    }
-} // namespace AST
-
-void
-Dump::visit (MaybeNamedParam &param)
-{
-  // Syntax:
-  //     OuterAttribute* ( ( IDENTIFIER | _ ) : )? Type
-
-  visit_items_joined_by_separator (param.get_outer_attrs (), " ");
-  switch (param.get_param_kind ())
-    {
-    case MaybeNamedParam::UNNAMED:
-      break;
-    case MaybeNamedParam::IDENTIFIER:
-      stream << " " << param.get_name () << ": ";
-      break;
-    case MaybeNamedParam::WILDCARD:
-      stream << " _: ";
-      break;
-    }
-  visit (param.get_type ());
-}
-
-void
-Dump::visit (Token &tok)
-{
-  stream << tok.as_string ();
-}
-
-void
-Dump::visit (DelimTokenTree &delim_tok_tree)
-{
-  indentation.increment ();
-  stream << '\n' << indentation;
-
-  auto tokens = delim_tok_tree.to_token_stream ();
-  visit_items_joined_by_separator (tokens, " ");
-
-  indentation.decrement ();
-  stream << '\n' << indentation;
-}
-
-void
-Dump::visit (AttrInputMetaItemContainer &)
-{}
-
-void
-Dump::visit (IdentifierExpr &ident_expr)
-{
-  stream << ident_expr.get_ident ();
-}
-
-void
-Dump::visit (Lifetime &lifetime)
-{
-  // Syntax:
-  // Lifetime :
-  //   LIFETIME_OR_LABEL
-  //   | 'static
-  //   | '_
-  stream << lifetime.as_string ();
-}
-
-void
-Dump::visit (LifetimeParam &lifetime_param)
-{
-  // Syntax:
-  //   LIFETIME_OR_LABEL ( : LifetimeBounds )?
-  // LifetimeBounds :
-  //   ( Lifetime + )* Lifetime?
-
-  // TODO what to do with outer attr? They are not mentioned in the reference.
-
-  auto lifetime = lifetime_param.get_lifetime ();
-  visit (lifetime);
-
-  if (lifetime_param.has_lifetime_bounds ())
-    {
-      stream << ": ";
-      visit_items_joined_by_separator (lifetime_param.get_lifetime_bounds (),
-                                      " + ");
-    }
-}
-
-void
-Dump::visit (ConstGenericParam &)
-{}
-
-// rust-path.h
-void
-Dump::visit (PathInExpression &path)
-{
-  stream << path.as_string ();
-}
-
-void
-Dump::visit (TypePathSegment &segment)
-{
-  // Syntax:
-  //    PathIdentSegment
-
-  stream << segment.get_ident_segment ().as_string ();
-}
-
-void
-Dump::visit (TypePathSegmentGeneric &segment)
-{
-  // Syntax:
-  //    PathIdentSegment `::`? (GenericArgs)?
-  // GenericArgs :
-  //    `<` `>`
-  //    | `<` ( GenericArg `,` )* GenericArg `,`? `>`
-
-  stream << segment.get_ident_segment ().as_string ();
-
-  if (segment.get_separating_scope_resolution ())
-    stream << "::";
-
-  stream << "<";
-
-  {
-    // Here we join 3 lists (each possibly empty) with a separator.
-
-    auto &lifetime_args = segment.get_generic_args ().get_lifetime_args ();
-    auto &generic_args = segment.get_generic_args ().get_generic_args ();
-    auto &binding_args = segment.get_generic_args ().get_binding_args ();
-
-    visit_items_joined_by_separator (lifetime_args, ", ");
-    if (!lifetime_args.empty ()
-       && (!generic_args.empty () || !binding_args.empty ()))
-      {
-       // Insert separator if some items have been already emitted and some
-       // more are to be emitted from any of the following collections.
-       stream << ", ";
-      }
-    visit_items_joined_by_separator (generic_args, ", ");
-    if (!generic_args.empty () && !binding_args.empty ())
-      {
-       // Insert separator if some item vas emitted from the previous
-       // collection and more are to be emitted from the last.
-       stream << ", ";
-      }
-    visit_items_joined_by_separator (binding_args, ", ");
-  }
-
-  stream << ">";
-}
-
-void
-Dump::visit (GenericArgsBinding &binding)
-{
-  // Syntax:
-  //    IDENTIFIER `=` Type
-
-  stream << binding.get_identifier () << " << ";
-  visit (binding.get_type ());
-}
-
-void
-Dump::visit (GenericArg &arg)
-{
-  // `GenericArg` implements `accept_vis` but it is not useful for this case as
-  // it ignores unresolved cases (`Kind::Either`).
-
-  switch (arg.get_kind ())
-    {
-    case GenericArg::Kind::Const:
-      visit (arg.get_expression ());
-      break;
-    case GenericArg::Kind::Type:
-      visit (arg.get_type ());
-      break;
-    case GenericArg::Kind::Either:
-      stream << arg.get_path ();
-      break;
-    case GenericArg::Kind::Error:
-      gcc_unreachable ();
-    }
-} // namespace AST
-
-void
-Dump::visit (TypePathSegmentFunction &segment)
-{
-  // Syntax:
-  //   PathIdentSegment `::`? (TypePathFn)?
-
-  stream << segment.get_ident_segment ().as_string ();
-
-  if (segment.get_separating_scope_resolution ())
-    stream << "::";
-
-  if (!segment.is_ident_only ())
-    visit (segment.get_type_path_function ());
-}
-
-void
-Dump::visit (TypePathFunction &type_path_fn)
-{
-  // Syntax:
-  //   `(` TypePathFnInputs? `)` (`->` Type)?
-  // TypePathFnInputs :
-  //   Type (`,` Type)* `,`?
-
-  stream << '(';
-  if (type_path_fn.has_inputs ())
-    visit_items_joined_by_separator (type_path_fn.get_params (), ", ");
-  stream << ')';
-
-  if (type_path_fn.has_return_type ())
-    {
-      stream << "->";
-      visit (type_path_fn.get_return_type ());
-    }
-}
-
-void
-Dump::visit (TypePath &path)
-{
-  // Syntax:
-  //    `::`? TypePathSegment (`::` TypePathSegment)*
-
-  if (path.has_opening_scope_resolution_op ())
-    stream << "::";
-  visit_items_joined_by_separator (path.get_segments (), "::");
-}
-
-void
-Dump::visit (QualifiedPathInExpression &path)
-{
-  stream << path.as_string ();
-}
-
-void
-Dump::visit (QualifiedPathInType &path)
-{
-  auto qualified_path_type = path.get_qualified_path_type ();
-  stream << "<";
-  visit (qualified_path_type.get_type ());
-  if (qualified_path_type.has_as_clause ())
-    {
-      stream << " as ";
-      visit (qualified_path_type.get_as_type_path ());
-    }
-  stream << ">::";
-  visit (path.get_associated_segment ());
-  visit_items_joined_by_separator (path.get_segments (), "::");
-}
-
-// rust-expr.h
-void
-Dump::visit (LiteralExpr &expr)
-{
-  switch (expr.get_lit_type ())
-    {
-    case Literal::CHAR:
-      stream << "'" << expr.as_string () << "'";
-      return;
-
-    case Literal::STRING:
-      stream << "\"" << expr.as_string () << "\"";
-      return;
-
-    case Literal::BYTE:
-      stream << "b'" << expr.as_string () << "'";
-      return;
-
-    case Literal::BYTE_STRING:
-      stream << "b\"" << expr.as_string () << "\"";
-      return;
-
-    case Literal::INT:
-    case Literal::FLOAT:
-    case Literal::BOOL:
-      stream << expr.as_string ();
-      return;
-
-    case Literal::ERROR:
-      stream << "/*ERROR*/";
-      return;
-    }
-}
-
-void
-Dump::visit (AttrInputLiteral &)
-{}
-
-void
-Dump::visit (AttrInputMacro &)
-{}
-
-void
-Dump::visit (MetaItemLitExpr &)
-{}
-
-void
-Dump::visit (MetaItemPathLit &)
-{}
-
-void
-Dump::visit (BorrowExpr &expr)
-{
-  stream << '&';
-  if (expr.get_is_double_borrow ())
-    stream << '&';
-  if (expr.get_is_mut ())
-    stream << "mut ";
-
-  visit (expr.get_borrowed_expr ());
-}
-
-void
-Dump::visit (DereferenceExpr &expr)
-{
-  stream << '*';
-  visit (expr.get_dereferenced_expr ());
-}
-
-void
-Dump::visit (ErrorPropagationExpr &expr)
-{
-  visit (expr.get_propagating_expr ());
-  stream << '?';
-}
-
-void
-Dump::visit (NegationExpr &expr)
-{
-  switch (expr.get_expr_type ())
-    {
-    case NegationOperator::NEGATE:
-      stream << "-(";
-      break;
-    case NegationOperator::NOT:
-      stream << "!(";
-      break;
-    }
-  visit (expr.get_negated_expr ());
-  stream << ')';
-}
-
-void
-Dump::visit (ArithmeticOrLogicalExpr &expr)
-{
-  auto op = "";
-  switch (expr.get_expr_type ())
-    {
-    case ArithmeticOrLogicalOperator::ADD:
-      op = "+";
-      break;
-
-    case ArithmeticOrLogicalOperator::SUBTRACT:
-      op = "-";
-      break;
-
-    case ArithmeticOrLogicalOperator::MULTIPLY:
-      op = "*";
-      break;
-
-    case ArithmeticOrLogicalOperator::DIVIDE:
-      op = "/";
-      break;
-
-    case ArithmeticOrLogicalOperator::MODULUS:
-      op = "%";
-      break;
-
-    case ArithmeticOrLogicalOperator::BITWISE_AND:
-      op = "&";
-      break;
-
-    case ArithmeticOrLogicalOperator::BITWISE_OR:
-      op = "|";
-      break;
-
-    case ArithmeticOrLogicalOperator::BITWISE_XOR:
-      op = "^";
-      break;
-
-    case ArithmeticOrLogicalOperator::LEFT_SHIFT:
-      op = "<<";
-      break;
-
-    case ArithmeticOrLogicalOperator::RIGHT_SHIFT:
-      op = ">>";
-      break;
-    }
-
-  visit (expr.get_left_expr ());
-  stream << " " << op << " ";
-  visit (expr.get_right_expr ());
-}
-
-void
-Dump::visit (ComparisonExpr &expr)
-{
-  auto op = "";
-  switch (expr.get_expr_type ())
-    {
-    case ComparisonOperator::EQUAL:
-      op = "==";
-      break;
-    case ComparisonOperator::NOT_EQUAL:
-      op = "!=";
-      break;
-
-    case ComparisonOperator::GREATER_THAN:
-      op = ">";
-      break;
-
-    case ComparisonOperator::LESS_THAN:
-      op = "<";
-      break;
-
-    case ComparisonOperator::GREATER_OR_EQUAL:
-      op = ">=";
-      break;
-
-    case ComparisonOperator::LESS_OR_EQUAL:
-      op = "<=";
-      break;
-    }
-
-  visit (expr.get_left_expr ());
-  stream << " " << op << " ";
-  visit (expr.get_right_expr ());
-}
-
-void
-Dump::visit (LazyBooleanExpr &expr)
-{
-  auto op = "";
-  switch (expr.get_expr_type ())
-    {
-    case LazyBooleanOperator::LOGICAL_AND:
-      op = "&&";
-      break;
-    case LazyBooleanOperator::LOGICAL_OR:
-      op = "||";
-      break;
-    }
-
-  visit (expr.get_left_expr ());
-  stream << " " << op << " ";
-  visit (expr.get_right_expr ());
-}
-
-void
-Dump::visit (TypeCastExpr &expr)
-{
-  visit (expr.get_casted_expr ());
-  stream << " as ";
-  visit (expr.get_type_to_cast_to ());
-}
-
-void
-Dump::visit (AssignmentExpr &expr)
-{
-  expr.visit_lhs (*this);
-  stream << " = ";
-  expr.visit_rhs (*this);
-}
-
-void
-Dump::visit (CompoundAssignmentExpr &expr)
-{
-  auto op = "";
-  switch (expr.get_expr_type ())
-    {
-    case CompoundAssignmentOperator::ADD:
-      op = "+";
-      break;
-
-    case CompoundAssignmentOperator::SUBTRACT:
-      op = "-";
-      break;
-
-    case CompoundAssignmentOperator::MULTIPLY:
-      op = "*";
-      break;
-
-    case CompoundAssignmentOperator::DIVIDE:
-      op = "/";
-      break;
-
-    case CompoundAssignmentOperator::MODULUS:
-      op = "%";
-      break;
-
-    case CompoundAssignmentOperator::BITWISE_AND:
-      op = "&";
-      break;
-
-    case CompoundAssignmentOperator::BITWISE_OR:
-      op = "|";
-      break;
-
-    case CompoundAssignmentOperator::BITWISE_XOR:
-      op = "^";
-      break;
-
-    case CompoundAssignmentOperator::LEFT_SHIFT:
-      op = "<<";
-      break;
-
-    case CompoundAssignmentOperator::RIGHT_SHIFT:
-      op = ">>";
-      break;
-    }
-
-  visit (expr.get_left_expr ());
-  stream << " " << op << "= ";
-  visit (expr.get_right_expr ());
-}
-
-void
-Dump::visit (GroupedExpr &expr)
-{
-  stream << '(';
-  visit (expr.get_expr_in_parens ());
-  stream << ')';
-}
-
-void
-Dump::visit (ArrayElemsValues &elems)
-{
-  visit_items_joined_by_separator (elems.get_values (), ", ");
-}
-
-void
-Dump::visit (ArrayElemsCopied &elems)
-{
-  visit (elems.get_elem_to_copy ());
-  stream << "; ";
-  visit (elems.get_num_copies ());
-}
-
-void
-Dump::visit (ArrayExpr &expr)
-{
-  stream << '[';
-  visit (expr.get_array_elems ());
-  stream << ']';
-}
-
-void
-Dump::visit (ArrayIndexExpr &expr)
-{
-  visit (expr.get_array_expr ());
-  stream << '[';
-  visit (expr.get_index_expr ());
-  stream << ']';
-}
-
-void
-Dump::visit (TupleExpr &)
-{}
-
-void
-Dump::visit (TupleIndexExpr &expr)
-{
-  visit (expr.get_tuple_expr ());
-  stream << '.' << expr.get_tuple_index ();
-}
-
-void
-Dump::visit (StructExprStruct &)
-{}
-
-void
-Dump::visit (StructExprFieldIdentifier &)
-{}
-
-void
-Dump::visit (StructExprFieldIdentifierValue &)
-{}
-
-void
-Dump::visit (StructExprFieldIndexValue &)
-{}
-
-void
-Dump::visit (StructExprStructFields &)
-{}
-
-void
-Dump::visit (StructExprStructBase &)
-{}
-
-void
-Dump::visit (CallExpr &expr)
-{
-  visit (expr.get_function_expr ());
-
-  stream << '(' << '\n';
-  indentation.increment ();
-
-  visit_items_as_lines (expr.get_params (), ",");
-
-  indentation.decrement ();
-  stream << indentation << ')';
-}
-
-void
-Dump::visit (MethodCallExpr &)
-{}
-
-void
-Dump::visit (FieldAccessExpr &)
-{}
-
-void
-Dump::visit (ClosureExprInner &)
-{}
-
-void
-Dump::visit (BlockExpr &expr)
-{
-  stream << "{\n";
-  indentation.increment ();
-
-  visit_items_as_lines (expr.get_statements (), ";");
-
-  if (expr.has_tail_expr ())
-    visit_as_line (expr.get_tail_expr (), " /* tail expr */\n");
-
-  indentation.decrement ();
-  stream << indentation << "}\n";
-}
-
-void
-Dump::visit (ClosureExprInnerTyped &)
-{}
-
-void
-Dump::visit (ContinueExpr &)
-{}
-
-void
-Dump::visit (BreakExpr &)
-{}
-
-void
-Dump::visit (RangeFromToExpr &expr)
-{
-  visit (expr.get_from_expr ());
-  stream << "..";
-  visit (expr.get_to_expr ());
-}
-
-void
-Dump::visit (RangeFromExpr &expr)
-{
-  visit (expr.get_from_expr ());
-  stream << "..";
-}
-
-void
-Dump::visit (RangeToExpr &expr)
-{
-  stream << "..";
-  visit (expr.get_to_expr ());
-}
-
-void
-Dump::visit (RangeFullExpr &)
-{
-  stream << "..";
-}
-
-void
-Dump::visit (RangeFromToInclExpr &expr)
-{
-  visit (expr.get_from_expr ());
-  stream << "..=";
-  visit (expr.get_to_expr ());
-}
-
-void
-Dump::visit (RangeToInclExpr &expr)
-{
-  stream << "..=";
-  visit (expr.get_to_expr ());
-}
-
-void
-Dump::visit (ReturnExpr &)
-{}
-
-void
-Dump::visit (UnsafeBlockExpr &)
-{}
-
-void
-Dump::visit (LoopExpr &)
-{}
-
-void
-Dump::visit (WhileLoopExpr &)
-{}
-
-void
-Dump::visit (WhileLetLoopExpr &)
-{}
-
-void
-Dump::visit (ForLoopExpr &)
-{}
-
-void
-Dump::visit (IfExpr &expr)
-{
-  stream << "if ";
-  visit (expr.get_condition_expr ());
-  stream << " ";
-  visit (expr.get_if_block ());
-}
-
-void
-Dump::visit (IfExprConseqElse &expr)
-{
-  stream << "if ";
-  visit (expr.get_condition_expr ());
-  stream << " ";
-  visit (expr.get_if_block ());
-  stream << indentation << "else ";
-  visit (expr.get_else_block ());
-}
-
-void
-Dump::visit (IfLetExpr &)
-{}
-
-void
-Dump::visit (IfLetExprConseqElse &)
-{}
-
-void
-Dump::visit (MatchExpr &)
-{}
-
-void
-Dump::visit (AwaitExpr &)
-{}
-
-void
-Dump::visit (AsyncBlockExpr &)
-{}
-
-// rust-item.h
-void
-Dump::visit (TypeParam &param)
-{
-  // Syntax:
-  //    IDENTIFIER( : TypeParamBounds? )? ( = Type )?
-  // TypeParamBounds :
-  //    TypeParamBound ( + TypeParamBound )* +?
-
-  stream << param.get_type_representation ();
-  if (param.has_type_param_bounds ())
-    {
-      stream << ": ";
-      visit_items_joined_by_separator (param.get_type_param_bounds (), " + ");
-    }
-  if (param.has_type ())
-    {
-      stream << " = ";
-      visit (param.get_type ());
-    }
-}
-
-void
-Dump::visit (WhereClause &rule)
-{
-  // Syntax:
-  //   where ( WhereClauseItem , )* WhereClauseItem ?
-  // WhereClauseItem :
-  //   LifetimeWhereClauseItem
-  //   | TypeBoundWhereClauseItem
-
-  stream << " where\n";
-  indentation.increment ();
-  visit_items_as_lines (rule.get_items (), ",");
-  indentation.decrement ();
-}
-
-void
-Dump::visit (LifetimeWhereClauseItem &item)
-{
-  // Syntax:
-  //   Lifetime : LifetimeBounds
-  // LifetimeBounds :
-  //   ( Lifetime + )* Lifetime?
-
-  visit (item.get_lifetime ());
-  stream << ": ";
-  visit_items_joined_by_separator (item.get_lifetime_bounds (), " + ");
-}
-
-void
-Dump::visit (TypeBoundWhereClauseItem &item)
-{
-  // Syntax:
-  //   ForLifetimes? Type : TypeParamBounds?
-  // TypeParamBounds :
-  //   TypeParamBound ( + TypeParamBound )* +?
-  // TypeParamBound :
-  //    Lifetime | TraitBound
-
-  if (item.has_for_lifetimes ())
-    visit (item.get_for_lifetimes ());
-
-  visit (item.get_type ());
-  stream << ": ";
-
-  visit_items_joined_by_separator (item.get_type_param_bounds (), " + ");
-}
-
-void
-Dump::visit (Method &method)
-{
-  visit (method.get_visibility ());
-  stream << "fn " << method.get_method_name () << '(';
-
-  stream << method.get_self_param ().as_string ();
-  if (!method.get_function_params ().empty ())
-    {
-      stream << ", ";
-      visit_items_joined_by_separator (method.get_function_params (), ", ");
-    }
-
-  stream << ") ";
-
-  if (method.has_return_type ())
-    {
-      stream << "-> ";
-      visit (method.get_return_type ());
-      stream << " ";
-    }
-
-  auto &block = method.get_definition ();
-  if (!block)
-    stream << ';';
-  else
-    visit (block);
-
-  stream << '\n';
-}
-
-void
-Dump::visit (Module &module)
-{
-  //  Syntax:
-  //   mod IDENTIFIER ;
-  //     | mod IDENTIFIER {
-  //     InnerAttribute*
-  //     Item*
-  //   }
-
-  visit (module.get_visibility ());
-  stream << "mod " << module.get_name ();
-
-  if (module.get_kind () == Module::UNLOADED)
-    {
-      stream << ";\n";
-    }
-  else /* Module::LOADED */
-    {
-      stream << " {\n";
-
-      indentation.increment ();
-
-      visit_items_as_lines (module.get_inner_attrs ());
-      visit_items_as_lines (module.get_items ());
-
-      indentation.decrement ();
-
-      stream << indentation << "}\n";
-    }
-}
-
-void
-Dump::visit (ExternCrate &)
-{}
-
-void
-Dump::visit (UseTreeGlob &)
-{}
-
-void
-Dump::visit (UseTreeList &)
-{}
-
-void
-Dump::visit (UseTreeRebind &)
-{}
-
-void
-Dump::visit (UseDeclaration &)
-{}
-
-void
-Dump::visit (Function &function)
-{
-  // Syntax:
-  //   FunctionQualifiers fn IDENTIFIER GenericParams?
-  //      ( FunctionParameters? )
-  //      FunctionReturnType? WhereClause?
-  //      ( BlockExpression | ; )
-
-  visit (function.get_visibility ());
-
-  stream << "fn " << function.get_function_name ();
-  if (function.has_generics ())
-    visit (function.get_generic_params ());
-
-  stream << '(';
-  visit_items_joined_by_separator (function.get_function_params ());
-  stream << ") ";
-
-  if (function.has_return_type ())
-    {
-      stream << "-> ";
-      visit (function.get_return_type ());
-      stream << " ";
-    }
-
-  if (function.has_where_clause ())
-    visit (function.get_where_clause ());
-
-  auto &block = function.get_definition ();
-  if (!block)
-    stream << ';';
-  else
-    visit (block);
-
-  stream << '\n';
-}
-
-void
-Dump::visit (TypeAlias &type_alias)
-{
-  // Syntax:
-  // Visibility? type IDENTIFIER GenericParams? WhereClause? = Type;
-
-  // Note: Associated types are handled by `AST::TraitItemType`.
-  if (type_alias.has_visibility ())
-    visit (type_alias.get_visibility ());
-  stream << "type " << type_alias.get_new_type_name ();
-  if (type_alias.has_generics ())
-    visit (type_alias.get_generic_params ());
-  if (type_alias.has_where_clause ())
-    visit (type_alias.get_where_clause ());
-  stream << " = ";
-  visit (type_alias.get_type_aliased ());
-  stream << ";\n";
-}
-
-void
-Dump::visit (StructStruct &struct_item)
-{
-  stream << "struct " << struct_item.get_identifier ();
-  if (struct_item.has_generics ())
-    visit (struct_item.get_generic_params ());
-  if (struct_item.has_where_clause ())
-    visit (struct_item.get_where_clause ());
-  if (struct_item.is_unit_struct ())
-    stream << ";\n";
-  else
-    visit_items_as_block (struct_item.get_fields (), ",");
-}
-
-void
-Dump::visit (TupleStruct &tuple_struct)
-{
-  stream << "struct " << tuple_struct.get_identifier ();
-  if (tuple_struct.has_generics ())
-    visit (tuple_struct.get_generic_params ());
-  if (tuple_struct.has_where_clause ())
-    visit (tuple_struct.get_where_clause ());
-
-  stream << '(';
-  visit_items_joined_by_separator (tuple_struct.get_fields (), ", ");
-  stream << ");\n";
-}
-
-void
-Dump::visit (EnumItem &item)
-{
-  stream << item.get_identifier ();
-}
-
-void
-Dump::visit (EnumItemTuple &item)
-{
-  stream << item.get_identifier () << '(';
-  visit_items_joined_by_separator (item.get_tuple_fields (), ", ");
-  stream << ')';
-}
-
-void
-Dump::visit (EnumItemStruct &item)
-{
-  stream << item.get_identifier ();
-  visit_items_as_block (item.get_struct_fields (), ",");
-}
-
-void
-Dump::visit (EnumItemDiscriminant &item)
-{
-  stream << item.get_identifier () << " = ";
-  visit (item.get_expr ());
-}
-
-void
-Dump::visit (Enum &enum_item)
-{
-  stream << "enum " << enum_item.get_identifier ();
-  if (enum_item.has_generics ())
-    visit (enum_item.get_generic_params ());
-  if (enum_item.has_where_clause ())
-    visit (enum_item.get_where_clause ());
-
-  visit_items_as_block (enum_item.get_variants (), ",");
-}
-
-void
-Dump::visit (Union &union_item)
-{
-  stream << "union " << union_item.get_identifier ();
-  if (union_item.has_generics ())
-    visit (union_item.get_generic_params ());
-  if (union_item.has_where_clause ())
-    visit (union_item.get_where_clause ());
-
-  visit_items_as_block (union_item.get_variants (), ",");
-}
-
-void
-Dump::visit (ConstantItem &)
-{}
-
-void
-Dump::visit (StaticItem &)
-{}
-
-void
-Dump::visit_function_common (std::unique_ptr<Type> &return_type,
-                            std::unique_ptr<BlockExpr> &block)
-{
-  // FIXME: This should format the `<vis> fn <name> ( [args] )` as well
-  if (return_type)
-    {
-      stream << "-> ";
-      visit (return_type);
-    }
-
-  if (block)
-    {
-      if (return_type)
-       {
-         stream << ' ';
-         visit (block);
-       }
-    }
-  else
-    stream << ";\n";
-}
-
-void
-Dump::visit (TraitItemFunc &item)
-{
-  auto func = item.get_trait_function_decl ();
-  stream << "fn " << func.get_identifier () << '(';
-
-  visit_items_joined_by_separator (func.get_function_params ());
-
-  stream << ") ";
-
-  visit_function_common (func.get_return_type (), item.get_definition ());
-}
-
-void
-Dump::visit (TraitItemMethod &item)
-{
-  auto method = item.get_trait_method_decl ();
-
-  // FIXME: Can we have visibility here?
-  // emit_visibility (method.get_visibility ());
-  stream << "fn " << method.get_identifier () << '(';
-
-  stream << method.get_self_param ().as_string ();
-
-  if (!method.get_function_params ().empty ())
-    {
-      stream << ", ";
-      visit_items_joined_by_separator (method.get_function_params (), ", ");
-    }
-
-  stream << ") ";
-
-  visit_function_common (method.get_return_type (), item.get_definition ());
-}
-
-void
-Dump::visit (TraitItemConst &item)
-{
-  stream << indentation << "const " << item.get_identifier () << ": ";
-  visit (item.get_type ());
-  stream << ";\n";
-}
-
-void
-Dump::visit (TraitItemType &item)
-{
-  stream << indentation << "type " << item.get_identifier () << ";\n";
-}
-
-void
-Dump::visit (Trait &trait)
-{
-  for (auto &attr : trait.get_outer_attrs ())
-    {
-      visit (attr);
-      stream << "\n" << indentation;
-    }
-
-  visit (trait.get_visibility ());
-
-  stream << "trait " << trait.get_identifier ();
-
-  // Traits actually have an implicit Self thrown at the start, so we must
-  // expect the number of generic params to be > 1
-  if (trait.get_generic_params ().size () > 1)
-    {
-      stream << "<";
-      visit_items_joined_by_separator (trait.get_generic_params (), ", ", 1);
-      stream << ">";
-    }
-
-  visit_items_as_block (trait.get_trait_items (), "");
-}
-
-void
-Dump::visit (InherentImpl &impl)
-{
-  stream << "impl ";
-
-  // FIXME: Handle generics
-
-  visit (impl.get_type ());
-
-  if (impl.has_where_clause ())
-    visit (impl.get_where_clause ());
-
-  // FIXME: Handle inner attributes
-
-  visit_items_as_block (impl.get_impl_items (), "");
-}
-
-void
-Dump::visit (TraitImpl &impl)
-{
-  stream << "impl ";
-  visit (impl.get_trait_path ());
-  stream << " for ";
-  visit (impl.get_type ());
-  stream << " {\n";
-
-  indentation.increment ();
-
-  for (auto &item : impl.get_impl_items ())
-    {
-      stream << indentation;
-      visit (item);
-    }
-
-  indentation.decrement ();
-  stream << "\n}\n";
-}
-
-void
-Dump::visit (ExternalTypeItem &type)
-{
-  visit (type.get_visibility ());
-
-  stream << "type " << type.get_identifier () << ';';
-}
-
-void
-Dump::visit (ExternalStaticItem &)
-{}
-
-void
-Dump::visit (ExternalFunctionItem &function)
-{
-  visit (function.get_visibility ());
-
-  stream << "fn " << function.get_identifier () << '(';
-
-  visit_items_joined_by_separator (function.get_function_params ());
-
-  stream << ')';
-  if (function.has_return_type ())
-    {
-      stream << "-> ";
-      visit (function.get_return_type ());
-    }
-}
-
-void
-Dump::visit (ExternBlock &block)
-{
-  stream << "extern ";
-
-  if (block.has_abi ())
-    stream << "\"" << block.get_abi () << "\" ";
-
-  visit_items_as_block (block.get_extern_items (), ";");
-}
-
-static std::pair<char, char>
-get_delimiters (DelimType delim)
-{
-  auto start_delim = '\0';
-  auto end_delim = '\0';
-
-  switch (delim)
-    {
-    case PARENS:
-      start_delim = '(';
-      end_delim = ')';
-      break;
-    case SQUARE:
-      start_delim = '[';
-      end_delim = ']';
-      break;
-    case CURLY:
-      start_delim = '{';
-      end_delim = '}';
-      break;
-    }
-
-  return {start_delim, end_delim};
-}
-
-void
-Dump::visit (MacroMatchFragment &match)
-{
-  stream << '$' << match.get_ident () << ':'
-        << match.get_frag_spec ().as_string ();
-}
-
-void
-Dump::visit (MacroMatchRepetition &repetition)
-{
-  stream << "$(";
-
-  visit_items_joined_by_separator (repetition.get_matches (), " ");
-
-  auto op_char = '\0';
-  switch (repetition.get_op ())
-    {
-    case MacroMatchRepetition::ANY:
-      op_char = '*';
-      break;
-    case MacroMatchRepetition::ONE_OR_MORE:
-      op_char = '+';
-      break;
-    case MacroMatchRepetition::ZERO_OR_ONE:
-      op_char = '?';
-      break;
-    case MacroMatchRepetition::NONE:
-      break;
-    }
-
-  stream << ')';
-
-  if (repetition.has_sep ())
-    stream << repetition.get_sep ()->as_string ();
-
-  stream << op_char;
-}
-
-void
-Dump::visit (MacroMatcher &matcher)
-{
-  auto delimiters = get_delimiters (matcher.get_delim_type ());
-
-  stream << delimiters.first;
-
-  visit_items_joined_by_separator (matcher.get_matches (), " ");
-
-  stream << delimiters.second;
-}
-
-void
-Dump::visit (MacroRule &rule)
-{
-  visit (rule.get_matcher ());
-  stream << " => ";
-  visit (rule.get_transcriber ().get_token_tree ());
-}
-
-void
-Dump::visit (MacroRulesDefinition &rules_def)
-{
-  for (auto &outer_attr : rules_def.get_outer_attrs ())
-    visit (outer_attr);
-
-  stream << "macro_rules! " << rules_def.get_rule_name ();
-
-  visit_items_as_block (rules_def.get_rules (), ";");
-}
-
-void
-Dump::visit (MacroInvocation &invocation)
-{
-  // FIXME: make this accurately reflect the original macro syntax.
-  stream << invocation.get_invoc_data ().as_string ();
-}
-
-void
-Dump::visit (MetaItemPath &)
-{}
-
-void
-Dump::visit (MetaItemSeq &)
-{}
-
-void
-Dump::visit (MetaWord &)
-{}
-
-void
-Dump::visit (MetaNameValueStr &)
-{}
-
-void
-Dump::visit (MetaListPaths &)
-{}
-
-void
-Dump::visit (MetaListNameValueStr &)
-{}
-
-// rust-pattern.h
-void
-Dump::visit (LiteralPattern &)
-{}
-
-void
-Dump::visit (IdentifierPattern &pattern)
-{
-  stream << pattern.get_ident ();
-}
-
-void
-Dump::visit (WildcardPattern &)
-{}
-
-void
-Dump::visit (RestPattern &)
-{}
-
-// void Dump::visit(RangePatternBound& ){}
-
-void
-Dump::visit (RangePatternBoundLiteral &)
-{}
-
-void
-Dump::visit (RangePatternBoundPath &)
-{}
-
-void
-Dump::visit (RangePatternBoundQualPath &)
-{}
-
-void
-Dump::visit (RangePattern &)
-{}
-
-void
-Dump::visit (ReferencePattern &)
-{}
-
-// void Dump::visit(StructPatternField& ){}
-
-void
-Dump::visit (StructPatternFieldTuplePat &)
-{}
-
-void
-Dump::visit (StructPatternFieldIdentPat &)
-{}
-
-void
-Dump::visit (StructPatternFieldIdent &)
-{}
-
-void
-Dump::visit (StructPattern &)
-{}
-
-// void Dump::visit(TupleStructItems& ){}
-
-void
-Dump::visit (TupleStructItemsNoRange &)
-{}
-
-void
-Dump::visit (TupleStructItemsRange &)
-{}
-
-void
-Dump::visit (TupleStructPattern &)
-{}
-
-// void Dump::visit(TuplePatternItems& ){}
-
-void
-Dump::visit (TuplePatternItemsMultiple &)
-{}
-
-void
-Dump::visit (TuplePatternItemsRanged &)
-{}
-
-void
-Dump::visit (TuplePattern &)
-{}
-
-void
-Dump::visit (GroupedPattern &)
-{}
-
-void
-Dump::visit (SlicePattern &)
-{}
-
-void
-Dump::visit (AltPattern &)
-{}
-
-// rust-stmt.h
-void
-Dump::visit (EmptyStmt &)
-{}
-
-void
-Dump::visit (LetStmt &stmt)
-{
-  stream << "let ";
-  auto &pattern = stmt.get_pattern ();
-  if (pattern)
-    visit (pattern);
-
-  if (stmt.has_type ())
-    {
-      stream << ": ";
-      visit (stmt.get_type ());
-    }
-
-  if (stmt.has_init_expr ())
-    {
-      stream << " = ";
-      visit (stmt.get_init_expr ());
-    }
-}
-
-void
-Dump::visit (ExprStmt &stmt)
-{
-  visit (stmt.get_expr ());
-}
-
-// rust-type.h
-void
-Dump::visit (TraitBound &bound)
-{
-  // Syntax:
-  //      ?? ForLifetimes? TypePath
-  //   | ( ?? ForLifetimes? TypePath )
-
-  if (bound.has_opening_question_mark ())
-    stream << "? ";
-
-  if (bound.has_for_lifetimes ())
-    visit (bound.get_for_lifetimes ());
-
-  visit (bound.get_type_path ());
-}
-
-void
-Dump::visit (ImplTraitType &type)
-{
-  // Syntax:
-  //    impl TypeParamBounds
-  // TypeParamBounds :
-  //    TypeParamBound ( + TypeParamBound )* +?
-
-  stream << "impl ";
-  visit_items_joined_by_separator (type.get_type_param_bounds (), " + ");
-}
-
-void
-Dump::visit (TraitObjectType &type)
-{
-  // Syntax:
-  //   dyn? TypeParamBounds
-  // TypeParamBounds :
-  //   TypeParamBound ( + TypeParamBound )* +?
-
-  if (type.is_dyn ())
-    stream << "dyn ";
-  visit_items_joined_by_separator (type.get_type_param_bounds (), " + ");
-}
-
-void
-Dump::visit (ParenthesisedType &type)
-{
-  // Syntax:
-  //    ( Type )
-
-  stream << "(";
-  visit (type.get_type_in_parens ());
-  stream << ")";
-}
-
-void
-Dump::visit (ImplTraitTypeOneBound &type)
-{
-  // Syntax:
-  //    impl TraitBound
-
-  stream << "impl ";
-  visit (type.get_trait_bound ());
-}
-
-void
-Dump::visit (TraitObjectTypeOneBound &type)
-{
-  // Syntax:
-  //    dyn? TraitBound
-
-  if (type.is_dyn ())
-    stream << "dyn ";
-  visit (type.get_trait_bound ());
-}
-
-void
-Dump::visit (TupleType &type)
-{
-  // Syntax:
-  //   ( )
-  //   | ( ( Type , )+ Type? )
-
-  stream << '(';
-  visit_items_joined_by_separator (type.get_elems (), ", ");
-  stream << ')';
-}
-
-void
-Dump::visit (NeverType &)
-{
-  // Syntax:
-  //  !
-
-  stream << '!';
-}
-
-void
-Dump::visit (RawPointerType &type)
-{
-  // Syntax:
-  //    * ( mut | const ) TypeNoBounds
-
-  if (type.get_pointer_type () == RawPointerType::MUT)
-    stream << "*mut ";
-  else /* RawPointerType::CONST */
-    stream << "*const ";
-
-  visit (type.get_type_pointed_to ());
-}
-
-void
-Dump::visit (ReferenceType &type)
-{
-  // Syntax:
-  //    & Lifetime? mut? TypeNoBounds
-
-  stream << '&';
-
-  if (type.has_lifetime ())
-    {
-      visit (type.get_lifetime ());
-      stream << ' ';
-    }
-
-  if (type.get_has_mut ())
-    stream << "mut ";
-
-  visit (type.get_type_referenced ());
-}
-
-void
-Dump::visit (ArrayType &type)
-{
-  // Syntax:
-  //    [ Type ; Expression ]
-
-  stream << '[';
-  visit (type.get_elem_type ());
-  stream << "; ";
-  visit (type.get_size_expr ());
-  stream << ']';
-}
-
-void
-Dump::visit (SliceType &type)
-{
-  // Syntax:
-  //    [ Type ]
-
-  stream << '[';
-  visit (type.get_elem_type ());
-  stream << ']';
-}
-
-void
-Dump::visit (InferredType &)
+Dump::debug (Visitable &v)
 {
-  // Syntax:
-  //    _
-
-  stream << "_";
+  Dump dump (std::cerr);
+  dump.process (v);
 }
 
 void
-Dump::visit (BareFunctionType &type)
+Dump::go (AST::Crate &crate)
 {
-  // Syntax:
-  //    ForLifetimes? FunctionTypeQualifiers fn
-  //      ( FunctionParametersMaybeNamedVariadic? ) BareFunctionReturnType?
-  //
-  //    BareFunctionReturnType:
-  //      -> TypeNoBounds
-  //
-  //    FunctionParametersMaybeNamedVariadic :
-  //      MaybeNamedFunctionParameters | MaybeNamedFunctionParametersVariadic
-  //
-  //    MaybeNamedFunctionParameters :
-  //      MaybeNamedParam ( , MaybeNamedParam )* ,?
-  //
-  //    MaybeNamedFunctionParametersVariadic :
-  //      ( MaybeNamedParam , )* MaybeNamedParam , OuterAttribute* ...
-
-  if (type.has_for_lifetimes ())
-    visit (type.get_for_lifetimes ());
-
-  visit (type.get_function_qualifiers ());
-
-  stream << "fn (";
-
-  visit_items_joined_by_separator (type.get_function_params (), ", ");
-
-  if (type.is_variadic ())
-    {
-      stream << ", ";
-      visit_items_joined_by_separator (type.get_variadic_attr (), " ");
-      stream << "...";
-    }
-
-  stream << ')';
-
-  if (type.has_return_type ())
-    {
-      stream << " -> ";
-      visit (type.get_return_type ());
-    }
+  process (crate);
 }
 
 void
-Dump::debug (Visitable &v)
+Dump::go (AST::Item &item)
 {
-  auto dump = Dump (std::cerr);
-
-  std::cerr << '\n';
-  v.accept_vis (dump);
-  std::cerr << '\n';
+  process (item);
 }
 
 } // namespace AST
index ed6f17074762ddbb09b125142f17b973151ecf0e..14d22ecf06bc4bff7cb29aa3760d74dab8d19750 100644 (file)
 // You should have received a copy of the GNU General Public License
 // along with GCC; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
+#ifndef RUST_AST_DUMP_H
+#define RUST_AST_DUMP_H
 
 #include "rust-ast-visitor.h"
 #include "rust-ast.h"
 #include "rust-ast-full.h"
 #include "rust-dump.h"
 
-#ifndef RUST_AST_DUMP_H
-#define RUST_AST_DUMP_H
+#include "rust-ast-collector.h"
 
 namespace Rust {
 namespace AST {
 
-class Dump : public ASTVisitor
+class Dump
 {
 public:
   Dump (std::ostream &stream);
@@ -38,255 +39,24 @@ public:
   void go (AST::Crate &crate);
   void go (AST::Item &item);
 
+  template <typename T> void process (T &v)
+  {
+    std::vector<TokenPtr> container;
+    TokenCollector collector (container);
+    collector.visit (v);
+
+    for (auto &token : collector.collect_tokens ())
+      {
+       stream << token->as_string () << " ";
+      }
+  }
+
   // Helper method to get a quick debug dump to standard error output
   static void debug (Visitable &v);
 
 private:
   std::ostream &stream;
   Indent indentation;
-
-  /**
-   * Compatibility layer for using the visitor pattern on polymorphic classes
-   * with a unified overload syntax. This allows us to call `visit` both on
-   * types implementing `accept_vis` method and for classes for which the
-   * `visit` method is directly implemented.
-   */
-  template <typename T> void visit (std::unique_ptr<T> &node);
-
-  /**
-   * @see visit<std::unique_ptr<T>>
-   */
-  template <typename T> void visit (T &node);
-
-  /**
-   * Visit all items in given @collection, placing the separator in between but
-   * not at the end.
-   * Start and end offset allow to visit only a "slice" from the collection.
-   */
-  template <typename T>
-  void visit_items_joined_by_separator (T &collection,
-                                       const std::string &separator = "",
-                                       size_t start_offset = 0,
-                                       size_t end_offset = 0);
-
-  /**
-   * Visit item placing indentation before and trailing string + end of line
-   * after.
-   */
-  template <typename T>
-  void visit_as_line (T &item, const std::string &trailing = "");
-
-  /**
-   * Visit each item in @collection "as line".
-   *
-   * @see visit_as_line
-   */
-  template <typename T>
-  void visit_items_as_lines (T &collection, const std::string &trailing = "");
-
-  /**
-   * Visit each item in @collection as lines inside a block delimited by braces
-   * with increased indentation. Also includes special handling for empty
-   * collection to print only the delimiters with no new line inside.
-   */
-  template <typename T>
-  void visit_items_as_block (T &collection, const std::string &line_trailing,
-                            char left_brace = '{', char right_brace = '}');
-
-  /**
-   * Visit common items of functions: Parameters, return type, block
-   */
-  void visit_function_common (std::unique_ptr<Type> &return_type,
-                             std::unique_ptr<BlockExpr> &block);
-
-  void visit (FunctionParam &param);
-  void visit (Attribute &attrib);
-  void visit (Visibility &vis);
-  void visit (std::vector<std::unique_ptr<GenericParam>> &params);
-  void visit (TupleField &field);
-  void visit (StructField &field);
-  void visit (SimplePathSegment &segment);
-  void visit (NamedFunctionParam &param);
-  void visit (MacroRule &rule);
-  void visit (WhereClause &rule);
-  void visit (std::vector<LifetimeParam> &for_lifetimes);
-  void visit (FunctionQualifiers &qualifiers);
-  void visit (MaybeNamedParam &param);
-  void visit (TypePathFunction &type_path_fn);
-  void visit (GenericArgsBinding &binding);
-  void visit (GenericArg &arg);
-
-  // rust-ast.h
-  void visit (Token &tok);
-  void visit (DelimTokenTree &delim_tok_tree);
-  void visit (AttrInputMetaItemContainer &input);
-  void visit (IdentifierExpr &ident_expr);
-  void visit (Lifetime &lifetime);
-  void visit (LifetimeParam &lifetime_param);
-  void visit (ConstGenericParam &const_param);
-
-  // rust-path.h
-  void visit (PathInExpression &path);
-  void visit (TypePathSegment &segment);
-  void visit (TypePathSegmentGeneric &segment);
-  void visit (TypePathSegmentFunction &segment);
-  void visit (TypePath &path);
-  void visit (QualifiedPathInExpression &path);
-  void visit (QualifiedPathInType &path);
-
-  // rust-expr.h
-  void visit (LiteralExpr &expr);
-  void visit (AttrInputLiteral &attr_input);
-  void visit (AttrInputMacro &attr_input);
-  void visit (MetaItemLitExpr &meta_item);
-  void visit (MetaItemPathLit &meta_item);
-  void visit (BorrowExpr &expr);
-  void visit (DereferenceExpr &expr);
-  void visit (ErrorPropagationExpr &expr);
-  void visit (NegationExpr &expr);
-  void visit (ArithmeticOrLogicalExpr &expr);
-  void visit (ComparisonExpr &expr);
-  void visit (LazyBooleanExpr &expr);
-  void visit (TypeCastExpr &expr);
-  void visit (AssignmentExpr &expr);
-  void visit (CompoundAssignmentExpr &expr);
-  void visit (GroupedExpr &expr);
-  void visit (ArrayElemsValues &elems);
-  void visit (ArrayElemsCopied &elems);
-  void visit (ArrayExpr &expr);
-  void visit (ArrayIndexExpr &expr);
-  void visit (TupleExpr &expr);
-  void visit (TupleIndexExpr &expr);
-  void visit (StructExprStruct &expr);
-  void visit (StructExprFieldIdentifier &field);
-  void visit (StructExprFieldIdentifierValue &field);
-  void visit (StructExprFieldIndexValue &field);
-  void visit (StructExprStructFields &expr);
-  void visit (StructExprStructBase &expr);
-  void visit (CallExpr &expr);
-  void visit (MethodCallExpr &expr);
-  void visit (FieldAccessExpr &expr);
-  void visit (ClosureExprInner &expr);
-  void visit (BlockExpr &expr);
-  void visit (ClosureExprInnerTyped &expr);
-  void visit (ContinueExpr &expr);
-  void visit (BreakExpr &expr);
-  void visit (RangeFromToExpr &expr);
-  void visit (RangeFromExpr &expr);
-  void visit (RangeToExpr &expr);
-  void visit (RangeFullExpr &expr);
-  void visit (RangeFromToInclExpr &expr);
-  void visit (RangeToInclExpr &expr);
-  void visit (ReturnExpr &expr);
-  void visit (UnsafeBlockExpr &expr);
-  void visit (LoopExpr &expr);
-  void visit (WhileLoopExpr &expr);
-  void visit (WhileLetLoopExpr &expr);
-  void visit (ForLoopExpr &expr);
-  void visit (IfExpr &expr);
-  void visit (IfExprConseqElse &expr);
-  void visit (IfLetExpr &expr);
-  void visit (IfLetExprConseqElse &expr);
-  void visit (MatchExpr &expr);
-  void visit (AwaitExpr &expr);
-  void visit (AsyncBlockExpr &expr);
-
-  // rust-item.h
-  void visit (TypeParam &param);
-  void visit (LifetimeWhereClauseItem &item);
-  void visit (TypeBoundWhereClauseItem &item);
-  void visit (Method &method);
-  void visit (Module &module);
-  void visit (ExternCrate &crate);
-  void visit (UseTreeGlob &use_tree);
-  void visit (UseTreeList &use_tree);
-  void visit (UseTreeRebind &use_tree);
-  void visit (UseDeclaration &use_decl);
-  void visit (Function &function);
-  void visit (TypeAlias &type_alias);
-  void visit (StructStruct &struct_item);
-  void visit (TupleStruct &tuple_struct);
-  void visit (EnumItem &item);
-  void visit (EnumItemTuple &item);
-  void visit (EnumItemStruct &item);
-  void visit (EnumItemDiscriminant &item);
-  void visit (Enum &enum_item);
-  void visit (Union &union_item);
-  void visit (ConstantItem &const_item);
-  void visit (StaticItem &static_item);
-  void visit (TraitItemFunc &item);
-  void visit (TraitItemMethod &item);
-  void visit (TraitItemConst &item);
-  void visit (TraitItemType &item);
-  void visit (Trait &trait);
-  void visit (InherentImpl &impl);
-  void visit (TraitImpl &impl);
-  void visit (ExternalTypeItem &item);
-  void visit (ExternalStaticItem &item);
-  void visit (ExternalFunctionItem &item);
-  void visit (ExternBlock &block);
-
-  // rust-macro.h
-  void visit (MacroMatchFragment &match);
-  void visit (MacroMatchRepetition &match);
-  void visit (MacroMatcher &matcher);
-  void visit (MacroRulesDefinition &rules_def);
-  void visit (MacroInvocation &macro_invoc);
-  void visit (MetaItemPath &meta_item);
-  void visit (MetaItemSeq &meta_item);
-  void visit (MetaWord &meta_item);
-  void visit (MetaNameValueStr &meta_item);
-  void visit (MetaListPaths &meta_item);
-  void visit (MetaListNameValueStr &meta_item);
-
-  // rust-pattern.h
-  void visit (LiteralPattern &pattern);
-  void visit (IdentifierPattern &pattern);
-  void visit (WildcardPattern &pattern);
-  void visit (RestPattern &pattern);
-  // void visit(RangePatternBound& bound);
-  void visit (RangePatternBoundLiteral &bound);
-  void visit (RangePatternBoundPath &bound);
-  void visit (RangePatternBoundQualPath &bound);
-  void visit (RangePattern &pattern);
-  void visit (ReferencePattern &pattern);
-  // void visit(StructPatternField& field);
-  void visit (StructPatternFieldTuplePat &field);
-  void visit (StructPatternFieldIdentPat &field);
-  void visit (StructPatternFieldIdent &field);
-  void visit (StructPattern &pattern);
-  // void visit(TupleStructItems& tuple_items);
-  void visit (TupleStructItemsNoRange &tuple_items);
-  void visit (TupleStructItemsRange &tuple_items);
-  void visit (TupleStructPattern &pattern);
-  // void visit(TuplePatternItems& tuple_items);
-  void visit (TuplePatternItemsMultiple &tuple_items);
-  void visit (TuplePatternItemsRanged &tuple_items);
-  void visit (TuplePattern &pattern);
-  void visit (GroupedPattern &pattern);
-  void visit (SlicePattern &pattern);
-  void visit (AltPattern &pattern);
-
-  // rust-stmt.h
-  void visit (EmptyStmt &stmt);
-  void visit (LetStmt &stmt);
-  void visit (ExprStmt &stmt);
-
-  // rust-type.h
-  void visit (TraitBound &bound);
-  void visit (ImplTraitType &type);
-  void visit (TraitObjectType &type);
-  void visit (ParenthesisedType &type);
-  void visit (ImplTraitTypeOneBound &type);
-  void visit (TraitObjectTypeOneBound &type);
-  void visit (TupleType &type);
-  void visit (NeverType &type);
-  void visit (RawPointerType &type);
-  void visit (ReferenceType &type);
-  void visit (ArrayType &type);
-  void visit (SliceType &type);
-  void visit (InferredType &type);
-  void visit (BareFunctionType &type);
 };
 
 } // namespace AST