mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-30 13:51:31 +00:00
Apply the proposed refactoring
This commit is contained in:
parent
7a2e449424
commit
762d293581
1 changed files with 43 additions and 38 deletions
|
@ -11,6 +11,34 @@ use hir_expand::name::{known, Name};
|
||||||
|
|
||||||
const MAX_PATH_LEN: usize = 15;
|
const MAX_PATH_LEN: usize = 15;
|
||||||
|
|
||||||
|
impl ModPath {
|
||||||
|
fn starts_with_std(&self) -> bool {
|
||||||
|
self.segments.first().filter(|&first_segment| first_segment == &known::std).is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
// When std library is present, paths starting with `std::`
|
||||||
|
// should be preferred over paths starting with `core::` and `alloc::`
|
||||||
|
fn should_start_with_std(&self) -> bool {
|
||||||
|
self.segments
|
||||||
|
.first()
|
||||||
|
.filter(|&first_segment| {
|
||||||
|
first_segment == &known::alloc || first_segment == &known::core
|
||||||
|
})
|
||||||
|
.is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn len(&self) -> usize {
|
||||||
|
self.segments.len()
|
||||||
|
+ match self.kind {
|
||||||
|
PathKind::Plain => 0,
|
||||||
|
PathKind::Super(i) => i as usize,
|
||||||
|
PathKind::Crate => 1,
|
||||||
|
PathKind::Abs => 0,
|
||||||
|
PathKind::DollarCrate(_) => 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: handle local items
|
// FIXME: handle local items
|
||||||
|
|
||||||
/// Find a path that can be used to refer to a certain item. This can depend on
|
/// Find a path that can be used to refer to a certain item. This can depend on
|
||||||
|
@ -102,7 +130,7 @@ fn find_path_inner(
|
||||||
let mut best_path = None;
|
let mut best_path = None;
|
||||||
let mut best_path_len = max_len;
|
let mut best_path_len = max_len;
|
||||||
for (module_id, name) in importable_locations {
|
for (module_id, name) in importable_locations {
|
||||||
let mut new_path = match find_path_inner(
|
let mut path = match find_path_inner(
|
||||||
db,
|
db,
|
||||||
ItemInNs::Types(ModuleDefId::ModuleId(module_id)),
|
ItemInNs::Types(ModuleDefId::ModuleId(module_id)),
|
||||||
from,
|
from,
|
||||||
|
@ -111,51 +139,28 @@ fn find_path_inner(
|
||||||
None => continue,
|
None => continue,
|
||||||
Some(path) => path,
|
Some(path) => path,
|
||||||
};
|
};
|
||||||
new_path.segments.push(name);
|
path.segments.push(name);
|
||||||
|
|
||||||
if prefer_new_path(best_path_len, best_path.as_ref(), &new_path) {
|
let new_path =
|
||||||
best_path_len = path_len(&new_path);
|
if let Some(best_path) = best_path { select_best_path(best_path, path) } else { path };
|
||||||
best_path = Some(new_path);
|
best_path_len = new_path.len();
|
||||||
}
|
best_path = Some(new_path);
|
||||||
}
|
}
|
||||||
best_path
|
best_path
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prefer_new_path(old_path_len: usize, old_path: Option<&ModPath>, new_path: &ModPath) -> bool {
|
fn select_best_path(old_path: ModPath, new_path: ModPath) -> ModPath {
|
||||||
match (old_path.and_then(|mod_path| mod_path.segments.first()), new_path.segments.first()) {
|
if old_path.starts_with_std() && new_path.should_start_with_std() {
|
||||||
(Some(old_path_start), Some(new_path_start))
|
old_path
|
||||||
if old_path_start == &known::std && use_std_instead(new_path_start) =>
|
} else if new_path.starts_with_std() && old_path.should_start_with_std() {
|
||||||
{
|
new_path
|
||||||
false
|
} else if new_path.len() < old_path.len() {
|
||||||
}
|
new_path
|
||||||
(Some(old_path_start), Some(new_path_start))
|
} else {
|
||||||
if new_path_start == &known::std && use_std_instead(old_path_start) =>
|
old_path
|
||||||
{
|
|
||||||
true
|
|
||||||
}
|
|
||||||
(None, Some(_)) => true,
|
|
||||||
(Some(_), None) => false,
|
|
||||||
_ => path_len(new_path) < old_path_len,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// When std library is present, paths starting with `std::`
|
|
||||||
// should be preferred over paths starting with `core::` and `alloc::`
|
|
||||||
fn use_std_instead(name: &Name) -> bool {
|
|
||||||
name == &known::core || name == &known::alloc
|
|
||||||
}
|
|
||||||
|
|
||||||
fn path_len(path: &ModPath) -> usize {
|
|
||||||
path.segments.len()
|
|
||||||
+ match path.kind {
|
|
||||||
PathKind::Plain => 0,
|
|
||||||
PathKind::Super(i) => i as usize,
|
|
||||||
PathKind::Crate => 1,
|
|
||||||
PathKind::Abs => 0,
|
|
||||||
PathKind::DollarCrate(_) => 1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn find_importable_locations(
|
fn find_importable_locations(
|
||||||
db: &impl DefDatabase,
|
db: &impl DefDatabase,
|
||||||
item: ItemInNs,
|
item: ItemInNs,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue