From 13bce1a1641cbcf57ae24677c238e2c1ca393dea Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 4 May 2020 12:10:26 +0200 Subject: Add test marks --- crates/ra_ide/src/references/rename.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'crates/ra_ide/src/references/rename.rs') diff --git a/crates/ra_ide/src/references/rename.rs b/crates/ra_ide/src/references/rename.rs index fd17bc9f2..916edaef2 100644 --- a/crates/ra_ide/src/references/rename.rs +++ b/crates/ra_ide/src/references/rename.rs @@ -7,14 +7,13 @@ use ra_syntax::{ algo::find_node_at_offset, ast, lex_single_valid_syntax_kind, AstNode, SyntaxKind, SyntaxNode, }; use ra_text_edit::TextEdit; +use test_utils::tested_by; use crate::{ - FilePosition, FileSystemEdit, RangeInfo, Reference, ReferenceKind, SourceChange, - SourceFileEdit, TextRange, + references::find_all_refs, FilePosition, FileSystemEdit, RangeInfo, Reference, ReferenceKind, + SourceChange, SourceFileEdit, TextRange, }; -use super::find_all_refs; - pub(crate) fn rename( db: &RootDatabase, position: FilePosition, @@ -52,11 +51,13 @@ fn source_edit_from_reference(reference: Reference, new_name: &str) -> SourceFil let file_id = reference.file_range.file_id; let range = match reference.kind { ReferenceKind::FieldShorthandForField => { + tested_by!(test_rename_struct_field_for_shorthand); replacement_text.push_str(new_name); replacement_text.push_str(": "); TextRange::new(reference.file_range.range.start(), reference.file_range.range.start()) } ReferenceKind::FieldShorthandForLocal => { + tested_by!(test_rename_local_for_field_shorthand); replacement_text.push_str(": "); replacement_text.push_str(new_name); TextRange::new(reference.file_range.range.end(), reference.file_range.range.end()) @@ -147,7 +148,7 @@ fn rename_reference( mod tests { use insta::assert_debug_snapshot; use ra_text_edit::TextEditBuilder; - use test_utils::assert_eq_text; + use test_utils::{assert_eq_text, covers}; use crate::{ mock_analysis::analysis_and_position, mock_analysis::single_file_with_position, FileId, @@ -379,6 +380,7 @@ mod tests { #[test] fn test_rename_struct_field_for_shorthand() { + covers!(test_rename_struct_field_for_shorthand); test_rename( r#" struct Foo { @@ -408,6 +410,7 @@ mod tests { #[test] fn test_rename_local_for_field_shorthand() { + covers!(test_rename_local_for_field_shorthand); test_rename( r#" struct Foo { -- cgit v1.2.3 From 3908fad1fe02efedc810d7bd8f765b1434684cef Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 5 May 2020 20:55:12 +0200 Subject: Normalize naming of diagnostics --- crates/ra_ide/src/references/rename.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'crates/ra_ide/src/references/rename.rs') diff --git a/crates/ra_ide/src/references/rename.rs b/crates/ra_ide/src/references/rename.rs index 916edaef2..52e55b0a0 100644 --- a/crates/ra_ide/src/references/rename.rs +++ b/crates/ra_ide/src/references/rename.rs @@ -122,7 +122,7 @@ fn rename_mod( source_file_edits.extend(ref_edits); } - Some(SourceChange::from_edits("rename", source_file_edits, file_system_edits)) + Some(SourceChange::from_edits("Rename", source_file_edits, file_system_edits)) } fn rename_reference( @@ -141,7 +141,7 @@ fn rename_reference( return None; } - Some(RangeInfo::new(range, SourceChange::source_file_edits("rename", edit))) + Some(RangeInfo::new(range, SourceChange::source_file_edits("Rename", edit))) } #[cfg(test)] @@ -530,7 +530,7 @@ mod tests { RangeInfo { range: 4..7, info: SourceChange { - label: "rename", + label: "Rename", source_file_edits: [ SourceFileEdit { file_id: FileId( @@ -582,7 +582,7 @@ mod tests { RangeInfo { range: 4..7, info: SourceChange { - label: "rename", + label: "Rename", source_file_edits: [ SourceFileEdit { file_id: FileId( @@ -665,7 +665,7 @@ mod tests { RangeInfo { range: 8..11, info: SourceChange { - label: "rename", + label: "Rename", source_file_edits: [ SourceFileEdit { file_id: FileId( -- cgit v1.2.3 From ca9e0f5fe9ad29ab0c5a0771a0d0eaec97e4104b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 5 May 2020 23:48:26 +0200 Subject: Fixup tests --- crates/ra_ide/src/references/rename.rs | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'crates/ra_ide/src/references/rename.rs') diff --git a/crates/ra_ide/src/references/rename.rs b/crates/ra_ide/src/references/rename.rs index 52e55b0a0..0398d53bc 100644 --- a/crates/ra_ide/src/references/rename.rs +++ b/crates/ra_ide/src/references/rename.rs @@ -537,10 +537,10 @@ mod tests { 2, ), edit: TextEdit { - atoms: [ - AtomTextEdit { - delete: 4..7, + indels: [ + Indel { insert: "foo2", + delete: 4..7, }, ], }, @@ -589,10 +589,10 @@ mod tests { 1, ), edit: TextEdit { - atoms: [ - AtomTextEdit { - delete: 4..7, + indels: [ + Indel { insert: "foo2", + delete: 4..7, }, ], }, @@ -672,10 +672,10 @@ mod tests { 2, ), edit: TextEdit { - atoms: [ - AtomTextEdit { - delete: 8..11, + indels: [ + Indel { insert: "foo2", + delete: 8..11, }, ], }, @@ -685,10 +685,10 @@ mod tests { 1, ), edit: TextEdit { - atoms: [ - AtomTextEdit { - delete: 27..30, + indels: [ + Indel { insert: "foo2", + delete: 27..30, }, ], }, @@ -720,13 +720,13 @@ mod tests { if let Some(change) = source_change { for edit in change.info.source_file_edits { file_id = Some(edit.file_id); - for atom in edit.edit.as_atoms() { - text_edit_builder.replace(atom.delete, atom.insert.clone()); + for indel in edit.edit.as_indels() { + text_edit_builder.replace(indel.delete, indel.insert.clone()); } } } - let result = - text_edit_builder.finish().apply(&*analysis.file_text(file_id.unwrap()).unwrap()); + let mut result = analysis.file_text(file_id.unwrap()).unwrap().to_string(); + text_edit_builder.finish().apply(&mut result); assert_eq_text!(expected, &*result); } } -- cgit v1.2.3 From bd9f1f7eb78843ddd91d259a04e988b0681a5db4 Mon Sep 17 00:00:00 2001 From: Fedor Sakharov Date: Wed, 6 May 2020 17:17:35 +0300 Subject: Fix rename of enum variant visible from module --- crates/ra_ide/src/references/rename.rs | 62 ++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'crates/ra_ide/src/references/rename.rs') diff --git a/crates/ra_ide/src/references/rename.rs b/crates/ra_ide/src/references/rename.rs index 0398d53bc..2cbb82c1a 100644 --- a/crates/ra_ide/src/references/rename.rs +++ b/crates/ra_ide/src/references/rename.rs @@ -712,6 +712,68 @@ mod tests { "###); } + #[test] + fn test_enum_variant_from_module_1() { + test_rename( + r#" + mod foo { + pub enum Foo { + Bar<|>, + } + } + + fn func(f: foo::Foo) { + match f { + foo::Foo::Bar => {} + } + } + "#, + "Baz", + r#" + mod foo { + pub enum Foo { + Baz, + } + } + + fn func(f: foo::Foo) { + match f { + foo::Foo::Baz => {} + } + } + "#, + ); + } + + #[test] + fn test_enum_variant_from_module_2() { + test_rename( + r#" + mod foo { + pub struct Foo { + pub bar<|>: uint, + } + } + + fn foo(f: foo::Foo) { + let _ = f.bar; + } + "#, + "baz", + r#" + mod foo { + pub struct Foo { + pub baz: uint, + } + } + + fn foo(f: foo::Foo) { + let _ = f.baz; + } + "#, + ); + } + fn test_rename(text: &str, new_name: &str, expected: &str) { let (analysis, position) = single_file_with_position(text); let source_change = analysis.rename(position, new_name).unwrap(); -- cgit v1.2.3 From d7d8bfc472fcb009c605b2ffba56cf04c4bc73a2 Mon Sep 17 00:00:00 2001 From: zbsz Date: Sun, 3 May 2020 22:12:18 -0700 Subject: Add 'self to parameter' renaming. --- crates/ra_ide/src/references/rename.rs | 211 ++++++++++++++++++++++++++++++++- 1 file changed, 206 insertions(+), 5 deletions(-) (limited to 'crates/ra_ide/src/references/rename.rs') diff --git a/crates/ra_ide/src/references/rename.rs b/crates/ra_ide/src/references/rename.rs index 2cbb82c1a..410dae75c 100644 --- a/crates/ra_ide/src/references/rename.rs +++ b/crates/ra_ide/src/references/rename.rs @@ -4,14 +4,16 @@ use hir::{ModuleSource, Semantics}; use ra_db::{RelativePath, RelativePathBuf, SourceDatabaseExt}; use ra_ide_db::RootDatabase; use ra_syntax::{ - algo::find_node_at_offset, ast, lex_single_valid_syntax_kind, AstNode, SyntaxKind, SyntaxNode, + algo::find_node_at_offset, ast, ast::TypeAscriptionOwner, lex_single_valid_syntax_kind, + AstNode, SyntaxKind, SyntaxNode, SyntaxToken, }; use ra_text_edit::TextEdit; +use std::convert::TryInto; use test_utils::tested_by; use crate::{ references::find_all_refs, FilePosition, FileSystemEdit, RangeInfo, Reference, ReferenceKind, - SourceChange, SourceFileEdit, TextRange, + SourceChange, SourceFileEdit, TextRange, TextSize, }; pub(crate) fn rename( @@ -21,17 +23,21 @@ pub(crate) fn rename( ) -> Option> { match lex_single_valid_syntax_kind(new_name)? { SyntaxKind::IDENT | SyntaxKind::UNDERSCORE => (), + SyntaxKind::SELF_KW => return rename_to_self(db, position), _ => return None, } let sema = Semantics::new(db); let source_file = sema.parse(position.file_id); - if let Some((ast_name, ast_module)) = - find_name_and_module_at_offset(source_file.syntax(), position) - { + let syntax = source_file.syntax(); + if let Some((ast_name, ast_module)) = find_name_and_module_at_offset(syntax, position) { let range = ast_name.syntax().text_range(); rename_mod(&sema, &ast_name, &ast_module, position, new_name) .map(|info| RangeInfo::new(range, info)) + } else if let Some(self_token) = + syntax.token_at_offset(position.offset).find(|t| t.kind() == SyntaxKind::SELF_KW) + { + rename_self_to_param(db, position, self_token, new_name) } else { rename_reference(sema.db, position, new_name) } @@ -125,6 +131,112 @@ fn rename_mod( Some(SourceChange::from_edits("Rename", source_file_edits, file_system_edits)) } +fn rename_to_self(db: &RootDatabase, position: FilePosition) -> Option> { + let sema = Semantics::new(db); + let source_file = sema.parse(position.file_id); + let syn = source_file.syntax(); + + let fn_def = find_node_at_offset::(syn, position.offset)?; + let params = fn_def.param_list()?; + if params.self_param().is_some() { + return None; // method already has self param + } + let first_param = params.params().next()?; + let mutable = match first_param.ascribed_type() { + Some(ast::TypeRef::ReferenceType(rt)) => rt.mut_token().is_some(), + _ => return None, // not renaming other types + }; + + let RangeInfo { range, info: refs } = find_all_refs(db, position, None)?; + + let param_range = first_param.syntax().text_range(); + let (param_ref, usages): (Vec, Vec) = refs + .into_iter() + .partition(|reference| param_range.intersect(reference.file_range.range).is_some()); + + if param_ref.is_empty() { + return None; + } + + let mut edits = usages + .into_iter() + .map(|reference| source_edit_from_reference(reference, "self")) + .collect::>(); + + edits.push(SourceFileEdit { + file_id: position.file_id, + edit: TextEdit::replace( + param_range, + String::from(if mutable { "&mut self" } else { "&self" }), + ), + }); + + Some(RangeInfo::new(range, SourceChange::source_file_edits("Rename", edits))) +} + +fn text_edit_from_self_param( + syn: &SyntaxNode, + self_param: &ast::SelfParam, + new_name: &str, +) -> Option { + fn target_type_name(impl_def: &ast::ImplDef) -> Option { + if let Some(ast::TypeRef::PathType(p)) = impl_def.target_type() { + return Some(p.path()?.segment()?.name_ref()?.text().to_string()); + } + None + } + + let impl_def = + find_node_at_offset::(syn, self_param.syntax().text_range().start())?; + let type_name = target_type_name(&impl_def)?; + + let mut replacement_text = String::from(new_name); + replacement_text.push_str(": "); + replacement_text.push_str(self_param.mut_token().map_or("&", |_| "&mut ")); + replacement_text.push_str(type_name.as_str()); + + Some(TextEdit::replace(self_param.syntax().text_range(), replacement_text)) +} + +fn rename_self_to_param( + db: &RootDatabase, + position: FilePosition, + self_token: SyntaxToken, + new_name: &str, +) -> Option> { + let sema = Semantics::new(db); + let source_file = sema.parse(position.file_id); + let syn = source_file.syntax(); + + let text = db.file_text(position.file_id); + let fn_def = find_node_at_offset::(syn, position.offset)?; + let search_range = fn_def.syntax().text_range(); + + let mut edits: Vec = vec![]; + + for (idx, _) in text.match_indices("self") { + let offset: TextSize = idx.try_into().unwrap(); + if !search_range.contains_inclusive(offset) { + continue; + } + if let Some(ref usage) = + syn.token_at_offset(offset).find(|t| t.kind() == SyntaxKind::SELF_KW) + { + let edit = if let Some(ref self_param) = ast::SelfParam::cast(usage.parent()) { + text_edit_from_self_param(syn, self_param, new_name)? + } else { + TextEdit::replace(usage.text_range(), String::from(new_name)) + }; + edits.push(SourceFileEdit { file_id: position.file_id, edit }); + } + } + + let range = ast::SelfParam::cast(self_token.parent()) + .map_or(self_token.text_range(), |p| p.syntax().text_range()); + + Some(RangeInfo::new(range, SourceChange::source_file_edits("Rename", edits))) +} + fn rename_reference( db: &RootDatabase, position: FilePosition, @@ -774,6 +886,95 @@ mod tests { ); } + #[test] + fn test_parameter_to_self() { + test_rename( + r#" + struct Foo { + i: i32, + } + + impl Foo { + fn f(foo<|>: &mut Foo) -> i32 { + foo.i + } + } + "#, + "self", + r#" + struct Foo { + i: i32, + } + + impl Foo { + fn f(&mut self) -> i32 { + self.i + } + } + "#, + ); + } + + #[test] + fn test_self_to_parameter() { + test_rename( + r#" + struct Foo { + i: i32, + } + + impl Foo { + fn f(&mut <|>self) -> i32 { + self.i + } + } + "#, + "foo", + r#" + struct Foo { + i: i32, + } + + impl Foo { + fn f(foo: &mut Foo) -> i32 { + foo.i + } + } + "#, + ); + } + + #[test] + fn test_self_in_path_to_parameter() { + test_rename( + r#" + struct Foo { + i: i32, + } + + impl Foo { + fn f(&self) -> i32 { + let self_var = 1; + self<|>.i + } + } + "#, + "foo", + r#" + struct Foo { + i: i32, + } + + impl Foo { + fn f(foo: &Foo) -> i32 { + let self_var = 1; + foo.i + } + } + "#, + ); + } + fn test_rename(text: &str, new_name: &str, expected: &str) { let (analysis, position) = single_file_with_position(text); let source_change = analysis.rename(position, new_name).unwrap(); -- cgit v1.2.3 From c847c079fd66d7ed09c64ff398baf05317b16500 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 17 May 2020 12:09:53 +0200 Subject: Add AssistConfig --- crates/ra_ide/src/references/rename.rs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'crates/ra_ide/src/references/rename.rs') diff --git a/crates/ra_ide/src/references/rename.rs b/crates/ra_ide/src/references/rename.rs index 410dae75c..68a53ad4b 100644 --- a/crates/ra_ide/src/references/rename.rs +++ b/crates/ra_ide/src/references/rename.rs @@ -670,6 +670,7 @@ mod tests { }, ], cursor_position: None, + is_snippet: false, }, }, ) @@ -722,6 +723,7 @@ mod tests { }, ], cursor_position: None, + is_snippet: false, }, }, ) @@ -818,6 +820,7 @@ mod tests { }, ], cursor_position: None, + is_snippet: false, }, }, ) -- cgit v1.2.3 From ecac5d7de2192873c24b7b06d4964d188d8abe6a Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 May 2020 12:59:20 +0200 Subject: Switch to new magic marks --- crates/ra_ide/src/references/rename.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'crates/ra_ide/src/references/rename.rs') diff --git a/crates/ra_ide/src/references/rename.rs b/crates/ra_ide/src/references/rename.rs index 68a53ad4b..62ec8d85d 100644 --- a/crates/ra_ide/src/references/rename.rs +++ b/crates/ra_ide/src/references/rename.rs @@ -9,7 +9,7 @@ use ra_syntax::{ }; use ra_text_edit::TextEdit; use std::convert::TryInto; -use test_utils::tested_by; +use test_utils::mark; use crate::{ references::find_all_refs, FilePosition, FileSystemEdit, RangeInfo, Reference, ReferenceKind, @@ -57,13 +57,13 @@ fn source_edit_from_reference(reference: Reference, new_name: &str) -> SourceFil let file_id = reference.file_range.file_id; let range = match reference.kind { ReferenceKind::FieldShorthandForField => { - tested_by!(test_rename_struct_field_for_shorthand); + mark::hit!(test_rename_struct_field_for_shorthand); replacement_text.push_str(new_name); replacement_text.push_str(": "); TextRange::new(reference.file_range.range.start(), reference.file_range.range.start()) } ReferenceKind::FieldShorthandForLocal => { - tested_by!(test_rename_local_for_field_shorthand); + mark::hit!(test_rename_local_for_field_shorthand); replacement_text.push_str(": "); replacement_text.push_str(new_name); TextRange::new(reference.file_range.range.end(), reference.file_range.range.end()) @@ -260,7 +260,7 @@ fn rename_reference( mod tests { use insta::assert_debug_snapshot; use ra_text_edit::TextEditBuilder; - use test_utils::{assert_eq_text, covers}; + use test_utils::{assert_eq_text, mark}; use crate::{ mock_analysis::analysis_and_position, mock_analysis::single_file_with_position, FileId, @@ -492,7 +492,7 @@ mod tests { #[test] fn test_rename_struct_field_for_shorthand() { - covers!(test_rename_struct_field_for_shorthand); + mark::check!(test_rename_struct_field_for_shorthand); test_rename( r#" struct Foo { @@ -522,7 +522,7 @@ mod tests { #[test] fn test_rename_local_for_field_shorthand() { - covers!(test_rename_local_for_field_shorthand); + mark::check!(test_rename_local_for_field_shorthand); test_rename( r#" struct Foo { -- cgit v1.2.3 From ff28c79ebd4c5a9a27542917940def9d4e66eea6 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 21 May 2020 14:34:27 +0200 Subject: Remove dead code for handling cursor positions --- crates/ra_ide/src/references/rename.rs | 3 --- 1 file changed, 3 deletions(-) (limited to 'crates/ra_ide/src/references/rename.rs') diff --git a/crates/ra_ide/src/references/rename.rs b/crates/ra_ide/src/references/rename.rs index 62ec8d85d..55c3319cb 100644 --- a/crates/ra_ide/src/references/rename.rs +++ b/crates/ra_ide/src/references/rename.rs @@ -669,7 +669,6 @@ mod tests { dst_path: "bar/foo2.rs", }, ], - cursor_position: None, is_snippet: false, }, }, @@ -722,7 +721,6 @@ mod tests { dst_path: "foo2/mod.rs", }, ], - cursor_position: None, is_snippet: false, }, }, @@ -819,7 +817,6 @@ mod tests { dst_path: "bar/foo2.rs", }, ], - cursor_position: None, is_snippet: false, }, }, -- cgit v1.2.3 From 5f57491c981530103e1e26dcd280e1a2df10f853 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 21 May 2020 15:56:18 +0200 Subject: Cleanup TextEdit --- crates/ra_ide/src/references/rename.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'crates/ra_ide/src/references/rename.rs') diff --git a/crates/ra_ide/src/references/rename.rs b/crates/ra_ide/src/references/rename.rs index 55c3319cb..fd2163dad 100644 --- a/crates/ra_ide/src/references/rename.rs +++ b/crates/ra_ide/src/references/rename.rs @@ -983,8 +983,8 @@ mod tests { if let Some(change) = source_change { for edit in change.info.source_file_edits { file_id = Some(edit.file_id); - for indel in edit.edit.as_indels() { - text_edit_builder.replace(indel.delete, indel.insert.clone()); + for indel in edit.edit.into_iter() { + text_edit_builder.replace(indel.delete, indel.insert); } } } -- cgit v1.2.3