@@ -3,8 +3,7 @@ use std::iter;
3
3
use hir:: Semantics ;
4
4
use ide_db:: RootDatabase ;
5
5
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 ,
8
7
} ;
9
8
10
9
use crate :: FilePosition ;
@@ -28,16 +27,37 @@ pub struct ExpandedMacro {
28
27
pub ( crate ) fn expand_macro ( db : & RootDatabase , position : FilePosition ) -> Option < ExpandedMacro > {
29
28
let sema = Semantics :: new ( db) ;
30
29
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 ( ) ?;
33
30
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
+ }
35
55
36
56
// FIXME:
37
57
// macro expansion may lose all white space information
38
58
// 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 } )
41
61
}
42
62
43
63
fn expand_macro_recur (
0 commit comments