mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-28 05:53:45 +00:00
Auto merge of #14015 - vasilev-alex:lifetime-rename, r=Veykril
Don't include lifetime or label apostrophe when renaming Closes #13907
This commit is contained in:
commit
46084a1e71
2 changed files with 61 additions and 14 deletions
|
@ -263,11 +263,10 @@ fn rename_reference(
|
|||
Definition::GenericParam(hir::GenericParam::LifetimeParam(_)) | Definition::Label(_)
|
||||
) {
|
||||
match ident_kind {
|
||||
IdentifierKind::Ident | IdentifierKind::Underscore => {
|
||||
cov_mark::hit!(rename_not_a_lifetime_ident_ref);
|
||||
IdentifierKind::Underscore => {
|
||||
bail!("Invalid name `{}`: not a lifetime identifier", new_name);
|
||||
}
|
||||
IdentifierKind::Lifetime => cov_mark::hit!(rename_lifetime),
|
||||
_ => cov_mark::hit!(rename_lifetime),
|
||||
}
|
||||
} else {
|
||||
match ident_kind {
|
||||
|
@ -335,7 +334,15 @@ pub fn source_edit_from_references(
|
|||
_ => false,
|
||||
};
|
||||
if !has_emitted_edit && !edited_ranges.contains(&range.start()) {
|
||||
edit.replace(range, new_name.to_string());
|
||||
let (range, new_name) = match name {
|
||||
ast::NameLike::Lifetime(_) => (
|
||||
TextRange::new(range.start() + syntax::TextSize::from(1), range.end()),
|
||||
new_name.strip_prefix('\'').unwrap_or(new_name).to_owned(),
|
||||
),
|
||||
_ => (range, new_name.to_owned()),
|
||||
};
|
||||
|
||||
edit.replace(range, new_name);
|
||||
edited_ranges.push(range.start());
|
||||
}
|
||||
}
|
||||
|
@ -501,7 +508,15 @@ fn source_edit_from_def(
|
|||
}
|
||||
}
|
||||
if edit.is_empty() {
|
||||
edit.replace(range, new_name.to_string());
|
||||
let (range, new_name) = match def {
|
||||
Definition::GenericParam(hir::GenericParam::LifetimeParam(_))
|
||||
| Definition::Label(_) => (
|
||||
TextRange::new(range.start() + syntax::TextSize::from(1), range.end()),
|
||||
new_name.strip_prefix('\'').unwrap_or(new_name).to_owned(),
|
||||
),
|
||||
_ => (range, new_name.to_owned()),
|
||||
};
|
||||
edit.replace(range, new_name);
|
||||
}
|
||||
Ok((file_id, edit.finish()))
|
||||
}
|
||||
|
@ -522,9 +537,6 @@ impl IdentifierKind {
|
|||
(SyntaxKind::LIFETIME_IDENT, _) if new_name != "'static" && new_name != "'_" => {
|
||||
Ok(IdentifierKind::Lifetime)
|
||||
}
|
||||
(SyntaxKind::LIFETIME_IDENT, _) => {
|
||||
bail!("Invalid name `{}`: not a lifetime identifier", new_name)
|
||||
}
|
||||
(_, Some(syntax_error)) => bail!("Invalid name `{}`: {}", new_name, syntax_error),
|
||||
(_, None) => bail!("Invalid name `{}`: not an identifier", new_name),
|
||||
},
|
||||
|
|
|
@ -13,7 +13,7 @@ use ide_db::{
|
|||
};
|
||||
use itertools::Itertools;
|
||||
use stdx::{always, never};
|
||||
use syntax::{ast, AstNode, SyntaxNode};
|
||||
use syntax::{ast, AstNode, SyntaxNode, TextRange, TextSize};
|
||||
|
||||
use text_edit::TextEdit;
|
||||
|
||||
|
@ -48,7 +48,13 @@ pub(crate) fn prepare_rename(
|
|||
frange.range.contains_inclusive(position.offset)
|
||||
&& frange.file_id == position.file_id
|
||||
);
|
||||
Ok(frange.range)
|
||||
|
||||
Ok(match name_like {
|
||||
ast::NameLike::Lifetime(_) => {
|
||||
TextRange::new(frange.range.start() + TextSize::from(1), frange.range.end())
|
||||
}
|
||||
_ => frange.range,
|
||||
})
|
||||
})
|
||||
.reduce(|acc, cur| match (acc, cur) {
|
||||
// ensure all ranges are the same
|
||||
|
@ -407,7 +413,7 @@ mod tests {
|
|||
#[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$0>() {}", expect![[r#"9..17: lifetime"#]]);
|
||||
check_prepare(r"fn name<'lifetime>() { name$0(); }", expect![[r#"23..27: name"#]]);
|
||||
}
|
||||
|
||||
|
@ -521,14 +527,18 @@ impl Foo {
|
|||
|
||||
#[test]
|
||||
fn test_rename_to_invalid_identifier_lifetime2() {
|
||||
cov_mark::check!(rename_not_a_lifetime_ident_ref);
|
||||
check(
|
||||
"foo",
|
||||
"_",
|
||||
r#"fn main<'a>(_: &'a$0 ()) {}"#,
|
||||
"error: Invalid name `foo`: not a lifetime identifier",
|
||||
r#"error: Invalid name `_`: not a lifetime identifier"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rename_accepts_lifetime_without_apostrophe() {
|
||||
check("foo", r#"fn main<'a>(_: &'a$0 ()) {}"#, r#"fn main<'foo>(_: &'foo ()) {}"#);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rename_to_underscore_invalid() {
|
||||
cov_mark::check!(rename_underscore_multiple);
|
||||
|
@ -1831,6 +1841,31 @@ fn foo<'a>() -> &'a () {
|
|||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rename_label_new_name_without_apostrophe() {
|
||||
check(
|
||||
"foo",
|
||||
r#"
|
||||
fn main() {
|
||||
'outer$0: loop {
|
||||
'inner: loop {
|
||||
break 'outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
"#,
|
||||
r#"
|
||||
fn main() {
|
||||
'foo: loop {
|
||||
'inner: loop {
|
||||
break 'foo;
|
||||
}
|
||||
}
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_self_to_self() {
|
||||
cov_mark::check!(rename_self_to_self);
|
||||
|
|
Loading…
Reference in a new issue