From 3c72fc05738b8a08dbf90dab18a15b9894d9e2a1 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 16 Jun 2020 18:45:58 +0200 Subject: Anchor file-system operations to the file, and not to the source root. Anchoring to the SourceRoot wont' work if the path is absolute: #[path = "/tmp/foo.rs"] mod foo; Anchoring to a file will. However, we *should* anchor, instead of just producing an abs path. I can imagine a situation where, for example, rust-analyzer processes crates from different machines (or, for example, from in-memory git branch), where the same absolute path in different crates might refer to different files in the end! --- crates/ra_ide/src/diagnostics.rs | 20 +++----- crates/ra_ide/src/references/rename.rs | 91 +++++++++++++++------------------- 2 files changed, 49 insertions(+), 62 deletions(-) (limited to 'crates/ra_ide/src') diff --git a/crates/ra_ide/src/diagnostics.rs b/crates/ra_ide/src/diagnostics.rs index e1bfd72f9..fd9abb55b 100644 --- a/crates/ra_ide/src/diagnostics.rs +++ b/crates/ra_ide/src/diagnostics.rs @@ -11,7 +11,7 @@ use hir::{ Semantics, }; use itertools::Itertools; -use ra_db::{RelativePath, SourceDatabase, SourceDatabaseExt}; +use ra_db::SourceDatabase; use ra_ide_db::RootDatabase; use ra_prof::profile; use ra_syntax::{ @@ -57,14 +57,10 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec }) .on::(|d| { let original_file = d.source().file_id.original_file(db); - let source_root = db.file_source_root(original_file); - let path = db - .file_relative_path(original_file) - .parent() - .unwrap_or_else(|| RelativePath::new("")) - .join(&d.candidate); - let fix = - Fix::new("Create module", FileSystemEdit::CreateFile { source_root, path }.into()); + let fix = Fix::new( + "Create module", + FileSystemEdit::CreateFile { anchor: original_file, dst: d.candidate.clone() }.into(), + ); res.borrow_mut().push(Diagnostic { range: sema.diagnostics_range(d).range, message: d.message(), @@ -612,10 +608,10 @@ mod tests { source_file_edits: [], file_system_edits: [ CreateFile { - source_root: SourceRootId( - 0, + anchor: FileId( + 1, ), - path: "foo.rs", + dst: "foo.rs", }, ], is_snippet: false, diff --git a/crates/ra_ide/src/references/rename.rs b/crates/ra_ide/src/references/rename.rs index 915d4f4d3..c4f07f905 100644 --- a/crates/ra_ide/src/references/rename.rs +++ b/crates/ra_ide/src/references/rename.rs @@ -1,7 +1,7 @@ //! FIXME: write short doc here use hir::{ModuleSource, Semantics}; -use ra_db::{RelativePath, RelativePathBuf, SourceDatabaseExt}; +use ra_db::{RelativePathBuf, SourceDatabaseExt}; use ra_ide_db::RootDatabase; use ra_syntax::{ algo::find_node_at_offset, ast, ast::TypeAscriptionOwner, lex_single_valid_syntax_kind, @@ -92,23 +92,14 @@ fn rename_mod( ModuleSource::SourceFile(..) => { let mod_path: RelativePathBuf = sema.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")) + let dst = if mod_path.file_stem() == Some("mod") { + format!("../{}/mod.rs", new_name) } else { - Some(mod_path.with_file_name(new_name).with_extension("rs")) + format!("{}.rs", new_name) }; - if let Some(path) = dst_path { - let move_file = FileSystemEdit::MoveFile { - src: file_id, - dst_source_root: sema.db.file_source_root(position.file_id), - dst_path: path, - }; - file_system_edits.push(move_file); - } + let move_file = + FileSystemEdit::MoveFile { src: file_id, anchor: position.file_id, dst }; + file_system_edits.push(move_file); } ModuleSource::Module(..) => {} } @@ -623,16 +614,16 @@ mod tests { #[test] fn test_rename_mod() { let (analysis, position) = analysis_and_position( - " - //- /lib.rs - mod bar; + r#" +//- /lib.rs +mod bar; - //- /bar.rs - mod foo<|>; +//- /bar.rs +mod foo<|>; - //- /bar/foo.rs - // emtpy - ", +//- /bar/foo.rs +// emtpy + "#, ); let new_name = "foo2"; let source_change = analysis.rename(position, new_name).unwrap(); @@ -662,10 +653,10 @@ mod tests { src: FileId( 3, ), - dst_source_root: SourceRootId( - 0, + anchor: FileId( + 2, ), - dst_path: "bar/foo2.rs", + dst: "foo2.rs", }, ], is_snippet: false, @@ -678,12 +669,12 @@ mod tests { #[test] fn test_rename_mod_in_dir() { let (analysis, position) = analysis_and_position( - " - //- /lib.rs - mod fo<|>o; - //- /foo/mod.rs - // emtpy - ", + r#" +//- /lib.rs +mod fo<|>o; +//- /foo/mod.rs +// emtpy + "#, ); let new_name = "foo2"; let source_change = analysis.rename(position, new_name).unwrap(); @@ -713,10 +704,10 @@ mod tests { src: FileId( 2, ), - dst_source_root: SourceRootId( - 0, + anchor: FileId( + 1, ), - dst_path: "foo2/mod.rs", + dst: "../foo2/mod.rs", }, ], is_snippet: false, @@ -753,19 +744,19 @@ mod tests { #[test] fn test_rename_mod_filename_and_path() { let (analysis, position) = analysis_and_position( - " - //- /lib.rs - mod bar; - fn f() { - bar::foo::fun() - } + r#" +//- /lib.rs +mod bar; +fn f() { + bar::foo::fun() +} - //- /bar.rs - pub mod foo<|>; +//- /bar.rs +pub mod foo<|>; - //- /bar/foo.rs - // pub fn fun() {} - ", +//- /bar/foo.rs +// pub fn fun() {} + "#, ); let new_name = "foo2"; let source_change = analysis.rename(position, new_name).unwrap(); @@ -808,10 +799,10 @@ mod tests { src: FileId( 3, ), - dst_source_root: SourceRootId( - 0, + anchor: FileId( + 2, ), - dst_path: "bar/foo2.rs", + dst: "foo2.rs", }, ], is_snippet: false, -- cgit v1.2.3