mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-30 13:51:31 +00:00
Use shortest path
This commit is contained in:
parent
1ea2b475a9
commit
df9d3bd25e
1 changed files with 19 additions and 4 deletions
|
@ -10,7 +10,6 @@ use hir_expand::name::Name;
|
||||||
|
|
||||||
// TODO don't import from super imports? or at least deprioritize
|
// TODO don't import from super imports? or at least deprioritize
|
||||||
// TODO use super?
|
// TODO use super?
|
||||||
// TODO use shortest path
|
|
||||||
// TODO performance / memoize
|
// TODO performance / memoize
|
||||||
|
|
||||||
pub fn find_path(db: &impl DefDatabase, item: ItemInNs, from: ModuleId) -> Option<ModPath> {
|
pub fn find_path(db: &impl DefDatabase, item: ItemInNs, from: ModuleId) -> Option<ModPath> {
|
||||||
|
@ -61,7 +60,7 @@ pub fn find_path(db: &impl DefDatabase, item: ItemInNs, from: ModuleId) -> Optio
|
||||||
|
|
||||||
// - otherwise, look for modules containing (reexporting) it and import it from one of those
|
// - otherwise, look for modules containing (reexporting) it and import it from one of those
|
||||||
let importable_locations = find_importable_locations(db, item, from);
|
let importable_locations = find_importable_locations(db, item, from);
|
||||||
// XXX going in order for now
|
let mut candidate_paths = Vec::new();
|
||||||
for (module_id, name) in importable_locations {
|
for (module_id, name) in importable_locations {
|
||||||
// TODO prevent infinite loops
|
// TODO prevent infinite loops
|
||||||
let mut path = match find_path(db, ItemInNs::Types(ModuleDefId::ModuleId(module_id)), from) {
|
let mut path = match find_path(db, ItemInNs::Types(ModuleDefId::ModuleId(module_id)), from) {
|
||||||
|
@ -69,9 +68,9 @@ pub fn find_path(db: &impl DefDatabase, item: ItemInNs, from: ModuleId) -> Optio
|
||||||
Some(path) => path,
|
Some(path) => path,
|
||||||
};
|
};
|
||||||
path.segments.push(name);
|
path.segments.push(name);
|
||||||
return Some(path);
|
candidate_paths.push(path);
|
||||||
}
|
}
|
||||||
None
|
candidate_paths.into_iter().min_by_key(|path| path.segments.len())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_importable_locations(db: &impl DefDatabase, item: ItemInNs, from: ModuleId) -> Vec<(ModuleId, Name)> {
|
fn find_importable_locations(db: &impl DefDatabase, item: ItemInNs, from: ModuleId) -> Vec<(ModuleId, Name)> {
|
||||||
|
@ -275,4 +274,20 @@ mod tests {
|
||||||
check_found_path(code, "None");
|
check_found_path(code, "None");
|
||||||
check_found_path(code, "Some");
|
check_found_path(code, "Some");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn shortest_path() {
|
||||||
|
let code = r#"
|
||||||
|
//- /main.rs
|
||||||
|
pub mod foo;
|
||||||
|
pub mod baz;
|
||||||
|
struct S;
|
||||||
|
<|>
|
||||||
|
//- /foo.rs
|
||||||
|
pub mod bar { pub struct S; }
|
||||||
|
//- /baz.rs
|
||||||
|
pub use crate::foo::bar::S;
|
||||||
|
"#;
|
||||||
|
check_found_path(code, "baz::S");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue