//!
//! Another can of worms are macros:
//!
-//! ```
+//! ```ignore
//! macro_rules! m { () => { fn f() {} } }
//! m!();
//! fn main() {
use crate::{
defs::Definition,
- helpers::node_ext::expr_as_name_ref,
search::FileReference,
source_change::{FileSystemEdit, SourceChange},
+ syntax_helpers::node_ext::expr_as_name_ref,
RootDatabase,
};
src.with_value(name.syntax()).original_file_range_opt(sema.db)
}
Definition::GenericParam(generic_param) => match generic_param {
- hir::GenericParam::TypeParam(type_param) => {
- let src = type_param.source(sema.db)?;
+ hir::GenericParam::LifetimeParam(lifetime_param) => {
+ let src = lifetime_param.source(sema.db)?;
+ src.with_value(src.value.lifetime()?.syntax()).original_file_range_opt(sema.db)
+ }
+ _ => {
+ let x = match generic_param {
+ hir::GenericParam::TypeParam(it) => it.merge(),
+ hir::GenericParam::ConstParam(it) => it.merge(),
+ hir::GenericParam::LifetimeParam(_) => return None,
+ };
+ let src = x.source(sema.db)?;
let name = match &src.value {
- Either::Left(type_param) => type_param.name()?,
- Either::Right(_trait) => return None,
+ Either::Left(x) => x.name()?,
+ Either::Right(_) => return None,
};
src.with_value(name.syntax()).original_file_range_opt(sema.db)
}
- hir::GenericParam::LifetimeParam(lifetime_param) => {
- let src = lifetime_param.source(sema.db)?;
- let lifetime = src.value.lifetime()?;
- src.with_value(lifetime.syntax()).original_file_range_opt(sema.db)
- }
- hir::GenericParam::ConstParam(it) => name_range(it, sema),
},
Definition::Label(label) => {
let src = label.source(sema.db);
let mut source_change = SourceChange::default();
let InFile { file_id, value: def_source } = module.definition_source(sema.db);
- let file_id = file_id.original_file(sema.db);
if let ModuleSource::SourceFile(..) = def_source {
- // mod is defined in path/to/dir/mod.rs
- let path = if module.is_mod_rs(sema.db) {
- format!("../{}/mod.rs", new_name)
- } else {
- format!("{}.rs", new_name)
- };
- let dst = AnchoredPathBuf { anchor: file_id, path };
- let move_file = FileSystemEdit::MoveFile { src: file_id, dst };
- source_change.push_file_system_edit(move_file);
+ let anchor = file_id.original_file(sema.db);
+ // not mod.rs and doesn't has children, rename file only
+ if !module.is_mod_rs(sema.db) && module.children(sema.db).next().is_none() {
+ let path = format!("{}.rs", new_name);
+ let dst = AnchoredPathBuf { anchor, path };
+ source_change.push_file_system_edit(FileSystemEdit::MoveFile { src: anchor, dst })
+ } else if let Some(mod_name) = module.name(sema.db) {
+ // is mod.rs or has children, rename dir
+ let src = AnchoredPathBuf { anchor, path: mod_name.to_string() };
+ let dst = AnchoredPathBuf { anchor, path: new_name.to_string() };
+ source_change.push_file_system_edit(FileSystemEdit::MoveDir {
+ src,
+ src_id: anchor,
+ dst,
+ })
+ }
}
- if let Some(InFile { file_id, value: decl_source }) = module.declaration_source(sema.db) {
- let file_id = file_id.original_file(sema.db);
- match decl_source.name() {
- Some(name) => source_change.insert_source_edit(
- file_id,
- TextEdit::replace(name.syntax().text_range(), new_name.to_string()),
- ),
+ if let Some(src) = module.declaration_source(sema.db) {
+ let file_id = src.file_id.original_file(sema.db);
+ match src.value.name() {
+ Some(name) => {
+ if let Some(file_range) =
+ src.with_value(name.syntax()).original_file_range_opt(sema.db)
+ {
+ source_change.insert_source_edit(
+ file_id,
+ TextEdit::replace(file_range.range, new_name.to_string()),
+ )
+ };
+ }
_ => never!("Module source node is missing a name"),
}
}
+
let def = Definition::Module(module);
let usages = def.usages(sema).all();
let ref_edits = usages.iter().map(|(&file_id, references)| {
(file_id, source_edit_from_references(references, def, new_name))
}));
- let (file_id, edit) = source_edit_from_def(sema, def, new_name)?;
- source_change.insert_source_edit(file_id, edit);
+ let mut insert_def_edit = |def| {
+ let (file_id, edit) = source_edit_from_def(sema, def, new_name)?;
+ source_change.insert_source_edit(file_id, edit);
+ Ok(())
+ };
+ match def {
+ Definition::Local(l) => l
+ .associated_locals(sema.db)
+ .iter()
+ .try_for_each(|&local| insert_def_edit(Definition::Local(local))),
+ def => insert_def_edit(def),
+ }?;
Ok(source_change)
}