From a7f4f7bfcc524a55ba559e0141a70aa799a8686d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 6 Jan 2019 15:58:45 +0300 Subject: split module source into decl/defin --- crates/ra_analysis/src/lib.rs | 2 +- crates/ra_analysis/src/runnables.rs | 6 ++--- crates/ra_hir/src/code_model_api.rs | 40 ++++++++++++++++++++++++---- crates/ra_hir/src/code_model_impl.rs | 51 ++++++++++++++++++++++++++++++++---- crates/ra_hir/src/impl_block.rs | 14 +++++----- crates/ra_hir/src/module.rs | 25 ++++++++++-------- 6 files changed, 106 insertions(+), 32 deletions(-) diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index 390c31c3f..77f77e9a8 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs @@ -397,7 +397,7 @@ impl Analysis { } /// Returns the root file of the given crate. pub fn crate_root(&self, crate_id: CrateId) -> Cancelable { - Ok(self.db.crate_root(crate_id)) + Ok(self.db.crate_graph().crate_root(crate_id)) } /// Returns the set of possible targets to run for the current file. pub fn runnables(&self, file_id: FileId) -> Cancelable> { diff --git a/crates/ra_analysis/src/runnables.rs b/crates/ra_analysis/src/runnables.rs index 474267605..f24aa514a 100644 --- a/crates/ra_analysis/src/runnables.rs +++ b/crates/ra_analysis/src/runnables.rs @@ -73,11 +73,11 @@ fn runnable_mod(db: &RootDatabase, file_id: FileId, module: ast::Module) -> Opti let module = hir::source_binder::module_from_child_node(db, file_id, module.syntax()).ok()??; let path = module - .path_to_root() + .path_to_root(db) + .ok()? .into_iter() .rev() - .into_iter() - .filter_map(|it| it.name().map(Clone::clone)) + .filter_map(|it| it.name(db).map(Clone::clone)) .join("::"); Some(Runnable { range, diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index eca7d0225..0c7f743d4 100644 --- a/crates/ra_hir/src/code_model_api.rs +++ b/crates/ra_hir/src/code_model_api.rs @@ -1,6 +1,7 @@ -use ra_db::{CrateId, Cancelable}; +use ra_db::{CrateId, Cancelable, FileId}; +use ra_syntax::{ast, SyntaxNode}; -use crate::{Name, db::HirDatabase, DefId, Path, PerNs, module::{ModuleSource, ModuleScope}}; +use crate::{Name, db::HirDatabase, DefId, Path, PerNs, module::{Problem, ModuleScope}}; /// 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 @@ -33,10 +34,27 @@ pub struct Module { pub(crate) def_id: DefId, } +/// An owned syntax node for a module. Unlike `ModuleSource`, +/// this holds onto the AST for the whole file. +pub enum ModuleSource { + SourceFile(ast::SourceFileNode), + Module(ast::ModuleNode), +} + impl Module { - // FIXME: what is a module source exactly? It should contain two nodes - pub fn source(&self, db: &impl HirDatabase) -> Cancelable { - Ok(self.source_impl(db)) + pub fn name(&self, db: &impl HirDatabase) -> Cancelable> { + self.name_impl(db) + } + + pub fn defenition_source(&self, db: &impl HirDatabase) -> Cancelable<(FileId, ModuleSource)> { + self.defenition_source_impl(db) + } + + pub fn declaration_source( + &self, + db: &impl HirDatabase, + ) -> Cancelable> { + self.declaration_source_impl(db) } /// Returns the crate this module is part of. @@ -56,6 +74,15 @@ impl Module { pub fn parent(&self, db: &impl HirDatabase) -> Cancelable> { self.parent_impl(db) } + pub fn path_to_root(&self, db: &impl HirDatabase) -> Cancelable> { + let mut res = vec![self.clone()]; + let mut curr = self.clone(); + while let Some(next) = curr.parent(db)? { + res.push(next.clone()); + curr = next + } + Ok(res) + } /// Returns a `ModuleScope`: a set of items, visible in this module. pub fn scope(&self, db: &impl HirDatabase) -> Cancelable { self.scope_impl(db) @@ -63,4 +90,7 @@ impl Module { pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> Cancelable> { self.resolve_path_impl(db, path) } + pub fn problems(&self, db: &impl HirDatabase) -> Cancelable> { + self.problems_impl(db) + } } diff --git a/crates/ra_hir/src/code_model_impl.rs b/crates/ra_hir/src/code_model_impl.rs index 7f5669c8f..4f4b506dd 100644 --- a/crates/ra_hir/src/code_model_impl.rs +++ b/crates/ra_hir/src/code_model_impl.rs @@ -1,12 +1,13 @@ -use ra_db::{CrateId, Cancelable, SourceRootId}; +use ra_db::{CrateId, Cancelable, SourceRootId, FileId}; +use ra_syntax::{ast, SyntaxNode, AstNode}; use crate::{ HirFileId, Crate, CrateDependency, AsName, DefId, DefLoc, DefKind, Name, Path, PathKind, PerNs, Def, ModuleId, - module::{ModuleSource, ModuleScope}, + module::{ModuleScope, Problem}, db::HirDatabase, }; -use crate::code_model_api::Module; +use crate::code_model_api::{Module, ModuleSource}; impl Crate { pub(crate) fn new(crate_id: CrateId) -> Crate { @@ -68,9 +69,44 @@ impl Module { Ok(module) } - pub(crate) fn source_impl(&self, db: &impl HirDatabase) -> ModuleSource { + pub(crate) fn name_impl(&self, db: &impl HirDatabase) -> Cancelable> { let loc = self.def_id.loc(db); - ModuleSource(loc.source_item_id) + let module_tree = db.module_tree(loc.source_root_id)?; + let link = ctry!(loc.module_id.parent_link(&module_tree)); + Ok(Some(link.name(&module_tree).clone())) + } + + pub fn defenition_source_impl( + &self, + db: &impl HirDatabase, + ) -> Cancelable<(FileId, ModuleSource)> { + let loc = self.def_id.loc(db); + let file_id = loc.source_item_id.file_id.as_original_file(); + let syntax_node = db.file_item(loc.source_item_id); + let syntax_node = syntax_node.borrowed(); + let module_source = if let Some(source_file) = ast::SourceFile::cast(syntax_node) { + ModuleSource::SourceFile(source_file.owned()) + } else { + let module = ast::Module::cast(syntax_node).unwrap(); + ModuleSource::Module(module.owned()) + }; + Ok((file_id, module_source)) + } + + pub fn declaration_source_impl( + &self, + db: &impl HirDatabase, + ) -> Cancelable> { + let loc = self.def_id.loc(db); + let module_tree = db.module_tree(loc.source_root_id)?; + let link = ctry!(loc.module_id.parent_link(&module_tree)); + let file_id = link + .owner(&module_tree) + .source(&module_tree) + .file_id() + .as_original_file(); + let src = link.bind_source(&module_tree, db); + Ok(Some((file_id, src))) } pub(crate) fn krate_impl(&self, db: &impl HirDatabase) -> Cancelable> { @@ -150,4 +186,9 @@ impl Module { } Ok(curr_per_ns) } + pub fn problems_impl(&self, db: &impl HirDatabase) -> Cancelable> { + let loc = self.def_id.loc(db); + let module_tree = db.module_tree(loc.source_root_id)?; + Ok(loc.module_id.problems(&module_tree, db)) + } } diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs index 891c93434..0d1b94c42 100644 --- a/crates/ra_hir/src/impl_block.rs +++ b/crates/ra_hir/src/impl_block.rs @@ -10,10 +10,10 @@ use crate::{ Function, db::HirDatabase, type_ref::TypeRef, - module::{ModuleSourceNode, ModuleId}, + module::ModuleId, }; -use crate::code_model_api::Module; +use crate::code_model_api::{Module, ModuleSource}; #[derive(Debug, Clone, PartialEq, Eq)] pub struct ImplBlock { @@ -150,13 +150,13 @@ impl ModuleImplBlocks { } fn collect(&mut self, db: &impl HirDatabase, module: Module) -> Cancelable<()> { - let module_source_node = module.source(db)?.resolve(db); - let node = match &module_source_node { - ModuleSourceNode::SourceFile(node) => node.borrowed().syntax(), - ModuleSourceNode::Module(node) => node.borrowed().syntax(), + let (file_id, module_source) = module.defenition_source(db)?; + let node = match &module_source { + ModuleSource::SourceFile(node) => node.borrowed().syntax(), + ModuleSource::Module(node) => node.borrowed().syntax(), }; - let source_file_items = db.file_items(module.source(db)?.file_id()); + let source_file_items = db.file_items(file_id.into()); for impl_block_ast in node.children().filter_map(ast::ImplBlock::cast) { let impl_block = ImplData::from_ast(db, &source_file_items, &module, impl_block_ast); diff --git a/crates/ra_hir/src/module.rs b/crates/ra_hir/src/module.rs index d1005eab6..ebaf5f47a 100644 --- a/crates/ra_hir/src/module.rs +++ b/crates/ra_hir/src/module.rs @@ -1,8 +1,6 @@ pub(super) mod imp; pub(super) mod nameres; -use log; - use ra_syntax::{ algo::generate, ast::{self, AstNode, NameOwner}, @@ -11,10 +9,7 @@ use ra_syntax::{ use ra_arena::{Arena, RawId, impl_arena_id}; use relative_path::RelativePathBuf; -use crate::{ - Name, HirDatabase, SourceItemId, SourceFileItemId, - HirFileId, -}; +use crate::{Name, HirDatabase, SourceItemId, SourceFileItemId, HirFileId}; pub use self::nameres::{ModuleScope, Resolution, Namespace, PerNs}; @@ -78,7 +73,7 @@ impl ModuleId { pub(crate) fn source(self, tree: &ModuleTree) -> ModuleSource { tree.mods[self].source } - fn parent_link(self, tree: &ModuleTree) -> Option { + pub(crate) fn parent_link(self, tree: &ModuleTree) -> Option { tree.mods[self].parent } pub(crate) fn parent(self, tree: &ModuleTree) -> Option { @@ -105,7 +100,11 @@ impl ModuleId { Some((link.name.clone(), module)) }) } - fn problems(self, tree: &ModuleTree, db: &impl HirDatabase) -> Vec<(SyntaxNode, Problem)> { + pub(crate) fn problems( + self, + tree: &ModuleTree, + db: &impl HirDatabase, + ) -> Vec<(SyntaxNode, Problem)> { tree.mods[self] .children .iter() @@ -120,13 +119,17 @@ impl ModuleId { } impl LinkId { - fn owner(self, tree: &ModuleTree) -> ModuleId { + pub(crate) fn owner(self, tree: &ModuleTree) -> ModuleId { tree.links[self].owner } - fn name(self, tree: &ModuleTree) -> &Name { + pub(crate) fn name(self, tree: &ModuleTree) -> &Name { &tree.links[self].name } - fn bind_source<'a>(self, tree: &ModuleTree, db: &impl HirDatabase) -> ast::ModuleNode { + pub(crate) fn bind_source<'a>( + self, + tree: &ModuleTree, + db: &impl HirDatabase, + ) -> ast::ModuleNode { let owner = self.owner(tree); match owner.source(tree).resolve(db) { ModuleSourceNode::SourceFile(root) => { -- cgit v1.2.3