Handle macro token cases for rename
This commit is contained in:
parent
3e1d97790b
commit
dd0421e587
@ -13,6 +13,7 @@
|
|||||||
mod rename;
|
mod rename;
|
||||||
mod search_scope;
|
mod search_scope;
|
||||||
|
|
||||||
|
use crate::expand::descend_into_macros_with_analyzer;
|
||||||
use hir::{InFile, SourceBinder};
|
use hir::{InFile, SourceBinder};
|
||||||
use once_cell::unsync::Lazy;
|
use once_cell::unsync::Lazy;
|
||||||
use ra_db::{SourceDatabase, SourceDatabaseExt};
|
use ra_db::{SourceDatabase, SourceDatabaseExt};
|
||||||
@ -192,14 +193,40 @@ fn process_definition(
|
|||||||
|
|
||||||
let parse = Lazy::new(|| SourceFile::parse(&text));
|
let parse = Lazy::new(|| SourceFile::parse(&text));
|
||||||
let mut sb = Lazy::new(|| SourceBinder::new(db));
|
let mut sb = Lazy::new(|| SourceBinder::new(db));
|
||||||
|
let mut analyzer = None;
|
||||||
|
|
||||||
for (idx, _) in text.match_indices(pat) {
|
for (idx, _) in text.match_indices(pat) {
|
||||||
let offset = TextUnit::from_usize(idx);
|
let offset = TextUnit::from_usize(idx);
|
||||||
|
|
||||||
if let Some(name_ref) =
|
let (name_ref, range) = if let Some(name_ref) =
|
||||||
find_node_at_offset::<ast::NameRef>(parse.tree().syntax(), offset)
|
find_node_at_offset::<ast::NameRef>(parse.tree().syntax(), offset)
|
||||||
{
|
{
|
||||||
let range = name_ref.syntax().text_range();
|
let range = name_ref.syntax().text_range();
|
||||||
|
(InFile::new(file_id.into(), name_ref), range)
|
||||||
|
} else {
|
||||||
|
// Handle macro token cases
|
||||||
|
let t = match parse.tree().syntax().token_at_offset(offset) {
|
||||||
|
TokenAtOffset::None => continue,
|
||||||
|
TokenAtOffset::Single(t) => t,
|
||||||
|
TokenAtOffset::Between(_, t) => t,
|
||||||
|
};
|
||||||
|
let range = t.text_range();
|
||||||
|
let analyzer = analyzer.get_or_insert(
|
||||||
|
sb.analyze(InFile::new(file_id.into(), parse.tree().syntax()), None),
|
||||||
|
);
|
||||||
|
|
||||||
|
let expanded = descend_into_macros_with_analyzer(
|
||||||
|
db,
|
||||||
|
&analyzer,
|
||||||
|
InFile::new(file_id.into(), t),
|
||||||
|
);
|
||||||
|
if let Some(token) = ast::NameRef::cast(expanded.value.parent()) {
|
||||||
|
(expanded.with_value(token), range)
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(search_range) = search_range {
|
if let Some(search_range) = search_range {
|
||||||
if !range.is_subrange(&search_range) {
|
if !range.is_subrange(&search_range) {
|
||||||
continue;
|
continue;
|
||||||
@ -208,11 +235,10 @@ fn process_definition(
|
|||||||
// FIXME: reuse sb
|
// FIXME: reuse sb
|
||||||
// See https://github.com/rust-lang/rust/pull/68198#issuecomment-574269098
|
// See https://github.com/rust-lang/rust/pull/68198#issuecomment-574269098
|
||||||
|
|
||||||
if let Some(d) = classify_name_ref(&mut sb, InFile::new(file_id.into(), &name_ref))
|
if let Some(d) = classify_name_ref(&mut sb, name_ref.as_ref()) {
|
||||||
{
|
|
||||||
if d == def {
|
if d == def {
|
||||||
let kind = if is_record_lit_name_ref(&name_ref)
|
let kind = if is_record_lit_name_ref(&name_ref.value)
|
||||||
|| is_call_expr_name_ref(&name_ref)
|
|| is_call_expr_name_ref(&name_ref.value)
|
||||||
{
|
{
|
||||||
ReferenceKind::StructLiteral
|
ReferenceKind::StructLiteral
|
||||||
} else {
|
} else {
|
||||||
@ -222,13 +248,12 @@ fn process_definition(
|
|||||||
refs.push(Reference {
|
refs.push(Reference {
|
||||||
file_range: FileRange { file_id, range },
|
file_range: FileRange { file_id, range },
|
||||||
kind,
|
kind,
|
||||||
access: reference_access(&d.kind, &name_ref),
|
access: reference_access(&d.kind, &name_ref.value),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
refs
|
refs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,6 +210,25 @@ fn main() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_rename_for_macro_args() {
|
||||||
|
test_rename(
|
||||||
|
r#"
|
||||||
|
macro_rules! foo {($i:ident) => {$i} }
|
||||||
|
fn main() {
|
||||||
|
let a<|> = "test";
|
||||||
|
foo!(a);
|
||||||
|
}"#,
|
||||||
|
"b",
|
||||||
|
r#"
|
||||||
|
macro_rules! foo {($i:ident) => {$i} }
|
||||||
|
fn main() {
|
||||||
|
let b = "test";
|
||||||
|
foo!(b);
|
||||||
|
}"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_rename_for_param_inside() {
|
fn test_rename_for_param_inside() {
|
||||||
test_rename(
|
test_rename(
|
||||||
|
Loading…
Reference in New Issue
Block a user