diff options
Diffstat (limited to 'crates/ra_hir/src/module/imp.rs')
-rw-r--r-- | crates/ra_hir/src/module/imp.rs | 50 |
1 files changed, 29 insertions, 21 deletions
diff --git a/crates/ra_hir/src/module/imp.rs b/crates/ra_hir/src/module/imp.rs index 4a19842c4..f3a346152 100644 --- a/crates/ra_hir/src/module/imp.rs +++ b/crates/ra_hir/src/module/imp.rs | |||
@@ -4,9 +4,10 @@ use ra_syntax::{ | |||
4 | ast::{self, NameOwner}, | 4 | ast::{self, NameOwner}, |
5 | SmolStr, | 5 | SmolStr, |
6 | }; | 6 | }; |
7 | use relative_path::RelativePathBuf; | 7 | use relative_path::{RelativePathBuf, RelativePath}; |
8 | use rustc_hash::{FxHashMap, FxHashSet}; | 8 | use rustc_hash::{FxHashMap, FxHashSet}; |
9 | use ra_db::{SourceRoot, SourceRootId, FileResolverImp, Cancelable, FileId,}; | 9 | use arrayvec::ArrayVec; |
10 | use ra_db::{SourceRoot, SourceRootId, Cancelable, FileId}; | ||
10 | 11 | ||
11 | use crate::{ | 12 | use crate::{ |
12 | HirDatabase, | 13 | HirDatabase, |
@@ -65,7 +66,7 @@ fn create_module_tree<'a>( | |||
65 | let mut visited = FxHashSet::default(); | 66 | let mut visited = FxHashSet::default(); |
66 | 67 | ||
67 | let source_root = db.source_root(source_root); | 68 | let source_root = db.source_root(source_root); |
68 | for &file_id in source_root.files.iter() { | 69 | for &file_id in source_root.files.values() { |
69 | let source = ModuleSource::new_file(file_id); | 70 | let source = ModuleSource::new_file(file_id); |
70 | if visited.contains(&source) { | 71 | if visited.contains(&source) { |
71 | continue; // TODO: use explicit crate_roots here | 72 | continue; // TODO: use explicit crate_roots here |
@@ -110,8 +111,7 @@ fn build_subtree( | |||
110 | 111 | ||
111 | let (points_to, problem) = match sub { | 112 | let (points_to, problem) = match sub { |
112 | Submodule::Declaration(name) => { | 113 | Submodule::Declaration(name) => { |
113 | let (points_to, problem) = | 114 | let (points_to, problem) = resolve_submodule(db, source, &name); |
114 | resolve_submodule(source, &name, &source_root.file_resolver); | ||
115 | let points_to = points_to | 115 | let points_to = points_to |
116 | .into_iter() | 116 | .into_iter() |
117 | .map(|file_id| match roots.remove(&file_id) { | 117 | .map(|file_id| match roots.remove(&file_id) { |
@@ -153,34 +153,42 @@ fn build_subtree( | |||
153 | } | 153 | } |
154 | 154 | ||
155 | fn resolve_submodule( | 155 | fn resolve_submodule( |
156 | db: &impl HirDatabase, | ||
156 | source: ModuleSource, | 157 | source: ModuleSource, |
157 | name: &SmolStr, | 158 | name: &SmolStr, |
158 | file_resolver: &FileResolverImp, | ||
159 | ) -> (Vec<FileId>, Option<Problem>) { | 159 | ) -> (Vec<FileId>, Option<Problem>) { |
160 | // TODO: handle submodules of inline modules properly | 160 | // FIXME: handle submodules of inline modules properly |
161 | let file_id = source.file_id(); | 161 | let file_id = source.file_id(); |
162 | let mod_name = file_resolver.file_stem(file_id); | 162 | let source_root_id = db.file_source_root(file_id); |
163 | let path = db.file_relative_path(file_id); | ||
164 | let root = RelativePathBuf::default(); | ||
165 | let dir_path = path.parent().unwrap_or(&root); | ||
166 | let mod_name = path.file_stem().unwrap_or("unknown"); | ||
163 | let is_dir_owner = mod_name == "mod" || mod_name == "lib" || mod_name == "main"; | 167 | let is_dir_owner = mod_name == "mod" || mod_name == "lib" || mod_name == "main"; |
164 | 168 | ||
165 | let file_mod = RelativePathBuf::from(format!("../{}.rs", name)); | 169 | let file_mod = dir_path.join(format!("{}.rs", name)); |
166 | let dir_mod = RelativePathBuf::from(format!("../{}/mod.rs", name)); | 170 | let dir_mod = dir_path.join(format!("{}/mod.rs", name)); |
167 | let file_dir_mod = RelativePathBuf::from(format!("../{}/{}.rs", mod_name, name)); | 171 | let file_dir_mod = dir_path.join(format!("{}/{}.rs", mod_name, name)); |
168 | let tmp1; | 172 | let mut candidates = ArrayVec::<[_; 2]>::new(); |
169 | let tmp2; | 173 | if is_dir_owner { |
170 | let candidates = if is_dir_owner { | 174 | candidates.push(file_mod.clone()); |
171 | tmp1 = [&file_mod, &dir_mod]; | 175 | candidates.push(dir_mod); |
172 | tmp1.iter() | ||
173 | } else { | 176 | } else { |
174 | tmp2 = [&file_dir_mod]; | 177 | candidates.push(file_dir_mod.clone()); |
175 | tmp2.iter() | ||
176 | }; | 178 | }; |
177 | 179 | let sr = db.source_root(source_root_id); | |
178 | let points_to = candidates | 180 | let points_to = candidates |
179 | .filter_map(|path| file_resolver.resolve(file_id, path)) | 181 | .into_iter() |
182 | .filter_map(|path| sr.files.get(&path)) | ||
183 | .map(|&it| it) | ||
180 | .collect::<Vec<_>>(); | 184 | .collect::<Vec<_>>(); |
181 | let problem = if points_to.is_empty() { | 185 | let problem = if points_to.is_empty() { |
182 | Some(Problem::UnresolvedModule { | 186 | Some(Problem::UnresolvedModule { |
183 | candidate: if is_dir_owner { file_mod } else { file_dir_mod }, | 187 | candidate: RelativePath::new("../").join(&if is_dir_owner { |
188 | file_mod | ||
189 | } else { | ||
190 | file_dir_mod | ||
191 | }), | ||
184 | }) | 192 | }) |
185 | } else { | 193 | } else { |
186 | None | 194 | None |