@@ -34,11 +34,9 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<
34
34
let mut name = None ;
35
35
for node in tok. ancestors ( ) {
36
36
if let Some ( item) = ast:: Item :: cast ( node. clone ( ) ) {
37
- expanded = sema. expand_attr_macro ( & item) ;
38
- if expanded. is_some ( ) {
39
- // FIXME: add the macro name
40
- // FIXME: make this recursive too
41
- name = Some ( "?" . to_string ( ) ) ;
37
+ if let Some ( def) = sema. resolve_attr_macro_call ( & item) {
38
+ name = def. name ( db) . map ( |name| name. to_string ( ) ) ;
39
+ expanded = expand_attr_macro_recur ( & sema, & item) ;
42
40
break ;
43
41
}
44
42
}
@@ -54,20 +52,33 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<
54
52
// macro expansion may lose all white space information
55
53
// But we hope someday we can use ra_fmt for that
56
54
let expansion = insert_whitespaces ( expanded?) ;
57
- Some ( ExpandedMacro { name : name? , expansion } )
55
+ Some ( ExpandedMacro { name : name. unwrap_or_else ( || "???" . to_owned ( ) ) , expansion } )
58
56
}
59
57
60
58
fn expand_macro_recur (
61
59
sema : & Semantics < RootDatabase > ,
62
60
macro_call : & ast:: MacroCall ,
63
61
) -> Option < SyntaxNode > {
64
62
let expanded = sema. expand ( macro_call) ?. clone_for_update ( ) ;
63
+ expand ( sema, expanded, ast:: MacroCall :: cast, expand_macro_recur)
64
+ }
65
+
66
+ fn expand_attr_macro_recur ( sema : & Semantics < RootDatabase > , item : & ast:: Item ) -> Option < SyntaxNode > {
67
+ let expanded = sema. expand_attr_macro ( item) ?. clone_for_update ( ) ;
68
+ expand ( sema, expanded, ast:: Item :: cast, expand_attr_macro_recur)
69
+ }
65
70
66
- let children = expanded. descendants ( ) . filter_map ( ast:: MacroCall :: cast) ;
71
+ fn expand < T : AstNode > (
72
+ sema : & Semantics < RootDatabase > ,
73
+ expanded : SyntaxNode ,
74
+ f : impl FnMut ( SyntaxNode ) -> Option < T > ,
75
+ exp : impl Fn ( & Semantics < RootDatabase > , & T ) -> Option < SyntaxNode > ,
76
+ ) -> Option < SyntaxNode > {
77
+ let children = expanded. descendants ( ) . filter_map ( f) ;
67
78
let mut replacements = Vec :: new ( ) ;
68
79
69
80
for child in children {
70
- if let Some ( new_node) = expand_macro_recur ( sema, & child) {
81
+ if let Some ( new_node) = exp ( sema, & child) {
71
82
// check if the whole original syntax is replaced
72
83
if expanded == * child. syntax ( ) {
73
84
return Some ( new_node) ;
0 commit comments