aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-10-11 08:49:39 +0100
committerGitHub <[email protected]>2019-10-11 08:49:39 +0100
commitf70c54ccfbf25a0d9c136c9176f5e17a4cf0e13a (patch)
treeab289f447399dca72e9d9d0193265ad51ccf6c82
parentef6ccd75e0961956cb8bd07c59382f85da1dadd3 (diff)
parente44c7ce2004913d3e928bc03df64647c6059ae0e (diff)
Merge #1994
1994: remove last traces of source roots from hir r=matklad a=matklad Co-authored-by: Aleksey Kladov <[email protected]>
-rw-r--r--crates/ra_db/src/lib.rs26
-rw-r--r--crates/ra_hir/src/debug.rs20
-rw-r--r--crates/ra_hir/src/nameres/collector.rs2
-rw-r--r--crates/ra_hir/src/nameres/mod_resolution.rs60
-rw-r--r--crates/ra_ide_api/src/diagnostics.rs11
5 files changed, 71 insertions, 48 deletions
diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs
index 603daed37..4d3a9c036 100644
--- a/crates/ra_db/src/lib.rs
+++ b/crates/ra_db/src/lib.rs
@@ -6,7 +6,7 @@ use std::{panic, sync::Arc};
6 6
7use ra_prof::profile; 7use ra_prof::profile;
8use ra_syntax::{ast, Parse, SourceFile, TextRange, TextUnit}; 8use ra_syntax::{ast, Parse, SourceFile, TextRange, TextUnit};
9use relative_path::RelativePathBuf; 9use relative_path::{RelativePath, RelativePathBuf};
10 10
11pub use crate::{ 11pub use crate::{
12 cancellation::Canceled, 12 cancellation::Canceled,
@@ -71,6 +71,11 @@ pub trait SourceDatabase: CheckCanceled + std::fmt::Debug {
71 /// Text of the file. 71 /// Text of the file.
72 #[salsa::input] 72 #[salsa::input]
73 fn file_text(&self, file_id: FileId) -> Arc<String>; 73 fn file_text(&self, file_id: FileId) -> Arc<String>;
74
75 #[salsa::transparent]
76 fn resolve_relative_path(&self, anchor: FileId, relative_path: &RelativePath)
77 -> Option<FileId>;
78
74 // Parses the file into the syntax tree. 79 // Parses the file into the syntax tree.
75 #[salsa::invoke(parse_query)] 80 #[salsa::invoke(parse_query)]
76 fn parse(&self, file_id: FileId) -> Parse<ast::SourceFile>; 81 fn parse(&self, file_id: FileId) -> Parse<ast::SourceFile>;
@@ -89,6 +94,25 @@ pub trait SourceDatabase: CheckCanceled + std::fmt::Debug {
89 fn crate_graph(&self) -> Arc<CrateGraph>; 94 fn crate_graph(&self) -> Arc<CrateGraph>;
90} 95}
91 96
97fn resolve_relative_path(
98 db: &impl SourceDatabase,
99 anchor: FileId,
100 relative_path: &RelativePath,
101) -> Option<FileId> {
102 let path = {
103 let mut path = db.file_relative_path(anchor);
104 // Workaround for relative path API: turn `lib.rs` into ``.
105 if !path.pop() {
106 path = RelativePathBuf::default();
107 }
108 path.push(relative_path);
109 path.normalize()
110 };
111 let source_root = db.file_source_root(anchor);
112 let source_root = db.source_root(source_root);
113 source_root.file_by_relative_path(&path)
114}
115
92fn source_root_crates(db: &impl SourceDatabase, id: SourceRootId) -> Arc<Vec<CrateId>> { 116fn source_root_crates(db: &impl SourceDatabase, id: SourceRootId) -> Arc<Vec<CrateId>> {
93 let root = db.source_root(id); 117 let root = db.source_root(id);
94 let graph = db.crate_graph(); 118 let graph = db.crate_graph();
diff --git a/crates/ra_hir/src/debug.rs b/crates/ra_hir/src/debug.rs
index 87f3180c3..48b69000b 100644
--- a/crates/ra_hir/src/debug.rs
+++ b/crates/ra_hir/src/debug.rs
@@ -22,7 +22,7 @@ use std::fmt;
22 22
23use ra_db::{CrateId, FileId}; 23use ra_db::{CrateId, FileId};
24 24
25use crate::{db::HirDatabase, Crate, Module, Name}; 25use crate::{db::HirDatabase, Crate, HirFileId, Module, Name};
26 26
27impl Crate { 27impl Crate {
28 pub fn debug(self, db: &impl HirDebugDatabase) -> impl fmt::Debug + '_ { 28 pub fn debug(self, db: &impl HirDebugDatabase) -> impl fmt::Debug + '_ {
@@ -36,6 +36,12 @@ impl Module {
36 } 36 }
37} 37}
38 38
39impl HirFileId {
40 pub fn debug(self, db: &impl HirDebugDatabase) -> impl fmt::Debug + '_ {
41 debug_fn(move |fmt| db.debug_hir_file_id(self, fmt))
42 }
43}
44
39pub trait HirDebugHelper: HirDatabase { 45pub trait HirDebugHelper: HirDatabase {
40 fn crate_name(&self, _krate: CrateId) -> Option<String> { 46 fn crate_name(&self, _krate: CrateId) -> Option<String> {
41 None 47 None
@@ -48,6 +54,7 @@ pub trait HirDebugHelper: HirDatabase {
48pub trait HirDebugDatabase { 54pub trait HirDebugDatabase {
49 fn debug_crate(&self, krate: Crate, fmt: &mut fmt::Formatter<'_>) -> fmt::Result; 55 fn debug_crate(&self, krate: Crate, fmt: &mut fmt::Formatter<'_>) -> fmt::Result;
50 fn debug_module(&self, module: Module, fmt: &mut fmt::Formatter<'_>) -> fmt::Result; 56 fn debug_module(&self, module: Module, fmt: &mut fmt::Formatter<'_>) -> fmt::Result;
57 fn debug_hir_file_id(&self, file_id: HirFileId, fmt: &mut fmt::Formatter<'_>) -> fmt::Result;
51} 58}
52 59
53impl<DB: HirDebugHelper> HirDebugDatabase for DB { 60impl<DB: HirDebugHelper> HirDebugDatabase for DB {
@@ -62,12 +69,19 @@ impl<DB: HirDebugHelper> HirDebugDatabase for DB {
62 69
63 fn debug_module(&self, module: Module, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { 70 fn debug_module(&self, module: Module, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
64 let file_id = module.definition_source(self).file_id.original_file(self); 71 let file_id = module.definition_source(self).file_id.original_file(self);
65 let path = self.file_path(file_id); 72 let path = self.file_path(file_id).unwrap_or_else(|| "N/A".to_string());
66 fmt.debug_struct("Module") 73 fmt.debug_struct("Module")
67 .field("name", &module.name(self).unwrap_or_else(Name::missing)) 74 .field("name", &module.name(self).unwrap_or_else(Name::missing))
68 .field("path", &path.unwrap_or_else(|| "N/A".to_string())) 75 .field("path", &path)
69 .finish() 76 .finish()
70 } 77 }
78
79 fn debug_hir_file_id(&self, file_id: HirFileId, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
80 let original = file_id.original_file(self);
81 let path = self.file_path(original).unwrap_or_else(|| "N/A".to_string());
82 let is_macro = file_id != original.into();
83 fmt.debug_struct("HirFileId").field("path", &path).field("macro", &is_macro).finish()
84 }
71} 85}
72 86
73fn debug_fn(f: impl Fn(&mut fmt::Formatter<'_>) -> fmt::Result) -> impl fmt::Debug { 87fn debug_fn(f: impl Fn(&mut fmt::Formatter<'_>) -> fmt::Result) -> impl fmt::Debug {
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs
index aa5885f04..b5fe16bfa 100644
--- a/crates/ra_hir/src/nameres/collector.rs
+++ b/crates/ra_hir/src/nameres/collector.rs
@@ -584,7 +584,7 @@ where
584 // out of line module, resolve, parse and recurse 584 // out of line module, resolve, parse and recurse
585 raw::ModuleData::Declaration { name, ast_id } => { 585 raw::ModuleData::Declaration { name, ast_id } => {
586 let ast_id = ast_id.with_file_id(self.file_id); 586 let ast_id = ast_id.with_file_id(self.file_id);
587 match self.mod_dir.resolve_submodule( 587 match self.mod_dir.resolve_declaration(
588 self.def_collector.db, 588 self.def_collector.db,
589 self.file_id, 589 self.file_id,
590 name, 590 name,
diff --git a/crates/ra_hir/src/nameres/mod_resolution.rs b/crates/ra_hir/src/nameres/mod_resolution.rs
index f50f9abe6..e8b808514 100644
--- a/crates/ra_hir/src/nameres/mod_resolution.rs
+++ b/crates/ra_hir/src/nameres/mod_resolution.rs
@@ -1,9 +1,7 @@
1//! This module resolves `mod foo;` declaration to file. 1//! This module resolves `mod foo;` declaration to file.
2use std::borrow::Cow;
3
4use ra_db::FileId; 2use ra_db::FileId;
5use ra_syntax::SmolStr; 3use ra_syntax::SmolStr;
6use relative_path::{RelativePath, RelativePathBuf}; 4use relative_path::RelativePathBuf;
7 5
8use crate::{db::DefDatabase, HirFileId, Name}; 6use crate::{db::DefDatabase, HirFileId, Name};
9 7
@@ -28,23 +26,22 @@ impl ModDir {
28 attr_path: Option<&SmolStr>, 26 attr_path: Option<&SmolStr>,
29 ) -> ModDir { 27 ) -> ModDir {
30 let mut path = self.path.clone(); 28 let mut path = self.path.clone();
31 match attr_path { 29 match attr_to_path(attr_path) {
32 None => path.push(&name.to_string()), 30 None => path.push(&name.to_string()),
33 Some(attr_path) => { 31 Some(attr_path) => {
34 if self.root_non_dir_owner { 32 if self.root_non_dir_owner {
35 path = path 33 // Workaround for relative path API: turn `lib.rs` into ``.
36 .parent() 34 if !path.pop() {
37 .map(|it| it.to_relative_path_buf()) 35 path = RelativePathBuf::default();
38 .unwrap_or_else(RelativePathBuf::new); 36 }
39 } 37 }
40 let attr_path = &*normalize_attribute_path(attr_path); 38 path.push(attr_path);
41 path.push(RelativePath::new(attr_path));
42 } 39 }
43 } 40 }
44 ModDir { path, root_non_dir_owner: false } 41 ModDir { path, root_non_dir_owner: false }
45 } 42 }
46 43
47 pub(super) fn resolve_submodule( 44 pub(super) fn resolve_declaration(
48 &self, 45 &self,
49 db: &impl DefDatabase, 46 db: &impl DefDatabase,
50 file_id: HirFileId, 47 file_id: HirFileId,
@@ -53,32 +50,25 @@ impl ModDir {
53 ) -> Result<(FileId, ModDir), RelativePathBuf> { 50 ) -> Result<(FileId, ModDir), RelativePathBuf> {
54 let empty_path = RelativePathBuf::default(); 51 let empty_path = RelativePathBuf::default();
55 let file_id = file_id.original_file(db); 52 let file_id = file_id.original_file(db);
56 let base_dir = {
57 let path = db.file_relative_path(file_id);
58 path.parent().unwrap_or(&empty_path).join(&self.path)
59 };
60 53
61 let mut candidate_files = Vec::new(); 54 let mut candidate_files = Vec::new();
62 match attr_path { 55 match attr_to_path(attr_path) {
63 Some(attr) => { 56 Some(attr_path) => {
64 let base = if self.root_non_dir_owner { 57 let base = if self.root_non_dir_owner {
65 base_dir.parent().unwrap_or(&empty_path) 58 self.path.parent().unwrap_or(&empty_path)
66 } else { 59 } else {
67 &base_dir 60 &self.path
68 }; 61 };
69 candidate_files.push(base.join(&*normalize_attribute_path(attr))) 62 candidate_files.push(base.join(attr_path))
70 } 63 }
71 None => { 64 None => {
72 candidate_files.push(base_dir.join(&format!("{}.rs", name))); 65 candidate_files.push(self.path.join(&format!("{}.rs", name)));
73 candidate_files.push(base_dir.join(&format!("{}/mod.rs", name))); 66 candidate_files.push(self.path.join(&format!("{}/mod.rs", name)));
74 } 67 }
75 }; 68 };
76 69
77 let source_root_id = db.file_source_root(file_id);
78 let source_root = db.source_root(source_root_id);
79 for candidate in candidate_files.iter() { 70 for candidate in candidate_files.iter() {
80 let candidate = candidate.normalize(); 71 if let Some(file_id) = db.resolve_relative_path(file_id, candidate) {
81 if let Some(file_id) = source_root.file_by_relative_path(&candidate) {
82 let mut root_non_dir_owner = false; 72 let mut root_non_dir_owner = false;
83 let mut mod_path = RelativePathBuf::new(); 73 let mut mod_path = RelativePathBuf::new();
84 if !(candidate.ends_with("mod.rs") || attr_path.is_some()) { 74 if !(candidate.ends_with("mod.rs") || attr_path.is_some()) {
@@ -88,22 +78,10 @@ impl ModDir {
88 return Ok((file_id, ModDir { path: mod_path, root_non_dir_owner })); 78 return Ok((file_id, ModDir { path: mod_path, root_non_dir_owner }));
89 } 79 }
90 } 80 }
91 let suggestion = candidate_files.first().unwrap(); 81 Err(candidate_files.remove(0))
92 Err(base_dir.join(suggestion))
93 } 82 }
94} 83}
95 84
96fn normalize_attribute_path(file_path: &str) -> Cow<str> { 85fn attr_to_path(attr: Option<&SmolStr>) -> Option<RelativePathBuf> {
97 let current_dir = "./"; 86 attr.and_then(|it| RelativePathBuf::from_path(&it.replace("\\", "/")).ok())
98 let windows_path_separator = r#"\"#;
99 let current_dir_normalize = if file_path.starts_with(current_dir) {
100 &file_path[current_dir.len()..]
101 } else {
102 file_path
103 };
104 if current_dir_normalize.contains(windows_path_separator) {
105 Cow::Owned(current_dir_normalize.replace(windows_path_separator, "/"))
106 } else {
107 Cow::Borrowed(current_dir_normalize)
108 }
109} 87}
diff --git a/crates/ra_ide_api/src/diagnostics.rs b/crates/ra_ide_api/src/diagnostics.rs
index 0435188c8..65f061443 100644
--- a/crates/ra_ide_api/src/diagnostics.rs
+++ b/crates/ra_ide_api/src/diagnostics.rs
@@ -12,6 +12,7 @@ use ra_syntax::{
12 Location, SyntaxNode, TextRange, T, 12 Location, SyntaxNode, TextRange, T,
13}; 13};
14use ra_text_edit::{TextEdit, TextEditBuilder}; 14use ra_text_edit::{TextEdit, TextEditBuilder};
15use relative_path::RelativePath;
15 16
16use crate::{db::RootDatabase, Diagnostic, FileId, FileSystemEdit, SourceChange, SourceFileEdit}; 17use crate::{db::RootDatabase, Diagnostic, FileId, FileSystemEdit, SourceChange, SourceFileEdit};
17 18
@@ -47,8 +48,14 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic>
47 }) 48 })
48 }) 49 })
49 .on::<hir::diagnostics::UnresolvedModule, _>(|d| { 50 .on::<hir::diagnostics::UnresolvedModule, _>(|d| {
50 let source_root = db.file_source_root(d.source().file_id.original_file(db)); 51 let original_file = d.source().file_id.original_file(db);
51 let create_file = FileSystemEdit::CreateFile { source_root, path: d.candidate.clone() }; 52 let source_root = db.file_source_root(original_file);
53 let path = db
54 .file_relative_path(original_file)
55 .parent()
56 .unwrap_or_else(|| RelativePath::new(""))
57 .join(&d.candidate);
58 let create_file = FileSystemEdit::CreateFile { source_root, path };
52 let fix = SourceChange::file_system_edit("create module", create_file); 59 let fix = SourceChange::file_system_edit("create module", create_file);
53 res.borrow_mut().push(Diagnostic { 60 res.borrow_mut().push(Diagnostic {
54 range: d.highlight_range(), 61 range: d.highlight_range(),