Skip to content

Commit dd0421e

Browse files
committed
Handle macro token cases for rename
1 parent 3e1d977 commit dd0421e

File tree

2 files changed

+69
-25
lines changed

2 files changed

+69
-25
lines changed

crates/ra_ide/src/references.rs

Lines changed: 50 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ mod classify;
1313
mod rename;
1414
mod search_scope;
1515

16+
use crate::expand::descend_into_macros_with_analyzer;
1617
use hir::{InFile, SourceBinder};
1718
use once_cell::unsync::Lazy;
1819
use 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
}

crates/ra_ide/src/references/rename.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,25 @@ mod tests {
210210
);
211211
}
212212

213+
#[test]
214+
fn test_rename_for_macro_args() {
215+
test_rename(
216+
r#"
217+
macro_rules! foo {($i:ident) => {$i} }
218+
fn main() {
219+
let a<|> = "test";
220+
foo!(a);
221+
}"#,
222+
"b",
223+
r#"
224+
macro_rules! foo {($i:ident) => {$i} }
225+
fn main() {
226+
let b = "test";
227+
foo!(b);
228+
}"#,
229+
);
230+
}
231+
213232
#[test]
214233
fn test_rename_for_param_inside() {
215234
test_rename(

0 commit comments

Comments
 (0)