mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-30 22:01:37 +00:00
move rename to a new mod
This commit is contained in:
parent
bc0f79f74a
commit
5c8cb56506
8 changed files with 233 additions and 105 deletions
|
@ -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}},
|
||||
};
|
||||
|
||||
|
|
|
@ -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<SourceFileEdit> {
|
||||
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<Option<SourceChange>> {
|
||||
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::<ast::Module>(syntax, position.offset),
|
||||
find_node_at_offset::<ast::Name>(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::<Vec<_>>()
|
||||
pub(crate) fn rename(&self, position: FilePosition, new_name: &str) -> Option<SourceChange> {
|
||||
rename(self, position, new_name)
|
||||
}
|
||||
|
||||
pub(crate) fn index_resolve(&self, name_ref: &ast::NameRef) -> Vec<FileSymbol> {
|
||||
=======
|
||||
};
|
||||
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::<Vec<_>>();
|
||||
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<Vec<FileSymbol>> {
|
||||
>>>>>>> rename mod
|
||||
let name = name_ref.text();
|
||||
let mut query = Query::new(name.to_string());
|
||||
query.exact();
|
||||
|
|
|
@ -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<Vec<SourceFileEdit>> {
|
||||
) -> Cancelable<Option<SourceChange>> {
|
||||
self.with_db(|db| db.rename(position, new_name))
|
||||
}
|
||||
|
||||
|
|
136
crates/ra_ide_api/src/rename.rs
Normal file
136
crates/ra_ide_api/src/rename.rs
Normal file
|
@ -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<SourceChange> {
|
||||
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::<ast::Name>(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<SourceChange> {
|
||||
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<SourceChange> {
|
||||
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::<Vec<_>>();
|
||||
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,
|
||||
});
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue