diff options
Diffstat (limited to 'crates/ra_hir/src/nameres')
-rw-r--r-- | crates/ra_hir/src/nameres/collector.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/mod_resolution.rs | 60 |
2 files changed, 20 insertions, 42 deletions
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. |
2 | use std::borrow::Cow; | ||
3 | |||
4 | use ra_db::FileId; | 2 | use ra_db::FileId; |
5 | use ra_syntax::SmolStr; | 3 | use ra_syntax::SmolStr; |
6 | use relative_path::{RelativePath, RelativePathBuf}; | 4 | use relative_path::RelativePathBuf; |
7 | 5 | ||
8 | use crate::{db::DefDatabase, HirFileId, Name}; | 6 | use 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 | ||
96 | fn normalize_attribute_path(file_path: &str) -> Cow<str> { | 85 | fn 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 | } |