@@ -13,6 +13,7 @@ mod classify;
1313mod rename;
1414mod search_scope;
1515
16+ use crate :: expand:: descend_into_macros_with_analyzer;
1617use hir:: { InFile , SourceBinder } ;
1718use once_cell:: unsync:: Lazy ;
1819use ra_db:: { SourceDatabase , SourceDatabaseExt } ;
@@ -192,39 +193,63 @@ fn process_definition(
192193
193194 let parse = Lazy :: new ( || SourceFile :: parse ( & text) ) ;
194195 let mut sb = Lazy :: new ( || SourceBinder :: new ( db) ) ;
196+ let mut analyzer = None ;
195197
196198 for ( idx, _) in text. match_indices ( pat) {
197199 let offset = TextUnit :: from_usize ( idx) ;
198200
199- if let Some ( name_ref) =
201+ let ( name_ref , range ) = if let Some ( name_ref) =
200202 find_node_at_offset :: < ast:: NameRef > ( parse. tree ( ) . syntax ( ) , offset)
201203 {
202204 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 (
215+ sb. analyze ( InFile :: new ( file_id. into ( ) , parse. tree ( ) . syntax ( ) ) , None ) ,
216+ ) ;
217+
218+ let expanded = descend_into_macros_with_analyzer (
219+ db,
220+ & analyzer,
221+ InFile :: new ( file_id. into ( ) , t) ,
222+ ) ;
223+ if let Some ( token) = ast:: NameRef :: cast ( expanded. value . parent ( ) ) {
224+ ( expanded. with_value ( token) , range)
225+ } else {
226+ continue ;
207227 }
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- }
228+ } ;
229+
230+ if let Some ( search_range) = search_range {
231+ if !range. is_subrange ( & search_range) {
232+ continue ;
233+ }
234+ }
235+ // FIXME: reuse sb
236+ // See https://github.com/rust-lang/rust/pull/68198#issuecomment-574269098
237+
238+ if let Some ( d) = classify_name_ref ( & mut sb, name_ref. as_ref ( ) ) {
239+ if d == def {
240+ let kind = if is_record_lit_name_ref ( & name_ref. value )
241+ || is_call_expr_name_ref ( & name_ref. value )
242+ {
243+ ReferenceKind :: StructLiteral
244+ } else {
245+ ReferenceKind :: Other
246+ } ;
247+
248+ refs. push ( Reference {
249+ file_range : FileRange { file_id, range } ,
250+ kind,
251+ access : reference_access ( & d. kind , & name_ref. value ) ,
252+ } ) ;
228253 }
229254 }
230255 }
0 commit comments