diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/base_db/src/lib.rs | 70 | ||||
-rw-r--r-- | crates/vfs/src/file_set.rs | 65 |
2 files changed, 74 insertions, 61 deletions
diff --git a/crates/base_db/src/lib.rs b/crates/base_db/src/lib.rs index 030b96829..9733e1fd3 100644 --- a/crates/base_db/src/lib.rs +++ b/crates/base_db/src/lib.rs | |||
@@ -167,7 +167,7 @@ impl<T: SourceDatabaseExt> FileLoader for FileLoaderDelegate<&'_ T> { | |||
167 | } | 167 | } |
168 | 168 | ||
169 | fn possible_sudmobule_names(&self, module_file: FileId) -> Vec<String> { | 169 | fn possible_sudmobule_names(&self, module_file: FileId) -> Vec<String> { |
170 | self.source_root(module_file).file_set.possible_sudmobule_names(module_file) | 170 | possible_sudmobule_names(&self.source_root(module_file).file_set, module_file) |
171 | } | 171 | } |
172 | } | 172 | } |
173 | 173 | ||
@@ -177,3 +177,71 @@ impl<T: SourceDatabaseExt> FileLoaderDelegate<&'_ T> { | |||
177 | self.0.source_root(source_root) | 177 | self.0.source_root(source_root) |
178 | } | 178 | } |
179 | } | 179 | } |
180 | |||
181 | fn possible_sudmobule_names(module_files: &FileSet, module_file: FileId) -> Vec<String> { | ||
182 | let directory_to_look_for_submodules = match module_files | ||
183 | .path_for_file(&module_file) | ||
184 | .and_then(|module_file_path| get_directory_with_submodules(module_file_path)) | ||
185 | { | ||
186 | Some(directory) => directory, | ||
187 | None => return Vec::new(), | ||
188 | }; | ||
189 | module_files | ||
190 | .iter() | ||
191 | .filter(|submodule_file| submodule_file != &module_file) | ||
192 | .filter_map(|submodule_file| { | ||
193 | let submodule_path = module_files.path_for_file(&submodule_file)?; | ||
194 | if submodule_path.parent()? == directory_to_look_for_submodules { | ||
195 | submodule_path.file_name_and_extension() | ||
196 | } else { | ||
197 | None | ||
198 | } | ||
199 | }) | ||
200 | .filter_map(|file_name_and_extension| { | ||
201 | match file_name_and_extension { | ||
202 | // TODO kb wrong resolution for nested non-file modules (mod tests {mod <|>) | ||
203 | // TODO kb in src/bin when a module is included into another, | ||
204 | // the included file gets "moved" into a directory below and now cannot add any other modules | ||
205 | ("mod", Some("rs")) | ("lib", Some("rs")) | ("main", Some("rs")) => None, | ||
206 | (file_name, Some("rs")) => Some(file_name.to_owned()), | ||
207 | (subdirectory_name, None) => { | ||
208 | let mod_rs_path = | ||
209 | directory_to_look_for_submodules.join(subdirectory_name)?.join("mod.rs")?; | ||
210 | if module_files.file_for_path(&mod_rs_path).is_some() { | ||
211 | Some(subdirectory_name.to_owned()) | ||
212 | } else { | ||
213 | None | ||
214 | } | ||
215 | } | ||
216 | _ => None, | ||
217 | } | ||
218 | }) | ||
219 | .collect() | ||
220 | } | ||
221 | |||
222 | fn get_directory_with_submodules(module_file_path: &VfsPath) -> Option<VfsPath> { | ||
223 | let module_directory_path = module_file_path.parent()?; | ||
224 | match module_file_path.file_name_and_extension()? { | ||
225 | ("mod", Some("rs")) | ("lib", Some("rs")) | ("main", Some("rs")) => { | ||
226 | Some(module_directory_path) | ||
227 | } | ||
228 | (regular_rust_file_name, Some("rs")) => { | ||
229 | if matches!( | ||
230 | ( | ||
231 | module_directory_path | ||
232 | .parent() | ||
233 | .as_ref() | ||
234 | .and_then(|path| path.file_name_and_extension()), | ||
235 | module_directory_path.file_name_and_extension(), | ||
236 | ), | ||
237 | (Some(("src", None)), Some(("bin", None))) | ||
238 | ) { | ||
239 | // files in /src/bin/ can import each other directly | ||
240 | Some(module_directory_path) | ||
241 | } else { | ||
242 | module_directory_path.join(regular_rust_file_name) | ||
243 | } | ||
244 | } | ||
245 | _ => None, | ||
246 | } | ||
247 | } | ||
diff --git a/crates/vfs/src/file_set.rs b/crates/vfs/src/file_set.rs index cb65c17e0..4aa2d6526 100644 --- a/crates/vfs/src/file_set.rs +++ b/crates/vfs/src/file_set.rs | |||
@@ -26,74 +26,19 @@ impl FileSet { | |||
26 | self.files.get(&path).copied() | 26 | self.files.get(&path).copied() |
27 | } | 27 | } |
28 | 28 | ||
29 | pub fn possible_sudmobule_names(&self, module_file: FileId) -> Vec<String> { | 29 | pub fn file_for_path(&self, path: &VfsPath) -> Option<&FileId> { |
30 | let directory_to_look_for_submodules = match self.get_directory_with_submodules(module_file) | 30 | self.files.get(path) |
31 | { | ||
32 | Some(directory) => directory, | ||
33 | None => return Vec::new(), | ||
34 | }; | ||
35 | self.paths | ||
36 | .iter() | ||
37 | .filter_map(|(_, path)| { | ||
38 | if path.parent()? == directory_to_look_for_submodules { | ||
39 | path.file_name_and_extension() | ||
40 | } else { | ||
41 | None | ||
42 | } | ||
43 | }) | ||
44 | .filter_map(|file_name_and_extension| match file_name_and_extension { | ||
45 | // TODO kb do not include the module file name itself, if present | ||
46 | // TODO kb wrong resolution for nesСпаted non-file modules (mod tests {mod <|>) | ||
47 | // TODO kb in src/bin when a module is included into another, | ||
48 | // the included file gets "moved" into a directory below and now cannot add any other modules | ||
49 | ("mod", Some("rs")) | ("lib", Some("rs")) | ("main", Some("rs")) => None, | ||
50 | (file_name, Some("rs")) => Some(file_name.to_owned()), | ||
51 | (subdirectory_name, None) => { | ||
52 | let mod_rs_path = | ||
53 | directory_to_look_for_submodules.join(subdirectory_name)?.join("mod.rs")?; | ||
54 | if self.files.contains_key(&mod_rs_path) { | ||
55 | Some(subdirectory_name.to_owned()) | ||
56 | } else { | ||
57 | None | ||
58 | } | ||
59 | } | ||
60 | _ => None, | ||
61 | }) | ||
62 | .collect() | ||
63 | } | 31 | } |
64 | 32 | ||
65 | fn get_directory_with_submodules(&self, module_file: FileId) -> Option<VfsPath> { | 33 | pub fn path_for_file(&self, file: &FileId) -> Option<&VfsPath> { |
66 | let module_file_path = &self.paths[&module_file]; | 34 | self.paths.get(file) |
67 | let module_directory_path = module_file_path.parent()?; | ||
68 | match module_file_path.file_name_and_extension() { | ||
69 | Some(("mod", Some("rs"))) | Some(("lib", Some("rs"))) | Some(("main", Some("rs"))) => { | ||
70 | Some(module_directory_path) | ||
71 | } | ||
72 | Some((regular_rust_file_name, Some("rs"))) => { | ||
73 | if matches!( | ||
74 | ( | ||
75 | module_directory_path | ||
76 | .parent() | ||
77 | .as_ref() | ||
78 | .and_then(|path| path.file_name_and_extension()), | ||
79 | module_directory_path.file_name_and_extension(), | ||
80 | ), | ||
81 | (Some(("src", None)), Some(("bin", None))) | ||
82 | ) { | ||
83 | // files in /src/bin/ can import each other directly | ||
84 | Some(module_directory_path) | ||
85 | } else { | ||
86 | module_directory_path.join(regular_rust_file_name) | ||
87 | } | ||
88 | } | ||
89 | _ => None, | ||
90 | } | ||
91 | } | 35 | } |
92 | 36 | ||
93 | pub fn insert(&mut self, file_id: FileId, path: VfsPath) { | 37 | pub fn insert(&mut self, file_id: FileId, path: VfsPath) { |
94 | self.files.insert(path.clone(), file_id); | 38 | self.files.insert(path.clone(), file_id); |
95 | self.paths.insert(file_id, path); | 39 | self.paths.insert(file_id, path); |
96 | } | 40 | } |
41 | |||
97 | pub fn iter(&self) -> impl Iterator<Item = FileId> + '_ { | 42 | pub fn iter(&self) -> impl Iterator<Item = FileId> + '_ { |
98 | self.paths.keys().copied() | 43 | self.paths.keys().copied() |
99 | } | 44 | } |