aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/module/imp.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/module/imp.rs')
-rw-r--r--crates/ra_hir/src/module/imp.rs50
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};
7use relative_path::RelativePathBuf; 7use relative_path::{RelativePathBuf, RelativePath};
8use rustc_hash::{FxHashMap, FxHashSet}; 8use rustc_hash::{FxHashMap, FxHashSet};
9use ra_db::{SourceRoot, SourceRootId, FileResolverImp, Cancelable, FileId,}; 9use arrayvec::ArrayVec;
10use ra_db::{SourceRoot, SourceRootId, Cancelable, FileId};
10 11
11use crate::{ 12use 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
155fn resolve_submodule( 155fn 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