From 33965f0f3ee236ab57c1389d5693511915ab4554 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 5 Sep 2019 21:36:40 +0300 Subject: [PATCH] fix renaming of modules --- crates/ra_ide_api/src/lib.rs | 4 +- crates/ra_ide_api/src/references.rs | 154 ++++++++++-------- .../ra_lsp_server/src/main_loop/handlers.rs | 14 +- 3 files changed, 92 insertions(+), 80 deletions(-) diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index 514dcaf962..e90fbd4285 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs @@ -466,7 +466,7 @@ impl Analysis { &self, position: FilePosition, ) -> Cancelable> { - self.with_db(|db| references::find_all_refs(db, position)) + self.with_db(|db| references::find_all_refs(db, position).map(|it| it.info)) } /// Returns a short text describing element at position. @@ -536,7 +536,7 @@ impl Analysis { &self, position: FilePosition, new_name: &str, - ) -> Cancelable> { + ) -> Cancelable>> { self.with_db(|db| references::rename(db, position, new_name)) } diff --git a/crates/ra_ide_api/src/references.rs b/crates/ra_ide_api/src/references.rs index d8a00067fe..5f1f0efc30 100644 --- a/crates/ra_ide_api/src/references.rs +++ b/crates/ra_ide_api/src/references.rs @@ -4,7 +4,7 @@ use ra_syntax::{algo::find_node_at_offset, ast, AstNode, SourceFile, SyntaxNode} use relative_path::{RelativePath, RelativePathBuf}; use crate::{ - db::RootDatabase, FileId, FilePosition, FileRange, FileSystemEdit, NavigationTarget, + db::RootDatabase, FileId, FilePosition, FileRange, FileSystemEdit, NavigationTarget, RangeInfo, SourceChange, SourceFileEdit, TextRange, }; @@ -48,9 +48,9 @@ impl IntoIterator for ReferenceSearchResult { pub(crate) fn find_all_refs( db: &RootDatabase, position: FilePosition, -) -> Option { +) -> Option> { let parse = db.parse(position.file_id); - let (binding, analyzer) = find_binding(db, &parse.tree(), position)?; + let RangeInfo { range, info: (binding, analyzer) } = find_binding(db, &parse.tree(), position)?; let declaration = NavigationTarget::from_bind_pat(position.file_id, &binding); let references = analyzer @@ -59,24 +59,26 @@ pub(crate) fn find_all_refs( .map(move |ref_desc| FileRange { file_id: position.file_id, range: ref_desc.range }) .collect::>(); - return Some(ReferenceSearchResult { declaration, references }); + return Some(RangeInfo::new(range, ReferenceSearchResult { declaration, references })); fn find_binding<'a>( db: &RootDatabase, source_file: &SourceFile, position: FilePosition, - ) -> Option<(ast::BindPat, hir::SourceAnalyzer)> { + ) -> Option> { let syntax = source_file.syntax(); if let Some(binding) = find_node_at_offset::(syntax, position.offset) { + let range = binding.syntax().text_range(); let analyzer = hir::SourceAnalyzer::new(db, position.file_id, binding.syntax(), None); - return Some((binding, analyzer)); + return Some(RangeInfo::new(range, (binding, analyzer))); }; let name_ref = find_node_at_offset::(syntax, position.offset)?; + let range = name_ref.syntax().text_range(); let analyzer = hir::SourceAnalyzer::new(db, position.file_id, name_ref.syntax(), None); let resolved = analyzer.resolve_local_name(&name_ref)?; if let Either::A(ptr) = resolved.ptr() { if let ast::Pat::BindPat(binding) = ptr.to_node(source_file.syntax()) { - return Some((binding, analyzer)); + return Some(RangeInfo::new(range, (binding, analyzer))); } } None @@ -87,12 +89,14 @@ pub(crate) fn rename( db: &RootDatabase, position: FilePosition, new_name: &str, -) -> Option { +) -> Option> { let parse = db.parse(position.file_id); if let Some((ast_name, ast_module)) = find_name_and_module_at_offset(parse.tree().syntax(), position) { + let range = ast_name.syntax().text_range(); rename_mod(db, &ast_name, &ast_module, position, new_name) + .map(|info| RangeInfo::new(range, info)) } else { rename_reference(db, position, new_name) } @@ -107,7 +111,7 @@ fn find_name_and_module_at_offset( Some((ast_name, ast_module)) } -fn source_edit_from_fileid_range( +fn source_edit_from_file_id_range( file_id: FileId, range: TextRange, new_name: &str, @@ -179,19 +183,19 @@ fn rename_reference( db: &RootDatabase, position: FilePosition, new_name: &str, -) -> Option { - let refs = find_all_refs(db, position)?; +) -> Option> { + let RangeInfo { range, info: refs } = find_all_refs(db, position)?; let edit = refs .into_iter() - .map(|range| source_edit_from_fileid_range(range.file_id, range.range, new_name)) + .map(|range| source_edit_from_file_id_range(range.file_id, range.range, new_name)) .collect::>(); if edit.is_empty() { return None; } - Some(SourceChange::source_file_edits("rename", edit)) + Some(RangeInfo::new(range, SourceChange::source_file_edits("rename", edit))) } #[cfg(test)] @@ -342,38 +346,43 @@ mod tests { let new_name = "foo2"; let source_change = analysis.rename(position, new_name).unwrap(); assert_debug_snapshot!(&source_change, -@r#"Some( - SourceChange { - label: "rename", - source_file_edits: [ - SourceFileEdit { - file_id: FileId( - 2, - ), - edit: TextEdit { - atoms: [ - AtomTextEdit { - delete: [4; 7), - insert: "foo2", +@r###" + Some( + RangeInfo { + range: [4; 7), + info: SourceChange { + label: "rename", + source_file_edits: [ + SourceFileEdit { + file_id: FileId( + 2, + ), + edit: TextEdit { + atoms: [ + AtomTextEdit { + delete: [4; 7), + insert: "foo2", + }, + ], + }, }, ], + file_system_edits: [ + MoveFile { + src: FileId( + 3, + ), + dst_source_root: SourceRootId( + 0, + ), + dst_path: "bar/foo2.rs", + }, + ], + cursor_position: None, }, }, - ], - file_system_edits: [ - MoveFile { - src: FileId( - 3, - ), - dst_source_root: SourceRootId( - 0, - ), - dst_path: "bar/foo2.rs", - }, - ], - cursor_position: None, - }, -)"#); + ) + "###); } #[test] @@ -389,38 +398,43 @@ mod tests { let new_name = "foo2"; let source_change = analysis.rename(position, new_name).unwrap(); assert_debug_snapshot!(&source_change, - @r###"Some( - SourceChange { - label: "rename", - source_file_edits: [ - SourceFileEdit { - file_id: FileId( - 1, - ), - edit: TextEdit { - atoms: [ - AtomTextEdit { - delete: [4; 7), - insert: "foo2", + @r###" + Some( + RangeInfo { + range: [4; 7), + info: SourceChange { + label: "rename", + source_file_edits: [ + SourceFileEdit { + file_id: FileId( + 1, + ), + edit: TextEdit { + atoms: [ + AtomTextEdit { + delete: [4; 7), + insert: "foo2", + }, + ], + }, }, ], + file_system_edits: [ + MoveFile { + src: FileId( + 2, + ), + dst_source_root: SourceRootId( + 0, + ), + dst_path: "foo2/mod.rs", + }, + ], + cursor_position: None, }, }, - ], - file_system_edits: [ - MoveFile { - src: FileId( - 2, - ), - dst_source_root: SourceRootId( - 0, - ), - dst_path: "foo2/mod.rs", - }, - ], - cursor_position: None, - }, -)"### + ) + "### ); } @@ -430,7 +444,7 @@ mod tests { let mut text_edit_builder = ra_text_edit::TextEditBuilder::default(); let mut file_id: Option = None; if let Some(change) = source_change { - for edit in change.source_file_edits { + 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()); diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index eb805a6d39..948d543ea2 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs @@ -460,18 +460,16 @@ pub fn handle_prepare_rename( // We support renaming references like handle_rename does. // In the future we may want to reject the renaming of things like keywords here too. - let refs = match world.analysis().find_all_refs(position)? { + let optional_change = world.analysis().rename(position, "dummy")?; + let range = match optional_change { None => return Ok(None), - Some(refs) => refs, + Some(it) => it.range, }; - // Refs should always have a declaration - let r = refs.declaration(); let file_id = params.text_document.try_conv_with(&world)?; let line_index = world.analysis().file_line_index(file_id)?; - let loc = to_location(r.file_id(), r.range(), &world, &line_index)?; - - Ok(Some(PrepareRenameResponse::Range(loc.range))) + let range = range.conv_with(&line_index); + Ok(Some(PrepareRenameResponse::Range(range))) } pub fn handle_rename(world: WorldSnapshot, params: RenameParams) -> Result> { @@ -488,7 +486,7 @@ pub fn handle_rename(world: WorldSnapshot, params: RenameParams) -> Result return Ok(None), - Some(it) => it, + Some(it) => it.info, }; let source_change_req = change.try_conv_with(&world)?;