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_hir_def/src/diagnostics.rs | 3 +- crates/ra_hir_def/src/nameres.rs | 3 +- crates/ra_hir_def/src/nameres/mod_resolution.rs | 8 +-- crates/ra_ide/src/diagnostics.rs | 20 +++--- crates/ra_ide/src/references/rename.rs | 91 +++++++++++-------------- crates/ra_ide_db/src/source_change.rs | 6 +- crates/rust-analyzer/src/global_state.rs | 9 +-- crates/rust-analyzer/src/to_proto.rs | 8 +-- 8 files changed, 67 insertions(+), 81 deletions(-) (limited to 'crates') diff --git a/crates/ra_hir_def/src/diagnostics.rs b/crates/ra_hir_def/src/diagnostics.rs index 510c5e064..30db48f86 100644 --- a/crates/ra_hir_def/src/diagnostics.rs +++ b/crates/ra_hir_def/src/diagnostics.rs @@ -3,7 +3,6 @@ use std::any::Any; use hir_expand::diagnostics::Diagnostic; -use ra_db::RelativePathBuf; use ra_syntax::{ast, AstPtr, SyntaxNodePtr}; use hir_expand::{HirFileId, InFile}; @@ -12,7 +11,7 @@ use hir_expand::{HirFileId, InFile}; pub struct UnresolvedModule { pub file: HirFileId, pub decl: AstPtr, - pub candidate: RelativePathBuf, + pub candidate: String, } impl Diagnostic for UnresolvedModule { diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index f279c2ad4..b3e5f491a 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs @@ -296,7 +296,6 @@ pub enum ModuleSource { mod diagnostics { use hir_expand::diagnostics::DiagnosticSink; - use ra_db::RelativePathBuf; use ra_syntax::{ast, AstPtr}; use crate::{db::DefDatabase, diagnostics::UnresolvedModule, nameres::LocalModuleId, AstId}; @@ -306,7 +305,7 @@ mod diagnostics { UnresolvedModule { module: LocalModuleId, declaration: AstId, - candidate: RelativePathBuf, + candidate: String, }, } diff --git a/crates/ra_hir_def/src/nameres/mod_resolution.rs b/crates/ra_hir_def/src/nameres/mod_resolution.rs index cede4a6fc..19fe0615a 100644 --- a/crates/ra_hir_def/src/nameres/mod_resolution.rs +++ b/crates/ra_hir_def/src/nameres/mod_resolution.rs @@ -44,7 +44,7 @@ impl ModDir { file_id: HirFileId, name: &Name, attr_path: Option<&SmolStr>, - ) -> Result<(FileId, ModDir), RelativePathBuf> { + ) -> Result<(FileId, ModDir), String> { let file_id = file_id.original_file(db.upcast()); let mut candidate_files = Vec::new(); @@ -52,11 +52,11 @@ impl ModDir { Some(attr_path) => { let base = if self.root_non_dir_owner { self.path.parent().unwrap() } else { &self.path }; - candidate_files.push(base.join(attr_path)) + candidate_files.push(base.join(attr_path).to_string()) } None => { - candidate_files.push(self.path.join(&format!("{}.rs", name))); - candidate_files.push(self.path.join(&format!("{}/mod.rs", name))); + candidate_files.push(self.path.join(&format!("{}.rs", name)).to_string()); + candidate_files.push(self.path.join(&format!("{}/mod.rs", name)).to_string()); } }; 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, diff --git a/crates/ra_ide_db/src/source_change.rs b/crates/ra_ide_db/src/source_change.rs index f40ae8304..0bbd3c3e5 100644 --- a/crates/ra_ide_db/src/source_change.rs +++ b/crates/ra_ide_db/src/source_change.rs @@ -3,7 +3,7 @@ //! //! It can be viewed as a dual for `AnalysisChange`. -use ra_db::{FileId, RelativePathBuf, SourceRootId}; +use ra_db::FileId; use ra_text_edit::TextEdit; #[derive(Debug, Clone)] @@ -44,8 +44,8 @@ impl From> for SourceChange { #[derive(Debug, Clone)] pub enum FileSystemEdit { - CreateFile { source_root: SourceRootId, path: RelativePathBuf }, - MoveFile { src: FileId, dst_source_root: SourceRootId, dst_path: RelativePathBuf }, + CreateFile { anchor: FileId, dst: String }, + MoveFile { src: FileId, anchor: FileId, dst: String }, } impl From for SourceChange { diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs index 9d5685d88..73ca2a709 100644 --- a/crates/rust-analyzer/src/global_state.rs +++ b/crates/rust-analyzer/src/global_state.rs @@ -16,7 +16,7 @@ use ra_ide::{ Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, LibraryData, SourceRootId, }; use ra_project_model::{ProcMacroClient, ProjectWorkspace}; -use ra_vfs::{LineEndings, RootEntry, Vfs, VfsChange, VfsFile, VfsRoot, VfsTask, Watch}; +use ra_vfs::{LineEndings, RootEntry, Vfs, VfsChange, VfsFile, VfsTask, Watch}; use relative_path::RelativePathBuf; use stdx::format_to; @@ -298,9 +298,10 @@ impl GlobalStateSnapshot { self.vfs.read().file_line_endings(VfsFile(id.0)) } - pub fn path_to_url(&self, root: SourceRootId, path: &RelativePathBuf) -> Url { - let base = self.vfs.read().root2path(VfsRoot(root.0)); - let path = path.to_path(base); + pub fn anchored_path(&self, file_id: FileId, path: &str) -> Url { + let mut base = self.vfs.read().file2path(VfsFile(file_id.0)); + base.pop(); + let path = base.join(path); url_from_abs_path(&path) } diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index 881aa1c55..2851b4d31 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs @@ -528,13 +528,13 @@ pub(crate) fn resource_op( file_system_edit: FileSystemEdit, ) -> lsp_types::ResourceOp { match file_system_edit { - FileSystemEdit::CreateFile { source_root, path } => { - let uri = snap.path_to_url(source_root, &path); + FileSystemEdit::CreateFile { anchor, dst } => { + let uri = snap.anchored_path(anchor, &dst); lsp_types::ResourceOp::Create(lsp_types::CreateFile { uri, options: None }) } - FileSystemEdit::MoveFile { src, dst_source_root, dst_path } => { + FileSystemEdit::MoveFile { src, anchor, dst } => { let old_uri = snap.file_id_to_url(src); - let new_uri = snap.path_to_url(dst_source_root, &dst_path); + let new_uri = snap.anchored_path(anchor, &dst); lsp_types::ResourceOp::Rename(lsp_types::RenameFile { old_uri, new_uri, options: None }) } } -- cgit v1.2.3