split module source into decl/defin

This commit is contained in:
Aleksey Kladov 2019-01-06 15:58:45 +03:00
parent 9cb02fd931
commit a7f4f7bfcc
6 changed files with 106 additions and 32 deletions

View file

@ -397,7 +397,7 @@ impl Analysis {
}
/// Returns the root file of the given crate.
pub fn crate_root(&self, crate_id: CrateId) -> Cancelable<FileId> {
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<Vec<Runnable>> {

View file

@ -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,

View file

@ -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<ModuleSource> {
Ok(self.source_impl(db))
pub fn name(&self, db: &impl HirDatabase) -> Cancelable<Option<Name>> {
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<Option<(FileId, ast::ModuleNode)>> {
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<Option<Module>> {
self.parent_impl(db)
}
pub fn path_to_root(&self, db: &impl HirDatabase) -> Cancelable<Vec<Module>> {
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<ModuleScope> {
self.scope_impl(db)
@ -63,4 +90,7 @@ impl Module {
pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> Cancelable<PerNs<DefId>> {
self.resolve_path_impl(db, path)
}
pub fn problems(&self, db: &impl HirDatabase) -> Cancelable<Vec<(SyntaxNode, Problem)>> {
self.problems_impl(db)
}
}

View file

@ -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<Option<Name>> {
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<Option<(FileId, ast::ModuleNode)>> {
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<Option<Crate>> {
@ -150,4 +186,9 @@ impl Module {
}
Ok(curr_per_ns)
}
pub fn problems_impl(&self, db: &impl HirDatabase) -> Cancelable<Vec<(SyntaxNode, Problem)>> {
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))
}
}

View file

@ -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);

View file

@ -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<LinkId> {
pub(crate) fn parent_link(self, tree: &ModuleTree) -> Option<LinkId> {
tree.mods[self].parent
}
pub(crate) fn parent(self, tree: &ModuleTree) -> Option<ModuleId> {
@ -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) => {