Branch data Line data Source code
1 : : // Copyright (C) 2020-2024 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 : :
27 : : namespace Rust {
28 : : namespace AST {
29 : :
30 : : class CollectItem
31 : : {
32 : : public:
33 : : enum class Kind
34 : : {
35 : : Comment,
36 : : Newline,
37 : : Indentation,
38 : : Token,
39 : : };
40 : :
41 : 54467 : CollectItem (TokenPtr token) : token (token), kind (Kind::Token) {}
42 : 675 : CollectItem (std::string comment) : comment (comment), kind (Kind::Comment) {}
43 : 11990 : CollectItem (Kind kind) : kind (kind) { rust_assert (kind != Kind::Token); }
44 : 7777 : CollectItem (size_t level) : indent_level (level), kind (Kind::Indentation) {}
45 : :
46 : 74909 : Kind get_kind () { return kind; }
47 : :
48 : 54467 : TokenPtr get_token ()
49 : : {
50 : 54467 : rust_assert (kind == Kind::Token);
51 : 54467 : return token;
52 : : }
53 : :
54 : 675 : std::string get_comment ()
55 : : {
56 : 675 : rust_assert (kind == Kind::Comment);
57 : 675 : return comment;
58 : : }
59 : :
60 : 17962 : size_t get_indent_level ()
61 : : {
62 : 17962 : rust_assert (kind == Kind::Indentation);
63 : 17962 : return indent_level;
64 : : }
65 : :
66 : : private:
67 : : TokenPtr token;
68 : : std::string comment;
69 : : size_t indent_level;
70 : : Kind kind;
71 : : };
72 : :
73 : 2056 : class TokenCollector : public ASTVisitor
74 : : {
75 : : public:
76 : 2056 : TokenCollector () : indent_level (0) {}
77 : :
78 : : bool output_trailing_commas = false;
79 : :
80 : : void visit (AST::Crate &crate);
81 : : void visit (AST::Item &item);
82 : :
83 : : std::vector<TokenPtr> collect_tokens () const;
84 : : std::vector<CollectItem> collect () const;
85 : :
86 : : private:
87 : : std::vector<CollectItem> tokens;
88 : : size_t indent_level;
89 : :
90 : 108934 : void push (TokenPtr token) { tokens.push_back ({token}); }
91 : :
92 : : /**
93 : : * Visit all items in given @collection, placing the separator in between but
94 : : * not at the end.
95 : : */
96 : : template <typename T>
97 : 8474 : void visit_items_joined_by_separator (T &collection,
98 : : TokenId separator = COMMA,
99 : : size_t start_offset = 0,
100 : : size_t end_offset = 0)
101 : : {
102 : 8474 : if (collection.size () > start_offset)
103 : : {
104 : 7152 : visit (collection.at (start_offset));
105 : 7152 : auto size = collection.size () - end_offset;
106 : 8688 : for (size_t i = start_offset + 1; i < size; i++)
107 : : {
108 : 3072 : push (Rust::Token::make (separator, UNDEF_LOCATION));
109 : 1536 : visit (collection.at (i));
110 : : }
111 : : }
112 : 8474 : }
113 : :
114 : : /**
115 : : * Visit item placing end of line after.
116 : : */
117 : : template <typename T>
118 : 3198 : void visit_as_line (T &item, std::vector<TokenPtr> trailing = {})
119 : : {
120 : 3198 : indentation ();
121 : 3198 : visit (item);
122 : 3214 : for (auto &token : trailing)
123 : 32 : push (token);
124 : 3198 : newline ();
125 : 3198 : }
126 : :
127 : : /**
128 : : * Visit each item in @collection "as line".
129 : : *
130 : : * @see visit_as_line
131 : : */
132 : : template <typename T>
133 : 6826 : void visit_items_as_lines (T &collection, std::vector<TokenPtr> trailing = {})
134 : : {
135 : 10024 : for (auto &item : collection)
136 : 3198 : visit_as_line (item, trailing);
137 : 6826 : }
138 : :
139 : : /**
140 : : * Visit each item in @collection as lines inside a block delimited by braces
141 : : * with increased indentation. Also includes special handling for empty
142 : : * collection to print only the delimiters with no new line inside.
143 : : */
144 : : template <typename T>
145 : 2027 : void visit_items_as_block (T &collection, std::vector<TokenPtr> trailing = {},
146 : : TokenId left_brace = LEFT_CURLY,
147 : : TokenId right_brace = RIGHT_CURLY)
148 : : {
149 : 4054 : push (Rust::Token::make (left_brace, UNDEF_LOCATION));
150 : 2027 : if (collection.empty ())
151 : : {
152 : 1144 : push (Rust::Token::make (right_brace, UNDEF_LOCATION));
153 : 1144 : newline ();
154 : : }
155 : : else
156 : : {
157 : 883 : newline ();
158 : 883 : increment_indentation ();
159 : 883 : visit_items_as_lines (collection, trailing);
160 : 883 : decrement_indentation ();
161 : 883 : indentation ();
162 : 883 : push (Rust::Token::make (right_brace, UNDEF_LOCATION));
163 : 883 : newline ();
164 : : }
165 : 2027 : }
166 : :
167 : : void trailing_comma ();
168 : : void newline ();
169 : : void indentation ();
170 : : void increment_indentation ();
171 : : void decrement_indentation ();
172 : : void comment (std::string comment);
173 : : /**
174 : : * Visit common items of functions: Parameters, return type, block
175 : : */
176 : : void visit_function_common (std::unique_ptr<Type> &return_type,
177 : : std::unique_ptr<BlockExpr> &block);
178 : :
179 : : void visit_closure_common (ClosureExpr &expr);
180 : :
181 : : void visit_loop_common (BaseLoopExpr &expr);
182 : :
183 : : public:
184 : : /**
185 : : * Compatibility layer for using the visitor pattern on polymorphic classes
186 : : * with a unified overload syntax. This allows us to call `visit` both on
187 : : * types implementing `accept_vis` method and for classes for which the
188 : : * `visit` method is directly implemented.
189 : : */
190 : 9780 : template <typename T> void visit (std::unique_ptr<T> &node)
191 : : {
192 : 9780 : node->accept_vis (*this);
193 : 583 : }
194 : :
195 : : /**
196 : : * @see visit<std::unique_ptr<T>>
197 : : */
198 : 9478 : template <typename T> void visit (T &node) { node.accept_vis (*this); }
199 : :
200 : : void visit (Visitable &v);
201 : : void visit (LoopLabel &label);
202 : :
203 : : void visit (Literal &lit, location_t locus = UNDEF_LOCATION);
204 : :
205 : : void visit (FunctionParam ¶m);
206 : : void visit (VariadicParam ¶m);
207 : : void visit (Attribute &attrib);
208 : : void visit (Visibility &vis);
209 : : void visit (std::vector<std::unique_ptr<GenericParam>> ¶ms);
210 : : void visit (TupleField &field);
211 : : void visit (StructField &field);
212 : : void visit (SimplePathSegment &segment);
213 : : void visit (NamedFunctionParam ¶m);
214 : : void visit (MacroRule &rule);
215 : : void visit (WhereClause &rule);
216 : : void visit (std::vector<LifetimeParam> &for_lifetimes);
217 : : void visit (FunctionQualifiers &qualifiers);
218 : : void visit (MaybeNamedParam ¶m);
219 : : void visit (TypePathFunction &type_path_fn);
220 : : void visit (GenericArgsBinding &binding);
221 : : void visit (GenericArg &arg);
222 : :
223 : : // rust-ast.h
224 : : void visit (Token &tok);
225 : : void visit (DelimTokenTree &delim_tok_tree);
226 : : void visit (AttrInputMetaItemContainer &input);
227 : : void visit (IdentifierExpr &ident_expr);
228 : : void visit (Lifetime &lifetime);
229 : : void visit (LifetimeParam &lifetime_param);
230 : : void visit (ConstGenericParam &const_param);
231 : :
232 : : // rust-path.h
233 : : void visit (SimplePath &path);
234 : : void visit (PathExprSegment &segment);
235 : : void visit (PathIdentSegment &segment);
236 : : void visit (PathInExpression &path);
237 : : void visit (TypePathSegment &segment);
238 : : void visit (TypePathSegmentGeneric &segment);
239 : : void visit (TypePathSegmentFunction &segment);
240 : : void visit (TypePath &path);
241 : : void visit (QualifiedPathType &path);
242 : : void visit (QualifiedPathInExpression &path);
243 : : void visit (QualifiedPathInType &path);
244 : :
245 : : // rust-expr.h
246 : : void visit (LiteralExpr &expr);
247 : : void visit (AttrInputLiteral &attr_input);
248 : : void visit (AttrInputMacro &attr_input);
249 : : void visit (MetaItemLitExpr &meta_item);
250 : : void visit (MetaItemPathLit &meta_item);
251 : : void visit (BorrowExpr &expr);
252 : : void visit (DereferenceExpr &expr);
253 : : void visit (ErrorPropagationExpr &expr);
254 : : void visit (NegationExpr &expr);
255 : : void visit (ArithmeticOrLogicalExpr &expr);
256 : : void visit (ComparisonExpr &expr);
257 : : void visit (LazyBooleanExpr &expr);
258 : : void visit (TypeCastExpr &expr);
259 : : void visit (AssignmentExpr &expr);
260 : : void visit (CompoundAssignmentExpr &expr);
261 : : void visit (GroupedExpr &expr);
262 : : void visit (ArrayElemsValues &elems);
263 : : void visit (ArrayElemsCopied &elems);
264 : : void visit (ArrayExpr &expr);
265 : : void visit (ArrayIndexExpr &expr);
266 : : void visit (TupleExpr &expr);
267 : : void visit (TupleIndexExpr &expr);
268 : : void visit (StructExprStruct &expr);
269 : : void visit (StructExprFieldIdentifier &field);
270 : : void visit (StructExprFieldIdentifierValue &field);
271 : : void visit (StructExprFieldIndexValue &field);
272 : : void visit (StructBase &base);
273 : : void visit (StructExprStructFields &expr);
274 : : void visit (StructExprStructBase &expr);
275 : : void visit (CallExpr &expr);
276 : : void visit (MethodCallExpr &expr);
277 : : void visit (FieldAccessExpr &expr);
278 : : void visit (ClosureParam ¶m);
279 : : void visit (ClosureExprInner &expr);
280 : : void visit (BlockExpr &expr);
281 : : void visit (ClosureExprInnerTyped &expr);
282 : : void visit (ContinueExpr &expr);
283 : : void visit (BreakExpr &expr);
284 : : void visit (RangeFromToExpr &expr);
285 : : void visit (RangeFromExpr &expr);
286 : : void visit (RangeToExpr &expr);
287 : : void visit (RangeFullExpr &expr);
288 : : void visit (RangeFromToInclExpr &expr);
289 : : void visit (RangeToInclExpr &expr);
290 : : void visit (ReturnExpr &expr);
291 : : void visit (UnsafeBlockExpr &expr);
292 : : void visit (LoopExpr &expr);
293 : : void visit (WhileLoopExpr &expr);
294 : : void visit (WhileLetLoopExpr &expr);
295 : : void visit (ForLoopExpr &expr);
296 : : void visit (IfExpr &expr);
297 : : void visit (IfExprConseqElse &expr);
298 : : void visit (IfLetExpr &expr);
299 : : void visit (IfLetExprConseqElse &expr);
300 : : void visit (MatchArm &arm);
301 : : void visit (MatchCase &arm);
302 : : void visit (MatchExpr &expr);
303 : : void visit (AwaitExpr &expr);
304 : : void visit (AsyncBlockExpr &expr);
305 : :
306 : : // rust-item.h
307 : : void visit (TypeParam ¶m);
308 : : void visit (LifetimeWhereClauseItem &item);
309 : : void visit (TypeBoundWhereClauseItem &item);
310 : : void visit (Module &module);
311 : : void visit (ExternCrate &crate);
312 : : void visit (UseTreeGlob &use_tree);
313 : : void visit (UseTreeList &use_tree);
314 : : void visit (UseTreeRebind &use_tree);
315 : : void visit (UseDeclaration &use_decl);
316 : : void visit (Function &function);
317 : : void visit (TypeAlias &type_alias);
318 : : void visit (StructStruct &struct_item);
319 : : void visit (TupleStruct &tuple_struct);
320 : : void visit (EnumItem &item);
321 : : void visit (EnumItemTuple &item);
322 : : void visit (EnumItemStruct &item);
323 : : void visit (EnumItemDiscriminant &item);
324 : : void visit (Enum &enumeration);
325 : : void visit (Union &union_item);
326 : : void visit (ConstantItem &const_item);
327 : : void visit (StaticItem &static_item);
328 : : void visit (SelfParam ¶m);
329 : : void visit (TraitItemConst &item);
330 : : void visit (TraitItemType &item);
331 : : void visit (Trait &trait);
332 : : void visit (InherentImpl &impl);
333 : : void visit (TraitImpl &impl);
334 : : void visit (ExternalTypeItem &item);
335 : : void visit (ExternalStaticItem &item);
336 : : void visit (ExternBlock &block);
337 : :
338 : : // rust-macro.h
339 : : void visit (MacroMatchFragment &match);
340 : : void visit (MacroMatchRepetition &match);
341 : : void visit (MacroMatcher &matcher);
342 : : void visit (MacroRulesDefinition &rules_def);
343 : : void visit (MacroInvocData &invoc_data);
344 : : void visit (MacroInvocation ¯o_invoc);
345 : : void visit (MetaItemPath &meta_item);
346 : : void visit (MetaItemSeq &meta_item);
347 : : void visit (MetaWord &meta_item);
348 : : void visit (MetaNameValueStr &meta_item);
349 : : void visit (MetaListPaths &meta_item);
350 : : void visit (MetaListNameValueStr &meta_item);
351 : :
352 : : // rust-pattern.h
353 : : void visit (LiteralPattern &pattern);
354 : : void visit (IdentifierPattern &pattern);
355 : : void visit (WildcardPattern &pattern);
356 : : void visit (RestPattern &pattern);
357 : : // void visit(RangePatternBound& bound);
358 : : void visit (RangePatternBoundLiteral &bound);
359 : : void visit (RangePatternBoundPath &bound);
360 : : void visit (RangePatternBoundQualPath &bound);
361 : : void visit (RangePattern &pattern);
362 : : void visit (ReferencePattern &pattern);
363 : : // void visit(StructPatternField& field);
364 : : void visit (StructPatternFieldTuplePat &field);
365 : : void visit (StructPatternFieldIdentPat &field);
366 : : void visit (StructPatternFieldIdent &field);
367 : : void visit (StructPattern &pattern);
368 : : // void visit(TupleStructItems& tuple_items);
369 : : void visit (TupleStructItemsNoRange &tuple_items);
370 : : void visit (TupleStructItemsRange &tuple_items);
371 : : void visit (TupleStructPattern &pattern);
372 : : // void visit(TuplePatternItems& tuple_items);
373 : : void visit (TuplePatternItemsMultiple &tuple_items);
374 : : void visit (TuplePatternItemsRanged &tuple_items);
375 : : void visit (TuplePattern &pattern);
376 : : void visit (GroupedPattern &pattern);
377 : : void visit (SlicePattern &pattern);
378 : : void visit (AltPattern &pattern);
379 : :
380 : : // rust-stmt.h
381 : : void visit (EmptyStmt &stmt);
382 : : void visit (LetStmt &stmt);
383 : : void visit (ExprStmt &stmt);
384 : :
385 : : // rust-type.h
386 : : void visit (TraitBound &bound);
387 : : void visit (ImplTraitType &type);
388 : : void visit (TraitObjectType &type);
389 : : void visit (ParenthesisedType &type);
390 : : void visit (ImplTraitTypeOneBound &type);
391 : : void visit (TraitObjectTypeOneBound &type);
392 : : void visit (TupleType &type);
393 : : void visit (NeverType &type);
394 : : void visit (RawPointerType &type);
395 : : void visit (ReferenceType &type);
396 : : void visit (ArrayType &type);
397 : : void visit (SliceType &type);
398 : : void visit (InferredType &type);
399 : : void visit (BareFunctionType &type);
400 : :
401 : : void visit (FormatArgs &fmt);
402 : : };
403 : : } // namespace AST
404 : :
405 : : } // namespace Rust
406 : :
407 : : #endif // !RUST_AST_COLLECTOR_H
|