ItemTree: Treat items in MacroStmts as top-level

This commit is contained in:
Jonas Schievink 2021-01-28 18:00:10 +01:00
parent f421ee6722
commit 2aebde6c0b
2 changed files with 32 additions and 4 deletions

View file

@ -98,15 +98,17 @@ impl ItemTree {
ctx.lower_module_items(&items) ctx.lower_module_items(&items)
}, },
ast::MacroStmts(stmts) => { ast::MacroStmts(stmts) => {
ctx.lower_inner_items(stmts.syntax()) // The produced statements can include items, which should be added as top-level
// items.
ctx.lower_macro_stmts(stmts)
}, },
// Macros can expand to expressions. We return an empty item tree in this case, but
// still need to collect inner items.
ast::Expr(e) => { ast::Expr(e) => {
// Macros can expand to expressions. We return an empty item tree in this case, but
// still need to collect inner items.
ctx.lower_inner_items(e.syntax()) ctx.lower_inner_items(e.syntax())
}, },
_ => { _ => {
panic!("cannot create item tree from {:?}", syntax); panic!("cannot create item tree from {:?} {}", syntax, syntax);
}, },
} }
}; };

View file

@ -61,6 +61,32 @@ impl Ctx {
self.tree self.tree
} }
pub(super) fn lower_macro_stmts(mut self, stmts: ast::MacroStmts) -> ItemTree {
self.tree.top_level = stmts
.statements()
.filter_map(|stmt| match stmt {
ast::Stmt::Item(item) => Some(item),
_ => None,
})
.flat_map(|item| self.lower_mod_item(&item, false))
.flat_map(|items| items.0)
.collect();
// Non-items need to have their inner items collected.
for stmt in stmts.statements() {
match stmt {
ast::Stmt::ExprStmt(_) | ast::Stmt::LetStmt(_) => {
self.collect_inner_items(stmt.syntax())
}
_ => {}
}
}
if let Some(expr) = stmts.expr() {
self.collect_inner_items(expr.syntax());
}
self.tree
}
pub(super) fn lower_inner_items(mut self, within: &SyntaxNode) -> ItemTree { pub(super) fn lower_inner_items(mut self, within: &SyntaxNode) -> ItemTree {
self.collect_inner_items(within); self.collect_inner_items(within);
self.tree self.tree