@@ -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,62 @@ 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_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 ;
207226 }
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+ } ) ;
228252 }
229253 }
230254 }
0 commit comments