| // Copyright (C) 2020-2025 Free Software Foundation, Inc. |
| |
| // This file is part of GCC. |
| |
| // GCC is free software; you can redistribute it and/or modify it under |
| // the terms of the GNU General Public License as published by the Free |
| // Software Foundation; either version 3, or (at your option) any later |
| // version. |
| |
| // GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
| // WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| // for more details. |
| |
| // 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/>. |
| |
| #include "rust-ast-collector.h" |
| #include "rust-ast.h" |
| #include "rust-builtin-ast-nodes.h" |
| #include "rust-diagnostics.h" |
| #include "rust-expr.h" |
| #include "rust-item.h" |
| #include "rust-keyword-values.h" |
| #include "rust-location.h" |
| #include "rust-path.h" |
| #include "rust-system.h" |
| #include "rust-token.h" |
| |
| namespace Rust { |
| namespace AST { |
| |
| std::vector<TokenPtr> |
| TokenCollector::collect_tokens () const |
| { |
| std::vector<TokenPtr> result; |
| for (auto item : tokens) |
| { |
| if (item.get_kind () == CollectItem::Kind::Token) |
| { |
| result.emplace_back (item.get_token ()); |
| } |
| } |
| return result; |
| } |
| |
| std::vector<CollectItem> |
| TokenCollector::collect () const |
| { |
| return tokens; |
| } |
| |
| void |
| TokenCollector::visit (AST::Crate &crate) |
| { |
| visit_items_as_lines (crate.inner_attrs); |
| visit_items_as_lines (crate.items); |
| } |
| |
| void |
| TokenCollector::visit (AST::Item &item) |
| { |
| item.accept_vis (*this); |
| } |
| |
| void |
| TokenCollector::trailing_comma () |
| { |
| if (output_trailing_commas) |
| { |
| push (Rust::Token::make (COMMA, UNDEF_LOCATION)); |
| } |
| } |
| |
| void |
| TokenCollector::newline () |
| { |
| tokens.push_back ({CollectItem::Kind::Newline}); |
| } |
| |
| void |
| TokenCollector::indentation () |
| { |
| tokens.push_back ({indent_level}); |
| } |
| |
| void |
| TokenCollector::increment_indentation () |
| { |
| indent_level++; |
| } |
| |
| void |
| TokenCollector::decrement_indentation () |
| { |
| rust_assert (indent_level != 0); |
| indent_level--; |
| } |
| |
| void |
| TokenCollector::comment (std::string comment) |
| { |
| tokens.push_back ({comment}); |
| } |
| |
| void |
| TokenCollector::visit (Visitable &v) |
| { |
| v.accept_vis (*this); |
| } |
| |
| void |
| TokenCollector::visit (FunctionParam ¶m) |
| { |
| visit_items_as_lines (param.get_outer_attrs ()); |
| if (!param.is_variadic ()) |
| { |
| visit (param.get_pattern ()); |
| push (Rust::Token::make (COLON, UNDEF_LOCATION)); |
| visit (param.get_type ()); |
| } |
| else |
| { |
| if (param.has_name ()) |
| { |
| visit (param.get_pattern ()); |
| push (Rust::Token::make (COLON, UNDEF_LOCATION)); |
| } |
| push (Rust::Token::make (ELLIPSIS, UNDEF_LOCATION)); |
| } |
| } |
| |
| void |
| TokenCollector::visit (VariadicParam ¶m) |
| { |
| if (param.has_pattern ()) |
| { |
| visit (param.get_pattern ()); |
| push (Rust::Token::make (COLON, UNDEF_LOCATION)); |
| } |
| push (Rust::Token::make (ELLIPSIS, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (Attribute &attrib) |
| { |
| push (Rust::Token::make (HASH, attrib.get_locus ())); |
| if (attrib.is_inner_attribute ()) |
| push (Rust::Token::make (EXCLAM, UNDEF_LOCATION)); |
| push (Rust::Token::make (LEFT_SQUARE, UNDEF_LOCATION)); |
| visit (attrib.get_path ()); |
| |
| if (attrib.has_attr_input ()) |
| { |
| switch (attrib.get_attr_input ().get_attr_input_type ()) |
| { |
| case AST::AttrInput::AttrInputType::LITERAL: |
| { |
| visit (static_cast<AttrInputLiteral &> (attrib.get_attr_input ())); |
| break; |
| } |
| case AST::AttrInput::AttrInputType::MACRO: |
| { |
| visit (static_cast<AttrInputMacro &> (attrib.get_attr_input ())); |
| break; |
| } |
| case AST::AttrInput::AttrInputType::META_ITEM: |
| { |
| visit (static_cast<AttrInputMetaItemContainer &> ( |
| attrib.get_attr_input ())); |
| break; |
| } |
| case AST::AttrInput::AttrInputType::TOKEN_TREE: |
| { |
| visit (static_cast<DelimTokenTree &> (attrib.get_attr_input ())); |
| break; |
| } |
| default: |
| rust_unreachable (); |
| } |
| } |
| push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (SimplePath &path) |
| { |
| if (path.has_opening_scope_resolution ()) |
| { |
| push (Rust::Token::make (SCOPE_RESOLUTION, path.get_locus ())); |
| } |
| visit_items_joined_by_separator (path.get_segments (), SCOPE_RESOLUTION); |
| } |
| |
| void |
| TokenCollector::visit (SimplePathSegment &segment) |
| { |
| auto name = segment.get_segment_name (); |
| if (segment.is_crate_path_seg ()) |
| { |
| push (Rust::Token::make (CRATE, segment.get_locus ())); |
| } |
| else if (segment.is_super_path_seg ()) |
| { |
| push (Rust::Token::make (SUPER, segment.get_locus ())); |
| } |
| else if (segment.is_lower_self_seg ()) |
| { |
| push (Rust::Token::make (SELF, segment.get_locus ())); |
| } |
| else if (segment.is_big_self ()) |
| { |
| push (Rust::Token::make (SELF_ALIAS, segment.get_locus ())); |
| } |
| else |
| { |
| push ( |
| Rust::Token::make_identifier (segment.get_locus (), std::move (name))); |
| } |
| } |
| |
| void |
| TokenCollector::visit (Visibility &vis) |
| { |
| switch (vis.get_vis_type ()) |
| { |
| case Visibility::PUB: |
| push (Rust::Token::make (PUB, vis.get_locus ())); |
| break; |
| case Visibility::PUB_CRATE: |
| push (Rust::Token::make (PUB, vis.get_locus ())); |
| push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION)); |
| push (Rust::Token::make (CRATE, UNDEF_LOCATION)); |
| push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION)); |
| break; |
| case Visibility::PUB_SELF: |
| push (Rust::Token::make (PUB, vis.get_locus ())); |
| push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION)); |
| push (Rust::Token::make (SELF, UNDEF_LOCATION)); |
| push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION)); |
| break; |
| case Visibility::PUB_SUPER: |
| push (Rust::Token::make (PUB, vis.get_locus ())); |
| push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION)); |
| push (Rust::Token::make (SUPER, UNDEF_LOCATION)); |
| push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION)); |
| break; |
| case Visibility::PUB_IN_PATH: |
| push (Rust::Token::make (PUB, vis.get_locus ())); |
| push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION)); |
| push (Rust::Token::make (IN, UNDEF_LOCATION)); |
| visit (vis.get_path ()); |
| push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION)); |
| break; |
| case Visibility::PRIV: |
| break; |
| } |
| } |
| |
| void |
| TokenCollector::visit (std::vector<std::unique_ptr<GenericParam>> ¶ms) |
| { |
| push (Rust::Token::make (LEFT_ANGLE, UNDEF_LOCATION)); |
| visit_items_joined_by_separator (params, COMMA); |
| push (Rust::Token::make (RIGHT_ANGLE, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (TupleField &field) |
| { |
| for (auto attr : field.get_outer_attrs ()) |
| { |
| visit (attr); |
| } |
| visit (field.get_visibility ()); |
| visit (field.get_field_type ()); |
| } |
| |
| void |
| TokenCollector::visit (StructField &field) |
| { |
| for (auto attr : field.get_outer_attrs ()) |
| { |
| visit (attr); |
| } |
| visit (field.get_visibility ()); |
| auto name = field.get_field_name ().as_string (); |
| push (Rust::Token::make_identifier (field.get_locus (), std::move (name))); |
| push (Rust::Token::make (COLON, UNDEF_LOCATION)); |
| visit (field.get_field_type ()); |
| } |
| |
| void |
| TokenCollector::visit (std::vector<LifetimeParam> &for_lifetimes) |
| { |
| push (Rust::Token::make (FOR, UNDEF_LOCATION)); |
| push (Rust::Token::make (LEFT_ANGLE, UNDEF_LOCATION)); |
| visit_items_joined_by_separator (for_lifetimes, COMMA); |
| push (Rust::Token::make (RIGHT_ANGLE, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (FunctionQualifiers &qualifiers) |
| { |
| // Syntax: |
| // `const`? `async`? `unsafe`? (`extern` Abi?)? |
| // unsafe? (extern Abi?)? |
| |
| if (qualifiers.is_async ()) |
| push (Rust::Token::make (ASYNC, qualifiers.get_locus ())); |
| if (qualifiers.is_const ()) |
| push (Rust::Token::make (CONST, qualifiers.get_locus ())); |
| if (qualifiers.is_unsafe ()) |
| push (Rust::Token::make (UNSAFE, qualifiers.get_locus ())); |
| if (qualifiers.is_extern ()) |
| { |
| push (Rust::Token::make (EXTERN_KW, qualifiers.get_locus ())); |
| if (qualifiers.has_abi ()) |
| { |
| push (Rust::Token::make_string (UNDEF_LOCATION, |
| qualifiers.get_extern_abi ())); |
| } |
| } |
| } |
| |
| void |
| TokenCollector::visit (MaybeNamedParam ¶m) |
| { |
| // Syntax: |
| // OuterAttribute* ( ( IDENTIFIER | _ ) : )? Type |
| |
| for (auto attr : param.get_outer_attrs ()) |
| { |
| visit (attr); |
| } |
| auto param_name = param.get_name ().as_string (); |
| switch (param.get_param_kind ()) |
| { |
| case MaybeNamedParam::UNNAMED: |
| break; |
| case MaybeNamedParam::IDENTIFIER: |
| push ( |
| Rust::Token::make_identifier (UNDEF_LOCATION, std::move (param_name))); |
| push (Rust::Token::make (COLON, UNDEF_LOCATION)); |
| break; |
| case MaybeNamedParam::WILDCARD: |
| push (Rust::Token::make (UNDERSCORE, UNDEF_LOCATION)); |
| push (Rust::Token::make (COLON, UNDEF_LOCATION)); |
| break; |
| } |
| visit (param.get_type ()); |
| } |
| |
| void |
| TokenCollector::visit (Token &tok) |
| { |
| std::string data = tok.get_tok_ptr ()->has_str () ? tok.get_str () : ""; |
| switch (tok.get_id ()) |
| { |
| case IDENTIFIER: |
| push (Rust::Token::make_identifier (tok.get_locus (), std::move (data))); |
| break; |
| case INT_LITERAL: |
| push (Rust::Token::make_int (tok.get_locus (), std::move (data), |
| tok.get_type_hint ())); |
| break; |
| case FLOAT_LITERAL: |
| push (Rust::Token::make_float (tok.get_locus (), std::move (data), |
| tok.get_type_hint ())); |
| break; |
| case STRING_LITERAL: |
| push (Rust::Token::make_string (tok.get_locus (), std::move (data))); |
| break; |
| case CHAR_LITERAL: |
| push (Rust::Token::make_char ( |
| tok.get_locus (), |
| // FIXME: This need to be fixed to properly support UTF-8 |
| static_cast<uint32_t> (data[0]))); |
| break; |
| case BYTE_CHAR_LITERAL: |
| push (Rust::Token::make_byte_char (tok.get_locus (), data[0])); |
| break; |
| case BYTE_STRING_LITERAL: |
| push (Rust::Token::make_byte_string (tok.get_locus (), std::move (data))); |
| break; |
| case RAW_STRING_LITERAL: |
| push (Rust::Token::make_raw_string (tok.get_locus (), std::move (data))); |
| break; |
| case INNER_DOC_COMMENT: |
| push (Rust::Token::make_inner_doc_comment (tok.get_locus (), |
| std::move (data))); |
| break; |
| case OUTER_DOC_COMMENT: |
| push (Rust::Token::make_outer_doc_comment (tok.get_locus (), |
| std::move (data))); |
| break; |
| case LIFETIME: |
| push (Rust::Token::make_lifetime (tok.get_locus (), std::move (data))); |
| break; |
| default: |
| push (Rust::Token::make (tok.get_id (), tok.get_locus ())); |
| } |
| } |
| |
| void |
| TokenCollector::visit (DelimTokenTree &delim_tok_tree) |
| { |
| for (auto &token : delim_tok_tree.to_token_stream ()) |
| { |
| visit (token); |
| } |
| } |
| |
| void |
| TokenCollector::visit (AttrInputMetaItemContainer &container) |
| { |
| for (auto &item : container.get_items ()) |
| { |
| visit (item); |
| } |
| } |
| |
| void |
| TokenCollector::visit (IdentifierExpr &ident_expr) |
| { |
| auto ident = ident_expr.get_ident ().as_string (); |
| push ( |
| Rust::Token::make_identifier (ident_expr.get_locus (), std::move (ident))); |
| } |
| |
| void |
| TokenCollector::visit (Lifetime &lifetime) |
| { |
| // Syntax: |
| // Lifetime : |
| // LIFETIME_OR_LABEL |
| // | 'static |
| // | '_ |
| |
| auto name = lifetime.get_lifetime_name (); |
| switch (lifetime.get_lifetime_type ()) |
| { |
| case Lifetime::LifetimeType::NAMED: |
| push ( |
| Rust::Token::make_lifetime (lifetime.get_locus (), std::move (name))); |
| break; |
| case Lifetime::LifetimeType::STATIC: |
| push (Rust::Token::make_lifetime (lifetime.get_locus (), |
| Values::Keywords::STATIC_KW)); |
| break; |
| case Lifetime::LifetimeType::WILDCARD: |
| push (Rust::Token::make_lifetime (lifetime.get_locus (), |
| Values::Keywords::UNDERSCORE)); |
| break; |
| } |
| } |
| |
| void |
| TokenCollector::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. |
| |
| visit_items_as_lines (lifetime_param.get_outer_attrs ()); |
| auto lifetime = lifetime_param.get_lifetime (); |
| visit (lifetime); |
| |
| if (lifetime_param.has_lifetime_bounds ()) |
| { |
| push (Rust::Token::make (COLON, UNDEF_LOCATION)); |
| for (auto &bound : lifetime_param.get_lifetime_bounds ()) |
| { |
| visit (bound); |
| } |
| } |
| } |
| |
| void |
| TokenCollector::visit (ConstGenericParam ¶m) |
| { |
| // Syntax: |
| // const IDENTIFIER : Type ( = Block | IDENTIFIER | -?LITERAL )? |
| |
| visit_items_as_lines (param.get_outer_attrs ()); |
| push (Rust::Token::make (CONST, param.get_locus ())); |
| auto id = param.get_name ().as_string (); |
| push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id))); |
| push (Rust::Token::make (COLON, UNDEF_LOCATION)); |
| if (param.has_type ()) |
| visit (param.get_type ()); |
| if (param.has_default_value ()) |
| { |
| push (Rust::Token::make (EQUAL, UNDEF_LOCATION)); |
| visit (param.get_default_value_unchecked ()); |
| } |
| } |
| |
| void |
| TokenCollector::visit (PathExprSegment &segment) |
| { |
| visit (segment.get_ident_segment ()); |
| if (segment.has_generic_args ()) |
| { |
| auto generics = segment.get_generic_args (); |
| push (Rust::Token::make (SCOPE_RESOLUTION, segment.get_locus ())); |
| push (Rust::Token::make (LEFT_ANGLE, generics.get_locus ())); |
| |
| auto &lifetime_args = generics.get_lifetime_args (); |
| auto &generic_args = generics.get_generic_args (); |
| auto &binding_args = generics.get_binding_args (); |
| |
| visit_items_joined_by_separator (generic_args, COMMA); |
| |
| if (!lifetime_args.empty () |
| && (!generic_args.empty () || !binding_args.empty ())) |
| { |
| push (Rust::Token::make (COMMA, UNDEF_LOCATION)); |
| } |
| |
| visit_items_joined_by_separator (binding_args, COMMA); |
| |
| if (!generic_args.empty () && !binding_args.empty ()) |
| { |
| push (Rust::Token::make (COMMA, UNDEF_LOCATION)); |
| } |
| |
| visit_items_joined_by_separator (lifetime_args, COMMA); |
| |
| push (Rust::Token::make (RIGHT_ANGLE, UNDEF_LOCATION)); |
| } |
| } |
| |
| void |
| TokenCollector::visit (PathInExpression &path) |
| { |
| if (path.is_lang_item ()) |
| { |
| push (Rust::Token::make (TokenId::HASH, path.get_locus ())); |
| push (Rust::Token::make (TokenId::LEFT_SQUARE, path.get_locus ())); |
| push (Rust::Token::make_identifier (path.get_locus (), "lang")); |
| push (Rust::Token::make (TokenId::EQUAL, path.get_locus ())); |
| push ( |
| Rust::Token::make_string (path.get_locus (), |
| LangItem::ToString (path.get_lang_item ()))); |
| push (Rust::Token::make (TokenId::RIGHT_SQUARE, path.get_locus ())); |
| |
| return; |
| } |
| |
| if (path.opening_scope_resolution ()) |
| push (Rust::Token::make (SCOPE_RESOLUTION, path.get_locus ())); |
| |
| visit_items_joined_by_separator (path.get_segments (), SCOPE_RESOLUTION); |
| } |
| |
| void |
| TokenCollector::visit (TypePathSegment &segment) |
| { |
| // Syntax: |
| // PathIdentSegment |
| |
| auto locus = segment.is_lang_item () |
| ? segment.get_locus () |
| : segment.get_ident_segment ().get_locus (); |
| auto segment_string = segment.is_lang_item () |
| ? LangItem::PrettyString (segment.get_lang_item ()) |
| : segment.get_ident_segment ().as_string (); |
| push (Rust::Token::make_identifier (locus, std::move (segment_string))); |
| } |
| |
| void |
| TokenCollector::visit (TypePathSegmentGeneric &segment) |
| { |
| // Syntax: |
| // PathIdentSegment `::`? (GenericArgs)? |
| // GenericArgs : |
| // `<` `>` |
| // | `<` ( GenericArg `,` )* GenericArg `,`? `>` |
| |
| auto locus = segment.is_lang_item () |
| ? segment.get_locus () |
| : segment.get_ident_segment ().get_locus (); |
| auto segment_string = segment.is_lang_item () |
| ? LangItem::PrettyString (segment.get_lang_item ()) |
| : segment.get_ident_segment ().as_string (); |
| push (Rust::Token::make_identifier (locus, std::move (segment_string))); |
| |
| if (segment.get_separating_scope_resolution ()) |
| push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION)); |
| |
| push (Rust::Token::make (LEFT_ANGLE, UNDEF_LOCATION)); |
| |
| { |
| 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, COMMA); |
| if (!lifetime_args.empty () |
| && (!generic_args.empty () || !binding_args.empty ())) |
| push (Rust::Token::make (COMMA, UNDEF_LOCATION)); |
| visit_items_joined_by_separator (generic_args, COMMA); |
| if (!generic_args.empty () && !binding_args.empty ()) |
| push (Rust::Token::make (COMMA, UNDEF_LOCATION)); |
| visit_items_joined_by_separator (binding_args, COMMA); |
| } |
| |
| push (Rust::Token::make (RIGHT_ANGLE, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (GenericArgsBinding &binding) |
| { |
| // Syntax: |
| // IDENTIFIER `=` Type |
| auto identifier = binding.get_identifier ().as_string (); |
| push (Rust::Token::make_identifier (binding.get_locus (), |
| std::move (identifier))); |
| |
| push (Rust::Token::make (EQUAL, UNDEF_LOCATION)); |
| visit (binding.get_type ()); |
| } |
| |
| void |
| TokenCollector::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: |
| { |
| auto path = arg.get_path (); |
| push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (path))); |
| } |
| break; |
| } |
| } |
| |
| void |
| TokenCollector::visit (TypePathSegmentFunction &segment) |
| { |
| // Syntax: |
| // PathIdentSegment `::`? (TypePathFn)? |
| |
| auto ident_segment = segment.get_ident_segment (); |
| auto id = ident_segment.as_string (); |
| push ( |
| Rust::Token::make_identifier (ident_segment.get_locus (), std::move (id))); |
| |
| if (segment.get_separating_scope_resolution ()) |
| push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION)); |
| |
| if (!segment.is_ident_only ()) |
| visit (segment.get_type_path_function ()); |
| } |
| |
| void |
| TokenCollector::visit (TypePathFunction &type_path_fn) |
| { |
| // Syntax: |
| // `(` TypePathFnInputs? `)` (`->` Type)? |
| // TypePathFnInputs : |
| // Type (`,` Type)* `,`? |
| |
| push (Rust::Token::make (LEFT_PAREN, type_path_fn.get_locus ())); |
| if (type_path_fn.has_inputs ()) |
| visit_items_joined_by_separator (type_path_fn.get_params (), COMMA); |
| push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION)); |
| |
| if (type_path_fn.has_return_type ()) |
| { |
| push (Rust::Token::make (RETURN_TYPE, UNDEF_LOCATION)); |
| visit (type_path_fn.get_return_type ()); |
| } |
| } |
| |
| void |
| TokenCollector::visit (TypePath &path) |
| { |
| // Syntax: |
| // `::`? TypePathSegment (`::` TypePathSegment)* |
| |
| if (path.has_opening_scope_resolution_op ()) |
| push (Rust::Token::make (SCOPE_RESOLUTION, path.get_locus ())); |
| |
| visit_items_joined_by_separator (path.get_segments (), SCOPE_RESOLUTION); |
| } |
| |
| void |
| TokenCollector::visit (PathIdentSegment &segment) |
| { |
| if (segment.is_super_path_seg ()) |
| { |
| push (Rust::Token::make (SUPER, segment.get_locus ())); |
| } |
| else if (segment.is_crate_path_seg ()) |
| { |
| push (Rust::Token::make (CRATE, segment.get_locus ())); |
| } |
| else if (segment.is_lower_self_seg ()) |
| { |
| push (Rust::Token::make (SELF, segment.get_locus ())); |
| } |
| else if (segment.is_big_self_seg ()) |
| { |
| push (Rust::Token::make (SELF_ALIAS, segment.get_locus ())); |
| } |
| else |
| { |
| auto id = segment.as_string (); |
| push ( |
| Rust::Token::make_identifier (segment.get_locus (), std::move (id))); |
| } |
| } |
| |
| void |
| TokenCollector::visit (QualifiedPathInExpression &path) |
| { |
| visit (path.get_qualified_path_type ()); |
| for (auto &segment : path.get_segments ()) |
| { |
| push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION)); |
| visit (segment); |
| } |
| } |
| |
| void |
| TokenCollector::visit (QualifiedPathType &path) |
| { |
| push (Rust::Token::make (LEFT_ANGLE, path.get_locus ())); |
| visit (path.get_type ()); |
| if (path.has_as_clause ()) |
| { |
| push (Rust::Token::make (AS, UNDEF_LOCATION)); |
| visit (path.get_as_type_path ()); |
| } |
| push (Rust::Token::make (RIGHT_ANGLE, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (QualifiedPathInType &path) |
| { |
| visit (path.get_qualified_path_type ()); |
| |
| push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION)); |
| visit (path.get_associated_segment ()); |
| for (auto &segment : path.get_segments ()) |
| { |
| push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION)); |
| visit (segment); |
| } |
| } |
| |
| void |
| TokenCollector::visit (Literal &lit, location_t locus) |
| { |
| auto value = lit.as_string (); |
| switch (lit.get_lit_type ()) |
| { |
| case Literal::LitType::CHAR: |
| push ( |
| Rust::Token::make_char (locus, |
| // TODO: Change this to support utf-8 properly |
| Codepoint (static_cast<uint32_t> (value[0])))); |
| break; |
| case Literal::LitType::STRING: |
| push (Rust::Token::make_string (locus, std::move (value))); |
| break; |
| case Literal::LitType::BYTE: |
| push (Rust::Token::make_byte_char (locus, value[0])); |
| break; |
| case Literal::LitType::BYTE_STRING: |
| push (Rust::Token::make_byte_string (locus, std::move (value))); |
| break; |
| case Literal::LitType::RAW_STRING: |
| push (Rust::Token::make_raw_string (locus, std::move (value))); |
| break; |
| case Literal::LitType::INT: |
| push ( |
| Rust::Token::make_int (locus, std::move (value), lit.get_type_hint ())); |
| break; |
| case Literal::LitType::FLOAT: |
| push (Rust::Token::make_float (locus, std::move (value), |
| lit.get_type_hint ())); |
| break; |
| case Literal::LitType::BOOL: |
| { |
| if (value == Values::Keywords::FALSE_LITERAL) |
| push (Rust::Token::make (FALSE_LITERAL, locus)); |
| else if (value == Values::Keywords::TRUE_LITERAL) |
| push (Rust::Token::make (TRUE_LITERAL, locus)); |
| else |
| rust_unreachable (); // Not a boolean |
| break; |
| } |
| case Literal::LitType::ERROR: |
| rust_unreachable (); |
| break; |
| } |
| } |
| |
| void |
| TokenCollector::visit (LiteralExpr &expr) |
| { |
| auto lit = expr.get_literal (); |
| visit (lit, expr.get_locus ()); |
| } |
| |
| void |
| TokenCollector::visit (AttrInputLiteral &literal) |
| { |
| push (Rust::Token::make (EQUAL, UNDEF_LOCATION)); |
| visit (literal.get_literal ()); |
| } |
| |
| void |
| TokenCollector::visit (AttrInputMacro ¯o) |
| { |
| push (Rust::Token::make (EQUAL, UNDEF_LOCATION)); |
| visit (macro.get_macro ()); |
| } |
| |
| void |
| TokenCollector::visit (MetaItemLitExpr &item) |
| { |
| auto lit = item.get_literal (); |
| visit (lit); |
| } |
| |
| void |
| TokenCollector::visit (MetaItemPathExpr &item) |
| { |
| auto &path = item.get_path (); |
| auto &expr = item.get_expr (); |
| visit (path); |
| push (Rust::Token::make (EQUAL, item.get_locus ())); |
| visit (expr); |
| } |
| |
| void |
| TokenCollector::visit (BorrowExpr &expr) |
| { |
| push (Rust::Token::make (AMP, expr.get_locus ())); |
| if (expr.get_is_double_borrow ()) |
| push (Rust::Token::make (AMP, UNDEF_LOCATION)); |
| |
| if (expr.is_raw_borrow ()) |
| { |
| push (Rust::Token::make_identifier (expr.get_locus (), |
| Values::WeakKeywords::RAW)); |
| if (expr.get_is_mut ()) |
| push (Rust::Token::make (MUT, UNDEF_LOCATION)); |
| else |
| push (Rust::Token::make (CONST, UNDEF_LOCATION)); |
| } |
| else |
| { |
| if (expr.get_is_mut ()) |
| push (Rust::Token::make (MUT, UNDEF_LOCATION)); |
| } |
| |
| if (expr.has_borrow_expr ()) |
| visit (expr.get_borrowed_expr ()); |
| } |
| |
| void |
| TokenCollector::visit (DereferenceExpr &expr) |
| { |
| push (Rust::Token::make (ASTERISK, expr.get_locus ())); |
| visit (expr.get_dereferenced_expr ()); |
| } |
| |
| void |
| TokenCollector::visit (ErrorPropagationExpr &expr) |
| { |
| visit (expr.get_propagating_expr ()); |
| push (Rust::Token::make (QUESTION_MARK, expr.get_locus ())); |
| } |
| |
| void |
| TokenCollector::visit (NegationExpr &expr) |
| { |
| switch (expr.get_expr_type ()) |
| { |
| case NegationOperator::NEGATE: |
| push (Rust::Token::make (MINUS, expr.get_locus ())); |
| break; |
| case NegationOperator::NOT: |
| push (Rust::Token::make (EXCLAM, expr.get_locus ())); |
| break; |
| } |
| visit (expr.get_negated_expr ()); |
| } |
| |
| void |
| TokenCollector::visit (ArithmeticOrLogicalExpr &expr) |
| { |
| visit (expr.get_left_expr ()); |
| switch (expr.get_expr_type ()) |
| { |
| case ArithmeticOrLogicalOperator::ADD: |
| push (Rust::Token::make (PLUS, expr.get_locus ())); |
| break; |
| |
| case ArithmeticOrLogicalOperator::SUBTRACT: |
| push (Rust::Token::make (MINUS, expr.get_locus ())); |
| break; |
| |
| case ArithmeticOrLogicalOperator::MULTIPLY: |
| push (Rust::Token::make (ASTERISK, expr.get_locus ())); |
| break; |
| |
| case ArithmeticOrLogicalOperator::DIVIDE: |
| push (Rust::Token::make (DIV, expr.get_locus ())); |
| break; |
| |
| case ArithmeticOrLogicalOperator::MODULUS: |
| push (Rust::Token::make (PERCENT, expr.get_locus ())); |
| break; |
| |
| case ArithmeticOrLogicalOperator::BITWISE_AND: |
| push (Rust::Token::make (AMP, expr.get_locus ())); |
| break; |
| |
| case ArithmeticOrLogicalOperator::BITWISE_OR: |
| push (Rust::Token::make (PIPE, expr.get_locus ())); |
| break; |
| |
| case ArithmeticOrLogicalOperator::BITWISE_XOR: |
| push (Rust::Token::make (CARET, expr.get_locus ())); |
| break; |
| |
| case ArithmeticOrLogicalOperator::LEFT_SHIFT: |
| push (Rust::Token::make (LEFT_SHIFT, expr.get_locus ())); |
| break; |
| |
| case ArithmeticOrLogicalOperator::RIGHT_SHIFT: |
| push (Rust::Token::make (RIGHT_SHIFT, expr.get_locus ())); |
| break; |
| } |
| |
| visit (expr.get_right_expr ()); |
| } |
| |
| void |
| TokenCollector::visit (ComparisonExpr &expr) |
| { |
| visit (expr.get_left_expr ()); |
| |
| switch (expr.get_expr_type ()) |
| { |
| case ComparisonOperator::EQUAL: |
| push (Rust::Token::make (EQUAL_EQUAL, expr.get_locus ())); |
| break; |
| case ComparisonOperator::NOT_EQUAL: |
| push (Rust::Token::make (NOT_EQUAL, expr.get_locus ())); |
| break; |
| case ComparisonOperator::GREATER_THAN: |
| push (Rust::Token::make (RIGHT_ANGLE, expr.get_locus ())); |
| break; |
| case ComparisonOperator::LESS_THAN: |
| push (Rust::Token::make (LEFT_ANGLE, expr.get_locus ())); |
| break; |
| case ComparisonOperator::GREATER_OR_EQUAL: |
| push (Rust::Token::make (GREATER_OR_EQUAL, expr.get_locus ())); |
| break; |
| |
| case ComparisonOperator::LESS_OR_EQUAL: |
| push (Rust::Token::make (LESS_OR_EQUAL, expr.get_locus ())); |
| break; |
| } |
| visit (expr.get_right_expr ()); |
| } |
| |
| void |
| TokenCollector::visit (LazyBooleanExpr &expr) |
| { |
| visit (expr.get_left_expr ()); |
| |
| switch (expr.get_expr_type ()) |
| { |
| case LazyBooleanOperator::LOGICAL_AND: |
| push (Rust::Token::make (LOGICAL_AND, expr.get_locus ())); |
| break; |
| case LazyBooleanOperator::LOGICAL_OR: |
| push (Rust::Token::make (OR, expr.get_locus ())); |
| break; |
| } |
| |
| visit (expr.get_right_expr ()); |
| } |
| |
| void |
| TokenCollector::visit (TypeCastExpr &expr) |
| { |
| visit (expr.get_casted_expr ()); |
| push (Rust::Token::make (AS, expr.get_locus ())); |
| visit (expr.get_type_to_cast_to ()); |
| } |
| |
| void |
| TokenCollector::visit (AssignmentExpr &expr) |
| { |
| expr.visit_lhs (*this); |
| push (Rust::Token::make (EQUAL, expr.get_locus ())); |
| expr.visit_rhs (*this); |
| } |
| |
| void |
| TokenCollector::visit (CompoundAssignmentExpr &expr) |
| { |
| visit (expr.get_left_expr ()); |
| |
| switch (expr.get_expr_type ()) |
| { |
| case CompoundAssignmentOperator::ADD: |
| push (Rust::Token::make (PLUS_EQ, expr.get_locus ())); |
| break; |
| case CompoundAssignmentOperator::SUBTRACT: |
| push (Rust::Token::make (MINUS_EQ, expr.get_locus ())); |
| break; |
| case CompoundAssignmentOperator::MULTIPLY: |
| push (Rust::Token::make (ASTERISK_EQ, expr.get_locus ())); |
| break; |
| case CompoundAssignmentOperator::DIVIDE: |
| push (Rust::Token::make (DIV_EQ, expr.get_locus ())); |
| break; |
| case CompoundAssignmentOperator::MODULUS: |
| push (Rust::Token::make (PERCENT_EQ, expr.get_locus ())); |
| break; |
| case CompoundAssignmentOperator::BITWISE_AND: |
| push (Rust::Token::make (AMP_EQ, expr.get_locus ())); |
| break; |
| case CompoundAssignmentOperator::BITWISE_OR: |
| push (Rust::Token::make (PIPE_EQ, expr.get_locus ())); |
| break; |
| case CompoundAssignmentOperator::BITWISE_XOR: |
| push (Rust::Token::make (CARET_EQ, expr.get_locus ())); |
| break; |
| case CompoundAssignmentOperator::LEFT_SHIFT: |
| push (Rust::Token::make (LEFT_SHIFT_EQ, expr.get_locus ())); |
| break; |
| case CompoundAssignmentOperator::RIGHT_SHIFT: |
| push (Rust::Token::make (RIGHT_SHIFT_EQ, expr.get_locus ())); |
| break; |
| } |
| visit (expr.get_right_expr ()); |
| } |
| |
| void |
| TokenCollector::visit (GroupedExpr &expr) |
| { |
| push (Rust::Token::make (LEFT_PAREN, expr.get_locus ())); |
| visit (expr.get_expr_in_parens ()); |
| push (Rust::Token::make (RIGHT_PAREN, expr.get_locus ())); |
| } |
| |
| void |
| TokenCollector::visit (ArrayElemsValues &elems) |
| { |
| visit_items_joined_by_separator (elems.get_values (), COMMA); |
| } |
| |
| void |
| TokenCollector::visit (ArrayElemsCopied &elems) |
| { |
| visit (elems.get_elem_to_copy ()); |
| push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION)); |
| visit (elems.get_num_copies ()); |
| } |
| |
| void |
| TokenCollector::visit (ArrayExpr &expr) |
| { |
| push (Rust::Token::make (LEFT_SQUARE, expr.get_locus ())); |
| visit (expr.get_array_elems ()); |
| push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (ArrayIndexExpr &expr) |
| { |
| visit (expr.get_array_expr ()); |
| push (Rust::Token::make (LEFT_SQUARE, expr.get_locus ())); |
| visit (expr.get_index_expr ()); |
| push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (TupleExpr &expr) |
| { |
| visit_items_as_lines (expr.get_outer_attrs ()); |
| push (Rust::Token::make (LEFT_PAREN, expr.get_locus ())); |
| visit_items_joined_by_separator (expr.get_tuple_elems (), COMMA); |
| push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (TupleIndexExpr &expr) |
| { |
| visit (expr.get_tuple_expr ()); |
| push (Rust::Token::make (DOT, expr.get_locus ())); |
| push (Rust::Token::make_int (UNDEF_LOCATION, |
| std::to_string (expr.get_tuple_index ()))); |
| } |
| |
| void |
| TokenCollector::visit (StructExprStruct &expr) |
| { |
| visit (expr.get_struct_name ()); |
| } |
| |
| void |
| TokenCollector::visit (StructExprFieldIdentifier &expr) |
| { |
| visit_items_as_lines (expr.get_outer_attrs ()); |
| auto id = expr.get_field_name ().as_string (); |
| push (Rust::Token::make_identifier (expr.get_locus (), std::move (id))); |
| } |
| |
| void |
| TokenCollector::visit (StructExprFieldIdentifierValue &expr) |
| { |
| visit_items_as_lines (expr.get_outer_attrs ()); |
| auto id = expr.get_field_name (); |
| push (Rust::Token::make_identifier (expr.get_locus (), std::move (id))); |
| push (Rust::Token::make (COLON, UNDEF_LOCATION)); |
| visit (expr.get_value ()); |
| } |
| |
| void |
| TokenCollector::visit (StructExprFieldIndexValue &expr) |
| { |
| visit_items_as_lines (expr.get_outer_attrs ()); |
| push (Rust::Token::make_int (expr.get_locus (), |
| std::to_string (expr.get_index ()))); |
| push (Rust::Token::make (COLON, UNDEF_LOCATION)); |
| visit (expr.get_value ()); |
| } |
| |
| void |
| TokenCollector::visit (StructBase &base) |
| { |
| push (Rust::Token::make (DOT_DOT, UNDEF_LOCATION)); |
| visit (base.get_base_struct ()); |
| } |
| |
| void |
| TokenCollector::visit (StructExprStructFields &expr) |
| { |
| visit (expr.get_struct_name ()); |
| push (Rust::Token::make (LEFT_CURLY, expr.get_locus ())); |
| visit_items_joined_by_separator (expr.get_fields (), COMMA); |
| if (expr.has_struct_base ()) |
| { |
| push (Rust::Token::make (COMMA, UNDEF_LOCATION)); |
| visit (expr.get_struct_base ()); |
| } |
| else |
| { |
| trailing_comma (); |
| } |
| push (Rust::Token::make (RIGHT_CURLY, expr.get_locus ())); |
| } |
| |
| void |
| TokenCollector::visit (StructExprStructBase &) |
| { |
| // FIXME: Implement this node |
| rust_unreachable (); |
| } |
| |
| void |
| TokenCollector::visit (CallExpr &expr) |
| { |
| visit (expr.get_function_expr ()); |
| |
| push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION)); |
| |
| visit_items_joined_by_separator (expr.get_params (), COMMA); |
| |
| push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (MethodCallExpr &expr) |
| { |
| visit (expr.get_receiver_expr ()); |
| push (Rust::Token::make (DOT, expr.get_locus ())); |
| visit (expr.get_method_name ()); |
| push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION)); |
| visit_items_joined_by_separator (expr.get_params (), COMMA); |
| trailing_comma (); |
| push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (FieldAccessExpr &expr) |
| { |
| visit (expr.get_receiver_expr ()); |
| push (Rust::Token::make (DOT, expr.get_locus ())); |
| auto field_name = expr.get_field_name ().as_string (); |
| push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (field_name))); |
| } |
| |
| void |
| TokenCollector::visit (ClosureParam ¶m) |
| { |
| visit_items_as_lines (param.get_outer_attrs ()); |
| visit (param.get_pattern ()); |
| if (param.has_type_given ()) |
| { |
| push (Rust::Token::make (COLON, param.get_locus ())); |
| visit (param.get_type ()); |
| } |
| } |
| |
| void |
| TokenCollector::visit_closure_common (ClosureExpr &expr) |
| { |
| if (expr.get_has_move ()) |
| { |
| push (Rust::Token::make (MOVE, expr.get_locus ())); |
| } |
| push (Rust::Token::make (PIPE, UNDEF_LOCATION)); |
| visit_items_joined_by_separator (expr.get_params (), COMMA); |
| push (Rust::Token::make (PIPE, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (ClosureExprInner &expr) |
| { |
| visit_closure_common (expr); |
| visit (expr.get_definition_expr ()); |
| } |
| |
| void |
| TokenCollector::visit (BlockExpr &expr) |
| { |
| visit_items_as_lines (expr.get_outer_attrs ()); |
| push (Rust::Token::make (LEFT_CURLY, expr.get_locus ())); |
| newline (); |
| increment_indentation (); |
| visit_items_as_lines (expr.get_inner_attrs ()); |
| |
| visit_items_as_lines (expr.get_statements (), {}); |
| |
| if (expr.has_tail_expr ()) |
| { |
| indentation (); |
| visit (expr.get_tail_expr ()); |
| comment ("tail expr"); |
| newline (); |
| } |
| |
| decrement_indentation (); |
| indentation (); |
| push (Rust::Token::make (RIGHT_CURLY, expr.get_locus ())); |
| newline (); |
| } |
| |
| void |
| TokenCollector::visit (AnonConst &expr) |
| { |
| if (!expr.is_deferred ()) |
| { |
| visit (expr.get_inner_expr ()); |
| return; |
| } |
| |
| push (Rust::Token::make_string (expr.get_locus (), "_")); |
| } |
| |
| void |
| TokenCollector::visit (ConstBlock &expr) |
| { |
| push (Rust::Token::make (CONST, expr.get_locus ())); |
| |
| // The inner expression is already a block expr, so we don't need to add |
| // curlies |
| visit (expr.get_const_expr ()); |
| } |
| |
| void |
| TokenCollector::visit (ClosureExprInnerTyped &expr) |
| { |
| visit_closure_common (expr); |
| push (Rust::Token::make (RETURN_TYPE, expr.get_locus ())); |
| visit (expr.get_return_type ()); |
| visit (expr.get_definition_expr ()); |
| } |
| |
| void |
| TokenCollector::visit (ContinueExpr &expr) |
| { |
| push (Rust::Token::make (CONTINUE, expr.get_locus ())); |
| if (expr.has_label ()) |
| visit (expr.get_label_unchecked ()); |
| } |
| |
| void |
| TokenCollector::visit (BreakExpr &expr) |
| { |
| push (Rust::Token::make (BREAK, expr.get_locus ())); |
| if (expr.has_label ()) |
| visit (expr.get_label_unchecked ()); |
| if (expr.has_break_expr ()) |
| visit (expr.get_break_expr ()); |
| } |
| |
| void |
| TokenCollector::visit (RangeFromToExpr &expr) |
| { |
| visit (expr.get_from_expr ()); |
| push (Rust::Token::make (DOT_DOT, expr.get_locus ())); |
| visit (expr.get_to_expr ()); |
| } |
| |
| void |
| TokenCollector::visit (RangeFromExpr &expr) |
| { |
| visit (expr.get_from_expr ()); |
| push (Rust::Token::make (DOT_DOT, expr.get_locus ())); |
| } |
| |
| void |
| TokenCollector::visit (RangeToExpr &expr) |
| { |
| push (Rust::Token::make (DOT_DOT, expr.get_locus ())); |
| visit (expr.get_to_expr ()); |
| } |
| |
| void |
| TokenCollector::visit (RangeFullExpr &expr) |
| { |
| push (Rust::Token::make (DOT_DOT, expr.get_locus ())); |
| } |
| |
| void |
| TokenCollector::visit (RangeFromToInclExpr &expr) |
| { |
| visit (expr.get_from_expr ()); |
| push (Rust::Token::make (DOT_DOT_EQ, expr.get_locus ())); |
| visit (expr.get_to_expr ()); |
| } |
| |
| void |
| TokenCollector::visit (RangeToInclExpr &expr) |
| { |
| push (Rust::Token::make (DOT_DOT_EQ, expr.get_locus ())); |
| visit (expr.get_to_expr ()); |
| } |
| |
| void |
| TokenCollector::visit (BoxExpr &expr) |
| { |
| push (Rust::Token::make (BOX, expr.get_locus ())); |
| visit (expr.get_boxed_expr ()); |
| } |
| |
| void |
| TokenCollector::visit (ReturnExpr &expr) |
| { |
| push (Rust::Token::make (RETURN_KW, expr.get_locus ())); |
| if (expr.has_returned_expr ()) |
| visit (expr.get_returned_expr ()); |
| } |
| |
| void |
| TokenCollector::visit (TryExpr &expr) |
| { |
| push (Rust::Token::make (TRY, expr.get_locus ())); |
| visit (expr.get_block_expr ()); |
| } |
| |
| void |
| TokenCollector::visit (UnsafeBlockExpr &expr) |
| { |
| push (Rust::Token::make (UNSAFE, expr.get_locus ())); |
| visit (expr.get_block_expr ()); |
| } |
| |
| void |
| TokenCollector::visit (LoopLabel &label) |
| { |
| visit (label.get_lifetime ()); |
| push (Rust::Token::make (COLON, label.get_locus ())); |
| } |
| |
| void |
| TokenCollector::visit_loop_common (BaseLoopExpr &expr) |
| { |
| if (expr.has_loop_label ()) |
| visit (expr.get_loop_label ()); |
| } |
| |
| void |
| TokenCollector::visit (LoopExpr &expr) |
| { |
| visit_loop_common (expr); |
| push (Rust::Token::make (LOOP, expr.get_locus ())); |
| visit (expr.get_loop_block ()); |
| } |
| |
| void |
| TokenCollector::visit (WhileLoopExpr &expr) |
| { |
| visit_loop_common (expr); |
| push (Rust::Token::make (WHILE, expr.get_locus ())); |
| visit (expr.get_predicate_expr ()); |
| visit (expr.get_loop_block ()); |
| } |
| |
| void |
| TokenCollector::visit (WhileLetLoopExpr &expr) |
| { |
| visit_loop_common (expr); |
| push (Rust::Token::make (WHILE, expr.get_locus ())); |
| push (Rust::Token::make (LET, UNDEF_LOCATION)); |
| // TODO: The reference mention only one Pattern |
| for (auto &item : expr.get_patterns ()) |
| { |
| visit (item); |
| } |
| push (Rust::Token::make (EQUAL, UNDEF_LOCATION)); |
| visit (expr.get_scrutinee_expr ()); |
| visit (expr.get_loop_block ()); |
| } |
| |
| void |
| TokenCollector::visit (ForLoopExpr &expr) |
| { |
| visit_loop_common (expr); |
| push (Rust::Token::make (FOR, expr.get_locus ())); |
| visit (expr.get_pattern ()); |
| push (Rust::Token::make (IN, UNDEF_LOCATION)); |
| visit (expr.get_iterator_expr ()); |
| visit (expr.get_loop_block ()); |
| } |
| |
| void |
| TokenCollector::visit (IfExpr &expr) |
| { |
| push (Rust::Token::make (IF, expr.get_locus ())); |
| visit (expr.get_condition_expr ()); |
| visit (expr.get_if_block ()); |
| } |
| |
| void |
| TokenCollector::visit (IfExprConseqElse &expr) |
| { |
| visit (static_cast<IfExpr &> (expr)); |
| indentation (); |
| push (Rust::Token::make (ELSE, expr.get_locus ())); |
| visit (expr.get_else_block ()); |
| } |
| |
| void |
| TokenCollector::visit (IfLetExpr &expr) |
| { |
| push (Rust::Token::make (IF, expr.get_locus ())); |
| push (Rust::Token::make (LET, UNDEF_LOCATION)); |
| for (auto &pattern : expr.get_patterns ()) |
| { |
| visit (pattern); |
| } |
| push (Rust::Token::make (EQUAL, UNDEF_LOCATION)); |
| visit (expr.get_value_expr ()); |
| visit (expr.get_if_block ()); |
| } |
| |
| void |
| TokenCollector::visit (IfLetExprConseqElse &expr) |
| { |
| visit (static_cast<IfLetExpr &> (expr)); |
| indentation (); |
| push (Rust::Token::make (ELSE, expr.get_locus ())); |
| visit (expr.get_else_block ()); |
| } |
| |
| void |
| TokenCollector::visit (MatchArm &arm) |
| { |
| visit_items_as_lines (arm.get_outer_attrs ()); |
| for (auto &pattern : arm.get_patterns ()) |
| { |
| visit (pattern); |
| } |
| if (arm.has_match_arm_guard ()) |
| { |
| push (Rust::Token::make (IF, UNDEF_LOCATION)); |
| visit (arm.get_guard_expr ()); |
| } |
| } |
| |
| void |
| TokenCollector::visit (MatchCase &match_case) |
| { |
| indentation (); |
| visit (match_case.get_arm ()); |
| push (Rust::Token::make (MATCH_ARROW, UNDEF_LOCATION)); |
| visit (match_case.get_expr ()); |
| indentation (); |
| push (Rust::Token::make (COMMA, UNDEF_LOCATION)); |
| newline (); |
| } |
| |
| void |
| TokenCollector::visit (MatchExpr &expr) |
| { |
| push (Rust::Token::make (MATCH_KW, expr.get_locus ())); |
| visit (expr.get_scrutinee_expr ()); |
| push (Rust::Token::make (LEFT_CURLY, UNDEF_LOCATION)); |
| newline (); |
| increment_indentation (); |
| visit_items_as_lines (expr.get_inner_attrs ()); |
| for (auto &arm : expr.get_match_cases ()) |
| { |
| visit (arm); |
| } |
| decrement_indentation (); |
| indentation (); |
| push (Rust::Token::make (RIGHT_CURLY, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (AwaitExpr &expr) |
| { |
| visit (expr.get_awaited_expr ()); |
| push (Rust::Token::make (DOT, expr.get_locus ())); |
| // TODO: Check status of await keyword (Context dependant ?) |
| push (Rust::Token::make_identifier (UNDEF_LOCATION, Values::Keywords::AWAIT)); |
| } |
| |
| void |
| TokenCollector::visit (AsyncBlockExpr &expr) |
| { |
| push (Rust::Token::make (ASYNC, expr.get_locus ())); |
| if (expr.get_has_move ()) |
| push (Rust::Token::make (MOVE, UNDEF_LOCATION)); |
| visit (expr.get_block_expr ()); |
| } |
| |
| void |
| TokenCollector::visit (InlineAsm &expr) |
| { |
| push (Rust::Token::make_identifier (expr.get_locus (), "asm")); |
| push (Rust::Token::make (EXCLAM, expr.get_locus ())); |
| push (Rust::Token::make (LEFT_PAREN, expr.get_locus ())); |
| |
| for (auto &template_str : expr.get_template_strs ()) |
| push (Rust::Token::make_string (template_str.get_locus (), |
| std::move (template_str.symbol))); |
| |
| push (Rust::Token::make (COLON, expr.get_locus ())); |
| |
| for (auto &operand : expr.get_operands ()) |
| { |
| using RegisterType = AST::InlineAsmOperand::RegisterType; |
| switch (operand.get_register_type ()) |
| { |
| case RegisterType::In: |
| { |
| visit (operand.get_in ().expr); |
| break; |
| } |
| case RegisterType::Out: |
| { |
| visit (operand.get_out ().expr); |
| break; |
| } |
| case RegisterType::InOut: |
| { |
| visit (operand.get_in_out ().expr); |
| break; |
| } |
| case RegisterType::SplitInOut: |
| { |
| auto split = operand.get_split_in_out (); |
| visit (split.in_expr); |
| visit (split.out_expr); |
| break; |
| } |
| case RegisterType::Const: |
| { |
| visit (operand.get_const ().anon_const.get_inner_expr ()); |
| break; |
| } |
| case RegisterType::Sym: |
| { |
| visit (operand.get_sym ().expr); |
| break; |
| } |
| case RegisterType::Label: |
| { |
| visit (operand.get_label ().expr); |
| break; |
| } |
| } |
| push (Rust::Token::make (COMMA, expr.get_locus ())); |
| } |
| push (Rust::Token::make (COLON, expr.get_locus ())); |
| |
| for (auto &clobber : expr.get_clobber_abi ()) |
| { |
| push (Rust::Token::make_string (expr.get_locus (), |
| std::move (clobber.symbol))); |
| push (Rust::Token::make (COMMA, expr.get_locus ())); |
| } |
| push (Rust::Token::make (COLON, expr.get_locus ())); |
| |
| for (auto it = expr.named_args.begin (); it != expr.named_args.end (); ++it) |
| { |
| auto &arg = *it; |
| push ( |
| Rust::Token::make_identifier (expr.get_locus (), arg.first.c_str ())); |
| push (Rust::Token::make (EQUAL, expr.get_locus ())); |
| push (Rust::Token::make_identifier (expr.get_locus (), |
| std::to_string (arg.second))); |
| |
| push (Rust::Token::make (COMMA, expr.get_locus ())); |
| } |
| |
| push (Rust::Token::make (COLON, expr.get_locus ())); |
| |
| for (auto &option : expr.get_options ()) |
| { |
| push (Rust::Token::make_identifier ( |
| expr.get_locus (), InlineAsm::option_to_string (option).c_str ())); |
| push (Rust::Token::make (COMMA, expr.get_locus ())); |
| } |
| |
| push (Rust::Token::make (RIGHT_PAREN, expr.get_locus ())); |
| } |
| |
| void |
| TokenCollector::visit (LlvmInlineAsm &expr) |
| { |
| push (Rust::Token::make_identifier (expr.get_locus (), "llvm_asm")); |
| push (Rust::Token::make (EXCLAM, expr.get_locus ())); |
| push (Rust::Token::make (LEFT_PAREN, expr.get_locus ())); |
| for (auto &template_str : expr.get_templates ()) |
| push (Rust::Token::make_string (template_str.get_locus (), |
| std::move (template_str.symbol))); |
| |
| push (Rust::Token::make (COLON, expr.get_locus ())); |
| for (auto output : expr.get_outputs ()) |
| { |
| push (Rust::Token::make_string (expr.get_locus (), |
| std::move (output.constraint))); |
| visit (output.expr); |
| push (Rust::Token::make (COMMA, expr.get_locus ())); |
| } |
| |
| push (Rust::Token::make (COLON, expr.get_locus ())); |
| for (auto input : expr.get_inputs ()) |
| { |
| push (Rust::Token::make_string (expr.get_locus (), |
| std::move (input.constraint))); |
| visit (input.expr); |
| push (Rust::Token::make (COMMA, expr.get_locus ())); |
| } |
| |
| push (Rust::Token::make (COLON, expr.get_locus ())); |
| for (auto &clobber : expr.get_clobbers ()) |
| { |
| push (Rust::Token::make_string (expr.get_locus (), |
| std::move (clobber.symbol))); |
| push (Rust::Token::make (COMMA, expr.get_locus ())); |
| } |
| push (Rust::Token::make (COLON, expr.get_locus ())); |
| // Dump options |
| |
| push (Rust::Token::make (RIGHT_PAREN, expr.get_locus ())); |
| } |
| |
| // rust-item.h |
| |
| void |
| TokenCollector::visit (TypeParam ¶m) |
| { |
| // Syntax: |
| // IDENTIFIER( : TypeParamBounds? )? ( = Type )? |
| // TypeParamBounds : |
| // TypeParamBound ( + TypeParamBound )* +? |
| |
| visit_items_as_lines (param.get_outer_attrs ()); |
| auto id = param.get_type_representation ().as_string (); |
| push (Rust::Token::make_identifier (param.get_locus (), std::move (id))); |
| if (param.has_type_param_bounds ()) |
| { |
| push (Rust::Token::make (COLON, UNDEF_LOCATION)); |
| visit_items_joined_by_separator (param.get_type_param_bounds (), PLUS); |
| } |
| if (param.has_type ()) |
| { |
| push (Rust::Token::make (EQUAL, UNDEF_LOCATION)); |
| visit (param.get_type ()); |
| } |
| } |
| |
| void |
| TokenCollector::visit (WhereClause &rule) |
| { |
| // Syntax: |
| // where ( WhereClauseItem , )* WhereClauseItem ? |
| // WhereClauseItem : |
| // LifetimeWhereClauseItem |
| // | TypeBoundWhereClauseItem |
| |
| push (Rust::Token::make (WHERE, UNDEF_LOCATION)); |
| newline (); |
| increment_indentation (); |
| visit_items_joined_by_separator (rule.get_items (), COMMA); |
| decrement_indentation (); |
| } |
| |
| void |
| TokenCollector::visit (LifetimeWhereClauseItem &item) |
| { |
| // Syntax: |
| // Lifetime : LifetimeBounds |
| // LifetimeBounds : |
| // ( Lifetime + )* Lifetime? |
| |
| visit (item.get_lifetime ()); |
| push (Rust::Token::make (COLON, UNDEF_LOCATION)); |
| visit_items_joined_by_separator (item.get_lifetime_bounds (), PLUS); |
| } |
| |
| void |
| TokenCollector::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 ()); |
| |
| push (Rust::Token::make (COLON, UNDEF_LOCATION)); |
| visit_items_joined_by_separator (item.get_type_param_bounds (), PLUS); |
| } |
| |
| void |
| TokenCollector::visit (Module &module) |
| { |
| // Syntax: |
| // mod IDENTIFIER ; |
| // | mod IDENTIFIER { |
| // InnerAttribute* |
| // Item* |
| // } |
| |
| visit_items_as_lines (module.get_outer_attrs ()); |
| visit (module.get_visibility ()); |
| auto name = module.get_name ().as_string (); |
| push (Rust::Token::make (MOD, module.get_locus ())); |
| push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (name))); |
| |
| if (module.get_kind () == Module::UNLOADED) |
| { |
| push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION)); |
| newline (); |
| } |
| else /* Module::LOADED */ |
| { |
| push (Rust::Token::make (LEFT_CURLY, UNDEF_LOCATION)); |
| newline (); |
| increment_indentation (); |
| |
| visit_items_as_lines (module.get_inner_attrs ()); |
| visit_items_as_lines (module.get_items ()); |
| |
| decrement_indentation (); |
| |
| push (Rust::Token::make (RIGHT_CURLY, UNDEF_LOCATION)); |
| newline (); |
| } |
| } |
| |
| void |
| TokenCollector::visit (ExternCrate &crate) |
| { |
| visit_items_as_lines (crate.get_outer_attrs ()); |
| push (Rust::Token::make (EXTERN_KW, crate.get_locus ())); |
| push (Rust::Token::make (CRATE, UNDEF_LOCATION)); |
| auto ref = crate.get_referenced_crate (); |
| push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (ref))); |
| if (crate.has_as_clause ()) |
| { |
| auto as_clause = crate.get_as_clause (); |
| push (Rust::Token::make (AS, UNDEF_LOCATION)); |
| push ( |
| Rust::Token::make_identifier (UNDEF_LOCATION, std::move (as_clause))); |
| } |
| push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION)); |
| newline (); |
| } |
| |
| void |
| TokenCollector::visit (UseTreeGlob &use_tree) |
| { |
| switch (use_tree.get_glob_type ()) |
| { |
| case UseTreeGlob::PathType::PATH_PREFIXED: |
| { |
| auto path = use_tree.get_path (); |
| visit (path); |
| push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION)); |
| } |
| break; |
| case UseTreeGlob::PathType::NO_PATH: |
| push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION)); |
| break; |
| case UseTreeGlob::PathType::GLOBAL: |
| break; |
| } |
| push (Rust::Token::make (ASTERISK, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (UseTreeList &use_tree) |
| { |
| switch (use_tree.get_path_type ()) |
| { |
| case UseTreeList::PathType::PATH_PREFIXED: |
| { |
| auto path = use_tree.get_path (); |
| visit (path); |
| push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION)); |
| } |
| break; |
| case UseTreeList::PathType::NO_PATH: |
| push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION)); |
| break; |
| case UseTreeList::PathType::GLOBAL: |
| break; |
| } |
| |
| push (Rust::Token::make (LEFT_CURLY, UNDEF_LOCATION)); |
| if (use_tree.has_trees ()) |
| { |
| visit_items_joined_by_separator (use_tree.get_trees (), COMMA); |
| } |
| push (Rust::Token::make (RIGHT_CURLY, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (UseTreeRebind &use_tree) |
| { |
| auto path = use_tree.get_path (); |
| visit (path); |
| switch (use_tree.get_new_bind_type ()) |
| { |
| case UseTreeRebind::NewBindType::IDENTIFIER: |
| { |
| push (Rust::Token::make (AS, UNDEF_LOCATION)); |
| auto id = use_tree.get_identifier ().as_string (); |
| push ( |
| Rust::Token::make_identifier (use_tree.get_locus (), std::move (id))); |
| } |
| break; |
| case UseTreeRebind::NewBindType::WILDCARD: |
| push (Rust::Token::make (AS, UNDEF_LOCATION)); |
| push (Rust::Token::make (UNDERSCORE, use_tree.get_locus ())); |
| break; |
| case UseTreeRebind::NewBindType::NONE: |
| break; |
| } |
| } |
| |
| void |
| TokenCollector::visit (UseDeclaration &decl) |
| { |
| visit_items_as_lines (decl.get_outer_attrs ()); |
| push (Rust::Token::make (USE, decl.get_locus ())); |
| visit (*decl.get_tree ()); |
| push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION)); |
| newline (); |
| } |
| |
| void |
| TokenCollector::visit (Function &function) |
| { |
| // Syntax: |
| // FunctionQualifiers fn IDENTIFIER GenericParams? |
| // ( FunctionParameters? ) |
| // FunctionReturnType? WhereClause? |
| // ( BlockExpression | ; ) |
| visit_items_as_lines (function.get_outer_attrs ()); |
| |
| visit (function.get_visibility ()); |
| auto qualifiers = function.get_qualifiers (); |
| visit (qualifiers); |
| |
| push (Rust::Token::make (FN_KW, function.get_locus ())); |
| auto name = function.get_function_name ().as_string (); |
| push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (name))); |
| if (function.has_generics ()) |
| visit (function.get_generic_params ()); |
| |
| push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION)); |
| |
| visit_items_joined_by_separator (function.get_function_params ()); |
| push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION)); |
| |
| if (function.has_return_type ()) |
| { |
| push (Rust::Token::make (RETURN_TYPE, UNDEF_LOCATION)); |
| visit (function.get_return_type ()); |
| } |
| |
| if (function.has_where_clause ()) |
| visit (function.get_where_clause ()); |
| |
| if (function.has_body ()) |
| visit (*function.get_definition ()); |
| else |
| push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION)); |
| newline (); |
| } |
| |
| void |
| TokenCollector::visit (TypeAlias &type_alias) |
| { |
| // Syntax: |
| // Visibility? type IDENTIFIER GenericParams? WhereClause? = Type; |
| |
| // Note: Associated types are handled by `AST::TraitItemType`. |
| |
| visit_items_as_lines (type_alias.get_outer_attrs ()); |
| if (type_alias.has_visibility ()) |
| visit (type_alias.get_visibility ()); |
| auto alias_name = type_alias.get_new_type_name ().as_string (); |
| push (Rust::Token::make (TYPE, type_alias.get_locus ())); |
| push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (alias_name))); |
| |
| if (type_alias.has_generics ()) |
| visit (type_alias.get_generic_params ()); |
| |
| if (type_alias.has_where_clause ()) |
| visit (type_alias.get_where_clause ()); |
| |
| push (Rust::Token::make (EQUAL, UNDEF_LOCATION)); |
| visit (type_alias.get_type_aliased ()); |
| push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (StructStruct &struct_item) |
| { |
| visit_items_as_lines (struct_item.get_outer_attrs ()); |
| if (struct_item.has_visibility ()) |
| visit (struct_item.get_visibility ()); |
| auto struct_name = struct_item.get_identifier ().as_string (); |
| push (Rust::Token::make (STRUCT_KW, struct_item.get_locus ())); |
| push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (struct_name))); |
| |
| 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 ()) |
| { |
| push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION)); |
| newline (); |
| } |
| else |
| visit_items_as_block (struct_item.get_fields (), |
| {Rust::Token::make (COMMA, UNDEF_LOCATION)}); |
| } |
| |
| void |
| TokenCollector::visit (TupleStruct &tuple_struct) |
| { |
| visit_items_as_lines (tuple_struct.get_outer_attrs ()); |
| auto struct_name = tuple_struct.get_identifier ().as_string (); |
| push (Rust::Token::make (STRUCT_KW, tuple_struct.get_locus ())); |
| push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (struct_name))); |
| if (tuple_struct.has_generics ()) |
| visit (tuple_struct.get_generic_params ()); |
| if (tuple_struct.has_where_clause ()) |
| visit (tuple_struct.get_where_clause ()); |
| |
| push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION)); |
| visit_items_joined_by_separator (tuple_struct.get_fields (), COMMA); |
| push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION)); |
| push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION)); |
| newline (); |
| } |
| |
| void |
| TokenCollector::visit (EnumItem &item) |
| { |
| visit_items_as_lines (item.get_outer_attrs ()); |
| auto id = item.get_identifier ().as_string (); |
| push (Rust::Token::make_identifier (item.get_locus (), std::move (id))); |
| } |
| |
| void |
| TokenCollector::visit (EnumItemTuple &item) |
| { |
| auto id = item.get_identifier ().as_string (); |
| push (Rust::Token::make_identifier (item.get_locus (), std::move (id))); |
| push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION)); |
| visit_items_joined_by_separator (item.get_tuple_fields (), COMMA); |
| push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (EnumItemStruct &item) |
| { |
| auto id = item.get_identifier ().as_string (); |
| push (Rust::Token::make_identifier (item.get_locus (), std::move (id))); |
| visit_items_as_block (item.get_struct_fields (), |
| {Rust::Token::make (COMMA, UNDEF_LOCATION)}); |
| } |
| |
| void |
| TokenCollector::visit (EnumItemDiscriminant &item) |
| { |
| auto id = item.get_identifier ().as_string (); |
| push (Rust::Token::make_identifier (item.get_locus (), std::move (id))); |
| push (Rust::Token::make (EQUAL, UNDEF_LOCATION)); |
| visit (item.get_expr ()); |
| } |
| |
| void |
| TokenCollector::visit (Enum &enumeration) |
| { |
| visit_items_as_lines (enumeration.get_outer_attrs ()); |
| if (enumeration.has_visibility ()) |
| visit (enumeration.get_visibility ()); |
| push (Rust::Token::make (ENUM_KW, enumeration.get_locus ())); |
| auto id = enumeration.get_identifier ().as_string (); |
| push ( |
| Rust::Token::make_identifier (enumeration.get_locus (), std::move (id))); |
| if (enumeration.has_generics ()) |
| visit (enumeration.get_generic_params ()); |
| if (enumeration.has_where_clause ()) |
| visit (enumeration.get_where_clause ()); |
| |
| visit_items_as_block (enumeration.get_variants (), |
| {Rust::Token::make (COMMA, UNDEF_LOCATION)}); |
| } |
| |
| void |
| TokenCollector::visit (Union &union_item) |
| { |
| visit_items_as_lines (union_item.get_outer_attrs ()); |
| auto id = union_item.get_identifier ().as_string (); |
| push (Rust::Token::make_identifier (union_item.get_locus (), |
| Values::WeakKeywords::UNION)); |
| push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id))); |
| |
| 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 (), |
| {Rust::Token::make (COMMA, UNDEF_LOCATION)}); |
| } |
| |
| void |
| TokenCollector::visit (ConstantItem &item) |
| { |
| visit_items_as_lines (item.get_outer_attrs ()); |
| push (Rust::Token::make (CONST, item.get_locus ())); |
| if (item.is_unnamed ()) |
| { |
| push (Rust::Token::make (UNDERSCORE, UNDEF_LOCATION)); |
| } |
| else |
| { |
| push (Rust::Token::make_identifier (item.get_identifier ())); |
| } |
| push (Rust::Token::make (COLON, UNDEF_LOCATION)); |
| visit (item.get_type ()); |
| if (item.has_expr ()) |
| { |
| push (Rust::Token::make (EQUAL, UNDEF_LOCATION)); |
| visit (item.get_expr ()); |
| } |
| push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (StaticItem &item) |
| { |
| visit_items_as_lines (item.get_outer_attrs ()); |
| push (Rust::Token::make (STATIC_KW, item.get_locus ())); |
| if (item.is_mutable ()) |
| push (Rust::Token::make (MUT, UNDEF_LOCATION)); |
| |
| auto id = item.get_identifier ().as_string (); |
| push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id))); |
| push (Rust::Token::make (COLON, UNDEF_LOCATION)); |
| |
| visit (item.get_type ()); |
| |
| if (item.has_expr ()) |
| { |
| push (Rust::Token::make (EQUAL, UNDEF_LOCATION)); |
| visit (item.get_expr ()); |
| } |
| push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::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) |
| { |
| push (Rust::Token::make (RETURN_TYPE, UNDEF_LOCATION)); |
| visit (return_type); |
| } |
| |
| if (block) |
| { |
| visit (block); |
| } |
| else |
| { |
| push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION)); |
| newline (); |
| } |
| } |
| |
| void |
| TokenCollector::visit (SelfParam ¶m) |
| { |
| if (param.get_has_ref ()) |
| { |
| push (Rust::Token::make (AMP, UNDEF_LOCATION)); |
| if (param.has_lifetime ()) |
| { |
| auto lifetime = param.get_lifetime (); |
| visit (lifetime); |
| } |
| if (param.get_is_mut ()) |
| push (Rust::Token::make (MUT, UNDEF_LOCATION)); |
| } |
| push (Rust::Token::make (SELF, UNDEF_LOCATION)); |
| if (param.has_type ()) |
| { |
| push (Rust::Token::make (COLON, UNDEF_LOCATION)); |
| visit (param.get_type ()); |
| } |
| } |
| |
| void |
| TokenCollector::visit (TraitItemConst &item) |
| { |
| auto id = item.get_identifier ().as_string (); |
| indentation (); |
| push (Rust::Token::make (CONST, item.get_locus ())); |
| push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id))); |
| push (Rust::Token::make (COLON, UNDEF_LOCATION)); |
| visit (item.get_type ()); |
| push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION)); |
| newline (); |
| } |
| |
| void |
| TokenCollector::visit (TraitItemType &item) |
| { |
| visit_items_as_lines (item.get_outer_attrs ()); |
| auto id = item.get_identifier ().as_string (); |
| indentation (); |
| |
| push (Rust::Token::make (TYPE, item.get_locus ())); |
| push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id))); |
| push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION)); |
| newline (); |
| } |
| |
| void |
| TokenCollector::visit (Trait &trait) |
| { |
| for (auto &attr : trait.get_outer_attrs ()) |
| { |
| visit (attr); |
| newline (); |
| indentation (); |
| } |
| |
| visit (trait.get_visibility ()); |
| |
| auto id = trait.get_identifier ().as_string (); |
| push (Rust::Token::make (TRAIT, trait.get_locus ())); |
| push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id))); |
| |
| visit (trait.get_generic_params ()); |
| |
| visit_items_as_block (trait.get_trait_items (), {}); |
| } |
| |
| void |
| TokenCollector::visit (InherentImpl &impl) |
| { |
| visit_items_as_lines (impl.get_outer_attrs ()); |
| push (Rust::Token::make (IMPL, impl.get_locus ())); |
| visit (impl.get_generic_params ()); |
| |
| 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 |
| TokenCollector::visit (TraitImpl &impl) |
| { |
| visit_items_as_lines (impl.get_outer_attrs ()); |
| push (Rust::Token::make (IMPL, impl.get_locus ())); |
| visit (impl.get_generic_params ()); |
| if (impl.is_exclam ()) |
| push (Rust::Token::make (EXCLAM, UNDEF_LOCATION)); |
| visit (impl.get_trait_path ()); |
| push (Rust::Token::make (FOR, UNDEF_LOCATION)); |
| visit (impl.get_type ()); |
| |
| if (impl.has_where_clause ()) |
| visit (impl.get_where_clause ()); |
| |
| visit_items_as_block (impl.get_impl_items ()); |
| } |
| |
| void |
| TokenCollector::visit (ExternalTypeItem &type) |
| { |
| visit (type.get_visibility ()); |
| |
| auto id = type.get_identifier ().as_string (); |
| |
| push (Rust::Token::make (TYPE, UNDEF_LOCATION)); |
| push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id))); |
| push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (ExternalStaticItem &item) |
| { |
| auto id = item.get_identifier ().as_string (); |
| visit_items_as_lines (item.get_outer_attrs ()); |
| if (item.has_visibility ()) |
| visit (item.get_visibility ()); |
| push (Rust::Token::make (STATIC_KW, item.get_locus ())); |
| if (item.is_mut ()) |
| push (Rust::Token::make (MUT, UNDEF_LOCATION)); |
| push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id))); |
| push (Rust::Token::make (COLON, UNDEF_LOCATION)); |
| visit (item.get_type ()); |
| // TODO: No expr ? The "(= Expression)?" part from the reference seems missing |
| // in the ast. |
| push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (ExternBlock &block) |
| { |
| visit_items_as_lines (block.get_outer_attrs ()); |
| push (Rust::Token::make (EXTERN_KW, block.get_locus ())); |
| |
| if (block.has_abi ()) |
| { |
| auto abi = block.get_abi (); |
| push (Rust::Token::make_string (UNDEF_LOCATION, std::move (abi))); |
| } |
| |
| visit_items_as_block (block.get_extern_items (), {}); |
| } |
| |
| static std::pair<TokenId, TokenId> |
| get_delimiters (DelimType delim) |
| { |
| switch (delim) |
| { |
| case PARENS: |
| return {LEFT_PAREN, RIGHT_PAREN}; |
| case SQUARE: |
| return {LEFT_SQUARE, RIGHT_SQUARE}; |
| case CURLY: |
| return {LEFT_CURLY, RIGHT_CURLY}; |
| default: |
| rust_unreachable (); |
| } |
| } |
| |
| void |
| TokenCollector::visit (MacroMatchFragment &match) |
| { |
| auto id = match.get_ident ().as_string (); |
| auto frag_spec = match.get_frag_spec ().as_string (); |
| push (Rust::Token::make (DOLLAR_SIGN, UNDEF_LOCATION)); |
| push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id))); |
| push (Rust::Token::make (COLON, UNDEF_LOCATION)); |
| push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (frag_spec))); |
| } |
| |
| void |
| TokenCollector::visit (MacroMatchRepetition &repetition) |
| { |
| push (Rust::Token::make (DOLLAR_SIGN, UNDEF_LOCATION)); |
| push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION)); |
| |
| for (auto &match : repetition.get_matches ()) |
| { |
| visit (match); |
| } |
| |
| push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION)); |
| |
| if (repetition.has_sep ()) |
| { |
| push (Rust::Token::make (repetition.get_sep ()->get_id (), |
| repetition.get_sep ()->get_locus ())); |
| } |
| switch (repetition.get_op ()) |
| { |
| case MacroMatchRepetition::ANY: |
| push (Rust::Token::make (ASTERISK, UNDEF_LOCATION)); |
| break; |
| case MacroMatchRepetition::ONE_OR_MORE: |
| push (Rust::Token::make (PLUS, UNDEF_LOCATION)); |
| break; |
| case MacroMatchRepetition::ZERO_OR_ONE: |
| push (Rust::Token::make (QUESTION_MARK, UNDEF_LOCATION)); |
| break; |
| case MacroMatchRepetition::NONE: |
| break; |
| } |
| } |
| |
| void |
| TokenCollector::visit (MacroMatcher &matcher) |
| { |
| auto delimiters = get_delimiters (matcher.get_delim_type ()); |
| |
| push (Rust::Token::make (delimiters.first, UNDEF_LOCATION)); |
| |
| for (auto &item : matcher.get_matches ()) |
| { |
| visit (item); |
| } |
| |
| push (Rust::Token::make (delimiters.second, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (MacroRule &rule) |
| { |
| visit (rule.get_matcher ()); |
| push (Rust::Token::make (MATCH_ARROW, rule.get_locus ())); |
| visit (rule.get_transcriber ().get_token_tree ()); |
| } |
| |
| void |
| TokenCollector::visit (MacroRulesDefinition &rules_def) |
| { |
| for (auto &outer_attr : rules_def.get_outer_attrs ()) |
| visit (outer_attr); |
| |
| auto rule_name = rules_def.get_rule_name ().as_string (); |
| |
| push (Rust::Token::make_identifier (rules_def.get_locus (), |
| Values::WeakKeywords::MACRO_RULES)); |
| push (Rust::Token::make (EXCLAM, UNDEF_LOCATION)); |
| |
| push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (rule_name))); |
| |
| visit_items_as_block (rules_def.get_rules (), |
| {Rust::Token::make (SEMICOLON, UNDEF_LOCATION)}); |
| } |
| |
| void |
| TokenCollector::visit (MacroInvocation &invocation) |
| { |
| auto data = invocation.get_invoc_data (); |
| visit (data.get_path ()); |
| push (Rust::Token::make (EXCLAM, UNDEF_LOCATION)); |
| visit (data.get_delim_tok_tree ()); |
| if (invocation.has_semicolon ()) |
| push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (MetaItemPath &item) |
| { |
| auto path = item.to_path_item (); |
| visit (path); |
| } |
| |
| void |
| TokenCollector::visit (MetaItemSeq &item) |
| { |
| visit (item.get_path ()); |
| // TODO: Double check this, there is probably a mistake. |
| push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION)); |
| visit_items_joined_by_separator (item.get_seq (), COMMA); |
| push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (MetaWord &word) |
| { |
| auto id = word.get_ident ().as_string (); |
| |
| push (Rust::Token::make_identifier (word.get_locus (), std::move (id))); |
| } |
| |
| void |
| TokenCollector::visit (MetaNameValueStr &name) |
| { |
| auto pair = name.get_name_value_pair (); |
| auto id = std::get<0> (pair).as_string (); |
| auto value = std::get<1> (pair); |
| |
| push (Rust::Token::make_identifier (name.get_locus (), std::move (id))); |
| push (Rust::Token::make (EQUAL, name.get_locus ())); |
| push (Rust::Token::make (DOUBLE_QUOTE, UNDEF_LOCATION)); |
| push (Rust::Token::make_identifier (name.get_locus (), std::move (value))); |
| push (Rust::Token::make (DOUBLE_QUOTE, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (MetaListPaths &list) |
| { |
| auto id = list.get_ident ().as_string (); |
| |
| push (Rust::Token::make_identifier (list.get_locus (), std::move (id))); |
| push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION)); |
| |
| visit_items_joined_by_separator (list.get_paths (), COMMA); |
| |
| push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (MetaListNameValueStr &list) |
| { |
| auto id = list.get_ident ().as_string (); |
| |
| push (Rust::Token::make_identifier (list.get_locus (), std::move (id))); |
| push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION)); |
| |
| visit_items_joined_by_separator (list.get_values (), COMMA); |
| |
| push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION)); |
| } |
| |
| // rust-pattern.h |
| void |
| TokenCollector::visit (LiteralPattern &pattern) |
| { |
| visit (pattern.get_literal (), pattern.get_locus ()); |
| } |
| |
| void |
| TokenCollector::visit (IdentifierPattern &pattern) |
| { |
| if (pattern.get_is_ref ()) |
| { |
| push (Rust::Token::make (REF, pattern.get_locus ())); |
| } |
| if (pattern.get_is_mut ()) |
| { |
| push (Rust::Token::make (MUT, UNDEF_LOCATION)); |
| } |
| |
| auto id = pattern.get_ident ().as_string (); |
| push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id))); |
| |
| if (pattern.has_subpattern ()) |
| { |
| push (Rust::Token::make (PATTERN_BIND, UNDEF_LOCATION)); |
| visit (pattern.get_subpattern ()); |
| } |
| } |
| |
| void |
| TokenCollector::visit (WildcardPattern &pattern) |
| { |
| push (Rust::Token::make (UNDERSCORE, pattern.get_locus ())); |
| } |
| |
| void |
| TokenCollector::visit (RestPattern &pattern) |
| { |
| push (Rust::Token::make (DOT_DOT, pattern.get_locus ())); |
| } |
| |
| // void TokenCollector::visit(RangePatternBound& ){} |
| |
| void |
| TokenCollector::visit (RangePatternBoundLiteral &pattern) |
| { |
| if (pattern.get_has_minus ()) |
| { |
| push (Rust::Token::make (MINUS, pattern.get_locus ())); |
| } |
| auto literal = pattern.get_literal (); |
| visit (literal); |
| } |
| |
| void |
| TokenCollector::visit (RangePatternBoundPath &pattern) |
| { |
| visit (pattern.get_path ()); |
| } |
| |
| void |
| TokenCollector::visit (RangePatternBoundQualPath &pattern) |
| { |
| visit (pattern.get_qualified_path ()); |
| } |
| |
| void |
| TokenCollector::visit (RangePattern &pattern) |
| { |
| if (pattern.get_has_lower_bound () && pattern.get_has_upper_bound ()) |
| { |
| visit (pattern.get_lower_bound ()); |
| if (pattern.get_has_ellipsis_syntax ()) |
| push (Rust::Token::make (ELLIPSIS, pattern.get_locus ())); |
| else |
| push (Rust::Token::make (DOT_DOT_EQ, pattern.get_locus ())); |
| visit (pattern.get_upper_bound ()); |
| } |
| else if (pattern.get_has_lower_bound ()) |
| { |
| visit (pattern.get_lower_bound ()); |
| push (Rust::Token::make (DOT_DOT, pattern.get_locus ())); |
| } |
| else |
| { |
| push (Rust::Token::make (DOT_DOT_EQ, pattern.get_locus ())); |
| visit (pattern.get_upper_bound ()); |
| } |
| } |
| |
| void |
| TokenCollector::visit (ReferencePattern &pattern) |
| { |
| if (pattern.is_double_reference ()) |
| { |
| push (Rust::Token::make (LOGICAL_AND, pattern.get_locus ())); |
| } |
| else |
| { |
| push (Rust::Token::make (AMP, pattern.get_locus ())); |
| } |
| |
| if (pattern.get_is_mut ()) |
| { |
| push (Rust::Token::make (MUT, UNDEF_LOCATION)); |
| } |
| |
| visit (pattern.get_referenced_pattern ()); |
| } |
| |
| // void TokenCollector::visit(StructPatternField& ){} |
| |
| void |
| TokenCollector::visit (StructPatternFieldTuplePat &pattern) |
| { |
| visit_items_as_lines (pattern.get_outer_attrs ()); |
| push (Rust::Token::make_int (pattern.get_locus (), |
| std::to_string (pattern.get_index ()))); |
| push (Rust::Token::make (COLON, pattern.get_locus ())); |
| visit (pattern.get_index_pattern ()); |
| } |
| |
| void |
| TokenCollector::visit (StructPatternFieldIdentPat &pattern) |
| { |
| visit_items_as_lines (pattern.get_outer_attrs ()); |
| |
| auto id = pattern.get_identifier ().as_string (); |
| push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id))); |
| |
| push (Rust::Token::make (COLON, pattern.get_locus ())); |
| |
| visit (pattern.get_ident_pattern ()); |
| } |
| |
| void |
| TokenCollector::visit (StructPatternFieldIdent &pattern) |
| { |
| visit_items_as_lines (pattern.get_outer_attrs ()); |
| if (pattern.is_ref ()) |
| push (Rust::Token::make (REF, UNDEF_LOCATION)); |
| if (pattern.is_mut ()) |
| push (Rust::Token::make (MUT, UNDEF_LOCATION)); |
| |
| auto id = pattern.get_identifier ().as_string (); |
| push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id))); |
| } |
| |
| void |
| TokenCollector::visit (StructPattern &pattern) |
| { |
| visit (pattern.get_path ()); |
| push (Rust::Token::make (LEFT_CURLY, pattern.get_locus ())); |
| auto elems = pattern.get_struct_pattern_elems (); |
| if (elems.has_struct_pattern_fields ()) |
| { |
| visit_items_joined_by_separator (elems.get_struct_pattern_fields ()); |
| if (elems.has_etc ()) |
| { |
| push (Rust::Token::make (COMMA, UNDEF_LOCATION)); |
| visit_items_as_lines (elems.get_etc_outer_attrs ()); |
| } |
| } |
| else |
| { |
| visit_items_as_lines (elems.get_etc_outer_attrs ()); |
| } |
| |
| push (Rust::Token::make (RIGHT_CURLY, UNDEF_LOCATION)); |
| } |
| |
| // void TokenCollector::visit(TupleStructItems& ){} |
| |
| void |
| TokenCollector::visit (TupleStructItemsNoRange &pattern) |
| { |
| visit_items_joined_by_separator (pattern.get_patterns ()); |
| } |
| |
| void |
| TokenCollector::visit (TupleStructItemsRange &pattern) |
| { |
| for (auto &lower : pattern.get_lower_patterns ()) |
| { |
| visit (lower); |
| } |
| push (Rust::Token::make (DOT_DOT, UNDEF_LOCATION)); |
| for (auto &upper : pattern.get_lower_patterns ()) |
| { |
| visit (upper); |
| } |
| } |
| |
| void |
| TokenCollector::visit (TupleStructPattern &pattern) |
| { |
| visit (pattern.get_path ()); |
| push (Rust::Token::make (LEFT_PAREN, pattern.get_locus ())); |
| visit (pattern.get_items ()); |
| push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION)); |
| } |
| |
| // void |
| // TokenCollector::visit (TuplePatternItems &) |
| // {} |
| |
| void |
| TokenCollector::visit (TuplePatternItemsMultiple &pattern) |
| { |
| visit_items_joined_by_separator (pattern.get_patterns (), COMMA); |
| } |
| |
| void |
| TokenCollector::visit (TuplePatternItemsRanged &pattern) |
| { |
| for (auto &lower : pattern.get_lower_patterns ()) |
| { |
| visit (lower); |
| } |
| push (Rust::Token::make (DOT_DOT, UNDEF_LOCATION)); |
| for (auto &upper : pattern.get_lower_patterns ()) |
| { |
| visit (upper); |
| } |
| } |
| |
| void |
| TokenCollector::visit (TuplePattern &pattern) |
| { |
| push (Rust::Token::make (LEFT_PAREN, pattern.get_locus ())); |
| visit (pattern.get_items ()); |
| push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (GroupedPattern &pattern) |
| { |
| push (Rust::Token::make (LEFT_PAREN, pattern.get_locus ())); |
| visit (pattern.get_pattern_in_parens ()); |
| push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (SlicePatternItemsNoRest &items) |
| { |
| visit_items_joined_by_separator (items.get_patterns (), COMMA); |
| } |
| |
| void |
| TokenCollector::visit (SlicePatternItemsHasRest &items) |
| { |
| if (!items.get_lower_patterns ().empty ()) |
| { |
| visit_items_joined_by_separator (items.get_lower_patterns (), COMMA); |
| push (Rust::Token::make (COMMA, UNDEF_LOCATION)); |
| } |
| |
| push (Rust::Token::make (DOT_DOT, UNDEF_LOCATION)); |
| |
| if (!items.get_upper_patterns ().empty ()) |
| { |
| push (Rust::Token::make (COMMA, UNDEF_LOCATION)); |
| visit_items_joined_by_separator (items.get_upper_patterns (), COMMA); |
| } |
| } |
| |
| void |
| TokenCollector::visit (SlicePattern &pattern) |
| { |
| push (Rust::Token::make (LEFT_SQUARE, pattern.get_locus ())); |
| visit (pattern.get_items ()); |
| push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (AltPattern &pattern) |
| { |
| visit_items_joined_by_separator (pattern.get_alts (), PIPE); |
| } |
| |
| // rust-stmt.h |
| void |
| TokenCollector::visit (EmptyStmt &) |
| {} |
| |
| void |
| TokenCollector::visit (LetStmt &stmt) |
| { |
| push (Rust::Token::make (LET, stmt.get_locus ())); |
| auto &pattern = stmt.get_pattern (); |
| visit (pattern); |
| |
| if (stmt.has_type ()) |
| { |
| push (Rust::Token::make (COLON, UNDEF_LOCATION)); |
| visit (stmt.get_type ()); |
| } |
| |
| if (stmt.has_init_expr ()) |
| { |
| push (Rust::Token::make (EQUAL, UNDEF_LOCATION)); |
| visit (stmt.get_init_expr ()); |
| } |
| |
| if (stmt.has_else_expr ()) |
| { |
| push (Rust::Token::make (ELSE, UNDEF_LOCATION)); |
| visit (stmt.get_else_expr ()); |
| } |
| |
| push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (ExprStmt &stmt) |
| { |
| visit (stmt.get_expr ()); |
| if (stmt.is_semicolon_followed ()) |
| push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION)); |
| } |
| |
| // rust-type.h |
| void |
| TokenCollector::visit (TraitBound &bound) |
| { |
| // Syntax: |
| // ?? ForLifetimes? TypePath |
| // | ( ?? ForLifetimes? TypePath ) |
| |
| if (bound.has_opening_question_mark ()) |
| push (Rust::Token::make (QUESTION_MARK, bound.get_locus ())); |
| |
| if (bound.has_for_lifetimes ()) |
| visit (bound.get_for_lifetimes ()); |
| |
| visit (bound.get_type_path ()); |
| } |
| |
| void |
| TokenCollector::visit (ImplTraitType &type) |
| { |
| // Syntax: |
| // impl TypeParamBounds |
| // TypeParamBounds : |
| // TypeParamBound ( + TypeParamBound )* +? |
| |
| push (Rust::Token::make (IMPL, type.get_locus ())); |
| visit_items_joined_by_separator (type.get_type_param_bounds (), PLUS); |
| } |
| |
| void |
| TokenCollector::visit (TraitObjectType &type) |
| { |
| // Syntax: |
| // dyn? TypeParamBounds |
| // TypeParamBounds : |
| // TypeParamBound ( + TypeParamBound )* +? |
| |
| if (type.is_dyn ()) |
| push (Rust::Token::make (DYN, type.get_locus ())); |
| visit_items_joined_by_separator (type.get_type_param_bounds (), PLUS); |
| } |
| |
| void |
| TokenCollector::visit (ParenthesisedType &type) |
| { |
| // Syntax: |
| // ( Type ) |
| |
| push (Rust::Token::make (LEFT_PAREN, type.get_locus ())); |
| visit (type.get_type_in_parens ()); |
| push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (ImplTraitTypeOneBound &type) |
| { |
| // Syntax: |
| // impl TraitBound |
| |
| push (Rust::Token::make (IMPL, type.get_locus ())); |
| visit (type.get_trait_bound ()); |
| } |
| |
| void |
| TokenCollector::visit (TraitObjectTypeOneBound &type) |
| { |
| // Syntax: |
| // dyn? TraitBound |
| |
| if (type.is_dyn ()) |
| push (Rust::Token::make (DYN, type.get_locus ())); |
| visit (type.get_trait_bound ()); |
| } |
| |
| void |
| TokenCollector::visit (TupleType &type) |
| { |
| // Syntax: |
| // ( ) |
| // | ( ( Type , )+ Type? ) |
| |
| push (Rust::Token::make (LEFT_PAREN, type.get_locus ())); |
| visit_items_joined_by_separator (type.get_elems (), COMMA); |
| push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (NeverType &type) |
| { |
| // Syntax: |
| // ! |
| |
| push (Rust::Token::make (EXCLAM, type.get_locus ())); |
| } |
| |
| void |
| TokenCollector::visit (RawPointerType &type) |
| { |
| // Syntax: |
| // * ( mut | const ) TypeNoBounds |
| |
| push (Rust::Token::make (ASTERISK, type.get_locus ())); |
| if (type.get_pointer_type () == RawPointerType::MUT) |
| push (Rust::Token::make (MUT, UNDEF_LOCATION)); |
| else /* RawPointerType::CONST */ |
| push (Rust::Token::make (CONST, UNDEF_LOCATION)); |
| |
| visit (type.get_type_pointed_to ()); |
| } |
| |
| void |
| TokenCollector::visit (ReferenceType &type) |
| { |
| // Syntax: |
| // & Lifetime? mut? TypeNoBounds |
| |
| push (Rust::Token::make (AMP, type.get_locus ())); |
| |
| if (type.has_lifetime ()) |
| { |
| visit (type.get_lifetime ()); |
| } |
| |
| if (type.get_has_mut ()) |
| push (Rust::Token::make (MUT, UNDEF_LOCATION)); |
| |
| visit (type.get_type_referenced ()); |
| } |
| |
| void |
| TokenCollector::visit (ArrayType &type) |
| { |
| // Syntax: |
| // [ Type ; Expression ] |
| |
| push (Rust::Token::make (LEFT_SQUARE, type.get_locus ())); |
| visit (type.get_elem_type ()); |
| push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION)); |
| visit (type.get_size_expr ()); |
| push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (SliceType &type) |
| { |
| // Syntax: |
| // [ Type ] |
| |
| push (Rust::Token::make (LEFT_SQUARE, type.get_locus ())); |
| visit (type.get_elem_type ()); |
| push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION)); |
| } |
| |
| void |
| TokenCollector::visit (InferredType &type) |
| { |
| // Syntax: |
| // _ |
| |
| push (Rust::Token::make (UNDERSCORE, type.get_locus ())); |
| } |
| |
| void |
| TokenCollector::visit (BareFunctionType &type) |
| { |
| // 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 ()); |
| |
| push (Rust::Token::make (FN_KW, type.get_locus ())); |
| push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION)); |
| |
| visit_items_joined_by_separator (type.get_function_params (), COMMA); |
| |
| if (type.is_variadic ()) |
| { |
| push (Rust::Token::make (COMMA, UNDEF_LOCATION)); |
| for (auto &item : type.get_variadic_attr ()) |
| { |
| visit (item); |
| } |
| push (Rust::Token::make (ELLIPSIS, UNDEF_LOCATION)); |
| } |
| |
| push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION)); |
| |
| if (type.has_return_type ()) |
| { |
| push (Rust::Token::make (RETURN_TYPE, UNDEF_LOCATION)); |
| visit (type.get_return_type ()); |
| } |
| } |
| |
| void |
| TokenCollector::visit (AST::FormatArgs &fmt) |
| { |
| rust_sorry_at (fmt.get_locus (), "%s:%u: unimplemented FormatArgs visitor", |
| __FILE__, __LINE__); |
| } |
| |
| void |
| TokenCollector::visit (AST::OffsetOf &offset_of) |
| { |
| auto loc = offset_of.get_locus (); |
| |
| push (Rust::Token::make_identifier (loc, "offset_of")); |
| push (Rust::Token::make (EXCLAM, loc)); |
| push (Rust::Token::make (LEFT_PAREN, loc)); |
| |
| visit (offset_of.get_type ()); |
| |
| push (Rust::Token::make (COMMA, loc)); |
| |
| push (Rust::Token::make_identifier (offset_of.get_field ())); |
| |
| push (Rust::Token::make (RIGHT_PAREN, loc)); |
| } |
| |
| } // namespace AST |
| } // namespace Rust |