From 4bed588001a1d6cd5c83a3eefc6ef77c439de40b Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 28 Aug 2020 21:28:30 +0300 Subject: First steps for mod<|> completion --- crates/base_db/src/lib.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'crates/base_db/src') diff --git a/crates/base_db/src/lib.rs b/crates/base_db/src/lib.rs index ee3415850..71e85c6ac 100644 --- a/crates/base_db/src/lib.rs +++ b/crates/base_db/src/lib.rs @@ -96,6 +96,7 @@ pub trait FileLoader { /// `#[path = "C://no/way"]` fn resolve_path(&self, anchor: FileId, path: &str) -> Option; fn relevant_crates(&self, file_id: FileId) -> Arc>; + fn list_some_random_files_todo(&self, anchor: FileId) -> Vec<(FileId, String)>; } /// Database which stores all significant input facts: source code and project @@ -155,8 +156,8 @@ impl FileLoader for FileLoaderDelegate<&'_ T> { } fn resolve_path(&self, anchor: FileId, path: &str) -> Option { // FIXME: this *somehow* should be platform agnostic... - let source_root = self.0.file_source_root(anchor); - let source_root = self.0.source_root(source_root); + // self.source_root(anchor) + let source_root = self.source_root(anchor); source_root.file_set.resolve_path(anchor, path) } @@ -164,4 +165,15 @@ impl FileLoader for FileLoaderDelegate<&'_ T> { let source_root = self.0.file_source_root(file_id); self.0.source_root_crates(source_root) } + + fn list_some_random_files_todo(&self, anchor: FileId) -> Vec<(FileId, String)> { + self.source_root(anchor).file_set.list_some_random_files_todo(anchor) + } +} + +impl FileLoaderDelegate<&'_ T> { + fn source_root(&self, anchor: FileId) -> Arc { + let source_root = self.0.file_source_root(anchor); + self.0.source_root(source_root) + } } -- cgit v1.2.3 From 17870a3e2c39770a99f9ab5ce090abbe1dc334d2 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Thu, 3 Sep 2020 23:18:23 +0300 Subject: Better API --- crates/base_db/src/lib.rs | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'crates/base_db/src') diff --git a/crates/base_db/src/lib.rs b/crates/base_db/src/lib.rs index 71e85c6ac..37a8432bd 100644 --- a/crates/base_db/src/lib.rs +++ b/crates/base_db/src/lib.rs @@ -96,7 +96,7 @@ pub trait FileLoader { /// `#[path = "C://no/way"]` fn resolve_path(&self, anchor: FileId, path: &str) -> Option; fn relevant_crates(&self, file_id: FileId) -> Arc>; - fn list_some_random_files_todo(&self, anchor: FileId) -> Vec<(FileId, String)>; + fn possible_sudmobules(&self, module_file: FileId) -> Vec<(FileId, String)>; } /// Database which stores all significant input facts: source code and project @@ -166,8 +166,25 @@ impl FileLoader for FileLoaderDelegate<&'_ T> { self.0.source_root_crates(source_root) } - fn list_some_random_files_todo(&self, anchor: FileId) -> Vec<(FileId, String)> { - self.source_root(anchor).file_set.list_some_random_files_todo(anchor) + fn possible_sudmobules(&self, module_file: FileId) -> Vec<(FileId, String)> { + fn possible_sudmobules_opt( + module_files: &FileSet, + module_file: FileId, + ) -> Option> { + // TODO kb resolve path thinks that the input is a file... + let directory_with_module_file = module_files.resolve_path(module_file, "/../")?; + let directory_with_applicable_modules = + match module_files.file_name_and_extension(module_file)? { + ("mod", "rs") | ("lib", "rs") => Some(directory_with_module_file), + (directory_with_module_name, "rs") => module_files + .resolve_path(directory_with_module_file, directory_with_module_name), + _ => None, + }?; + Some(module_files.list_files(directory_with_applicable_modules)) + } + + possible_sudmobules_opt(&self.source_root(module_file).file_set, module_file) + .unwrap_or_default() } } -- cgit v1.2.3 From 0de71f7bc9482c9d1ef7e9d36ec5d6c5fd378781 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 4 Sep 2020 01:32:06 +0300 Subject: Properly use FileSet API --- crates/base_db/src/lib.rs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'crates/base_db/src') diff --git a/crates/base_db/src/lib.rs b/crates/base_db/src/lib.rs index 37a8432bd..1bc4690c9 100644 --- a/crates/base_db/src/lib.rs +++ b/crates/base_db/src/lib.rs @@ -171,16 +171,14 @@ impl FileLoader for FileLoaderDelegate<&'_ T> { module_files: &FileSet, module_file: FileId, ) -> Option> { - // TODO kb resolve path thinks that the input is a file... - let directory_with_module_file = module_files.resolve_path(module_file, "/../")?; - let directory_with_applicable_modules = - match module_files.file_name_and_extension(module_file)? { - ("mod", "rs") | ("lib", "rs") => Some(directory_with_module_file), - (directory_with_module_name, "rs") => module_files - .resolve_path(directory_with_module_file, directory_with_module_name), - _ => None, - }?; - Some(module_files.list_files(directory_with_applicable_modules)) + match module_files.file_name_and_extension(module_file)? { + ("mod", Some("rs")) | ("lib", Some("rs")) => { + module_files.list_files(module_file, None) + } + (directory_with_module_name, Some("rs")) => module_files + .list_files(module_file, Some(&format!("../{}/", directory_with_module_name))), + _ => None, + } } possible_sudmobules_opt(&self.source_root(module_file).file_set, module_file) -- cgit v1.2.3 From 8aa740dab46f138cacdf6391d46c87d6df810161 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 4 Sep 2020 02:25:00 +0300 Subject: Happy path implemented --- crates/base_db/src/lib.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'crates/base_db/src') diff --git a/crates/base_db/src/lib.rs b/crates/base_db/src/lib.rs index 1bc4690c9..3e0b6637d 100644 --- a/crates/base_db/src/lib.rs +++ b/crates/base_db/src/lib.rs @@ -96,7 +96,7 @@ pub trait FileLoader { /// `#[path = "C://no/way"]` fn resolve_path(&self, anchor: FileId, path: &str) -> Option; fn relevant_crates(&self, file_id: FileId) -> Arc>; - fn possible_sudmobules(&self, module_file: FileId) -> Vec<(FileId, String)>; + fn possible_sudmobule_names(&self, module_file: FileId) -> Vec; } /// Database which stores all significant input facts: source code and project @@ -166,11 +166,11 @@ impl FileLoader for FileLoaderDelegate<&'_ T> { self.0.source_root_crates(source_root) } - fn possible_sudmobules(&self, module_file: FileId) -> Vec<(FileId, String)> { + fn possible_sudmobule_names(&self, module_file: FileId) -> Vec { fn possible_sudmobules_opt( module_files: &FileSet, module_file: FileId, - ) -> Option> { + ) -> Option> { match module_files.file_name_and_extension(module_file)? { ("mod", Some("rs")) | ("lib", Some("rs")) => { module_files.list_files(module_file, None) @@ -181,8 +181,16 @@ impl FileLoader for FileLoaderDelegate<&'_ T> { } } - possible_sudmobules_opt(&self.source_root(module_file).file_set, module_file) + let module_files = &self.source_root(module_file).file_set; + possible_sudmobules_opt(module_files, module_file) .unwrap_or_default() + .into_iter() + .filter_map(|submodule_file| module_files.file_name_and_extension(submodule_file)) + .map(|(file_name, extension)| match extension { + Some(extension) => format!("{}.{}", file_name, extension), + None => file_name.to_owned(), + }) + .collect() } } -- cgit v1.2.3 From d163f9f114c8180bec6285ad9962fabbf3af5b18 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 4 Sep 2020 13:33:07 +0300 Subject: Small refactoring --- crates/base_db/src/lib.rs | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) (limited to 'crates/base_db/src') diff --git a/crates/base_db/src/lib.rs b/crates/base_db/src/lib.rs index 3e0b6637d..55ef9fc24 100644 --- a/crates/base_db/src/lib.rs +++ b/crates/base_db/src/lib.rs @@ -167,29 +167,23 @@ impl FileLoader for FileLoaderDelegate<&'_ T> { } fn possible_sudmobule_names(&self, module_file: FileId) -> Vec { - fn possible_sudmobules_opt( - module_files: &FileSet, - module_file: FileId, - ) -> Option> { - match module_files.file_name_and_extension(module_file)? { - ("mod", Some("rs")) | ("lib", Some("rs")) => { - module_files.list_files(module_file, None) - } - (directory_with_module_name, Some("rs")) => module_files - .list_files(module_file, Some(&format!("../{}/", directory_with_module_name))), - _ => None, - } - } - let module_files = &self.source_root(module_file).file_set; - possible_sudmobules_opt(module_files, module_file) - .unwrap_or_default() + let possible_submodule_files = match module_files.file_name_and_extension(module_file) { + Some(("mod", Some("rs"))) | Some(("lib", Some("rs"))) => { + module_files.list_files_with_extensions(module_file, None) + } + Some((directory_with_module_name, Some("rs"))) => module_files + .list_files_with_extensions( + module_file, + Some(&format!("../{}/", directory_with_module_name)), + ), + _ => Vec::new(), + }; + + possible_submodule_files .into_iter() - .filter_map(|submodule_file| module_files.file_name_and_extension(submodule_file)) - .map(|(file_name, extension)| match extension { - Some(extension) => format!("{}.{}", file_name, extension), - None => file_name.to_owned(), - }) + .filter(|(_, extension)| extension == &Some("rs")) + .map(|(file_name, _)| file_name.to_owned()) .collect() } } -- cgit v1.2.3 From 486c5c3285682408b125613475a34a0bc9a2c097 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 4 Sep 2020 15:13:31 +0300 Subject: Exclude special files --- crates/base_db/src/lib.rs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'crates/base_db/src') diff --git a/crates/base_db/src/lib.rs b/crates/base_db/src/lib.rs index 55ef9fc24..c72e254f4 100644 --- a/crates/base_db/src/lib.rs +++ b/crates/base_db/src/lib.rs @@ -172,17 +172,22 @@ impl FileLoader for FileLoaderDelegate<&'_ T> { Some(("mod", Some("rs"))) | Some(("lib", Some("rs"))) => { module_files.list_files_with_extensions(module_file, None) } + // TODO kb for `src/bin/foo.rs`, we need to check for modules in `src/bin/` Some((directory_with_module_name, Some("rs"))) => module_files .list_files_with_extensions( module_file, Some(&format!("../{}/", directory_with_module_name)), ), + // TODO kb also consider the case when there's no `../module_name.rs`, but `../module_name/mod.rs` _ => Vec::new(), }; possible_submodule_files .into_iter() .filter(|(_, extension)| extension == &Some("rs")) + .filter(|(file_name, _)| file_name != &"mod") + .filter(|(file_name, _)| file_name != &"lib") + .filter(|(file_name, _)| file_name != &"main") .map(|(file_name, _)| file_name.to_owned()) .collect() } -- cgit v1.2.3 From b2bcc5278db23c3ba0a4f47a3ef6ee411aaaa8dc Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Sun, 6 Sep 2020 01:41:18 +0300 Subject: Properly handle special cases (binaries, mod.rs) --- crates/base_db/src/lib.rs | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) (limited to 'crates/base_db/src') diff --git a/crates/base_db/src/lib.rs b/crates/base_db/src/lib.rs index c72e254f4..030b96829 100644 --- a/crates/base_db/src/lib.rs +++ b/crates/base_db/src/lib.rs @@ -167,29 +167,7 @@ impl FileLoader for FileLoaderDelegate<&'_ T> { } fn possible_sudmobule_names(&self, module_file: FileId) -> Vec { - let module_files = &self.source_root(module_file).file_set; - let possible_submodule_files = match module_files.file_name_and_extension(module_file) { - Some(("mod", Some("rs"))) | Some(("lib", Some("rs"))) => { - module_files.list_files_with_extensions(module_file, None) - } - // TODO kb for `src/bin/foo.rs`, we need to check for modules in `src/bin/` - Some((directory_with_module_name, Some("rs"))) => module_files - .list_files_with_extensions( - module_file, - Some(&format!("../{}/", directory_with_module_name)), - ), - // TODO kb also consider the case when there's no `../module_name.rs`, but `../module_name/mod.rs` - _ => Vec::new(), - }; - - possible_submodule_files - .into_iter() - .filter(|(_, extension)| extension == &Some("rs")) - .filter(|(file_name, _)| file_name != &"mod") - .filter(|(file_name, _)| file_name != &"lib") - .filter(|(file_name, _)| file_name != &"main") - .map(|(file_name, _)| file_name.to_owned()) - .collect() + self.source_root(module_file).file_set.possible_sudmobule_names(module_file) } } -- cgit v1.2.3 From 33179a0ae1ba9a908cc34a4cf87599ed779b9886 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Mon, 7 Sep 2020 16:17:50 +0300 Subject: Move rust-related logic from vfs to base_db level --- crates/base_db/src/lib.rs | 70 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) (limited to 'crates/base_db/src') 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 FileLoader for FileLoaderDelegate<&'_ T> { } fn possible_sudmobule_names(&self, module_file: FileId) -> Vec { - self.source_root(module_file).file_set.possible_sudmobule_names(module_file) + possible_sudmobule_names(&self.source_root(module_file).file_set, module_file) } } @@ -177,3 +177,71 @@ impl FileLoaderDelegate<&'_ T> { self.0.source_root(source_root) } } + +fn possible_sudmobule_names(module_files: &FileSet, module_file: FileId) -> Vec { + let directory_to_look_for_submodules = match module_files + .path_for_file(&module_file) + .and_then(|module_file_path| get_directory_with_submodules(module_file_path)) + { + Some(directory) => directory, + None => return Vec::new(), + }; + module_files + .iter() + .filter(|submodule_file| submodule_file != &module_file) + .filter_map(|submodule_file| { + let submodule_path = module_files.path_for_file(&submodule_file)?; + if submodule_path.parent()? == directory_to_look_for_submodules { + submodule_path.file_name_and_extension() + } else { + None + } + }) + .filter_map(|file_name_and_extension| { + match file_name_and_extension { + // TODO kb wrong resolution for nested non-file modules (mod tests {mod <|>) + // TODO kb in src/bin when a module is included into another, + // the included file gets "moved" into a directory below and now cannot add any other modules + ("mod", Some("rs")) | ("lib", Some("rs")) | ("main", Some("rs")) => None, + (file_name, Some("rs")) => Some(file_name.to_owned()), + (subdirectory_name, None) => { + let mod_rs_path = + directory_to_look_for_submodules.join(subdirectory_name)?.join("mod.rs")?; + if module_files.file_for_path(&mod_rs_path).is_some() { + Some(subdirectory_name.to_owned()) + } else { + None + } + } + _ => None, + } + }) + .collect() +} + +fn get_directory_with_submodules(module_file_path: &VfsPath) -> Option { + let module_directory_path = module_file_path.parent()?; + match module_file_path.file_name_and_extension()? { + ("mod", Some("rs")) | ("lib", Some("rs")) | ("main", Some("rs")) => { + Some(module_directory_path) + } + (regular_rust_file_name, Some("rs")) => { + if matches!( + ( + module_directory_path + .parent() + .as_ref() + .and_then(|path| path.file_name_and_extension()), + module_directory_path.file_name_and_extension(), + ), + (Some(("src", None)), Some(("bin", None))) + ) { + // files in /src/bin/ can import each other directly + Some(module_directory_path) + } else { + module_directory_path.join(regular_rust_file_name) + } + } + _ => None, + } +} -- cgit v1.2.3 From 6ba479cd058aa54a9f161085c7ff9ac1f12d8df3 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Mon, 7 Sep 2020 19:21:39 +0300 Subject: Finally cretae the mod completion module --- crates/base_db/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates/base_db/src') diff --git a/crates/base_db/src/lib.rs b/crates/base_db/src/lib.rs index 9733e1fd3..321007d33 100644 --- a/crates/base_db/src/lib.rs +++ b/crates/base_db/src/lib.rs @@ -199,7 +199,7 @@ fn possible_sudmobule_names(module_files: &FileSet, module_file: FileId) -> Vec< }) .filter_map(|file_name_and_extension| { match file_name_and_extension { - // TODO kb wrong resolution for nested non-file modules (mod tests {mod <|>) + // TODO kb wrong resolution for nested non-file modules (mod tests { mod <|> }) // TODO kb in src/bin when a module is included into another, // the included file gets "moved" into a directory below and now cannot add any other modules ("mod", Some("rs")) | ("lib", Some("rs")) | ("main", Some("rs")) => None, -- cgit v1.2.3 From f9c14ac7204c38633e70b3efd47a5b1f9056afd0 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Mon, 7 Sep 2020 20:52:37 +0300 Subject: Move most of the logic into the completion module --- crates/base_db/src/input.rs | 8 ++++- crates/base_db/src/lib.rs | 84 ++------------------------------------------- 2 files changed, 9 insertions(+), 83 deletions(-) (limited to 'crates/base_db/src') diff --git a/crates/base_db/src/input.rs b/crates/base_db/src/input.rs index f3d65cdf0..9a61f1d56 100644 --- a/crates/base_db/src/input.rs +++ b/crates/base_db/src/input.rs @@ -12,7 +12,7 @@ use cfg::CfgOptions; use rustc_hash::{FxHashMap, FxHashSet}; use syntax::SmolStr; use tt::TokenExpander; -use vfs::file_set::FileSet; +use vfs::{file_set::FileSet, VfsPath}; pub use vfs::FileId; @@ -43,6 +43,12 @@ impl SourceRoot { pub fn new_library(file_set: FileSet) -> SourceRoot { SourceRoot { is_library: true, file_set } } + pub fn path_for_file(&self, file: &FileId) -> Option<&VfsPath> { + self.file_set.path_for_file(file) + } + pub fn file_for_path(&self, path: &VfsPath) -> Option<&FileId> { + self.file_set.file_for_path(path) + } pub fn iter(&self) -> impl Iterator + '_ { self.file_set.iter() } diff --git a/crates/base_db/src/lib.rs b/crates/base_db/src/lib.rs index 321007d33..ee3415850 100644 --- a/crates/base_db/src/lib.rs +++ b/crates/base_db/src/lib.rs @@ -96,7 +96,6 @@ pub trait FileLoader { /// `#[path = "C://no/way"]` fn resolve_path(&self, anchor: FileId, path: &str) -> Option; fn relevant_crates(&self, file_id: FileId) -> Arc>; - fn possible_sudmobule_names(&self, module_file: FileId) -> Vec; } /// Database which stores all significant input facts: source code and project @@ -156,8 +155,8 @@ impl FileLoader for FileLoaderDelegate<&'_ T> { } fn resolve_path(&self, anchor: FileId, path: &str) -> Option { // FIXME: this *somehow* should be platform agnostic... - // self.source_root(anchor) - let source_root = self.source_root(anchor); + let source_root = self.0.file_source_root(anchor); + let source_root = self.0.source_root(source_root); source_root.file_set.resolve_path(anchor, path) } @@ -165,83 +164,4 @@ impl FileLoader for FileLoaderDelegate<&'_ T> { let source_root = self.0.file_source_root(file_id); self.0.source_root_crates(source_root) } - - fn possible_sudmobule_names(&self, module_file: FileId) -> Vec { - possible_sudmobule_names(&self.source_root(module_file).file_set, module_file) - } -} - -impl FileLoaderDelegate<&'_ T> { - fn source_root(&self, anchor: FileId) -> Arc { - let source_root = self.0.file_source_root(anchor); - self.0.source_root(source_root) - } -} - -fn possible_sudmobule_names(module_files: &FileSet, module_file: FileId) -> Vec { - let directory_to_look_for_submodules = match module_files - .path_for_file(&module_file) - .and_then(|module_file_path| get_directory_with_submodules(module_file_path)) - { - Some(directory) => directory, - None => return Vec::new(), - }; - module_files - .iter() - .filter(|submodule_file| submodule_file != &module_file) - .filter_map(|submodule_file| { - let submodule_path = module_files.path_for_file(&submodule_file)?; - if submodule_path.parent()? == directory_to_look_for_submodules { - submodule_path.file_name_and_extension() - } else { - None - } - }) - .filter_map(|file_name_and_extension| { - match file_name_and_extension { - // TODO kb wrong resolution for nested non-file modules (mod tests { mod <|> }) - // TODO kb in src/bin when a module is included into another, - // the included file gets "moved" into a directory below and now cannot add any other modules - ("mod", Some("rs")) | ("lib", Some("rs")) | ("main", Some("rs")) => None, - (file_name, Some("rs")) => Some(file_name.to_owned()), - (subdirectory_name, None) => { - let mod_rs_path = - directory_to_look_for_submodules.join(subdirectory_name)?.join("mod.rs")?; - if module_files.file_for_path(&mod_rs_path).is_some() { - Some(subdirectory_name.to_owned()) - } else { - None - } - } - _ => None, - } - }) - .collect() -} - -fn get_directory_with_submodules(module_file_path: &VfsPath) -> Option { - let module_directory_path = module_file_path.parent()?; - match module_file_path.file_name_and_extension()? { - ("mod", Some("rs")) | ("lib", Some("rs")) | ("main", Some("rs")) => { - Some(module_directory_path) - } - (regular_rust_file_name, Some("rs")) => { - if matches!( - ( - module_directory_path - .parent() - .as_ref() - .and_then(|path| path.file_name_and_extension()), - module_directory_path.file_name_and_extension(), - ), - (Some(("src", None)), Some(("bin", None))) - ) { - // files in /src/bin/ can import each other directly - Some(module_directory_path) - } else { - module_directory_path.join(regular_rust_file_name) - } - } - _ => None, - } } -- cgit v1.2.3