4674: Recursively search submodules to find modules in which a definition is visible. r=matklad a=umanwizard



Co-authored-by: Brennan Vincent <brennan@materialize.io>
This commit is contained in:
bors[bot] 2020-05-31 17:07:37 +00:00 committed by GitHub
commit e4bdc14951
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 18 deletions

View file

@ -615,6 +615,33 @@ mod tests {
);
}
#[test]
fn test_find_all_refs_nested_module() {
let code = r#"
//- /lib.rs
mod foo {
mod bar;
}
fn f<|>() {}
//- /foo/bar.rs
use crate::f;
fn g() {
f();
}
"#;
let (analysis, pos) = analysis_and_position(code);
let refs = analysis.find_all_refs(pos, None).unwrap().unwrap();
check_result(
refs,
"f FN_DEF FileId(1) 25..34 28..29 Other",
&["FileId(2) 11..12 Other", "FileId(2) 27..28 StructLiteral"],
);
}
fn get_all_refs(text: &str) -> ReferenceSearchResult {
let (analysis, position) = single_file_with_position(text);
analysis.find_all_refs(position, None).unwrap().unwrap()

View file

@ -124,29 +124,33 @@ impl Definition {
let vis = self.visibility(db);
// FIXME:
// The following logic are wrong that it does not search
// for submodules within other files recursively.
if let Some(Visibility::Module(module)) = vis.and_then(|it| it.into()) {
let module: Module = module.into();
let mut res = FxHashMap::default();
let src = module.definition_source(db);
let file_id = src.file_id.original_file(db);
match src.value {
ModuleSource::Module(m) => {
let range = Some(m.syntax().text_range());
res.insert(file_id, range);
}
ModuleSource::SourceFile(_) => {
res.insert(file_id, None);
res.extend(module.children(db).map(|m| {
let src = m.definition_source(db);
(src.file_id.original_file(db), None)
}));
}
let mut to_visit = vec![module];
let mut is_first = true;
while let Some(module) = to_visit.pop() {
let src = module.definition_source(db);
let file_id = src.file_id.original_file(db);
match src.value {
ModuleSource::Module(m) => {
if is_first {
let range = Some(m.syntax().text_range());
res.insert(file_id, range);
} else {
// We have already added the enclosing file to the search scope,
// so do nothing.
}
}
ModuleSource::SourceFile(_) => {
res.insert(file_id, None);
}
};
is_first = false;
to_visit.extend(module.children(db));
}
return SearchScope::new(res);
}