@@ -13,6 +13,7 @@ mod classify;
13
13
mod rename;
14
14
mod search_scope;
15
15
16
+ use crate :: expand:: descend_into_macros_with_analyzer;
16
17
use hir:: { InFile , SourceBinder } ;
17
18
use once_cell:: unsync:: Lazy ;
18
19
use ra_db:: { SourceDatabase , SourceDatabaseExt } ;
@@ -192,39 +193,62 @@ fn process_definition(
192
193
193
194
let parse = Lazy :: new ( || SourceFile :: parse ( & text) ) ;
194
195
let mut sb = Lazy :: new ( || SourceBinder :: new ( db) ) ;
196
+ let mut analyzer = None ;
195
197
196
198
for ( idx, _) in text. match_indices ( pat) {
197
199
let offset = TextUnit :: from_usize ( idx) ;
198
200
199
- if let Some ( name_ref) =
201
+ let ( name_ref , range ) = if let Some ( name_ref) =
200
202
find_node_at_offset :: < ast:: NameRef > ( parse. tree ( ) . syntax ( ) , offset)
201
203
{
202
204
let range = name_ref. syntax ( ) . text_range ( ) ;
203
- if let Some ( search_range) = search_range {
204
- if !range. is_subrange ( & search_range) {
205
- continue ;
206
- }
205
+ ( InFile :: new ( file_id. into ( ) , name_ref) , range)
206
+ } else {
207
+ // Handle macro token cases
208
+ let t = match parse. tree ( ) . syntax ( ) . token_at_offset ( offset) {
209
+ TokenAtOffset :: None => continue ,
210
+ TokenAtOffset :: Single ( t) => t,
211
+ TokenAtOffset :: Between ( _, t) => t,
212
+ } ;
213
+ let range = t. text_range ( ) ;
214
+ let analyzer = analyzer. get_or_insert_with ( || {
215
+ sb. analyze ( InFile :: new ( file_id. into ( ) , parse. tree ( ) . syntax ( ) ) , None )
216
+ } ) ;
217
+ let expanded = descend_into_macros_with_analyzer (
218
+ db,
219
+ & analyzer,
220
+ InFile :: new ( file_id. into ( ) , t) ,
221
+ ) ;
222
+ if let Some ( token) = ast:: NameRef :: cast ( expanded. value . parent ( ) ) {
223
+ ( expanded. with_value ( token) , range)
224
+ } else {
225
+ continue ;
207
226
}
208
- // FIXME: reuse sb
209
- // See https://github.com/rust-lang/rust/pull/68198#issuecomment-574269098
210
-
211
- if let Some ( d) = classify_name_ref ( & mut sb, InFile :: new ( file_id. into ( ) , & name_ref) )
212
- {
213
- if d == def {
214
- let kind = if is_record_lit_name_ref ( & name_ref)
215
- || is_call_expr_name_ref ( & name_ref)
216
- {
217
- ReferenceKind :: StructLiteral
218
- } else {
219
- ReferenceKind :: Other
220
- } ;
221
-
222
- refs. push ( Reference {
223
- file_range : FileRange { file_id, range } ,
224
- kind,
225
- access : reference_access ( & d. kind , & name_ref) ,
226
- } ) ;
227
- }
227
+ } ;
228
+
229
+ if let Some ( search_range) = search_range {
230
+ if !range. is_subrange ( & search_range) {
231
+ continue ;
232
+ }
233
+ }
234
+ // FIXME: reuse sb
235
+ // See https://github.com/rust-lang/rust/pull/68198#issuecomment-574269098
236
+
237
+ if let Some ( d) = classify_name_ref ( & mut sb, name_ref. as_ref ( ) ) {
238
+ if d == def {
239
+ let kind = if is_record_lit_name_ref ( & name_ref. value )
240
+ || is_call_expr_name_ref ( & name_ref. value )
241
+ {
242
+ ReferenceKind :: StructLiteral
243
+ } else {
244
+ ReferenceKind :: Other
245
+ } ;
246
+
247
+ refs. push ( Reference {
248
+ file_range : FileRange { file_id, range } ,
249
+ kind,
250
+ access : reference_access ( & d. kind , & name_ref. value ) ,
251
+ } ) ;
228
252
}
229
253
}
230
254
}
0 commit comments