mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 13:03:31 +00:00
Return original text range in PrepareRename responses when inside macro
This commit is contained in:
parent
052fe49179
commit
98d2dbb90e
1 changed files with 47 additions and 7 deletions
|
@ -21,7 +21,7 @@ use crate::{display::TryToNav, FilePosition, FileSystemEdit, RangeInfo, SourceCh
|
|||
|
||||
type RenameResult<T> = Result<T, RenameError>;
|
||||
#[derive(Debug)]
|
||||
pub struct RenameError(pub(crate) String);
|
||||
pub struct RenameError(String);
|
||||
|
||||
impl fmt::Display for RenameError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
|
@ -47,16 +47,15 @@ pub(crate) fn prepare_rename(
|
|||
let sema = Semantics::new(db);
|
||||
let source_file = sema.parse(position.file_id);
|
||||
let syntax = source_file.syntax();
|
||||
let range = match &sema
|
||||
let name_like = sema
|
||||
.find_node_at_offset_with_descend(&syntax, position.offset)
|
||||
.ok_or_else(|| format_err!("No references found at position"))?
|
||||
{
|
||||
.ok_or_else(|| format_err!("No references found at position"))?;
|
||||
let node = match &name_like {
|
||||
ast::NameLike::Name(it) => it.syntax(),
|
||||
ast::NameLike::NameRef(it) => it.syntax(),
|
||||
ast::NameLike::Lifetime(it) => it.syntax(),
|
||||
}
|
||||
.text_range();
|
||||
Ok(RangeInfo::new(range, ()))
|
||||
};
|
||||
Ok(RangeInfo::new(sema.original_range(node).range, ()))
|
||||
}
|
||||
|
||||
// Feature: Rename
|
||||
|
@ -546,6 +545,8 @@ mod tests {
|
|||
|
||||
use crate::{fixture, FileId};
|
||||
|
||||
use super::{RangeInfo, RenameError};
|
||||
|
||||
fn check(new_name: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
|
||||
let ra_fixture_after = &trim_indent(ra_fixture_after);
|
||||
let (analysis, position) = fixture::position(ra_fixture_before);
|
||||
|
@ -591,6 +592,45 @@ mod tests {
|
|||
expect.assert_debug_eq(&source_change)
|
||||
}
|
||||
|
||||
fn check_prepare(ra_fixture: &str, expect: Expect) {
|
||||
let (analysis, position) = fixture::position(ra_fixture);
|
||||
let result = analysis
|
||||
.prepare_rename(position)
|
||||
.unwrap_or_else(|err| panic!("PrepareRename was cancelled: {}", err));
|
||||
match result {
|
||||
Ok(RangeInfo { range, info: () }) => {
|
||||
let source = analysis.file_text(position.file_id).unwrap();
|
||||
expect.assert_eq(&format!("{:?}: {}", range, &source[range]))
|
||||
}
|
||||
Err(RenameError(err)) => expect.assert_eq(&err),
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_prepare_rename_namelikes() {
|
||||
check_prepare(r"fn name$0<'lifetime>() {}", expect![[r#"3..7: name"#]]);
|
||||
check_prepare(r"fn name<'lifetime$0>() {}", expect![[r#"8..17: 'lifetime"#]]);
|
||||
check_prepare(r"fn name<'lifetime>() { name$0(); }", expect![[r#"23..27: name"#]]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_prepare_rename_in_macro() {
|
||||
check_prepare(
|
||||
r"macro_rules! foo {
|
||||
($ident:ident) => {
|
||||
pub struct $ident;
|
||||
}
|
||||
}
|
||||
foo!(Foo$0);",
|
||||
expect![[r#"83..86: Foo"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_prepare_rename_keyword() {
|
||||
check_prepare(r"struct$0 Foo;", expect![[r#"No references found at position"#]]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rename_to_underscore() {
|
||||
check("_", r#"fn main() { let i$0 = 1; }"#, r#"fn main() { let _ = 1; }"#);
|
||||
|
|
Loading…
Reference in a new issue