kill old module

This commit is contained in:
Aleksey Kladov 2019-01-06 15:16:21 +03:00
parent 3c2cb89087
commit 9cb02fd931
7 changed files with 67 additions and 234 deletions

View File

@ -1,7 +1,6 @@
use ra_db::{CrateId, Cancelable, FileId};
use ra_syntax::ast;
use ra_db::{CrateId, Cancelable};
use crate::{Name, db::HirDatabase, DefId, Path, PerNs};
use crate::{Name, db::HirDatabase, DefId, Path, PerNs, module::{ModuleSource, 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
@ -35,7 +34,8 @@ pub struct Module {
}
impl Module {
pub fn source(&self, db: &impl HirDatabase) -> Cancelable<(FileId, Option<ast::ModuleNode>)> {
// 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))
}
@ -56,7 +56,10 @@ impl Module {
pub fn parent(&self, db: &impl HirDatabase) -> Cancelable<Option<Module>> {
self.parent_impl(db)
}
/// Returns a `ModuleScope`: a set of items, visible in this module.
pub fn scope(&self, db: &impl HirDatabase) -> Cancelable<ModuleScope> {
self.scope_impl(db)
}
pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> Cancelable<PerNs<DefId>> {
self.resolve_path_impl(db, path)
}

View File

@ -1,7 +1,10 @@
use ra_db::{CrateId, Cancelable, FileId};
use ra_syntax::{AstNode, ast};
use ra_db::{CrateId, Cancelable, SourceRootId};
use crate::{HirFileId, db::HirDatabase, Crate, CrateDependency, AsName, DefId, DefLoc, DefKind, Name, Path, PathKind, PerNs, Def};
use crate::{
HirFileId, Crate, CrateDependency, AsName, DefId, DefLoc, DefKind, Name, Path, PathKind, PerNs, Def, ModuleId,
module::{ModuleSource, ModuleScope},
db::HirDatabase,
};
use crate::code_model_api::Module;
@ -48,21 +51,26 @@ impl Module {
pub(crate) fn new(def_id: DefId) -> Self {
crate::code_model_api::Module { def_id }
}
pub(crate) fn source_impl(&self, db: &impl HirDatabase) -> (FileId, Option<ast::ModuleNode>) {
let loc = self.def_id.loc(db);
let source_item_id = loc.source_item_id;
let module = match source_item_id.item_id {
None => None,
Some(_) => {
let syntax_node = db.file_item(source_item_id);
let module = ast::Module::cast(syntax_node.borrowed()).unwrap().owned();
Some(module)
}
pub(crate) fn from_module_id(
db: &impl HirDatabase,
source_root_id: SourceRootId,
module_id: ModuleId,
) -> Cancelable<Self> {
let module_tree = db.module_tree(source_root_id)?;
let def_loc = DefLoc {
kind: DefKind::Module,
source_root_id,
module_id,
source_item_id: module_id.source(&module_tree).0,
};
// FIXME: remove `as_original_file` here
let file_id = source_item_id.file_id.as_original_file();
(file_id, module)
let def_id = def_loc.id(db);
let module = Module::new(def_id);
Ok(module)
}
pub(crate) fn source_impl(&self, db: &impl HirDatabase) -> ModuleSource {
let loc = self.def_id.loc(db);
ModuleSource(loc.source_item_id)
}
pub(crate) fn krate_impl(&self, db: &impl HirDatabase) -> Cancelable<Option<Crate>> {
@ -79,41 +87,27 @@ impl Module {
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)
Module::from_module_id(db, loc.source_root_id, module_id)
}
/// Finds a child module with the specified name.
pub fn child_impl(&self, db: &impl HirDatabase, name: &Name) -> Cancelable<Option<Module>> {
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))
Module::from_module_id(db, loc.source_root_id, child_id).map(Some)
}
pub fn parent_impl(&self, db: &impl HirDatabase) -> Cancelable<Option<Module>> {
let loc = self.def_id.loc(db);
let module_tree = db.module_tree(loc.source_root_id)?;
let parent_id = ctry!(loc.module_id.parent(&module_tree));
let def_loc = DefLoc {
module_id: parent_id,
source_item_id: parent_id.source(&module_tree).0,
..loc
};
let def_id = def_loc.id(db);
let module = Module::new(def_id);
Ok(Some(module))
Module::from_module_id(db, loc.source_root_id, parent_id).map(Some)
}
/// Returns a `ModuleScope`: a set of items, visible in this module.
pub fn scope_impl(&self, db: &impl HirDatabase) -> Cancelable<ModuleScope> {
let loc = self.def_id.loc(db);
let item_map = db.item_map(loc.source_root_id)?;
let res = item_map.per_module[&loc.module_id].clone();
Ok(res)
}
pub fn resolve_path_impl(
&self,

View File

@ -2,7 +2,9 @@ use ra_db::{SourceRootId, LocationIntener, Cancelable, FileId};
use ra_syntax::{SourceFileNode, SyntaxKind, SyntaxNode, SyntaxNodeRef, SourceFile, AstNode, ast};
use ra_arena::{Arena, RawId, impl_arena_id};
use crate::{HirDatabase, PerNs, ModuleId, Module, Def, Function, Struct, Enum, ImplBlock, Crate};
use crate::{HirDatabase, PerNs, ModuleId, Def, Function, Struct, Enum, ImplBlock, Crate};
use crate::code_model_api::Module;
/// hir makes a heavy use of ids: integer (u32) handlers to various things. You
/// can think of id as a pointer (but without a lifetime) or a file descriptor
@ -151,7 +153,7 @@ impl DefId {
let loc = self.loc(db);
let res = match loc.kind {
DefKind::Module => {
let module = Module::new(db, loc.source_root_id, loc.module_id)?;
let module = Module::from_module_id(db, loc.source_root_id, loc.module_id)?;
Def::Module(module)
}
DefKind::Function => {
@ -175,12 +177,12 @@ impl DefId {
/// For a module, returns that module; for any other def, returns the containing module.
pub fn module(self, db: &impl HirDatabase) -> Cancelable<Module> {
let loc = self.loc(db);
Module::new(db, loc.source_root_id, loc.module_id)
Module::from_module_id(db, loc.source_root_id, loc.module_id)
}
/// Returns the containing crate.
pub fn krate(&self, db: &impl HirDatabase) -> Cancelable<Option<Crate>> {
Ok(self.module(db)?.krate(db))
Ok(self.module(db)?.krate(db)?)
}
/// Returns the containing impl block, if this is an impl item.

View File

@ -7,12 +7,14 @@ use ra_db::{LocationIntener, Cancelable, SourceRootId};
use crate::{
DefId, DefLoc, DefKind, SourceItemId, SourceFileItems,
Module, Function,
Function,
db::HirDatabase,
type_ref::TypeRef,
module::{ModuleSourceNode, ModuleId},
};
use crate::code_model_api::Module;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ImplBlock {
module_impl_blocks: Arc<ModuleImplBlocks>,
@ -64,7 +66,7 @@ impl ImplData {
) -> Self {
let target_trait = node.target_type().map(TypeRef::from_ast);
let target_type = TypeRef::from_ast_opt(node.target_type());
let file_id = module.source().file_id();
let module_loc = module.def_id.loc(db);
let items = if let Some(item_list) = node.item_list() {
item_list
.impl_items()
@ -75,14 +77,14 @@ impl ImplData {
ast::ImplItem::TypeDef(..) => DefKind::Item,
};
let item_id = file_items.id_of_unchecked(item_node.syntax());
let source_item_id = SourceItemId {
file_id: module_loc.source_item_id.file_id,
item_id: Some(item_id),
};
let def_loc = DefLoc {
kind,
source_root_id: module.source_root_id,
module_id: module.module_id,
source_item_id: SourceItemId {
file_id,
item_id: Some(item_id),
},
source_item_id,
..module_loc
};
let def_id = def_loc.id(db);
match item_node {
@ -148,13 +150,13 @@ impl ModuleImplBlocks {
}
fn collect(&mut self, db: &impl HirDatabase, module: Module) -> Cancelable<()> {
let module_source_node = module.source().resolve(db);
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 source_file_items = db.file_items(module.source().file_id());
let source_file_items = db.file_items(module.source(db)?.file_id());
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);
@ -174,7 +176,7 @@ pub(crate) fn impls_in_module(
module_id: ModuleId,
) -> Cancelable<Arc<ModuleImplBlocks>> {
let mut result = ModuleImplBlocks::new();
let module = Module::new(db, source_root_id, module_id)?;
let module = Module::from_module_id(db, source_root_id, module_id)?;
result.collect(db, module)?;
Ok(Arc::new(result))
}

View File

@ -56,6 +56,8 @@ pub use self::{
pub use self::function::FnSignatureInfo;
pub use self::code_model_api::Module;
pub enum Def {
Module(Module),
Function(Function),

View File

@ -1,7 +1,6 @@
pub(super) mod imp;
pub(super) mod nameres;
use std::sync::Arc;
use log;
use ra_syntax::{
@ -10,184 +9,15 @@ use ra_syntax::{
SyntaxNode,
};
use ra_arena::{Arena, RawId, impl_arena_id};
use ra_db::{SourceRootId, FileId, Cancelable};
use relative_path::RelativePathBuf;
use crate::{
Def, DefKind, DefLoc, DefId,
Name, Path, PathKind, HirDatabase, SourceItemId, SourceFileItemId, Crate,
Name, HirDatabase, SourceItemId, SourceFileItemId,
HirFileId,
};
pub use self::nameres::{ModuleScope, Resolution, Namespace, PerNs};
/// `Module` is API entry point to get all the information
/// about a particular module.
#[derive(Debug, Clone)]
pub struct Module {
tree: Arc<ModuleTree>,
pub(crate) source_root_id: SourceRootId,
pub(crate) module_id: ModuleId,
}
impl Module {
pub(super) fn new(
db: &impl HirDatabase,
source_root_id: SourceRootId,
module_id: ModuleId,
) -> Cancelable<Module> {
let module_tree = db.module_tree(source_root_id)?;
let res = Module {
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(&self, db: &impl HirDatabase) -> Option<(FileId, ast::ModuleNode)> {
let link = self.module_id.parent_link(&self.tree)?;
let file_id = link
.owner(&self.tree)
.source(&self.tree)
.file_id()
.as_original_file();
let src = link.bind_source(&self.tree, db);
Some((file_id, src))
}
pub fn file_id(&self) -> FileId {
self.source().file_id().as_original_file()
}
/// Parent module. Returns `None` if this is a root module.
pub fn parent(&self) -> Option<Module> {
let parent_id = self.module_id.parent(&self.tree)?;
Some(Module {
module_id: parent_id,
..self.clone()
})
}
/// Returns an iterator of all children of this module.
pub fn children<'a>(&'a self) -> impl Iterator<Item = (Name, Module)> + 'a {
self.module_id
.children(&self.tree)
.map(move |(name, module_id)| {
(
name,
Module {
module_id,
..self.clone()
},
)
})
}
/// Returns the crate this module is part of.
pub fn krate(&self, db: &impl HirDatabase) -> Option<Crate> {
let root_id = self.module_id.crate_root(&self.tree);
let file_id = root_id.source(&self.tree).file_id().as_original_file();
let crate_graph = db.crate_graph();
let crate_id = crate_graph.crate_id_for_crate_root(file_id)?;
Some(Crate::new(crate_id))
}
/// Returns the all modules on the way to the root.
pub fn path_to_root(&self) -> Vec<Module> {
generate(Some(self.clone()), move |it| it.parent()).collect::<Vec<Module>>()
}
/// The root of the tree this module is part of
pub fn crate_root(&self) -> Module {
let root_id = self.module_id.crate_root(&self.tree);
Module {
module_id: root_id,
..self.clone()
}
}
/// `name` is `None` for the crate's root module
pub fn name(&self) -> Option<&Name> {
let link = self.module_id.parent_link(&self.tree)?;
Some(link.name(&self.tree))
}
pub fn def_id(&self, db: &impl HirDatabase) -> DefId {
let def_loc = DefLoc {
kind: DefKind::Module,
source_root_id: self.source_root_id,
module_id: self.module_id,
source_item_id: self.module_id.source(&self.tree).0,
};
def_loc.id(db)
}
/// Finds a child module with the specified name.
pub fn child(&self, name: &Name) -> Option<Module> {
let child_id = self.module_id.child(&self.tree, name)?;
Some(Module {
module_id: child_id,
..self.clone()
})
}
/// Returns a `ModuleScope`: a set of items, visible in this module.
pub fn scope(&self, db: &impl HirDatabase) -> Cancelable<ModuleScope> {
let item_map = db.item_map(self.source_root_id)?;
let res = item_map.per_module[&self.module_id].clone();
Ok(res)
}
pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> Cancelable<PerNs<DefId>> {
let mut curr_per_ns = PerNs::types(
match path.kind {
PathKind::Crate => self.crate_root(),
PathKind::Self_ | PathKind::Plain => self.clone(),
PathKind::Super => {
if let Some(p) = self.parent() {
p
} else {
return Ok(PerNs::none());
}
}
}
.def_id(db),
);
let segments = &path.segments;
for name in segments.iter() {
let curr = if let Some(r) = curr_per_ns.as_ref().take(Namespace::Types) {
r
} else {
return Ok(PerNs::none());
};
let module = match curr.resolve(db)? {
Def::Module(it) => it,
// TODO here would be the place to handle enum variants...
_ => return Ok(PerNs::none()),
};
let scope = module.scope(db)?;
curr_per_ns = if let Some(r) = scope.get(&name) {
r.def_id
} else {
return Ok(PerNs::none());
};
}
Ok(curr_per_ns)
}
pub fn problems(&self, db: &impl HirDatabase) -> Vec<(SyntaxNode, Problem)> {
self.module_id.problems(&self.tree, db)
}
pub(crate) fn source(&self) -> ModuleSource {
self.module_id.source(&self.tree)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ModuleId(RawId);
impl_arena_id!(ModuleId);

View File

@ -31,7 +31,7 @@ use crate::{
Path, PathKind,
HirDatabase, Crate,
Name, AsName,
module::{Module, ModuleId, ModuleTree},
module::{ModuleId, ModuleTree},
};
/// Item map is the result of the name resolution. Item map contains, for each
@ -466,7 +466,7 @@ where
if source_root_id == self.source_root {
target_module_id
} else {
let module = Module::new(self.db, source_root_id, target_module_id)?;
let module = crate::code_model_api::Module::new(type_def_id);
let path = Path {
segments: import.path.segments[i + 1..].iter().cloned().collect(),
kind: PathKind::Crate,