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 : : #include "rust-expand-visitor.h"
20 : : #include "rust-proc-macro.h"
21 : : #include "rust-attributes.h"
22 : : #include "rust-ast.h"
23 : : #include "rust-type.h"
24 : : #include "rust-derive.h"
25 : :
26 : : namespace Rust {
27 : :
28 : : bool
29 : 2768 : is_builtin (AST::Attribute &attr)
30 : : {
31 : 2768 : auto &segments = attr.get_path ().get_segments ();
32 : 2768 : return !segments.empty ()
33 : 2768 : && !Analysis::BuiltinAttributeMappings::get ()
34 : 2768 : ->lookup_builtin (segments[0].get_segment_name ())
35 : 2768 : .is_error ();
36 : : }
37 : :
38 : : /* Expand all of the macro invocations currently contained in a crate */
39 : : void
40 : 5280 : ExpandVisitor::go (AST::Crate &crate)
41 : : {
42 : 5280 : visit (crate);
43 : 5280 : }
44 : :
45 : : static std::unique_ptr<AST::Item>
46 : 24 : builtin_derive_item (AST::Item &item, const AST::Attribute &derive,
47 : : BuiltinMacro to_derive)
48 : : {
49 : 0 : return AST::DeriveVisitor::derive (item, derive, to_derive);
50 : : }
51 : :
52 : : static std::vector<std::unique_ptr<AST::Item>>
53 : 0 : derive_item (AST::Item &item, AST::SimplePath &to_derive,
54 : : MacroExpander &expander)
55 : : {
56 : 0 : std::vector<std::unique_ptr<AST::Item>> result;
57 : 0 : auto frag = expander.expand_derive_proc_macro (item, to_derive);
58 : 0 : if (!frag.is_error ())
59 : : {
60 : 0 : for (auto &node : frag.get_nodes ())
61 : : {
62 : 0 : switch (node.get_kind ())
63 : : {
64 : 0 : case AST::SingleASTNode::ITEM:
65 : 0 : result.push_back (node.take_item ());
66 : 0 : break;
67 : 0 : default:
68 : 0 : rust_unreachable ();
69 : : }
70 : : }
71 : : }
72 : 0 : return result;
73 : 0 : }
74 : :
75 : : static std::vector<std::unique_ptr<AST::Item>>
76 : 1 : expand_item_attribute (AST::Item &item, AST::SimplePath &name,
77 : : MacroExpander &expander)
78 : : {
79 : 1 : std::vector<std::unique_ptr<AST::Item>> result;
80 : 1 : auto frag = expander.expand_attribute_proc_macro (item, name);
81 : 1 : if (!frag.is_error ())
82 : : {
83 : 0 : for (auto &node : frag.get_nodes ())
84 : : {
85 : 0 : switch (node.get_kind ())
86 : : {
87 : 0 : case AST::SingleASTNode::ITEM:
88 : 0 : result.push_back (node.take_item ());
89 : 0 : break;
90 : 0 : default:
91 : 0 : rust_unreachable ();
92 : : }
93 : : }
94 : : }
95 : 1 : return result;
96 : 1 : }
97 : :
98 : : /* Helper function to expand a given attribute on a statement and collect back
99 : : * statements.
100 : : * T should be anything that can be used as a statement accepting outer
101 : : * attributes.
102 : : */
103 : : template <typename T>
104 : : static std::vector<std::unique_ptr<AST::Stmt>>
105 : 0 : expand_stmt_attribute (T &statement, AST::SimplePath &attribute,
106 : : MacroExpander &expander)
107 : : {
108 : 0 : std::vector<std::unique_ptr<AST::Stmt>> result;
109 : 0 : auto frag = expander.expand_attribute_proc_macro (statement, attribute);
110 : 0 : if (!frag.is_error ())
111 : : {
112 : 0 : for (auto &node : frag.get_nodes ())
113 : : {
114 : 0 : switch (node.get_kind ())
115 : : {
116 : 0 : case AST::SingleASTNode::STMT:
117 : 0 : result.push_back (node.take_stmt ());
118 : : break;
119 : 0 : default:
120 : 0 : rust_unreachable ();
121 : : }
122 : : }
123 : : }
124 : 0 : return result;
125 : 0 : }
126 : :
127 : : void
128 : 16948 : expand_tail_expr (AST::BlockExpr &block_expr, MacroExpander &expander)
129 : : {
130 : 16948 : if (block_expr.has_tail_expr ())
131 : : {
132 : 11928 : auto tail = block_expr.take_tail_expr ();
133 : 11928 : auto attrs = tail->get_outer_attrs ();
134 : 11928 : bool changed = false;
135 : 12140 : for (auto it = attrs.begin (); it != attrs.end ();)
136 : : {
137 : 212 : auto current = *it;
138 : 212 : if (is_builtin (current))
139 : : {
140 : 212 : it++;
141 : : }
142 : : else
143 : : {
144 : 0 : it = attrs.erase (it);
145 : 0 : changed = true;
146 : 0 : auto new_stmts
147 : : = expand_stmt_attribute (block_expr, current.get_path (),
148 : 0 : expander);
149 : 0 : auto &stmts = block_expr.get_statements ();
150 : 0 : std::move (new_stmts.begin (), new_stmts.end (),
151 : : std::inserter (stmts, stmts.end ()));
152 : 0 : }
153 : 212 : }
154 : 11928 : if (changed)
155 : 0 : block_expr.normalize_tail_expr ();
156 : : else
157 : 11928 : block_expr.set_tail_expr (std::move (tail));
158 : 11928 : }
159 : 16948 : }
160 : :
161 : : void
162 : 5280 : ExpandVisitor::expand_inner_items (
163 : : std::vector<std::unique_ptr<AST::Item>> &items)
164 : : {
165 : 5280 : expander.push_context (MacroExpander::ContextType::ITEM);
166 : :
167 : 24729 : for (auto it = items.begin (); it != items.end (); it++)
168 : : {
169 : 19449 : auto &item = *it;
170 : 19449 : if (item->has_outer_attrs ())
171 : : {
172 : 2486 : auto &attrs = item->get_outer_attrs ();
173 : :
174 : 5062 : for (auto attr_it = attrs.begin (); attr_it != attrs.end ();
175 : : /* erase => No increment*/)
176 : : {
177 : 2577 : auto current = *attr_it;
178 : :
179 : 2577 : if (current.is_derive ())
180 : : {
181 : 25 : current.parse_attr_to_meta_item ();
182 : 25 : attr_it = attrs.erase (attr_it);
183 : : // Get traits to derive in the current attribute
184 : 25 : auto traits_to_derive = current.get_traits_to_derive ();
185 : 49 : for (auto &to_derive : traits_to_derive)
186 : : {
187 : 24 : auto maybe_builtin = MacroBuiltin::builtins.lookup (
188 : 24 : to_derive.get ().as_string ());
189 : 24 : if (maybe_builtin.has_value ())
190 : : {
191 : 24 : auto new_item
192 : 24 : = builtin_derive_item (*item, current,
193 : 24 : maybe_builtin.value ());
194 : : // this inserts the derive *before* the item - is it a
195 : : // problem?
196 : 24 : it = items.insert (it, std::move (new_item));
197 : 24 : }
198 : : else
199 : : {
200 : 0 : auto new_items
201 : 0 : = derive_item (*item, to_derive, expander);
202 : 0 : std::move (new_items.begin (), new_items.end (),
203 : : std::inserter (items, it));
204 : 0 : }
205 : : }
206 : 25 : }
207 : : else /* Attribute */
208 : : {
209 : 2552 : if (is_builtin (current))
210 : : {
211 : 2551 : attr_it++;
212 : : }
213 : : else
214 : : {
215 : 1 : attr_it = attrs.erase (attr_it);
216 : 1 : auto new_items
217 : 1 : = expand_item_attribute (*item, current.get_path (),
218 : 1 : expander);
219 : 1 : it = items.erase (it);
220 : 1 : std::move (new_items.begin (), new_items.end (),
221 : : std::inserter (items, it));
222 : : // TODO: Improve this ?
223 : : // item is invalid since it refers to now deleted,
224 : : // cancel the loop increment and break.
225 : 1 : it--;
226 : 1 : break;
227 : 1 : }
228 : : }
229 : 2577 : }
230 : : }
231 : : }
232 : :
233 : 5280 : std::function<std::unique_ptr<AST::Item> (AST::SingleASTNode)> extractor
234 : 1633 : = [] (AST::SingleASTNode node) { return node.take_item (); };
235 : :
236 : 5280 : expand_macro_children (items, extractor);
237 : :
238 : 5280 : expander.pop_context ();
239 : 5280 : }
240 : :
241 : : void
242 : 16948 : ExpandVisitor::expand_inner_stmts (AST::BlockExpr &expr)
243 : : {
244 : 16948 : auto &stmts = expr.get_statements ();
245 : 16948 : expander.push_context (MacroExpander::ContextType::STMT);
246 : :
247 : 35939 : for (auto it = stmts.begin (); it != stmts.end (); it++)
248 : : {
249 : 18991 : auto &stmt = *it;
250 : :
251 : : // skip all non-item statements
252 : 18991 : if (stmt->get_stmt_kind () != AST::Stmt::Kind::Item)
253 : 18208 : continue;
254 : :
255 : 783 : auto &item = static_cast<AST::Item &> (*stmt.get ());
256 : :
257 : 783 : if (item.has_outer_attrs ())
258 : : {
259 : 4 : auto &attrs = item.get_outer_attrs ();
260 : :
261 : 8 : for (auto attr_it = attrs.begin (); attr_it != attrs.end ();
262 : : /* erase => No increment*/)
263 : : {
264 : 4 : auto current = *attr_it;
265 : :
266 : 4 : if (current.is_derive ())
267 : : {
268 : 0 : attr_it = attrs.erase (attr_it);
269 : : // Get traits to derive in the current attribute
270 : 0 : auto traits_to_derive = current.get_traits_to_derive ();
271 : 0 : for (auto &to_derive : traits_to_derive)
272 : : {
273 : 0 : auto maybe_builtin = MacroBuiltin::builtins.lookup (
274 : 0 : to_derive.get ().as_string ());
275 : 0 : if (maybe_builtin.has_value ())
276 : : {
277 : 0 : auto new_item
278 : : = builtin_derive_item (item, current,
279 : 0 : maybe_builtin.value ());
280 : : // this inserts the derive *before* the item - is it a
281 : : // problem?
282 : 0 : it = stmts.insert (it, std::move (new_item));
283 : 0 : }
284 : : else
285 : : {
286 : 0 : auto new_items
287 : 0 : = derive_item (item, to_derive, expander);
288 : 0 : std::move (new_items.begin (), new_items.end (),
289 : : std::inserter (stmts, it));
290 : 0 : }
291 : : }
292 : 0 : }
293 : : else /* Attribute */
294 : : {
295 : 4 : if (is_builtin (current))
296 : : {
297 : 4 : attr_it++;
298 : : }
299 : : else
300 : : {
301 : 0 : attr_it = attrs.erase (attr_it);
302 : 0 : auto new_items
303 : : = expand_stmt_attribute (item, current.get_path (),
304 : 0 : expander);
305 : 0 : it = stmts.erase (it);
306 : 0 : std::move (new_items.begin (), new_items.end (),
307 : : std::inserter (stmts, it));
308 : : // TODO: Improve this ?
309 : : // item is invalid since it refers to now deleted,
310 : : // cancel the loop increment and break.
311 : 0 : it--;
312 : 0 : break;
313 : 0 : }
314 : : }
315 : 4 : }
316 : : }
317 : : }
318 : :
319 : 16948 : if (!expr.has_tail_expr ())
320 : 5037 : expr.normalize_tail_expr ();
321 : :
322 : 16948 : std::function<std::unique_ptr<AST::Stmt> (AST::SingleASTNode)> extractor
323 : 373 : = [] (AST::SingleASTNode node) { return node.take_stmt (); };
324 : :
325 : 16948 : expand_macro_children (stmts, extractor);
326 : :
327 : 16948 : expander.pop_context ();
328 : 16948 : }
329 : :
330 : : void
331 : 1103448 : ExpandVisitor::maybe_expand_expr (std::unique_ptr<AST::Expr> &expr)
332 : : {
333 : 1103448 : expander.push_context (MacroExpander::ContextType::EXPR);
334 : 1103448 : expr->accept_vis (*this);
335 : 1103448 : expander.pop_context ();
336 : :
337 : 1103448 : auto final_fragment = expander.take_expanded_fragment ();
338 : 1103448 : if (final_fragment.should_expand ()
339 : 1103448 : && final_fragment.is_expression_fragment ())
340 : 1667 : expr = final_fragment.take_expression_fragment ();
341 : 1103448 : }
342 : :
343 : : void
344 : 27999 : ExpandVisitor::maybe_expand_type (std::unique_ptr<AST::Type> &type)
345 : : {
346 : 27999 : expander.push_context (MacroExpander::ContextType::TYPE);
347 : :
348 : 27999 : type->accept_vis (*this);
349 : 27999 : auto final_fragment = expander.take_expanded_fragment ();
350 : 27999 : if (final_fragment.should_expand () && final_fragment.is_type_fragment ())
351 : 19 : type = final_fragment.take_type_fragment ();
352 : :
353 : 27999 : expander.pop_context ();
354 : 27999 : }
355 : :
356 : : // FIXME: Can this be refactored into a `scoped` method? Which takes a
357 : : // ContextType as parameter and a lambda? And maybe just an std::vector<T>&?
358 : : void
359 : 1234 : ExpandVisitor::expand_struct_fields (std::vector<AST::StructField> &fields)
360 : : {
361 : 2978 : for (auto &field : fields)
362 : : {
363 : 1744 : maybe_expand_type (field.get_field_type_ptr ());
364 : : }
365 : 1234 : }
366 : :
367 : : void
368 : 1058 : ExpandVisitor::expand_tuple_fields (std::vector<AST::TupleField> &fields)
369 : : {
370 : 2753 : for (auto &field : fields)
371 : 1695 : maybe_expand_type (field.get_field_type_ptr ());
372 : 1058 : }
373 : :
374 : : // FIXME: This can definitely be refactored with the method above
375 : : void
376 : 14975 : ExpandVisitor::expand_function_params (
377 : : std::vector<std::unique_ptr<AST::Param>> ¶ms)
378 : : {
379 : 27763 : for (auto &p : params)
380 : 12788 : visit (p);
381 : 14975 : }
382 : :
383 : : void
384 : 650 : ExpandVisitor::expand_generic_args (AST::GenericArgs &args)
385 : : {
386 : 1340 : for (auto &arg : args.get_generic_args ())
387 : : {
388 : 690 : switch (arg.get_kind ())
389 : : {
390 : 305 : case AST::GenericArg::Kind::Type:
391 : 305 : maybe_expand_type (arg.get_type_ptr ());
392 : 305 : break;
393 : 0 : case AST::GenericArg::Kind::Const:
394 : 0 : maybe_expand_expr (arg.get_expression_ptr ());
395 : 0 : break;
396 : : default:
397 : : break;
398 : : // FIXME: Figure out what to do here if there is ambiguity. Since the
399 : : // resolver comes after the expansion, we need to figure out a way to
400 : : // strip ambiguous values here
401 : : // TODO: ARTHUR: Probably add a `mark_as_strip` method to `GenericArg`
402 : : // or something. This would clean up this whole thing
403 : : }
404 : : }
405 : :
406 : : // FIXME: Can we have macro invocations in generic type bindings?
407 : : // expand binding args - strip sub-types only
408 : : // FIXME: ARTHUR: This needs a test! Foo<Item = macro!()>
409 : 652 : for (auto &binding : args.get_binding_args ())
410 : 2 : maybe_expand_type (binding.get_type_ptr ());
411 : 650 : }
412 : :
413 : : void
414 : 326 : ExpandVisitor::expand_qualified_path_type (AST::QualifiedPathType &path_type)
415 : : {
416 : 326 : maybe_expand_type (path_type.get_type_ptr ());
417 : :
418 : : // FIXME: ARTHUR: Can we do macro expansion in there? Needs a test!
419 : 326 : if (path_type.has_as_clause ())
420 : 301 : path_type.get_as_type_path ().accept_vis (*this);
421 : 326 : }
422 : :
423 : : void
424 : 55 : ExpandVisitor::expand_closure_params (std::vector<AST::ClosureParam> ¶ms)
425 : : {
426 : 110 : for (auto ¶m : params)
427 : : {
428 : 55 : if (param.has_type_given ())
429 : 51 : maybe_expand_type (param.get_type_ptr ());
430 : : }
431 : 55 : }
432 : :
433 : : void
434 : 106 : ExpandVisitor::expand_where_clause (AST::WhereClause &where_clause)
435 : : {
436 : 215 : for (auto &item : where_clause.get_items ())
437 : 109 : visit (item);
438 : 106 : }
439 : :
440 : : void
441 : 5280 : ExpandVisitor::visit (AST::Crate &crate)
442 : : {
443 : 5280 : expand_inner_items (crate.items);
444 : 5280 : }
445 : :
446 : : void
447 : 0 : ExpandVisitor::visit (AST::DelimTokenTree &)
448 : 0 : {}
449 : :
450 : : void
451 : 0 : ExpandVisitor::visit (AST::AttrInputMetaItemContainer &)
452 : 0 : {}
453 : :
454 : : void
455 : 17252 : ExpandVisitor::visit (AST::IdentifierExpr &ident_expr)
456 : 17252 : {}
457 : :
458 : : void
459 : 211 : ExpandVisitor::visit (AST::LifetimeParam &)
460 : 211 : {}
461 : :
462 : : void
463 : 28 : ExpandVisitor::visit (AST::ConstGenericParam &)
464 : 28 : {}
465 : :
466 : : void
467 : 2277 : ExpandVisitor::visit (AST::MacroInvocation ¯o_invoc)
468 : : {
469 : : // TODO: Can we do the AST fragment replacing here? Probably not, right?
470 : 2277 : expander.expand_invoc (macro_invoc, macro_invoc.has_semicolon ());
471 : 2277 : }
472 : :
473 : : void
474 : 13074 : ExpandVisitor::visit (AST::PathInExpression &path)
475 : : {
476 : 29579 : for (auto &segment : path.get_segments ())
477 : 33010 : if (segment.has_generic_args ())
478 : 650 : expand_generic_args (segment.get_generic_args ());
479 : 13074 : }
480 : :
481 : : void
482 : 1760 : ExpandVisitor::visit (AST::TypePathSegmentGeneric &segment)
483 : 1760 : {}
484 : :
485 : : void
486 : 19 : ExpandVisitor::visit (AST::TypePathSegmentFunction &segment)
487 : : {
488 : 19 : auto &type_path_function = segment.get_type_path_function ();
489 : :
490 : 38 : for (auto &type : type_path_function.get_params ())
491 : 19 : visit (type);
492 : :
493 : 19 : if (type_path_function.has_return_type ())
494 : 17 : maybe_expand_type (type_path_function.get_return_type_ptr ());
495 : 19 : }
496 : :
497 : : void
498 : 88 : ExpandVisitor::visit (AST::QualifiedPathInExpression &path)
499 : : {
500 : 88 : expand_qualified_path_type (path.get_qualified_path_type ());
501 : :
502 : 176 : for (auto &segment : path.get_segments ())
503 : 176 : if (segment.has_generic_args ())
504 : 0 : expand_generic_args (segment.get_generic_args ());
505 : 88 : }
506 : :
507 : : void
508 : 238 : ExpandVisitor::visit (AST::QualifiedPathInType &path)
509 : : {
510 : 238 : expand_qualified_path_type (path.get_qualified_path_type ());
511 : :
512 : : // this shouldn't strip any segments, but can strip inside them
513 : 238 : for (auto &segment : path.get_segments ())
514 : 0 : visit (segment);
515 : 238 : }
516 : :
517 : : void
518 : 538769 : ExpandVisitor::visit (AST::LiteralExpr &expr)
519 : 538769 : {}
520 : :
521 : : void
522 : 0 : ExpandVisitor::visit (AST::AttrInputLiteral &)
523 : 0 : {}
524 : :
525 : : void
526 : 0 : ExpandVisitor::visit (AST::AttrInputMacro ¯o)
527 : : {
528 : 0 : rust_sorry_at (UNDEF_LOCATION, "macros in attributes not supported");
529 : 0 : }
530 : :
531 : : void
532 : 0 : ExpandVisitor::visit (AST::MetaItemLitExpr &)
533 : 0 : {}
534 : :
535 : : void
536 : 0 : ExpandVisitor::visit (AST::MetaItemPathLit &)
537 : 0 : {}
538 : :
539 : : void
540 : 0 : ExpandVisitor::visit (AST::ErrorPropagationExpr &expr)
541 : : {
542 : 0 : visit (expr.get_propagating_expr ());
543 : 0 : }
544 : :
545 : : void
546 : 527327 : ExpandVisitor::visit (AST::ArithmeticOrLogicalExpr &expr)
547 : : {
548 : 527327 : maybe_expand_expr (expr.get_left_expr_ptr ());
549 : 527327 : maybe_expand_expr (expr.get_right_expr_ptr ());
550 : 527327 : }
551 : :
552 : : void
553 : 1135 : ExpandVisitor::visit (AST::ComparisonExpr &expr)
554 : : {
555 : 1135 : maybe_expand_expr (expr.get_left_expr_ptr ());
556 : 1135 : maybe_expand_expr (expr.get_right_expr_ptr ());
557 : 1135 : }
558 : :
559 : : void
560 : 497 : ExpandVisitor::visit (AST::LazyBooleanExpr &expr)
561 : : {
562 : 497 : maybe_expand_expr (expr.get_left_expr_ptr ());
563 : 497 : maybe_expand_expr (expr.get_right_expr_ptr ());
564 : 497 : }
565 : :
566 : : void
567 : 1794 : ExpandVisitor::visit (AST::AssignmentExpr &expr)
568 : : {
569 : 1794 : maybe_expand_expr (expr.get_left_expr_ptr ());
570 : 1794 : maybe_expand_expr (expr.get_right_expr_ptr ());
571 : 1794 : }
572 : :
573 : : void
574 : 198 : ExpandVisitor::visit (AST::CompoundAssignmentExpr &expr)
575 : : {
576 : 198 : maybe_expand_expr (expr.get_left_expr_ptr ());
577 : 198 : maybe_expand_expr (expr.get_right_expr_ptr ());
578 : 198 : }
579 : :
580 : : void
581 : 198 : ExpandVisitor::visit (AST::GroupedExpr &expr)
582 : : {
583 : 198 : maybe_expand_expr (expr.get_expr_in_parens_ptr ());
584 : 198 : }
585 : :
586 : : void
587 : 51 : ExpandVisitor::visit (AST::StructExprStruct &expr)
588 : 51 : {}
589 : :
590 : : void
591 : 8387 : ExpandVisitor::visit (AST::CallExpr &expr)
592 : : {
593 : 8387 : visit (expr.get_function_expr ());
594 : :
595 : 18290 : for (auto ¶m : expr.get_params ())
596 : 9903 : maybe_expand_expr (param);
597 : 8387 : }
598 : :
599 : : void
600 : 1267 : ExpandVisitor::visit (AST::MethodCallExpr &expr)
601 : : {
602 : 1267 : visit (expr.get_receiver_expr ());
603 : :
604 : 1865 : for (auto ¶m : expr.get_params ())
605 : 598 : maybe_expand_expr (param);
606 : 1267 : }
607 : :
608 : : void
609 : 25 : ExpandVisitor::visit (AST::ClosureExprInner &expr)
610 : : {
611 : 25 : expand_closure_params (expr.get_params ());
612 : :
613 : 25 : visit (expr.get_definition_expr ());
614 : 25 : }
615 : :
616 : : void
617 : 16948 : ExpandVisitor::visit (AST::BlockExpr &expr)
618 : : {
619 : 16948 : expand_inner_stmts (expr);
620 : :
621 : 16948 : expand_tail_expr (expr, expander);
622 : 16948 : if (expr.has_tail_expr ())
623 : 11928 : maybe_expand_expr (expr.get_tail_expr_ptr ());
624 : 16948 : }
625 : :
626 : : void
627 : 30 : ExpandVisitor::visit (AST::ClosureExprInnerTyped &expr)
628 : : {
629 : 30 : expand_closure_params (expr.get_params ());
630 : :
631 : 30 : maybe_expand_type (expr.get_return_type_ptr ());
632 : :
633 : 30 : visit (expr.get_definition_block ());
634 : 30 : }
635 : :
636 : : void
637 : 10 : ExpandVisitor::visit (AST::ContinueExpr &expr)
638 : 10 : {}
639 : :
640 : : void
641 : 375 : ExpandVisitor::visit (AST::IfExpr &expr)
642 : : {
643 : 375 : maybe_expand_expr (expr.get_condition_expr_ptr ());
644 : :
645 : 375 : visit (expr.get_if_block ());
646 : 375 : }
647 : :
648 : : void
649 : 465 : ExpandVisitor::visit (AST::IfExprConseqElse &expr)
650 : : {
651 : 465 : maybe_expand_expr (expr.get_condition_expr_ptr ());
652 : :
653 : 465 : visit (expr.get_if_block ());
654 : 465 : visit (expr.get_else_block ());
655 : 465 : }
656 : :
657 : : void
658 : 1 : ExpandVisitor::visit (AST::IfLetExpr &expr)
659 : : {
660 : 1 : maybe_expand_expr (expr.get_value_expr_ptr ());
661 : :
662 : 1 : visit (expr.get_if_block ());
663 : 1 : }
664 : :
665 : : void
666 : 2 : ExpandVisitor::visit (AST::IfLetExprConseqElse &expr)
667 : : {
668 : 2 : maybe_expand_expr (expr.get_value_expr_ptr ());
669 : :
670 : 2 : visit (expr.get_if_block ());
671 : 2 : visit (expr.get_else_block ());
672 : 2 : }
673 : :
674 : : void
675 : 240 : ExpandVisitor::visit (AST::MatchExpr &expr)
676 : : {
677 : 240 : visit (expr.get_scrutinee_expr ());
678 : :
679 : 821 : for (auto &match_case : expr.get_match_cases ())
680 : : {
681 : 581 : auto &arm = match_case.get_arm ();
682 : :
683 : 1162 : for (auto &pattern : arm.get_patterns ())
684 : 581 : visit (pattern);
685 : :
686 : 581 : if (arm.has_match_arm_guard ())
687 : 2 : maybe_expand_expr (arm.get_guard_expr_ptr ());
688 : :
689 : 581 : maybe_expand_expr (match_case.get_expr_ptr ());
690 : : }
691 : 240 : }
692 : :
693 : : void
694 : 3511 : ExpandVisitor::visit (AST::TypeParam ¶m)
695 : : {
696 : 3888 : for (auto &bound : param.get_type_param_bounds ())
697 : 377 : visit (bound);
698 : :
699 : 3511 : if (param.has_type ())
700 : 145 : maybe_expand_type (param.get_type_ptr ());
701 : 3511 : }
702 : :
703 : : void
704 : 0 : ExpandVisitor::visit (AST::LifetimeWhereClauseItem &)
705 : 0 : {}
706 : :
707 : : void
708 : 109 : ExpandVisitor::visit (AST::TypeBoundWhereClauseItem &item)
709 : : {
710 : 109 : maybe_expand_type (item.get_type_ptr ());
711 : :
712 : 218 : for (auto &bound : item.get_type_param_bounds ())
713 : 109 : visit (bound);
714 : 109 : }
715 : :
716 : : void
717 : 8 : ExpandVisitor::visit (AST::ExternCrate &crate)
718 : 8 : {}
719 : :
720 : : void
721 : 0 : ExpandVisitor::visit (AST::UseTreeGlob &)
722 : 0 : {}
723 : :
724 : : void
725 : 0 : ExpandVisitor::visit (AST::UseTreeList &)
726 : 0 : {}
727 : :
728 : : void
729 : 0 : ExpandVisitor::visit (AST::UseTreeRebind &)
730 : 0 : {}
731 : :
732 : : void
733 : 176 : ExpandVisitor::visit (AST::UseDeclaration &use_decl)
734 : 176 : {}
735 : :
736 : : void
737 : 14975 : ExpandVisitor::visit (AST::Function &function)
738 : : {
739 : 14975 : if (function.has_body ())
740 : 11748 : visit_inner_using_attrs (
741 : 11748 : function, function.get_definition ().value ()->get_inner_attrs ());
742 : 16513 : for (auto ¶m : function.get_generic_params ())
743 : 1538 : visit (param);
744 : :
745 : 14975 : expand_function_params (function.get_function_params ());
746 : :
747 : 14975 : if (function.has_return_type ())
748 : 10106 : maybe_expand_type (function.get_return_type_ptr ());
749 : :
750 : 14975 : if (function.has_where_clause ())
751 : 14 : expand_where_clause (function.get_where_clause ());
752 : :
753 : 14975 : if (function.has_body ())
754 : 11748 : visit (*function.get_definition ());
755 : 14975 : }
756 : :
757 : : void
758 : 1089 : ExpandVisitor::visit (AST::StructStruct &struct_item)
759 : : {
760 : 1369 : for (auto &generic : struct_item.get_generic_params ())
761 : 280 : visit (generic);
762 : :
763 : 1089 : if (struct_item.has_where_clause ())
764 : 2 : expand_where_clause (struct_item.get_where_clause ());
765 : :
766 : 1089 : expand_struct_fields (struct_item.get_fields ());
767 : 1089 : }
768 : :
769 : : void
770 : 813 : ExpandVisitor::visit (AST::TupleStruct &tuple_struct)
771 : : {
772 : 1167 : for (auto &generic : tuple_struct.get_generic_params ())
773 : 354 : visit (generic);
774 : :
775 : 813 : if (tuple_struct.has_where_clause ())
776 : 0 : expand_where_clause (tuple_struct.get_where_clause ());
777 : :
778 : 813 : expand_tuple_fields (tuple_struct.get_fields ());
779 : 813 : }
780 : :
781 : : void
782 : 228 : ExpandVisitor::visit (AST::EnumItem &item)
783 : 228 : {}
784 : :
785 : : void
786 : 245 : ExpandVisitor::visit (AST::EnumItemTuple &item)
787 : : {
788 : 245 : expand_tuple_fields (item.get_tuple_fields ());
789 : 245 : }
790 : :
791 : : void
792 : 51 : ExpandVisitor::visit (AST::EnumItemStruct &item)
793 : : {
794 : 51 : expand_struct_fields (item.get_struct_fields ());
795 : 51 : }
796 : :
797 : : void
798 : 11 : ExpandVisitor::visit (AST::EnumItemDiscriminant &item)
799 : : {
800 : 11 : maybe_expand_expr (item.get_expr_ptr ());
801 : 11 : }
802 : :
803 : : void
804 : 94 : ExpandVisitor::visit (AST::Union &union_item)
805 : : {
806 : 160 : for (auto &generic : union_item.get_generic_params ())
807 : 66 : visit (generic);
808 : :
809 : 94 : expand_struct_fields (union_item.get_variants ());
810 : 94 : }
811 : :
812 : : void
813 : 473 : ExpandVisitor::visit (AST::ConstantItem &const_item)
814 : : {
815 : 473 : maybe_expand_type (const_item.get_type_ptr ());
816 : :
817 : 473 : if (const_item.has_expr ())
818 : 472 : maybe_expand_expr (const_item.get_expr_ptr ());
819 : 473 : }
820 : :
821 : : void
822 : 42 : ExpandVisitor::visit (AST::StaticItem &static_item)
823 : : {
824 : 42 : maybe_expand_type (static_item.get_type_ptr ());
825 : :
826 : 42 : maybe_expand_expr (static_item.get_expr_ptr ());
827 : 42 : }
828 : :
829 : : void
830 : 44 : ExpandVisitor::visit (AST::TraitItemConst &const_item)
831 : : {
832 : 44 : maybe_expand_type (const_item.get_type_ptr ());
833 : :
834 : 44 : if (const_item.has_expr ())
835 : 10 : maybe_expand_expr (const_item.get_expr_ptr ());
836 : 44 : }
837 : :
838 : : void
839 : 2431 : ExpandVisitor::visit (AST::Trait &trait)
840 : : {
841 : 2817 : for (auto &generic : trait.get_generic_params ())
842 : 386 : visit (generic);
843 : :
844 : 2715 : for (auto &bound : trait.get_type_param_bounds ())
845 : 284 : visit (bound);
846 : :
847 : 2431 : if (trait.has_where_clause ())
848 : 14 : expand_where_clause (trait.get_where_clause ());
849 : :
850 : 2431 : expander.push_context (MacroExpander::ContextType::TRAIT);
851 : :
852 : 2431 : std::function<std::unique_ptr<AST::AssociatedItem> (AST::SingleASTNode)>
853 : : extractor
854 : 2 : = [] (AST::SingleASTNode node) { return node.take_trait_item (); };
855 : :
856 : 2431 : expand_macro_children (MacroExpander::ContextType::TRAIT,
857 : : trait.get_trait_items (), extractor);
858 : :
859 : 2431 : expander.pop_context ();
860 : 2431 : }
861 : :
862 : : void
863 : 791 : ExpandVisitor::visit (AST::InherentImpl &impl)
864 : : {
865 : 1582 : visit_inner_attrs (impl);
866 : : // just expand sub-stuff - can't actually strip generic params themselves
867 : 1062 : for (auto &generic : impl.get_generic_params ())
868 : 271 : visit (generic);
869 : :
870 : : // FIXME: Is that correct? How do we test that?
871 : 791 : expander.push_context (MacroExpander::ContextType::ITEM);
872 : :
873 : 791 : maybe_expand_type (impl.get_type_ptr ());
874 : :
875 : 791 : expander.pop_context ();
876 : :
877 : 791 : if (impl.has_where_clause ())
878 : 1 : expand_where_clause (impl.get_where_clause ());
879 : :
880 : 791 : std::function<std::unique_ptr<AST::AssociatedItem> (AST::SingleASTNode)>
881 : 2 : extractor = [] (AST::SingleASTNode node) { return node.take_impl_item (); };
882 : :
883 : 791 : expand_macro_children (MacroExpander::ContextType::IMPL,
884 : : impl.get_impl_items (), extractor);
885 : 791 : }
886 : :
887 : : void
888 : 2875 : ExpandVisitor::visit (AST::TraitImpl &impl)
889 : : {
890 : 5750 : visit_inner_attrs (impl);
891 : : // just expand sub-stuff - can't actually strip generic params themselves
892 : 3557 : for (auto ¶m : impl.get_generic_params ())
893 : 682 : visit (param);
894 : :
895 : : // FIXME: Is that correct? How do we test that?
896 : 2875 : expander.push_context (MacroExpander::ContextType::ITEM);
897 : :
898 : 2875 : maybe_expand_type (impl.get_type_ptr ());
899 : :
900 : 2875 : expander.pop_context ();
901 : :
902 : 2875 : visit (impl.get_trait_path ());
903 : :
904 : 2875 : if (impl.has_where_clause ())
905 : 75 : expand_where_clause (impl.get_where_clause ());
906 : :
907 : 2875 : std::function<std::unique_ptr<AST::AssociatedItem> (AST::SingleASTNode)>
908 : : extractor
909 : 39 : = [] (AST::SingleASTNode node) { return node.take_trait_impl_item (); };
910 : :
911 : 2875 : expand_macro_children (MacroExpander::ContextType::TRAIT_IMPL,
912 : : impl.get_impl_items (), extractor);
913 : 2875 : }
914 : :
915 : : void
916 : 1 : ExpandVisitor::visit (AST::ExternalTypeItem &item)
917 : 1 : {}
918 : :
919 : : void
920 : 1 : ExpandVisitor::visit (AST::ExternalStaticItem &static_item)
921 : : {
922 : 1 : maybe_expand_type (static_item.get_type_ptr ());
923 : 1 : }
924 : :
925 : : void
926 : 1280 : ExpandVisitor::visit (AST::ExternBlock &block)
927 : : {
928 : 2560 : visit_inner_attrs (block);
929 : 1280 : std::function<std::unique_ptr<AST::ExternalItem> (AST::SingleASTNode)>
930 : : extractor
931 : 3 : = [] (AST::SingleASTNode node) { return node.take_external_item (); };
932 : :
933 : 1280 : expand_macro_children (MacroExpander::ContextType::EXTERN,
934 : : block.get_extern_items (), extractor);
935 : 1280 : }
936 : :
937 : : void
938 : 0 : ExpandVisitor::visit (AST::MacroMatchRepetition &)
939 : 0 : {}
940 : :
941 : : void
942 : 0 : ExpandVisitor::visit (AST::MacroMatcher &)
943 : 0 : {}
944 : :
945 : : void
946 : 2608 : ExpandVisitor::visit (AST::MacroRulesDefinition &rules_def)
947 : 2608 : {}
948 : :
949 : : void
950 : 0 : ExpandVisitor::visit (AST::MetaItemPath &)
951 : 0 : {}
952 : :
953 : : void
954 : 0 : ExpandVisitor::visit (AST::MetaItemSeq &)
955 : 0 : {}
956 : :
957 : : void
958 : 0 : ExpandVisitor::visit (AST::MetaListPaths &)
959 : 0 : {}
960 : :
961 : : void
962 : 0 : ExpandVisitor::visit (AST::MetaListNameValueStr &)
963 : 0 : {}
964 : :
965 : : void
966 : 63 : ExpandVisitor::visit (AST::StructPatternFieldIdent &field)
967 : 63 : {}
968 : :
969 : : void
970 : 1 : ExpandVisitor::visit (AST::GroupedPattern &pattern)
971 : : {
972 : 1 : visit (pattern.get_pattern_in_parens ());
973 : 1 : }
974 : :
975 : : void
976 : 11232 : ExpandVisitor::visit (AST::LetStmt &stmt)
977 : : {
978 : 11232 : visit (stmt.get_pattern ());
979 : :
980 : 11232 : if (stmt.has_type ())
981 : 1769 : maybe_expand_type (stmt.get_type_ptr ());
982 : :
983 : 11232 : if (stmt.has_init_expr ())
984 : 10114 : maybe_expand_expr (stmt.get_init_expr_ptr ());
985 : 11232 : }
986 : :
987 : : void
988 : 6844 : ExpandVisitor::visit (AST::ExprStmt &stmt)
989 : : {
990 : 6844 : maybe_expand_expr (stmt.get_expr_ptr ());
991 : 6844 : }
992 : :
993 : : void
994 : 39 : ExpandVisitor::visit (AST::BareFunctionType &type)
995 : : {
996 : 78 : for (auto ¶m : type.get_function_params ())
997 : : {
998 : 39 : maybe_expand_type (param.get_type_ptr ());
999 : : }
1000 : :
1001 : 39 : if (type.has_return_type ())
1002 : 35 : visit (type.get_return_type ());
1003 : 39 : }
1004 : :
1005 : : void
1006 : 7434 : ExpandVisitor::visit (AST::FunctionParam ¶m)
1007 : : {
1008 : 7434 : maybe_expand_type (param.get_type_ptr ());
1009 : 7434 : }
1010 : :
1011 : : void
1012 : 4467 : ExpandVisitor::visit (AST::SelfParam ¶m)
1013 : : {
1014 : : /* TODO: maybe check for invariants being violated - e.g. both type and
1015 : : * lifetime? */
1016 : 4467 : if (param.has_type ())
1017 : 1 : maybe_expand_type (param.get_type_ptr ());
1018 : 4467 : }
1019 : :
1020 : : template <typename T>
1021 : : void
1022 : 0 : ExpandVisitor::expand_inner_attribute (T &item, AST::SimplePath &path)
1023 : : {
1024 : : // FIXME: Retrieve path from segments + local use statements instead of string
1025 : 0 : expander.expand_attribute_proc_macro (item, path);
1026 : 0 : }
1027 : :
1028 : : template <typename T>
1029 : : void
1030 : 16694 : ExpandVisitor::visit_inner_using_attrs (T &item,
1031 : : std::vector<AST::Attribute> &attrs)
1032 : : {
1033 : 16694 : for (auto it = attrs.begin (); it != attrs.end (); /* erase => No increment*/)
1034 : : {
1035 : 0 : auto current = *it;
1036 : :
1037 : 0 : if (!is_builtin (current) && !current.is_derive ())
1038 : : {
1039 : 0 : it = attrs.erase (it);
1040 : 0 : expand_inner_attribute (item, current.get_path ());
1041 : : }
1042 : : else
1043 : : {
1044 : 0 : it++;
1045 : : }
1046 : : }
1047 : 16694 : }
1048 : :
1049 : : template <typename T>
1050 : : void
1051 : 1280 : ExpandVisitor::visit_inner_attrs (T &item)
1052 : : {
1053 : 4946 : visit_inner_using_attrs (item, item.get_inner_attrs ());
1054 : : }
1055 : :
1056 : : } // namespace Rust
|