|
3 | 3 |
|
4 | 4 | use either::Either; |
5 | 5 |
|
6 | | -use hir_expand::name::{name, AsName, Name}; |
| 6 | +use hir_expand::{ |
| 7 | + name::{name, AsName, Name}, |
| 8 | + MacroDefId, MacroDefKind, |
| 9 | +}; |
7 | 10 | use ra_arena::Arena; |
8 | 11 | use ra_syntax::{ |
9 | 12 | ast::{ |
@@ -452,19 +455,30 @@ where |
452 | 455 | None => self.alloc_expr(Expr::Missing, syntax_ptr), |
453 | 456 | } |
454 | 457 | } |
455 | | - // FIXME expand to statements in statement position |
456 | 458 | ast::Expr::MacroCall(e) => { |
457 | | - let macro_call = self.expander.to_source(AstPtr::new(&e)); |
458 | | - match self.expander.enter_expand(self.db, e) { |
459 | | - Some((mark, expansion)) => { |
460 | | - self.source_map |
461 | | - .expansions |
462 | | - .insert(macro_call, self.expander.current_file_id); |
463 | | - let id = self.collect_expr(expansion); |
464 | | - self.expander.exit(self.db, mark); |
465 | | - id |
| 459 | + if let Some(name) = is_macro_rules(&e) { |
| 460 | + let mac = MacroDefId { |
| 461 | + krate: Some(self.expander.module.krate), |
| 462 | + ast_id: Some(self.expander.ast_id(&e)), |
| 463 | + kind: MacroDefKind::Declarative, |
| 464 | + }; |
| 465 | + self.body.item_scope.define_legacy_macro(name, mac); |
| 466 | + |
| 467 | + // FIXME: do we still need to allocate this as missing ? |
| 468 | + self.alloc_expr(Expr::Missing, syntax_ptr) |
| 469 | + } else { |
| 470 | + let macro_call = self.expander.to_source(AstPtr::new(&e)); |
| 471 | + match self.expander.enter_expand(self.db, Some(&self.body.item_scope), e) { |
| 472 | + Some((mark, expansion)) => { |
| 473 | + self.source_map |
| 474 | + .expansions |
| 475 | + .insert(macro_call, self.expander.current_file_id); |
| 476 | + let id = self.collect_expr(expansion); |
| 477 | + self.expander.exit(self.db, mark); |
| 478 | + id |
| 479 | + } |
| 480 | + None => self.alloc_expr(Expr::Missing, syntax_ptr), |
466 | 481 | } |
467 | | - None => self.alloc_expr(Expr::Missing, syntax_ptr), |
468 | 482 | } |
469 | 483 | } |
470 | 484 |
|
@@ -686,6 +700,16 @@ where |
686 | 700 | } |
687 | 701 | } |
688 | 702 |
|
| 703 | +fn is_macro_rules(m: &ast::MacroCall) -> Option<Name> { |
| 704 | + let name = m.path()?.segment()?.name_ref()?.as_name(); |
| 705 | + |
| 706 | + if name == name![macro_rules] { |
| 707 | + Some(m.name()?.as_name()) |
| 708 | + } else { |
| 709 | + None |
| 710 | + } |
| 711 | +} |
| 712 | + |
689 | 713 | impl From<ast::BinOp> for BinaryOp { |
690 | 714 | fn from(ast_op: ast::BinOp) -> Self { |
691 | 715 | match ast_op { |
|
0 commit comments