Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide/src/rename.rs')
-rw-r--r--crates/ide/src/rename.rs259
1 files changed, 236 insertions, 23 deletions
diff --git a/crates/ide/src/rename.rs b/crates/ide/src/rename.rs
index 9581474ca7..42b7472c64 100644
--- a/crates/ide/src/rename.rs
+++ b/crates/ide/src/rename.rs
@@ -12,12 +12,8 @@ use ide_db::{
FileId, FileRange, RootDatabase,
};
use itertools::Itertools;
-use span::Edition;
use stdx::{always, never};
-use syntax::{
- ast, utils::is_raw_identifier, AstNode, SmolStr, SyntaxKind, SyntaxNode, TextRange, TextSize,
- ToSmolStr,
-};
+use syntax::{ast, AstNode, SyntaxKind, SyntaxNode, TextRange, TextSize};
use text_edit::TextEdit;
@@ -102,7 +98,7 @@ pub(crate) fn rename(
// FIXME: This can use the `ide_db::rename_reference` (or def.rename) method once we can
// properly find "direct" usages/references.
.map(|(.., def)| {
- match IdentifierKind::classify(Edition::CURRENT_FIXME, new_name)? {
+ match IdentifierKind::classify(new_name)? {
IdentifierKind::Ident => (),
IdentifierKind::Lifetime => {
bail!("Cannot alias reference to a lifetime identifier")
@@ -124,7 +120,10 @@ pub(crate) fn rename(
let mut source_change = SourceChange::default();
source_change.extend(usages.references.get_mut(&file_id).iter().map(|refs| {
- (position.file_id, source_edit_from_references(refs, def, new_name))
+ (
+ position.file_id,
+ source_edit_from_references(refs, def, new_name, file_id.edition()),
+ )
}));
Ok(source_change)
@@ -162,11 +161,7 @@ pub(crate) fn will_rename_file(
let sema = Semantics::new(db);
let module = sema.file_to_module_def(file_id)?;
let def = Definition::Module(module);
- let mut change = if is_raw_identifier(new_name_stem) {
- def.rename(&sema, &SmolStr::from_iter(["r#", new_name_stem])).ok()?
- } else {
- def.rename(&sema, new_name_stem).ok()?
- };
+ let mut change = def.rename(&sema, new_name_stem).ok()?;
change.file_system_edits.clear();
Some(change)
}
@@ -270,7 +265,7 @@ fn find_definitions(
// if the name differs from the definitions name it has to be an alias
if def
.name(sema.db)
- .map_or(false, |it| it.display_no_db().to_smolstr() != name_ref.text().as_str())
+ .map_or(false, |it| !it.eq_ident(name_ref.text().as_str()))
{
Err(format_err!("Renaming aliases is currently unsupported"))
} else {
@@ -377,7 +372,7 @@ fn rename_to_self(
let usages = def.usages(sema).all();
let mut source_change = SourceChange::default();
source_change.extend(usages.iter().map(|(file_id, references)| {
- (file_id.into(), source_edit_from_references(references, def, "self"))
+ (file_id.into(), source_edit_from_references(references, def, "self", file_id.edition()))
}));
source_change.insert_source_edit(
file_id.original_file(sema.db),
@@ -398,7 +393,7 @@ fn rename_self_to_param(
return Ok(SourceChange::default());
}
- let identifier_kind = IdentifierKind::classify(Edition::CURRENT_FIXME, new_name)?;
+ let identifier_kind = IdentifierKind::classify(new_name)?;
let InFile { file_id, value: self_param } =
sema.source(self_param).ok_or_else(|| format_err!("cannot find function source"))?;
@@ -413,7 +408,7 @@ fn rename_self_to_param(
let mut source_change = SourceChange::default();
source_change.insert_source_edit(file_id.original_file(sema.db), edit);
source_change.extend(usages.iter().map(|(file_id, references)| {
- (file_id.into(), source_edit_from_references(references, def, new_name))
+ (file_id.into(), source_edit_from_references(references, def, new_name, file_id.edition()))
}));
Ok(source_change)
}
@@ -634,9 +629,9 @@ impl Foo {
#[test]
fn test_rename_to_invalid_identifier3() {
check(
- "let",
+ "super",
r#"fn main() { let i$0 = 1; }"#,
- "error: Invalid name `let`: not an identifier",
+ "error: Invalid name `super`: not an identifier",
);
}
@@ -685,11 +680,7 @@ impl Foo {
#[test]
fn test_rename_mod_invalid_raw_ident() {
- check(
- "r#self",
- r#"mod foo$0 {}"#,
- "error: Invalid name: `self` cannot be a raw identifier",
- );
+ check("r#self", r#"mod foo$0 {}"#, "error: Invalid name `self`: not an identifier");
}
#[test]
@@ -1544,6 +1535,228 @@ pub fn baz() {}
}
#[test]
+ fn test_rename_each_usage_gets_appropriate_rawness() {
+ check_expect(
+ "dyn",
+ r#"
+//- /a.rs crate:a edition:2015
+pub fn foo() {}
+
+//- /b.rs crate:b edition:2018 deps:a new_source_root:local
+fn bar() {
+ a::foo$0();
+}
+ "#,
+ expect![[r#"
+ source_file_edits: [
+ (
+ FileId(
+ 0,
+ ),
+ [
+ Indel {
+ insert: "dyn",
+ delete: 7..10,
+ },
+ ],
+ ),
+ (
+ FileId(
+ 1,
+ ),
+ [
+ Indel {
+ insert: "r#dyn",
+ delete: 18..21,
+ },
+ ],
+ ),
+ ]
+ file_system_edits: []
+ "#]],
+ );
+
+ check_expect(
+ "dyn",
+ r#"
+//- /a.rs crate:a edition:2018
+pub fn foo() {}
+
+//- /b.rs crate:b edition:2015 deps:a new_source_root:local
+fn bar() {
+ a::foo$0();
+}
+ "#,
+ expect![[r#"
+ source_file_edits: [
+ (
+ FileId(
+ 0,
+ ),
+ [
+ Indel {
+ insert: "r#dyn",
+ delete: 7..10,
+ },
+ ],
+ ),
+ (
+ FileId(
+ 1,
+ ),
+ [
+ Indel {
+ insert: "dyn",
+ delete: 18..21,
+ },
+ ],
+ ),
+ ]
+ file_system_edits: []
+ "#]],
+ );
+
+ check_expect(
+ "r#dyn",
+ r#"
+//- /a.rs crate:a edition:2018
+pub fn foo$0() {}
+
+//- /b.rs crate:b edition:2015 deps:a new_source_root:local
+fn bar() {
+ a::foo();
+}
+ "#,
+ expect![[r#"
+ source_file_edits: [
+ (
+ FileId(
+ 0,
+ ),
+ [
+ Indel {
+ insert: "r#dyn",
+ delete: 7..10,
+ },
+ ],
+ ),
+ (
+ FileId(
+ 1,
+ ),
+ [
+ Indel {
+ insert: "dyn",
+ delete: 18..21,
+ },
+ ],
+ ),
+ ]
+ file_system_edits: []
+ "#]],
+ );
+ }
+
+ #[test]
+ fn rename_raw_identifier() {
+ check_expect(
+ "abc",
+ r#"
+//- /a.rs crate:a edition:2015
+pub fn dyn() {}
+
+fn foo() {
+ dyn$0();
+}
+
+//- /b.rs crate:b edition:2018 deps:a new_source_root:local
+fn bar() {
+ a::r#dyn();
+}
+ "#,
+ expect![[r#"
+ source_file_edits: [
+ (
+ FileId(
+ 0,
+ ),
+ [
+ Indel {
+ insert: "abc",
+ delete: 7..10,
+ },
+ Indel {
+ insert: "abc",
+ delete: 32..35,
+ },
+ ],
+ ),
+ (
+ FileId(
+ 1,
+ ),
+ [
+ Indel {
+ insert: "abc",
+ delete: 18..23,
+ },
+ ],
+ ),
+ ]
+ file_system_edits: []
+ "#]],
+ );
+
+ check_expect(
+ "abc",
+ r#"
+//- /a.rs crate:a edition:2018
+pub fn r#dyn() {}
+
+fn foo() {
+ r#dyn$0();
+}
+
+//- /b.rs crate:b edition:2015 deps:a new_source_root:local
+fn bar() {
+ a::dyn();
+}
+ "#,
+ expect![[r#"
+ source_file_edits: [
+ (
+ FileId(
+ 0,
+ ),
+ [
+ Indel {
+ insert: "abc",
+ delete: 7..12,
+ },
+ Indel {
+ insert: "abc",
+ delete: 34..39,
+ },
+ ],
+ ),
+ (
+ FileId(
+ 1,
+ ),
+ [
+ Indel {
+ insert: "abc",
+ delete: 18..21,
+ },
+ ],
+ ),
+ ]
+ file_system_edits: []
+ "#]],
+ );
+ }
+
+ #[test]
fn test_enum_variant_from_module_1() {
cov_mark::check!(rename_non_local);
check(