@@ -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