From 147b0f94e60f66c73ee1ca1726de97d76721bfda Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 5 Jan 2019 01:37:40 +0300 Subject: Start code_model::Module --- crates/ra_hir/src/code_model_api.rs | 23 +++++++++++++- crates/ra_hir/src/code_model_impl.rs | 59 ++++++++++++++++++++++++++++++++++-- crates/ra_hir/src/module.rs | 6 ++-- crates/ra_hir/src/module/nameres.rs | 2 +- 4 files changed, 83 insertions(+), 7 deletions(-) (limited to 'crates/ra_hir') diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index e8b3a1fb6..63e2e34e8 100644 --- a/crates/ra_hir/src/code_model_api.rs +++ b/crates/ra_hir/src/code_model_api.rs @@ -1,6 +1,6 @@ use ra_db::{CrateId, Cancelable}; -use crate::{Module, Name, db::HirDatabase}; +use crate::{Name, db::HirDatabase, DefId}; /// hir::Crate describes a single crate. It's the main inteface with which /// crate's dependencies interact. Mostly, it should be just a proxy for the @@ -24,3 +24,24 @@ impl Crate { self.root_module_impl(db) } } + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Module { + pub(crate) def_id: DefId, +} + +impl Module { + /// Returns the crate this module is part of. + pub fn krate(&self, db: &impl HirDatabase) -> Cancelable> { + self.krate_impl(db) + } + + pub fn crate_root(&self, db: &impl HirDatabase) -> Cancelable { + self.crate_root_impl(db) + } + + /// Finds a child module with the specified name. + pub fn child(&self, db: &impl HirDatabase, name: &Name) -> Cancelable> { + self.child_impl(db, name) + } +} diff --git a/crates/ra_hir/src/code_model_impl.rs b/crates/ra_hir/src/code_model_impl.rs index 75d4e04c1..22079ba33 100644 --- a/crates/ra_hir/src/code_model_impl.rs +++ b/crates/ra_hir/src/code_model_impl.rs @@ -1,6 +1,9 @@ use ra_db::{CrateId, Cancelable}; -use crate::{Module, HirFileId, db::HirDatabase, Crate, CrateDependency, AsName}; +use crate::{HirFileId, db::HirDatabase, Crate, CrateDependency, AsName, DefId, DefLoc, DefKind, Name}; + +use crate::code_model_api::Module; + impl Crate { pub(crate) fn new(crate_id: CrateId) -> Crate { @@ -28,7 +31,59 @@ impl Crate { .modules_with_sources() .find(|(_, src)| src.file_id() == file_id)); - let module = Module::new(db, source_root_id, module_id)?; + let def_loc = DefLoc { + kind: DefKind::Module, + source_root_id, + module_id, + source_item_id: module_id.source(&module_tree).0, + }; + let def_id = def_loc.id(db); + + let module = Module::new(def_id); + Ok(Some(module)) + } +} + +impl Module { + fn new(def_id: DefId) -> Self { + crate::code_model_api::Module { def_id } + } + + pub(crate) fn krate_impl(&self, db: &impl HirDatabase) -> Cancelable> { + let root = self.crate_root(db)?; + let loc = root.def_id.loc(db); + let file_id = loc.source_item_id.file_id.as_original_file(); + + let crate_graph = db.crate_graph(); + let crate_id = ctry!(crate_graph.crate_id_for_crate_root(file_id)); + Ok(Some(Crate::new(crate_id))) + } + + pub(crate) fn crate_root_impl(&self, db: &impl HirDatabase) -> Cancelable { + let loc = self.def_id.loc(db); + let module_tree = db.module_tree(loc.source_root_id)?; + let module_id = loc.module_id.crate_root(&module_tree); + let def_loc = DefLoc { + module_id, + source_item_id: module_id.source(&module_tree).0, + ..loc + }; + let def_id = def_loc.id(db); + let module = Module::new(def_id); + Ok(module) + } + /// Finds a child module with the specified name. + pub fn child_impl(&self, db: &impl HirDatabase, name: &Name) -> Cancelable> { + let loc = self.def_id.loc(db); + let module_tree = db.module_tree(loc.source_root_id)?; + let child_id = ctry!(loc.module_id.child(&module_tree, name)); + let def_loc = DefLoc { + module_id: child_id, + source_item_id: child_id.source(&module_tree).0, + ..loc + }; + let def_id = def_loc.id(db); + let module = Module::new(def_id); Ok(Some(module)) } } diff --git a/crates/ra_hir/src/module.rs b/crates/ra_hir/src/module.rs index b9821115c..f0b673908 100644 --- a/crates/ra_hir/src/module.rs +++ b/crates/ra_hir/src/module.rs @@ -224,7 +224,7 @@ impl ModuleTree { /// `ModuleSource` is the syntax tree element that produced this module: /// either a file, or an inlinde module. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -pub struct ModuleSource(SourceItemId); +pub struct ModuleSource(pub(crate) SourceItemId); /// An owned syntax node for a module. Unlike `ModuleSource`, /// this holds onto the AST for the whole file. @@ -255,12 +255,12 @@ impl ModuleId { let link = self.parent_link(tree)?; Some(tree.links[link].owner) } - fn crate_root(self, tree: &ModuleTree) -> ModuleId { + pub(crate) fn crate_root(self, tree: &ModuleTree) -> ModuleId { generate(Some(self), move |it| it.parent(tree)) .last() .unwrap() } - fn child(self, tree: &ModuleTree, name: &Name) -> Option { + pub(crate) fn child(self, tree: &ModuleTree, name: &Name) -> Option { let link = tree.mods[self] .children .iter() diff --git a/crates/ra_hir/src/module/nameres.rs b/crates/ra_hir/src/module/nameres.rs index 3c6851a0a..cd634e42f 100644 --- a/crates/ra_hir/src/module/nameres.rs +++ b/crates/ra_hir/src/module/nameres.rs @@ -346,7 +346,7 @@ where let krate = Crate::new(crate_id); for dep in krate.dependencies(self.db) { if let Some(module) = dep.krate.root_module(self.db)? { - let def_id = module.def_id(self.db); + let def_id = module.def_id; self.add_module_item( &mut module_items, dep.name.clone(), -- cgit v1.2.3