Skip to content

Commit 33e747d

Browse files
Make "expand macro" command work with attribute macros
1 parent 8d87f9b commit 33e747d

File tree

2 files changed

+43
-7
lines changed

2 files changed

+43
-7
lines changed

crates/hir/src/semantics.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,12 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
117117
pub fn expand(&self, macro_call: &ast::MacroCall) -> Option<SyntaxNode> {
118118
self.imp.expand(macro_call)
119119
}
120+
121+
/// If `item` has an attribute macro attached to it, expands it.
122+
pub fn expand_attr_macro(&self, item: &ast::Item) -> Option<SyntaxNode> {
123+
self.imp.expand_attr_macro(item)
124+
}
125+
120126
pub fn speculative_expand(
121127
&self,
122128
actual_macro_call: &ast::MacroCall,
@@ -332,6 +338,16 @@ impl<'db> SemanticsImpl<'db> {
332338
Some(node)
333339
}
334340

341+
fn expand_attr_macro(&self, item: &ast::Item) -> Option<SyntaxNode> {
342+
let sa = self.analyze(item.syntax());
343+
let src = InFile::new(sa.file_id, item.clone());
344+
let macro_call_id = self.with_ctx(|ctx| ctx.item_to_macro_call(src))?;
345+
let file_id = macro_call_id.as_file();
346+
let node = self.db.parse_or_expand(file_id)?;
347+
self.cache(node.clone(), file_id);
348+
Some(node)
349+
}
350+
335351
fn speculative_expand(
336352
&self,
337353
actual_macro_call: &ast::MacroCall,

crates/ide/src/expand_macro.rs

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ use std::iter;
33
use hir::Semantics;
44
use ide_db::RootDatabase;
55
use syntax::{
6-
algo::find_node_at_offset, ast, ted, AstNode, NodeOrToken, SyntaxKind, SyntaxKind::*,
7-
SyntaxNode, WalkEvent, T,
6+
ast, match_ast, ted, AstNode, NodeOrToken, SyntaxKind, SyntaxKind::*, SyntaxNode, WalkEvent, T,
87
};
98

109
use crate::FilePosition;
@@ -28,16 +27,37 @@ pub struct ExpandedMacro {
2827
pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<ExpandedMacro> {
2928
let sema = Semantics::new(db);
3029
let file = sema.parse(position.file_id);
31-
let mac = find_node_at_offset::<ast::MacroCall>(file.syntax(), position.offset)?;
32-
let name = mac.path()?.segment()?.name_ref()?;
3330

34-
let expanded = expand_macro_recur(&sema, &mac)?;
31+
let tok = file.syntax().token_at_offset(position.offset).left_biased()?;
32+
let mut expanded = None;
33+
let mut name = None;
34+
for node in tok.ancestors() {
35+
match_ast! {
36+
match node {
37+
ast::MacroCall(mac) => {
38+
name = Some(mac.path()?.segment()?.name_ref()?.to_string());
39+
expanded = expand_macro_recur(&sema, &mac);
40+
break;
41+
},
42+
ast::Item(item) => {
43+
// FIXME: add the macro name
44+
// FIXME: make this recursive too
45+
name = Some("?".to_string());
46+
expanded = sema.expand_attr_macro(&item);
47+
if expanded.is_some() {
48+
break;
49+
}
50+
},
51+
_ => {}
52+
}
53+
}
54+
}
3555

3656
// FIXME:
3757
// macro expansion may lose all white space information
3858
// But we hope someday we can use ra_fmt for that
39-
let expansion = insert_whitespaces(expanded);
40-
Some(ExpandedMacro { name: name.to_string(), expansion })
59+
let expansion = insert_whitespaces(expanded?);
60+
Some(ExpandedMacro { name: name?, expansion })
4161
}
4262

4363
fn expand_macro_recur(

0 commit comments

Comments
 (0)