Skip to content

Commit f9c14ac

Browse files
Move most of the logic into the completion module
1 parent 6ba479c commit f9c14ac

File tree

8 files changed

+107
-118
lines changed

8 files changed

+107
-118
lines changed

crates/base_db/src/input.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use cfg::CfgOptions;
1212
use rustc_hash::{FxHashMap, FxHashSet};
1313
use syntax::SmolStr;
1414
use tt::TokenExpander;
15-
use vfs::file_set::FileSet;
15+
use vfs::{file_set::FileSet, VfsPath};
1616

1717
pub use vfs::FileId;
1818

@@ -43,6 +43,12 @@ impl SourceRoot {
4343
pub fn new_library(file_set: FileSet) -> SourceRoot {
4444
SourceRoot { is_library: true, file_set }
4545
}
46+
pub fn path_for_file(&self, file: &FileId) -> Option<&VfsPath> {
47+
self.file_set.path_for_file(file)
48+
}
49+
pub fn file_for_path(&self, path: &VfsPath) -> Option<&FileId> {
50+
self.file_set.file_for_path(path)
51+
}
4652
pub fn iter(&self) -> impl Iterator<Item = FileId> + '_ {
4753
self.file_set.iter()
4854
}

crates/base_db/src/lib.rs

Lines changed: 2 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ pub trait FileLoader {
9696
/// `#[path = "C://no/way"]`
9797
fn resolve_path(&self, anchor: FileId, path: &str) -> Option<FileId>;
9898
fn relevant_crates(&self, file_id: FileId) -> Arc<FxHashSet<CrateId>>;
99-
fn possible_sudmobule_names(&self, module_file: FileId) -> Vec<String>;
10099
}
101100

102101
/// Database which stores all significant input facts: source code and project
@@ -156,92 +155,13 @@ impl<T: SourceDatabaseExt> FileLoader for FileLoaderDelegate<&'_ T> {
156155
}
157156
fn resolve_path(&self, anchor: FileId, path: &str) -> Option<FileId> {
158157
// FIXME: this *somehow* should be platform agnostic...
159-
// self.source_root(anchor)
160-
let source_root = self.source_root(anchor);
158+
let source_root = self.0.file_source_root(anchor);
159+
let source_root = self.0.source_root(source_root);
161160
source_root.file_set.resolve_path(anchor, path)
162161
}
163162

164163
fn relevant_crates(&self, file_id: FileId) -> Arc<FxHashSet<CrateId>> {
165164
let source_root = self.0.file_source_root(file_id);
166165
self.0.source_root_crates(source_root)
167166
}
168-
169-
fn possible_sudmobule_names(&self, module_file: FileId) -> Vec<String> {
170-
possible_sudmobule_names(&self.source_root(module_file).file_set, module_file)
171-
}
172-
}
173-
174-
impl<T: SourceDatabaseExt> FileLoaderDelegate<&'_ T> {
175-
fn source_root(&self, anchor: FileId) -> Arc<SourceRoot> {
176-
let source_root = self.0.file_source_root(anchor);
177-
self.0.source_root(source_root)
178-
}
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-
}
247167
}

crates/hir_def/src/test_db.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,6 @@ impl FileLoader for TestDB {
6363
fn relevant_crates(&self, file_id: FileId) -> Arc<FxHashSet<CrateId>> {
6464
FileLoaderDelegate(self).relevant_crates(file_id)
6565
}
66-
fn possible_sudmobule_names(&self, module_file: FileId) -> Vec<String> {
67-
FileLoaderDelegate(self).possible_sudmobule_names(module_file)
68-
}
6966
}
7067

7168
impl TestDB {

crates/hir_expand/src/test_db.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,4 @@ impl FileLoader for TestDB {
4646
fn relevant_crates(&self, file_id: FileId) -> Arc<FxHashSet<CrateId>> {
4747
FileLoaderDelegate(self).relevant_crates(file_id)
4848
}
49-
fn possible_sudmobule_names(&self, module_file: FileId) -> Vec<String> {
50-
FileLoaderDelegate(self).possible_sudmobule_names(module_file)
51-
}
5249
}

crates/hir_ty/src/test_db.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,6 @@ impl FileLoader for TestDB {
7373
fn relevant_crates(&self, file_id: FileId) -> Arc<FxHashSet<CrateId>> {
7474
FileLoaderDelegate(self).relevant_crates(file_id)
7575
}
76-
fn possible_sudmobule_names(&self, module_file: FileId) -> Vec<String> {
77-
FileLoaderDelegate(self).possible_sudmobule_names(module_file)
78-
}
7976
}
8077

8178
impl TestDB {
Lines changed: 95 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,113 @@
11
//! Completes mod declarations.
22
3-
use base_db::FileLoader;
4-
use hir::ModuleSource;
3+
use base_db::{SourceDatabaseExt, VfsPath};
4+
use hir::{Module, ModuleSource};
5+
use ide_db::RootDatabase;
56

67
use super::{completion_context::CompletionContext, completion_item::Completions};
78

89
/// Complete mod declaration, i.e. `mod <|> ;`
910
pub(super) fn complete_mod(acc: &mut Completions, ctx: &CompletionContext) {
1011
let module_names_for_import = ctx
11-
.sema
12-
// TODO kb this is wrong, since we need not the file module
13-
.to_module_def(ctx.position.file_id)
12+
.scope
13+
.module()
1414
.and_then(|current_module| {
15-
dbg!(current_module.name(ctx.db));
16-
dbg!(current_module.definition_source(ctx.db));
17-
dbg!(current_module.declaration_source(ctx.db));
18-
let mut zz = Vec::new();
19-
let mut vv = Some(current_module);
20-
while let Some(ModuleSource::Module(_)) =
21-
vv.map(|vv| vv.definition_source(ctx.db).value)
22-
{
23-
zz.push(current_module.name(ctx.db));
24-
vv = current_module.parent(ctx.db);
25-
}
26-
dbg!(zz);
27-
let definition_source = current_module.definition_source(ctx.db);
15+
let module_path = path_to_closest_containing_module_file(current_module, ctx.db);
2816
// TODO kb filter out declarations in possible_sudmobule_names
2917
// let declaration_source = current_module.declaration_source(ctx.db);
30-
let module_definition_source_file = definition_source.file_id.original_file(ctx.db);
31-
let mod_declaration_candidates =
32-
ctx.db.possible_sudmobule_names(module_definition_source_file);
18+
let module_definition_source_file =
19+
current_module.definition_source(ctx.db).file_id.original_file(ctx.db);
20+
21+
let source_root_id = ctx.db.file_source_root(module_definition_source_file);
22+
let source_root = ctx.db.source_root(source_root_id);
23+
let directory_to_look_for_submodules = source_root
24+
.path_for_file(&module_definition_source_file)
25+
.and_then(|module_file_path| get_directory_with_submodules(module_file_path))?;
26+
27+
let mod_declaration_candidates = source_root
28+
.iter()
29+
.filter(|submodule_file| submodule_file != &module_definition_source_file)
30+
.filter_map(|submodule_file| {
31+
let submodule_path = source_root.path_for_file(&submodule_file)?;
32+
if submodule_path.parent()? == directory_to_look_for_submodules {
33+
submodule_path.file_name_and_extension()
34+
} else {
35+
None
36+
}
37+
})
38+
.filter_map(|file_name_and_extension| {
39+
match file_name_and_extension {
40+
// TODO kb wrong resolution for nested non-file modules (mod tests { mod <|> })
41+
// TODO kb in src/bin when a module is included into another,
42+
// the included file gets "moved" into a directory below and now cannot add any other modules
43+
("mod", Some("rs")) | ("lib", Some("rs")) | ("main", Some("rs")) => None,
44+
(file_name, Some("rs")) => Some(file_name.to_owned()),
45+
(subdirectory_name, None) => {
46+
let mod_rs_path = directory_to_look_for_submodules
47+
.join(subdirectory_name)?
48+
.join("mod.rs")?;
49+
if source_root.file_for_path(&mod_rs_path).is_some() {
50+
Some(subdirectory_name.to_owned())
51+
} else {
52+
None
53+
}
54+
}
55+
_ => None,
56+
}
57+
})
58+
.collect::<Vec<_>>();
3359
dbg!(mod_declaration_candidates);
3460
// TODO kb exlude existing children from the candidates
3561
let existing_children = current_module.children(ctx.db).collect::<Vec<_>>();
3662
None::<Vec<String>>
3763
})
3864
.unwrap_or_default();
3965
}
66+
67+
fn path_to_closest_containing_module_file(
68+
current_module: Module,
69+
db: &RootDatabase,
70+
) -> Vec<Module> {
71+
let mut path = Vec::new();
72+
73+
let mut current_module = Some(current_module);
74+
while let Some(ModuleSource::Module(_)) =
75+
current_module.map(|module| module.definition_source(db).value)
76+
{
77+
if let Some(module) = current_module {
78+
path.insert(0, module);
79+
current_module = module.parent(db);
80+
} else {
81+
current_module = None;
82+
}
83+
}
84+
85+
path
86+
}
87+
88+
fn get_directory_with_submodules(module_file_path: &VfsPath) -> Option<VfsPath> {
89+
let module_directory_path = module_file_path.parent()?;
90+
match module_file_path.file_name_and_extension()? {
91+
("mod", Some("rs")) | ("lib", Some("rs")) | ("main", Some("rs")) => {
92+
Some(module_directory_path)
93+
}
94+
(regular_rust_file_name, Some("rs")) => {
95+
if matches!(
96+
(
97+
module_directory_path
98+
.parent()
99+
.as_ref()
100+
.and_then(|path| path.file_name_and_extension()),
101+
module_directory_path.file_name_and_extension(),
102+
),
103+
(Some(("src", None)), Some(("bin", None)))
104+
) {
105+
// files in /src/bin/ can import each other directly
106+
Some(module_directory_path)
107+
} else {
108+
module_directory_path.join(regular_rust_file_name)
109+
}
110+
}
111+
_ => None,
112+
}
113+
}

crates/ide/src/completion/completion_context.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! FIXME: write short doc here
22
3-
use base_db::{FileLoader, SourceDatabase};
4-
use hir::{ModuleSource, Semantics, SemanticsScope, Type};
3+
use base_db::SourceDatabase;
4+
use hir::{Semantics, SemanticsScope, Type};
55
use ide_db::RootDatabase;
66
use syntax::{
77
algo::{find_covering_element, find_node_at_offset},
@@ -112,6 +112,7 @@ impl<'a> CompletionContext<'a> {
112112
};
113113
let fake_ident_token =
114114
file_with_fake_ident.syntax().token_at_offset(position.offset).right_biased().unwrap();
115+
115116
let krate = sema.to_module_def(position.file_id).map(|m| m.krate());
116117
let original_token =
117118
original_file.syntax().token_at_offset(position.offset).left_biased()?;

crates/ide_db/src/lib.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,6 @@ impl FileLoader for RootDatabase {
7474
fn relevant_crates(&self, file_id: FileId) -> Arc<FxHashSet<CrateId>> {
7575
FileLoaderDelegate(self).relevant_crates(file_id)
7676
}
77-
fn possible_sudmobule_names(&self, module_file: FileId) -> Vec<String> {
78-
FileLoaderDelegate(self).possible_sudmobule_names(module_file)
79-
}
8077
}
8178

8279
impl salsa::Database for RootDatabase {

0 commit comments

Comments
 (0)