LCOV - code coverage report
Current view: top level - gcc/rust/ast - rust-ast-collector.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 83.3 % 66 55
Test Date: 2026-02-28 14:20:25 Functions: 82.1 % 56 46
Legend: Lines:     hit not hit

            Line data    Source code
       1              : // Copyright (C) 2020-2026 Free Software Foundation, Inc.
       2              : 
       3              : // This file is part of GCC.
       4              : 
       5              : // GCC is free software; you can redistribute it and/or modify it under
       6              : // the terms of the GNU General Public License as published by the Free
       7              : // Software Foundation; either version 3, or (at your option) any later
       8              : // version.
       9              : 
      10              : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      11              : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12              : // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      13              : // for more details.
      14              : 
      15              : // You should have received a copy of the GNU General Public License
      16              : // along with GCC; see the file COPYING3.  If not see
      17              : // <http://www.gnu.org/licenses/>.
      18              : 
      19              : #ifndef RUST_AST_COLLECTOR_H
      20              : #define RUST_AST_COLLECTOR_H
      21              : 
      22              : #include "rust-token.h"
      23              : #include "rust-ast-visitor.h"
      24              : #include "rust-ast.h"
      25              : #include "rust-ast-full.h"
      26              : #include "rust-system.h"
      27              : 
      28              : namespace Rust {
      29              : namespace AST {
      30              : 
      31              : class CollectItem
      32              : {
      33              : public:
      34              :   enum class Kind
      35              :   {
      36              :     Comment,
      37              :     InternalComment,
      38              :     BeginNodeDescription,
      39              :     EndNodeDescription,
      40              :     Newline,
      41              :     Indentation,
      42              :     Token,
      43              :   };
      44              : 
      45        72891 :   CollectItem (TokenPtr token) : token (token), kind (Kind::Token) {}
      46        16399 :   CollectItem (Kind kind) : kind (kind) { rust_assert (kind != Kind::Token); }
      47        10894 :   CollectItem (size_t level) : indent_level (level), kind (Kind::Indentation) {}
      48              : 
      49              :   static CollectItem make_internal_comment (const std::string &internal_comment)
      50              :   {
      51              :     return CollectItem (internal_comment, Kind::InternalComment);
      52              :   }
      53              : 
      54            0 :   static CollectItem make_comment (const std::string &comment)
      55              :   {
      56            0 :     return CollectItem (comment, Kind::Comment);
      57              :   }
      58              : 
      59              :   static CollectItem
      60        52039 :   make_begin_node_description (const std::string &node_description)
      61              :   {
      62       104078 :     return CollectItem (node_description, Kind::BeginNodeDescription);
      63              :   }
      64              : 
      65              :   static CollectItem
      66        52039 :   make_end_node_description (const std::string &node_description)
      67              :   {
      68       104078 :     return CollectItem (node_description, Kind::EndNodeDescription);
      69              :   }
      70              : 
      71       204262 :   Kind get_kind () { return kind; }
      72              : 
      73        72891 :   TokenPtr get_token ()
      74              :   {
      75        72891 :     rust_assert (kind == Kind::Token);
      76        72891 :     return token;
      77              :   }
      78              : 
      79            0 :   std::string get_comment ()
      80              :   {
      81            0 :     rust_assert (kind == Kind::Comment);
      82            0 :     return comment;
      83              :   }
      84              : 
      85        25687 :   size_t get_indent_level ()
      86              :   {
      87        25687 :     rust_assert (kind == Kind::Indentation);
      88        25687 :     return indent_level;
      89              :   }
      90              : 
      91            0 :   std::string get_internal_comment ()
      92              :   {
      93            0 :     rust_assert (kind == Kind::InternalComment);
      94            0 :     return comment;
      95              :   }
      96              : 
      97            0 :   std::string get_node_description ()
      98              :   {
      99            0 :     rust_assert (kind == Kind::BeginNodeDescription
     100              :                  || kind == Kind::EndNodeDescription);
     101            0 :     return comment;
     102              :   }
     103              : 
     104              :   bool is_debug () { return debug; }
     105              : 
     106              : private:
     107       104078 :   CollectItem (std::string comment, Kind kind) : comment (comment), kind (kind)
     108       104078 :   {}
     109              : 
     110              :   TokenPtr token;
     111              :   std::string comment;
     112              :   size_t indent_level;
     113              :   Kind kind;
     114              :   bool debug = false;
     115              : };
     116              : 
     117         2624 : class TokenCollector : public ASTVisitor
     118              : {
     119              : public:
     120         2624 :   TokenCollector () : indent_level (0) {}
     121              : 
     122              :   bool output_trailing_commas = false;
     123              : 
     124              :   void visit (AST::Crate &crate);
     125              :   void visit (AST::Item &item);
     126              : 
     127              :   std::vector<TokenPtr> collect_tokens () const;
     128              :   std::vector<CollectItem> collect () const;
     129              : 
     130              : private:
     131              :   std::vector<CollectItem> tokens;
     132              :   size_t indent_level;
     133              : 
     134       145782 :   void push (TokenPtr token) { tokens.push_back ({token}); }
     135              : 
     136              :   /**
     137              :    * Visit all items in given @collection, placing the separator in between but
     138              :    * not at the end.
     139              :    */
     140              :   template <typename T>
     141        13317 :   void visit_items_joined_by_separator (T &collection,
     142              :                                         TokenId separator = COMMA,
     143              :                                         size_t start_offset = 0,
     144              :                                         size_t end_offset = 0)
     145              :   {
     146        13317 :     if (collection.size () > start_offset)
     147              :       {
     148         9641 :         visit (collection.at (start_offset));
     149         9641 :         auto size = collection.size () - end_offset;
     150        11548 :         for (size_t i = start_offset + 1; i < size; i++)
     151              :           {
     152         3814 :             push (Rust::Token::make (separator, UNDEF_LOCATION));
     153         1907 :             visit (collection.at (i));
     154              :           }
     155              :       }
     156        13317 :   }
     157              : 
     158              :   /**
     159              :    * Visit item placing end of line after.
     160              :    */
     161              :   template <typename T>
     162         4695 :   void visit_as_line (T &item, std::vector<TokenPtr> trailing = {})
     163              :   {
     164         4695 :     indentation ();
     165         4695 :     visit (item);
     166         4716 :     for (auto &token : trailing)
     167           42 :       push (token);
     168         4695 :     newline ();
     169         4695 :   }
     170              : 
     171              :   /**
     172              :    * Visit each item in @collection "as line".
     173              :    *
     174              :    * @see visit_as_line
     175              :    */
     176              :   template <typename T>
     177        10218 :   void visit_items_as_lines (T &collection, std::vector<TokenPtr> trailing = {})
     178              :   {
     179        14913 :     for (auto &item : collection)
     180         4695 :       visit_as_line (item, trailing);
     181        10218 :   }
     182              : 
     183              :   /**
     184              :    * Visit each item in @collection as lines inside a block delimited by braces
     185              :    * with increased indentation. Also includes special handling for empty
     186              :    * collection to print only the delimiters with no new line inside.
     187              :    */
     188              :   template <typename T>
     189         2556 :   void visit_items_as_block (T &collection, std::vector<TokenPtr> trailing = {},
     190              :                              TokenId left_brace = LEFT_CURLY,
     191              :                              TokenId right_brace = RIGHT_CURLY)
     192              :   {
     193         5112 :     push (Rust::Token::make (left_brace, UNDEF_LOCATION));
     194         2556 :     if (collection.empty ())
     195              :       {
     196         1297 :         push (Rust::Token::make (right_brace, UNDEF_LOCATION));
     197         1297 :         newline ();
     198              :       }
     199              :     else
     200              :       {
     201         1259 :         newline ();
     202         1259 :         increment_indentation ();
     203         1259 :         visit_items_as_lines (collection, trailing);
     204         1259 :         decrement_indentation ();
     205         1259 :         indentation ();
     206         1259 :         push (Rust::Token::make (right_brace, UNDEF_LOCATION));
     207         1259 :         newline ();
     208              :       }
     209         2556 :   }
     210              : 
     211              :   void describe_node (const std::string &node_name,
     212              :                       std::function<void ()> visitor);
     213              : 
     214              :   void trailing_comma ();
     215              :   void newline ();
     216              :   void indentation ();
     217              :   void increment_indentation ();
     218              :   void decrement_indentation ();
     219              :   void comment (std::string comment);
     220              :   /**
     221              :    * Visit common items of functions: Parameters, return type, block
     222              :    */
     223              :   void visit_function_common (std::unique_ptr<Type> &return_type,
     224              :                               std::unique_ptr<BlockExpr> &block);
     225              : 
     226              :   void visit_closure_common (ClosureExpr &expr);
     227              : 
     228              :   void visit_loop_common (BaseLoopExpr &expr);
     229              : 
     230              : public:
     231              :   /**
     232              :    * Compatibility layer for using the visitor pattern on polymorphic classes
     233              :    * with a unified overload syntax. This allows us to call `visit` both on
     234              :    * types implementing `accept_vis` method and for classes for which the
     235              :    * `visit` method is directly implemented.
     236              :    */
     237        13734 :   template <typename T> void visit (std::unique_ptr<T> &node)
     238              :   {
     239        13734 :     node->accept_vis (*this);
     240          822 :   }
     241              : 
     242              :   /**
     243              :    * @see visit<std::unique_ptr<T>>
     244              :    */
     245        13700 :   template <typename T> void visit (T &node) { node.accept_vis (*this); }
     246              : 
     247              :   void visit (Visitable &v);
     248              :   void visit (LoopLabel &label);
     249              : 
     250              :   void visit (Literal &lit, location_t locus = UNDEF_LOCATION);
     251              : 
     252              :   void visit (FunctionParam &param);
     253              :   void visit (VariadicParam &param);
     254              :   void visit (Attribute &attrib);
     255              :   void visit (Visibility &vis);
     256              :   void visit (std::vector<std::unique_ptr<GenericParam>> &params);
     257              :   void visit (TupleField &field);
     258              :   void visit (StructField &field);
     259              :   void visit (SimplePathSegment &segment);
     260              :   void visit (MacroRule &rule);
     261              :   void visit (WhereClause &rule);
     262              :   void visit (std::vector<LifetimeParam> &for_lifetimes);
     263              :   void visit (FunctionQualifiers &qualifiers);
     264              :   void visit (MaybeNamedParam &param);
     265              :   void visit (TypePathFunction &type_path_fn);
     266              :   void visit (GenericArgsBinding &binding);
     267              :   void visit (GenericArg &arg);
     268              : 
     269              :   // rust-ast.h
     270              :   void visit (Token &tok);
     271              :   void visit (DelimTokenTree &delim_tok_tree);
     272              :   void visit (AttrInputMetaItemContainer &input);
     273              :   void visit (IdentifierExpr &ident_expr);
     274              :   void visit (Lifetime &lifetime);
     275              :   void visit (LifetimeParam &lifetime_param);
     276              :   void visit (ConstGenericParam &const_param);
     277              : 
     278              :   // rust-path.h
     279              :   void visit (SimplePath &path);
     280              :   void visit (PathExprSegment &segment);
     281              :   void visit (PathIdentSegment &segment);
     282              :   void visit (PathInExpression &path);
     283              :   void visit (TypePathSegment &segment);
     284              :   void visit (TypePathSegmentGeneric &segment);
     285              :   void visit (TypePathSegmentFunction &segment);
     286              :   void visit (TypePath &path);
     287              :   void visit (QualifiedPathType &path);
     288              :   void visit (QualifiedPathInExpression &path);
     289              :   void visit (QualifiedPathInType &path);
     290              : 
     291              :   // rust-expr.h
     292              :   void visit (LiteralExpr &expr);
     293              :   void visit (AttrInputLiteral &attr_input);
     294              :   void visit (AttrInputMacro &attr_input);
     295              :   void visit (MetaItemLitExpr &meta_item);
     296              :   void visit (MetaItemPathExpr &meta_item);
     297              :   void visit (BorrowExpr &expr);
     298              :   void visit (DereferenceExpr &expr);
     299              :   void visit (ErrorPropagationExpr &expr);
     300              :   void visit (NegationExpr &expr);
     301              :   void visit (ArithmeticOrLogicalExpr &expr);
     302              :   void visit (ComparisonExpr &expr);
     303              :   void visit (LazyBooleanExpr &expr);
     304              :   void visit (TypeCastExpr &expr);
     305              :   void visit (AssignmentExpr &expr);
     306              :   void visit (CompoundAssignmentExpr &expr);
     307              :   void visit (GroupedExpr &expr);
     308              :   void visit (ArrayElemsValues &elems);
     309              :   void visit (ArrayElemsCopied &elems);
     310              :   void visit (ArrayExpr &expr);
     311              :   void visit (ArrayIndexExpr &expr);
     312              :   void visit (TupleExpr &expr);
     313              :   void visit (TupleIndexExpr &expr);
     314              :   void visit (StructExprStruct &expr);
     315              :   void visit (StructExprFieldIdentifier &field);
     316              :   void visit (StructExprFieldIdentifierValue &field);
     317              :   void visit (StructExprFieldIndexValue &field);
     318              :   void visit (StructBase &base);
     319              :   void visit (StructExprStructFields &expr);
     320              :   void visit (StructExprStructBase &expr);
     321              :   void visit (CallExpr &expr);
     322              :   void visit (MethodCallExpr &expr);
     323              :   void visit (FieldAccessExpr &expr);
     324              :   void visit (ClosureParam &param);
     325              :   void visit (ClosureExprInner &expr);
     326              :   void visit (BlockExpr &expr);
     327              :   void visit (AnonConst &expr);
     328              :   void visit (ConstBlock &expr);
     329              :   void visit (ClosureExprInnerTyped &expr);
     330              :   void visit (ContinueExpr &expr);
     331              :   void visit (BreakExpr &expr);
     332              :   void visit (RangeFromToExpr &expr);
     333              :   void visit (RangeFromExpr &expr);
     334              :   void visit (RangeToExpr &expr);
     335              :   void visit (RangeFullExpr &expr);
     336              :   void visit (RangeFromToInclExpr &expr);
     337              :   void visit (RangeToInclExpr &expr);
     338              :   void visit (ReturnExpr &expr);
     339              :   void visit (TryExpr &expr);
     340              :   void visit (BoxExpr &expr);
     341              :   void visit (UnsafeBlockExpr &expr);
     342              :   void visit (LoopExpr &expr);
     343              :   void visit (WhileLoopExpr &expr);
     344              :   void visit (WhileLetLoopExpr &expr);
     345              :   void visit (ForLoopExpr &expr);
     346              :   void visit (IfExpr &expr);
     347              :   void visit (IfExprConseqElse &expr);
     348              :   void visit (IfLetExpr &expr);
     349              :   void visit (IfLetExprConseqElse &expr);
     350              :   void visit (MatchArm &arm);
     351              :   void visit (MatchCase &arm);
     352              :   void visit (MatchExpr &expr);
     353              :   void visit (AwaitExpr &expr);
     354              :   void visit (AsyncBlockExpr &expr);
     355              :   void visit (InlineAsm &expr);
     356              :   void visit (LlvmInlineAsm &expr);
     357              :   // rust-item.h
     358              :   void visit (TypeParam &param);
     359              :   void visit (LifetimeWhereClauseItem &item);
     360              :   void visit (TypeBoundWhereClauseItem &item);
     361              :   void visit (Module &module);
     362              :   void visit (ExternCrate &crate);
     363              :   void visit (UseTreeGlob &use_tree);
     364              :   void visit (UseTreeList &use_tree);
     365              :   void visit (UseTreeRebind &use_tree);
     366              :   void visit (UseDeclaration &use_decl);
     367              :   void visit (Function &function);
     368              :   void visit (TypeAlias &type_alias);
     369              :   void visit (StructStruct &struct_item);
     370              :   void visit (TupleStruct &tuple_struct);
     371              :   void visit (EnumItem &item);
     372              :   void visit (EnumItemTuple &item);
     373              :   void visit (EnumItemStruct &item);
     374              :   void visit (EnumItemDiscriminant &item);
     375              :   void visit (Enum &enumeration);
     376              :   void visit (Union &union_item);
     377              :   void visit (ConstantItem &const_item);
     378              :   void visit (StaticItem &static_item);
     379              :   void visit (SelfParam &param);
     380              :   void visit (TraitItemType &item);
     381              :   void visit (Trait &trait);
     382              :   void visit (InherentImpl &impl);
     383              :   void visit (TraitImpl &impl);
     384              :   void visit (ExternalTypeItem &item);
     385              :   void visit (ExternalStaticItem &item);
     386              :   void visit (ExternBlock &block);
     387              : 
     388              :   // rust-macro.h
     389              :   void visit (MacroMatchFragment &match);
     390              :   void visit (MacroMatchRepetition &match);
     391              :   void visit (MacroMatcher &matcher);
     392              :   void visit (MacroRulesDefinition &rules_def);
     393              :   void visit (MacroInvocData &invoc_data);
     394              :   void visit (MacroInvocation &macro_invoc);
     395              :   void visit (MetaItemPath &meta_item);
     396              :   void visit (MetaItemSeq &meta_item);
     397              :   void visit (MetaWord &meta_item);
     398              :   void visit (MetaNameValueStr &meta_item);
     399              :   void visit (MetaListPaths &meta_item);
     400              :   void visit (MetaListNameValueStr &meta_item);
     401              : 
     402              :   // rust-pattern.h
     403              :   void visit (LiteralPattern &pattern);
     404              :   void visit (IdentifierPattern &pattern);
     405              :   void visit (WildcardPattern &pattern);
     406              :   void visit (RestPattern &pattern);
     407              :   // void visit(RangePatternBound& bound);
     408              :   void visit (RangePatternBoundLiteral &bound);
     409              :   void visit (RangePatternBoundPath &bound);
     410              :   void visit (RangePatternBoundQualPath &bound);
     411              :   void visit (RangePattern &pattern);
     412              :   void visit (ReferencePattern &pattern);
     413              :   // void visit(StructPatternField& field);
     414              :   void visit (StructPatternFieldTuplePat &field);
     415              :   void visit (StructPatternFieldIdentPat &field);
     416              :   void visit (StructPatternFieldIdent &field);
     417              :   void visit (StructPattern &pattern);
     418              :   // void visit(TupleStructItems& tuple_items);
     419              :   void visit (TupleStructItemsNoRest &tuple_items);
     420              :   void visit (TupleStructItemsHasRest &tuple_items);
     421              :   void visit (TupleStructPattern &pattern);
     422              :   // void visit(TuplePatternItems& tuple_items);
     423              :   void visit (TuplePatternItemsNoRest &tuple_items);
     424              :   void visit (TuplePatternItemsHasRest &tuple_items);
     425              :   void visit (TuplePattern &pattern);
     426              :   void visit (GroupedPattern &pattern);
     427              :   void visit (SlicePatternItemsNoRest &items);
     428              :   void visit (SlicePatternItemsHasRest &items);
     429              :   void visit (SlicePattern &pattern);
     430              :   void visit (AltPattern &pattern);
     431              : 
     432              :   // rust-stmt.h
     433              :   void visit (EmptyStmt &stmt);
     434              :   void visit (LetStmt &stmt);
     435              :   void visit (ExprStmt &stmt);
     436              : 
     437              :   // rust-type.h
     438              :   void visit (TraitBound &bound);
     439              :   void visit (ImplTraitType &type);
     440              :   void visit (TraitObjectType &type);
     441              :   void visit (ParenthesisedType &type);
     442              :   void visit (ImplTraitTypeOneBound &type);
     443              :   void visit (TraitObjectTypeOneBound &type);
     444              :   void visit (TupleType &type);
     445              :   void visit (NeverType &type);
     446              :   void visit (RawPointerType &type);
     447              :   void visit (ReferenceType &type);
     448              :   void visit (ArrayType &type);
     449              :   void visit (SliceType &type);
     450              :   void visit (InferredType &type);
     451              :   void visit (BareFunctionType &type);
     452              : 
     453              :   void visit (FormatArgs &fmt);
     454              :   void visit (OffsetOf &offset_of);
     455              : };
     456              : } // namespace AST
     457              : 
     458              : } // namespace Rust
     459              : 
     460              : #endif // !RUST_AST_COLLECTOR_H
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.