@@ -12,7 +12,8 @@ use hir_expand::ExpansionInfo;
1212use ra_db:: { FileId , FileRange } ;
1313use ra_prof:: profile;
1414use ra_syntax:: {
15- algo:: skip_trivia_token, ast, AstNode , Direction , SyntaxNode , SyntaxToken , TextRange , TextUnit ,
15+ algo:: { find_node_at_offset, skip_trivia_token} ,
16+ ast, AstNode , Direction , SyntaxNode , SyntaxToken , TextRange , TextUnit ,
1617} ;
1718use rustc_hash:: { FxHashMap , FxHashSet } ;
1819
@@ -108,6 +109,17 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
108109 token. value
109110 }
110111
112+ pub fn descend_node_at_offset < N : ast:: AstNode > (
113+ & self ,
114+ node : & SyntaxNode ,
115+ offset : TextUnit ,
116+ ) -> Option < N > {
117+ // Handle macro token cases
118+ node. token_at_offset ( offset)
119+ . map ( |token| self . descend_into_macros ( token) )
120+ . find_map ( |it| self . ancestors_with_macros ( it. parent ( ) ) . find_map ( N :: cast) )
121+ }
122+
111123 pub fn original_range ( & self , node : & SyntaxNode ) -> FileRange {
112124 let node = self . find_file ( node. clone ( ) ) ;
113125 original_range ( self . db , node. as_ref ( ) )
@@ -129,6 +141,8 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
129141 . kmerge_by ( |node1, node2| node1. text_range ( ) . len ( ) < node2. text_range ( ) . len ( ) )
130142 }
131143
144+ /// Find a AstNode by offset inside SyntaxNode, if it is inside *Macrofile*,
145+ /// search up until it is target AstNode type
132146 pub fn find_node_at_offset_with_macros < N : AstNode > (
133147 & self ,
134148 node : & SyntaxNode ,
@@ -137,6 +151,19 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
137151 self . ancestors_at_offset_with_macros ( node, offset) . find_map ( N :: cast)
138152 }
139153
154+ /// Find a AstNode by offset inside SyntaxNode, if it is inside *MacroCall*,
155+ /// descend it and find again
156+ pub fn find_node_at_offset_with_descend < N : AstNode > (
157+ & self ,
158+ node : & SyntaxNode ,
159+ offset : TextUnit ,
160+ ) -> Option < N > {
161+ if let Some ( it) = find_node_at_offset ( & node, offset) {
162+ return Some ( it) ;
163+ }
164+ self . descend_node_at_offset ( & node, offset)
165+ }
166+
140167 pub fn type_of_expr ( & self , expr : & ast:: Expr ) -> Option < Type > {
141168 self . analyze ( expr. syntax ( ) ) . type_of ( self . db , & expr)
142169 }
0 commit comments