Skip to content

Commit 305d921

Browse files
Merge #3064
3064: Handle macro token cases for rename r=matklad a=edwin0cheng Fixes #2957 Co-authored-by: Edwin Cheng <[email protected]>
2 parents 3c98681 + 3038470 commit 305d921

File tree

2 files changed

+68
-25
lines changed

2 files changed

+68
-25
lines changed

crates/ra_ide/src/references.rs

Lines changed: 49 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,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
}

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)