From 5c8cb56506646637e45a646657baf12fa9a8f49a Mon Sep 17 00:00:00 2001 From: gfreezy Date: Wed, 16 Jan 2019 21:39:01 +0800 Subject: move rename to a new mod --- crates/ra_ide_api/src/hover.rs | 3 +- crates/ra_ide_api/src/imp.rs | 95 ++-------------------------- crates/ra_ide_api/src/lib.rs | 3 +- crates/ra_ide_api/src/rename.rs | 136 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 144 insertions(+), 93 deletions(-) create mode 100644 crates/ra_ide_api/src/rename.rs (limited to 'crates/ra_ide_api/src') diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs index d91151c15..4d4bfbc4d 100644 --- a/crates/ra_ide_api/src/hover.rs +++ b/crates/ra_ide_api/src/hover.rs @@ -1,7 +1,6 @@ use ra_db::{SyntaxDatabase}; use ra_syntax::{ - AstNode, SyntaxNode, TreeArc, - ast::self, + AstNode, SyntaxNode, TreeArc, ast, algo::{find_covering_node, find_node_at_offset, find_leaf_at_offset, visit::{visitor, Visitor}}, }; diff --git a/crates/ra_ide_api/src/imp.rs b/crates/ra_ide_api/src/imp.rs index 3f0de8b5b..b52a3f4d5 100644 --- a/crates/ra_ide_api/src/imp.rs +++ b/crates/ra_ide_api/src/imp.rs @@ -1,10 +1,7 @@ use std::sync::Arc; use hir::{ - self, Problem, source_binder::{ - self, - module_from_declaration - }, ModuleSource, + self, Problem, source_binder }; use ra_db::{ FilesDatabase, SourceRoot, SourceRootId, SyntaxDatabase, @@ -22,6 +19,7 @@ use crate::{ CrateId, db, Diagnostic, FileId, FilePosition, FileRange, FileSystemEdit, Query, RootChange, SourceChange, SourceFileEdit, symbol_index::{FileSymbol, LibrarySymbolsQuery}, + rename::rename }; impl db::RootDatabase { @@ -234,94 +232,11 @@ impl db::RootDatabase { .collect() } -<<<<<<< HEAD - pub(crate) fn rename(&self, position: FilePosition, new_name: &str) -> Vec { - self.find_all_refs(position) - .iter() - .map(|(file_id, text_range)| SourceFileEdit { - file_id: *file_id, -======= - pub(crate) fn rename( - &self, - position: FilePosition, - new_name: &str, - ) -> Cancelable> { - let mut source_file_edits = Vec::new(); - let mut file_system_edits = Vec::new(); - - let source_file = self.source_file(position.file_id); - let syntax = source_file.syntax(); - // We are rename a mod - if let (Some(ast_module), Some(name)) = ( - find_node_at_offset::(syntax, position.offset), - find_node_at_offset::(syntax, position.offset), - ) { - if let Some(module) = module_from_declaration(self, position.file_id, &ast_module)? { - let (file_id, module_source) = module.definition_source(self)?; - match module_source { - ModuleSource::SourceFile(..) => { - let move_file = FileSystemEdit::MoveFile { - src: file_id, - dst_source_root: self.file_source_root(position.file_id), - dst_path: self - .file_relative_path(file_id) - .with_file_name(new_name) - .with_extension("rs"), - }; - file_system_edits.push(move_file); - } - ModuleSource::Module(..) => {} - } - } - - let edit = SourceFileEdit { - file_id: position.file_id, ->>>>>>> rename mod - edit: { - let mut builder = ra_text_edit::TextEditBuilder::default(); - builder.replace(name.syntax().range(), new_name.into()); - builder.finish() - }, -<<<<<<< HEAD - }) - .collect::>() + pub(crate) fn rename(&self, position: FilePosition, new_name: &str) -> Option { + rename(self, position, new_name) } - pub(crate) fn index_resolve(&self, name_ref: &ast::NameRef) -> Vec { -======= - }; - source_file_edits.push(edit); - } - // rename references - else { - let edit = self - .find_all_refs(position)? - .iter() - .map(|(file_id, text_range)| SourceFileEdit { - file_id: *file_id, - edit: { - let mut builder = ra_text_edit::TextEditBuilder::default(); - builder.replace(*text_range, new_name.into()); - builder.finish() - }, - }) - .collect::>(); - if edit.is_empty() { - return Ok(None); - } - source_file_edits = edit; - } - - return Ok(Some(SourceChange { - label: "rename".to_string(), - source_file_edits, - file_system_edits, - cursor_position: None, - })); - } - - pub(crate) fn index_resolve(&self, name_ref: &ast::NameRef) -> Cancelable> { ->>>>>>> rename mod + pub(crate) fn index_resolve(&self, name_ref: &ast::NameRef) -> Vec { let name = name_ref.text(); let mut query = Query::new(name.to_string()); query.exact(); diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index 7b47d7b6d..1845bf443 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs @@ -23,6 +23,7 @@ mod hover; mod call_info; mod syntax_highlighting; mod parent_module; +mod rename; use std::{fmt, sync::Arc}; @@ -464,7 +465,7 @@ impl Analysis { &self, position: FilePosition, new_name: &str, - ) -> Cancelable> { + ) -> Cancelable> { self.with_db(|db| db.rename(position, new_name)) } diff --git a/crates/ra_ide_api/src/rename.rs b/crates/ra_ide_api/src/rename.rs new file mode 100644 index 000000000..9f8a00ae7 --- /dev/null +++ b/crates/ra_ide_api/src/rename.rs @@ -0,0 +1,136 @@ +use relative_path::RelativePathBuf; + +use hir::{ + self, ModuleSource, source_binder::module_from_declaration, +}; +use ra_syntax::{ + algo::find_node_at_offset, + ast, + AstNode, + SyntaxNode +}; + +use crate::{ + db::RootDatabase, + FilePosition, + FileSystemEdit, + SourceChange, + SourceFileEdit, +}; +use ra_db::{FilesDatabase, SyntaxDatabase}; +use relative_path::RelativePath; + +pub(crate) fn rename( + db: &RootDatabase, + position: FilePosition, + new_name: &str, +) -> Option { + let source_file = db.source_file(position.file_id); + let syntax = source_file.syntax(); + + if let Some((ast_name, ast_module)) = find_name_and_module_at_offset(syntax, position) { + rename_mod(db, ast_name, ast_module, position, new_name) + } else { + rename_reference(db, position, new_name) + } +} + +fn find_name_and_module_at_offset( + syntax: &SyntaxNode, + position: FilePosition, +) -> Option<(&ast::Name, &ast::Module)> { + let ast_name = find_node_at_offset::(syntax, position.offset); + let ast_name_parent = ast_name + .and_then(|n| n.syntax().parent()) + .and_then(|p| ast::Module::cast(p)); + + if let (Some(ast_module), Some(name)) = (ast_name_parent, ast_name) { + return Some((name, ast_module)); + } + None +} + +fn rename_mod( + db: &RootDatabase, + ast_name: &ast::Name, + ast_module: &ast::Module, + position: FilePosition, + new_name: &str, +) -> Option { + let mut source_file_edits = Vec::new(); + let mut file_system_edits = Vec::new(); + + if let Some(module) = module_from_declaration(db, position.file_id, &ast_module) { + let (file_id, module_source) = module.definition_source(db); + match module_source { + ModuleSource::SourceFile(..) => { + let mod_path: RelativePathBuf = db.file_relative_path(file_id); + // mod is defined in path/to/dir/mod.rs + let dst_path = if mod_path.file_stem() == Some("mod") { + mod_path + .parent() + .and_then(|p| p.parent()) + .or_else(|| Some(RelativePath::new(""))) + .map(|p| p.join(new_name).join("mod.rs")) + } else { + Some(mod_path.with_file_name(new_name).with_extension("rs")) + }; + if let Some(path) = dst_path { + let move_file = FileSystemEdit::MoveFile { + src: file_id, + dst_source_root: db.file_source_root(position.file_id), + dst_path: path, + }; + file_system_edits.push(move_file); + } + } + ModuleSource::Module(..) => {} + } + } + + let edit = SourceFileEdit { + file_id: position.file_id, + edit: { + let mut builder = ra_text_edit::TextEditBuilder::default(); + builder.replace(ast_name.syntax().range(), new_name.into()); + builder.finish() + }, + }; + source_file_edits.push(edit); + + return Some(SourceChange { + label: "rename".to_string(), + source_file_edits, + file_system_edits, + cursor_position: None, + }); +} + +fn rename_reference( + db: &RootDatabase, + position: FilePosition, + new_name: &str, +) -> Option { + let edit = db + .find_all_refs(position) + .iter() + .map(|(file_id, text_range)| SourceFileEdit { + file_id: *file_id, + edit: { + let mut builder = ra_text_edit::TextEditBuilder::default(); + builder.replace(*text_range, new_name.into()); + builder.finish() + }, + }) + .collect::>(); + if edit.is_empty() { + return None; + } + + return Some(SourceChange { + label: "rename".to_string(), + source_file_edits: edit, + file_system_edits: Vec::new(), + cursor_position: None, + }); +} -- cgit v1.2.3