WIP: resolve across crates

This commit is contained in:
Aleksey Kladov 2018-12-09 12:45:47 +03:00
parent 8b9ff46b37
commit 6a16d3fb0b
1 changed files with 41 additions and 14 deletions

View File

@ -31,7 +31,7 @@ use crate::{
DefId, DefLoc, DefKind, DefId, DefLoc, DefKind,
SourceItemId, SourceFileItemId, SourceFileItems, SourceItemId, SourceFileItemId, SourceFileItems,
Path, PathKind, Path, PathKind,
HirDatabase, HirDatabase, Crate,
module::{ModuleId, ModuleTree}, module::{ModuleId, ModuleTree},
}; };
@ -218,8 +218,8 @@ where
module_tree: Arc<ModuleTree>, module_tree: Arc<ModuleTree>,
) -> Resolver<'a, DB> { ) -> Resolver<'a, DB> {
Resolver { Resolver {
db: db, db,
input: &input, input,
source_root, source_root,
module_tree, module_tree,
result: ItemMap::default(), result: ItemMap::default(),
@ -233,7 +233,7 @@ where
for &module_id in self.input.keys() { for &module_id in self.input.keys() {
self.db.check_canceled()?; self.db.check_canceled()?;
self.resolve_imports(module_id); self.resolve_imports(module_id)?;
} }
Ok(self.result) Ok(self.result)
} }
@ -297,40 +297,66 @@ where
self.result.per_module.insert(module_id, module_items); self.result.per_module.insert(module_id, module_items);
} }
fn resolve_imports(&mut self, module_id: ModuleId) { fn resolve_imports(&mut self, module_id: ModuleId) -> Cancelable<()> {
for import in self.input[&module_id].imports.iter() { for import in self.input[&module_id].imports.iter() {
self.resolve_import(module_id, import); self.resolve_import(module_id, import)?;
} }
Ok(())
} }
fn resolve_import(&mut self, module_id: ModuleId, import: &Import) { fn resolve_import(&mut self, module_id: ModuleId, import: &Import) -> Cancelable<()> {
let ptr = match import.kind { let ptr = match import.kind {
ImportKind::Glob => return, ImportKind::Glob => return Ok(()),
ImportKind::Named(ptr) => ptr, ImportKind::Named(ptr) => ptr,
}; };
let mut segments = import.path.segments.iter().enumerate();
let mut curr = match import.path.kind { let mut curr = match import.path.kind {
// TODO: handle extern crates // TODO: handle extern crates
PathKind::Plain => return, PathKind::Plain => {
let root_id = module_id.crate_root(&self.module_tree);
let file_id = root_id.source(&self.module_tree).file_id();
let crate_graph = self.db.crate_graph();
let crate_id = match crate_graph.crate_id_for_crate_root(file_id) {
None => return Ok(()),
Some(it) => it,
};
let krate = Crate::new(crate_id);
let crate_name = match segments.next() {
None => return Ok(()),
Some((_, it)) => it,
};
match krate
.dependencies(self.db)
.into_iter()
.find(|it| &it.name == crate_name)
{
None => return Ok(()),
Some(dep) => match dep.krate.root_module(self.db)? {
None => return Ok(()),
Some(it) => it.module_id,
},
}
}
PathKind::Self_ => module_id, PathKind::Self_ => module_id,
PathKind::Super => { PathKind::Super => {
match module_id.parent(&self.module_tree) { match module_id.parent(&self.module_tree) {
Some(it) => it, Some(it) => it,
// TODO: error // TODO: error
None => return, None => return Ok(()),
} }
} }
PathKind::Crate => module_id.crate_root(&self.module_tree), PathKind::Crate => module_id.crate_root(&self.module_tree),
}; };
for (i, name) in import.path.segments.iter().enumerate() { for (i, name) in segments {
let is_last = i == import.path.segments.len() - 1; let is_last = i == import.path.segments.len() - 1;
let def_id = match self.result.per_module[&curr].items.get(name) { let def_id = match self.result.per_module[&curr].items.get(name) {
None => return, None => return Ok(()),
Some(res) => match res.def_id { Some(res) => match res.def_id {
Some(it) => it, Some(it) => it,
None => return, None => return Ok(()),
}, },
}; };
@ -341,7 +367,7 @@ where
module_id, module_id,
.. ..
} => module_id, } => module_id,
_ => return, _ => return Ok(()),
} }
} else { } else {
self.update(module_id, |items| { self.update(module_id, |items| {
@ -353,6 +379,7 @@ where
}) })
} }
} }
Ok(())
} }
fn update(&mut self, module_id: ModuleId, f: impl FnOnce(&mut ModuleScope)) { fn update(&mut self, module_id: ModuleId, f: impl FnOnce(&mut ModuleScope)) {