scope-based resolve path
This commit is contained in:
parent
68f66e0f44
commit
f4860870da
@ -42,8 +42,7 @@ pub(super) fn completions(
|
||||
let module_scope = module.scope(db)?;
|
||||
acc.extend(
|
||||
module_scope
|
||||
.items
|
||||
.iter()
|
||||
.entries()
|
||||
.filter(|(_name, res)| {
|
||||
// Don't expose this item
|
||||
match res.import {
|
||||
@ -162,14 +161,11 @@ fn complete_path(
|
||||
Some(it) => it,
|
||||
};
|
||||
let module_scope = target_module.scope(db)?;
|
||||
let completions = module_scope
|
||||
.items
|
||||
.iter()
|
||||
.map(|(name, _res)| CompletionItem {
|
||||
label: name.to_string(),
|
||||
lookup: None,
|
||||
snippet: None,
|
||||
});
|
||||
let completions = module_scope.entries().map(|(name, _res)| CompletionItem {
|
||||
label: name.to_string(),
|
||||
lookup: None,
|
||||
snippet: None,
|
||||
});
|
||||
acc.extend(completions);
|
||||
Ok(())
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
descriptors::{Path, PathKind, DescriptorDatabase},
|
||||
input::SourceRootId,
|
||||
arena::{Arena, Id},
|
||||
loc2id::DefLoc,
|
||||
};
|
||||
|
||||
pub(crate) use self::nameres::ModuleScope;
|
||||
@ -76,6 +77,20 @@ fn guess_from_source(
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
fn new(
|
||||
db: &impl DescriptorDatabase,
|
||||
source_root_id: SourceRootId,
|
||||
module_id: ModuleId,
|
||||
) -> Cancelable<ModuleDescriptor> {
|
||||
let module_tree = db._module_tree(source_root_id)?;
|
||||
let res = ModuleDescriptor {
|
||||
tree: module_tree,
|
||||
source_root_id,
|
||||
module_id,
|
||||
};
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
/// Returns `mod foo;` or `mod foo {}` node whihc declared this module.
|
||||
/// Returns `None` for the root module
|
||||
pub fn parent_link_source(
|
||||
@ -133,25 +148,37 @@ pub(crate) fn scope(&self, db: &impl DescriptorDatabase) -> Cancelable<ModuleSco
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
pub(crate) fn resolve_path(&self, db: &impl DescriptorDatabase, path: Path) -> Cancelable<Option<ModuleDescriptor>> {
|
||||
let res = match self.do_resolve_path(path) {
|
||||
None => return Ok(None),
|
||||
Some(it) => it,
|
||||
pub(crate) fn resolve_path(
|
||||
&self,
|
||||
db: &impl DescriptorDatabase,
|
||||
path: Path,
|
||||
) -> Cancelable<Option<ModuleDescriptor>> {
|
||||
macro_rules! ctry {
|
||||
($expr:expr) => {
|
||||
match $expr {
|
||||
None => return Ok(None),
|
||||
Some(it) => it,
|
||||
}
|
||||
};
|
||||
};
|
||||
Ok(Some(res))
|
||||
}
|
||||
|
||||
fn do_resolve_path(&self, path: Path) -> Option<ModuleDescriptor> {
|
||||
let mut curr = match path.kind {
|
||||
PathKind::Crate => self.crate_root(),
|
||||
PathKind::Self_ | PathKind::Plain => self.clone(),
|
||||
PathKind::Super => self.parent()?,
|
||||
PathKind::Super => ctry!(self.parent()),
|
||||
};
|
||||
|
||||
let segments = path.segments;
|
||||
for name in segments {
|
||||
curr = curr.child(&name)?;
|
||||
let scope = curr.scope(db)?;
|
||||
let def_id = ctry!(ctry!(scope.get(&name)).def_id);
|
||||
curr = match db.id_maps().def_loc(def_id) {
|
||||
DefLoc::Module { id, source_root } => ModuleDescriptor::new(db, source_root, id)?,
|
||||
_ => return Ok(None),
|
||||
};
|
||||
}
|
||||
Some(curr)
|
||||
|
||||
Ok(Some(curr))
|
||||
}
|
||||
|
||||
pub fn problems(&self, db: &impl DescriptorDatabase) -> Vec<(SyntaxNode, Problem)> {
|
||||
|
@ -103,7 +103,16 @@ pub(crate) struct ItemMap {
|
||||
|
||||
#[derive(Debug, Default, PartialEq, Eq, Clone)]
|
||||
pub(crate) struct ModuleScope {
|
||||
pub(crate) items: FxHashMap<SmolStr, Resolution>,
|
||||
items: FxHashMap<SmolStr, Resolution>,
|
||||
}
|
||||
|
||||
impl ModuleScope {
|
||||
pub(crate) fn entries<'a>(&'a self) -> impl Iterator<Item = (&'a SmolStr, &Resolution)> + 'a {
|
||||
self.items.iter()
|
||||
}
|
||||
pub(crate) fn get(&self, name: &SmolStr) -> Option<&Resolution> {
|
||||
self.items.get(name)
|
||||
}
|
||||
}
|
||||
|
||||
/// A set of items and imports declared inside a module, without relation to
|
||||
|
Loading…
Reference in New Issue
Block a user