Skip to content

Commit 98d2dbb

Browse files
committed
Return original text range in PrepareRename responses when inside macro
1 parent 052fe49 commit 98d2dbb

File tree

1 file changed

+47
-7
lines changed

1 file changed

+47
-7
lines changed

crates/ide/src/references/rename.rs

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use crate::{display::TryToNav, FilePosition, FileSystemEdit, RangeInfo, SourceCh
2121

2222
type RenameResult<T> = Result<T, RenameError>;
2323
#[derive(Debug)]
24-
pub struct RenameError(pub(crate) String);
24+
pub struct RenameError(String);
2525

2626
impl fmt::Display for RenameError {
2727
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -47,16 +47,15 @@ pub(crate) fn prepare_rename(
4747
let sema = Semantics::new(db);
4848
let source_file = sema.parse(position.file_id);
4949
let syntax = source_file.syntax();
50-
let range = match &sema
50+
let name_like = sema
5151
.find_node_at_offset_with_descend(&syntax, position.offset)
52-
.ok_or_else(|| format_err!("No references found at position"))?
53-
{
52+
.ok_or_else(|| format_err!("No references found at position"))?;
53+
let node = match &name_like {
5454
ast::NameLike::Name(it) => it.syntax(),
5555
ast::NameLike::NameRef(it) => it.syntax(),
5656
ast::NameLike::Lifetime(it) => it.syntax(),
57-
}
58-
.text_range();
59-
Ok(RangeInfo::new(range, ()))
57+
};
58+
Ok(RangeInfo::new(sema.original_range(node).range, ()))
6059
}
6160

6261
// Feature: Rename
@@ -546,6 +545,8 @@ mod tests {
546545

547546
use crate::{fixture, FileId};
548547

548+
use super::{RangeInfo, RenameError};
549+
549550
fn check(new_name: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
550551
let ra_fixture_after = &trim_indent(ra_fixture_after);
551552
let (analysis, position) = fixture::position(ra_fixture_before);
@@ -591,6 +592,45 @@ mod tests {
591592
expect.assert_debug_eq(&source_change)
592593
}
593594

595+
fn check_prepare(ra_fixture: &str, expect: Expect) {
596+
let (analysis, position) = fixture::position(ra_fixture);
597+
let result = analysis
598+
.prepare_rename(position)
599+
.unwrap_or_else(|err| panic!("PrepareRename was cancelled: {}", err));
600+
match result {
601+
Ok(RangeInfo { range, info: () }) => {
602+
let source = analysis.file_text(position.file_id).unwrap();
603+
expect.assert_eq(&format!("{:?}: {}", range, &source[range]))
604+
}
605+
Err(RenameError(err)) => expect.assert_eq(&err),
606+
};
607+
}
608+
609+
#[test]
610+
fn test_prepare_rename_namelikes() {
611+
check_prepare(r"fn name$0<'lifetime>() {}", expect![[r#"3..7: name"#]]);
612+
check_prepare(r"fn name<'lifetime$0>() {}", expect![[r#"8..17: 'lifetime"#]]);
613+
check_prepare(r"fn name<'lifetime>() { name$0(); }", expect![[r#"23..27: name"#]]);
614+
}
615+
616+
#[test]
617+
fn test_prepare_rename_in_macro() {
618+
check_prepare(
619+
r"macro_rules! foo {
620+
($ident:ident) => {
621+
pub struct $ident;
622+
}
623+
}
624+
foo!(Foo$0);",
625+
expect![[r#"83..86: Foo"#]],
626+
);
627+
}
628+
629+
#[test]
630+
fn test_prepare_rename_keyword() {
631+
check_prepare(r"struct$0 Foo;", expect![[r#"No references found at position"#]]);
632+
}
633+
594634
#[test]
595635
fn test_rename_to_underscore() {
596636
check("_", r#"fn main() { let i$0 = 1; }"#, r#"fn main() { let _ = 1; }"#);

0 commit comments

Comments
 (0)