@@ -12,7 +12,8 @@ use hir_expand::ExpansionInfo;
12
12
use ra_db:: { FileId , FileRange } ;
13
13
use ra_prof:: profile;
14
14
use 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 ,
16
17
} ;
17
18
use rustc_hash:: { FxHashMap , FxHashSet } ;
18
19
@@ -108,6 +109,17 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
108
109
token. value
109
110
}
110
111
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
+
111
123
pub fn original_range ( & self , node : & SyntaxNode ) -> FileRange {
112
124
let node = self . find_file ( node. clone ( ) ) ;
113
125
original_range ( self . db , node. as_ref ( ) )
@@ -129,6 +141,8 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
129
141
. kmerge_by ( |node1, node2| node1. text_range ( ) . len ( ) < node2. text_range ( ) . len ( ) )
130
142
}
131
143
144
+ /// Find a AstNode by offset inside SyntaxNode, if it is inside *Macrofile*,
145
+ /// search up until it is target AstNode type
132
146
pub fn find_node_at_offset_with_macros < N : AstNode > (
133
147
& self ,
134
148
node : & SyntaxNode ,
@@ -137,6 +151,19 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
137
151
self . ancestors_at_offset_with_macros ( node, offset) . find_map ( N :: cast)
138
152
}
139
153
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
+
140
167
pub fn type_of_expr ( & self , expr : & ast:: Expr ) -> Option < Type > {
141
168
self . analyze ( expr. syntax ( ) ) . type_of ( self . db , & expr)
142
169
}
0 commit comments