Change ids strategy

this is a part of larghish hir refactoring which aims to

* replace per-source-root module trees with per crate trees
* switch from a monotyped DedId to type-specific ids
This commit is contained in:
Aleksey Kladov 2019-01-23 23:14:13 +03:00
parent cfb085ded8
commit 3ab1519cb2
26 changed files with 365 additions and 430 deletions

View File

@ -160,6 +160,7 @@ pub trait FilesDatabase: salsa::Database {
/// Contents of the source root.
#[salsa::input]
fn source_root(&self, id: SourceRootId) -> Arc<SourceRoot>;
fn source_root_crates(&self, id: SourceRootId) -> Arc<Vec<CrateId>>;
/// The set of "local" (that is, from the current workspace) roots.
/// Files in local roots are assumed to change frequently.
#[salsa::input]
@ -173,6 +174,17 @@ pub trait FilesDatabase: salsa::Database {
fn crate_graph(&self) -> Arc<CrateGraph>;
}
fn source_root_crates(db: &impl FilesDatabase, id: SourceRootId) -> Arc<Vec<CrateId>> {
let root = db.source_root(id);
let graph = db.crate_graph();
let res = root
.files
.values()
.filter_map(|&it| graph.crate_id_for_crate_root(it))
.collect::<Vec<_>>();
Arc::new(res)
}
#[cfg(test)]
mod tests {
use super::{CrateGraph, FileId, SmolStr};

View File

@ -13,7 +13,7 @@ pub use crate::{
cancellation::Canceled,
input::{
FilesDatabase, FileId, CrateId, SourceRoot, SourceRootId, CrateGraph, Dependency,
FileTextQuery, FileSourceRootQuery, SourceRootQuery, LocalRootsQuery, LibraryRootsQuery, CrateGraphQuery,
FileTextQuery, FileSourceRootQuery, SourceRootQuery, SourceRootCratesQuery, LocalRootsQuery, LibraryRootsQuery, CrateGraphQuery,
FileRelativePathQuery
},
loc2id::LocationIntener,

View File

@ -64,9 +64,9 @@ fn get_def_id(
..same_file_loc.source_item_id
};
let loc = DefLoc {
module: same_file_loc.module,
kind: expected_kind,
source_item_id,
..*same_file_loc
};
loc.id(db)
}

View File

@ -14,13 +14,14 @@ use crate::{
adt::VariantData,
generics::GenericParams,
code_model_impl::def_id_to_ast,
docs::{Documentation, Docs, docs_from_ast}
docs::{Documentation, Docs, docs_from_ast},
module_tree::ModuleId,
};
/// hir::Crate describes a single crate. It's the main interface with which
/// a crate's dependencies interact. Mostly, it should be just a proxy for the
/// root module.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Crate {
pub(crate) crate_id: CrateId,
}
@ -45,7 +46,6 @@ impl Crate {
#[derive(Debug)]
pub enum Def {
Module(Module),
Struct(Struct),
Enum(Enum),
EnumVariant(EnumVariant),
@ -57,9 +57,29 @@ pub enum Def {
Item,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Module {
pub(crate) def_id: DefId,
pub(crate) krate: CrateId,
pub(crate) module_id: ModuleId,
}
/// The defs which can be visible in the module.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ModuleDef {
Module(Module),
Def(DefId),
}
impl Into<ModuleDef> for Module {
fn into(self) -> ModuleDef {
ModuleDef::Module(self)
}
}
impl Into<ModuleDef> for DefId {
fn into(self) -> ModuleDef {
ModuleDef::Def(self)
}
}
pub enum ModuleSource {
@ -149,7 +169,7 @@ impl Module {
self.scope_impl(db)
}
pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> PerNs<DefId> {
pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> PerNs<ModuleDef> {
self.resolve_path_impl(db, path)
}

View File

@ -1,7 +1,7 @@
use ra_db::CrateId;
use crate::{
HirFileId, Crate, CrateDependency, AsName, DefLoc, DefKind, Module, SourceItemId,
Crate, CrateDependency, AsName, Module,
db::HirDatabase,
};
@ -21,27 +21,13 @@ impl Crate {
.collect()
}
pub(crate) fn root_module_impl(&self, db: &impl HirDatabase) -> Option<Module> {
let crate_graph = db.crate_graph();
let file_id = crate_graph.crate_root(self.crate_id);
let source_root_id = db.file_source_root(file_id);
let file_id = HirFileId::from(file_id);
let module_tree = db.module_tree(source_root_id);
// FIXME: teach module tree about crate roots instead of guessing
let source = SourceItemId {
file_id,
item_id: None,
};
let module_id = module_tree.find_module_by_source(source)?;
let module_tree = db.module_tree(self.crate_id);
let module_id = module_tree.modules().next()?;
let def_loc = DefLoc {
kind: DefKind::Module,
source_root_id,
let module = Module {
krate: self.crate_id,
module_id,
source_item_id: module_id.source(&module_tree),
};
let def_id = def_loc.id(db);
let module = Module::new(def_id);
Some(module)
}
}

View File

@ -1,52 +1,33 @@
use ra_db::{SourceRootId, FileId};
use ra_syntax::{ast, SyntaxNode, AstNode, TreeArc};
use ra_db::FileId;
use ra_syntax::{ast, SyntaxNode, TreeArc};
use crate::{
Module, ModuleSource, Problem,
Crate, DefId, DefLoc, DefKind, Name, Path, PathKind, PerNs, Def,
Module, ModuleSource, Problem, ModuleDef,
Crate, Name, Path, PathKind, PerNs, Def,
module_tree::ModuleId,
nameres::{ModuleScope, lower::ImportId},
db::HirDatabase,
};
impl Module {
pub(crate) fn new(def_id: DefId) -> Self {
crate::code_model_api::Module { def_id }
}
pub(crate) fn from_module_id(
db: &impl HirDatabase,
source_root_id: SourceRootId,
module_id: ModuleId,
) -> Self {
let module_tree = db.module_tree(source_root_id);
let def_loc = DefLoc {
kind: DefKind::Module,
source_root_id,
fn with_module_id(&self, module_id: ModuleId) -> Module {
Module {
module_id,
source_item_id: module_id.source(&module_tree),
};
let def_id = def_loc.id(db);
Module::new(def_id)
krate: self.krate,
}
}
pub(crate) fn name_impl(&self, db: &impl HirDatabase) -> Option<Name> {
let loc = self.def_id.loc(db);
let module_tree = db.module_tree(loc.source_root_id);
let link = loc.module_id.parent_link(&module_tree)?;
let module_tree = db.module_tree(self.krate);
let link = self.module_id.parent_link(&module_tree)?;
Some(link.name(&module_tree).clone())
}
pub(crate) fn definition_source_impl(&self, db: &impl HirDatabase) -> (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 module_source = if let Some(source_file) = ast::SourceFile::cast(&syntax_node) {
ModuleSource::SourceFile(source_file.to_owned())
} else {
let module = ast::Module::cast(&syntax_node).unwrap();
ModuleSource::Module(module.to_owned())
};
let module_tree = db.module_tree(self.krate);
let source = self.module_id.source(&module_tree);
let module_source = ModuleSource::from_source_item_id(db, source);
let file_id = source.file_id.as_original_file();
(file_id, module_source)
}
@ -54,9 +35,8 @@ impl Module {
&self,
db: &impl HirDatabase,
) -> Option<(FileId, TreeArc<ast::Module>)> {
let loc = self.def_id.loc(db);
let module_tree = db.module_tree(loc.source_root_id);
let link = loc.module_id.parent_link(&module_tree)?;
let module_tree = db.module_tree(self.krate);
let link = self.module_id.parent_link(&module_tree)?;
let file_id = link
.owner(&module_tree)
.source(&module_tree)
@ -71,85 +51,67 @@ impl Module {
db: &impl HirDatabase,
import: ImportId,
) -> TreeArc<ast::PathSegment> {
let loc = self.def_id.loc(db);
let source_map = db.lower_module_source_map(loc.source_root_id, loc.module_id);
let source_map = db.lower_module_source_map(self.clone());
let (_, source) = self.definition_source(db);
source_map.get(&source, import)
}
pub(crate) fn krate_impl(&self, db: &impl HirDatabase) -> Option<Crate> {
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 = crate_graph.crate_id_for_crate_root(file_id)?;
Some(Crate::new(crate_id))
pub(crate) fn krate_impl(&self, _db: &impl HirDatabase) -> Option<Crate> {
Some(Crate::new(self.krate))
}
pub(crate) fn crate_root_impl(&self, db: &impl HirDatabase) -> 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);
Module::from_module_id(db, loc.source_root_id, module_id)
let module_tree = db.module_tree(self.krate);
let module_id = self.module_id.crate_root(&module_tree);
self.with_module_id(module_id)
}
/// Finds a child module with the specified name.
pub(crate) fn child_impl(&self, db: &impl HirDatabase, name: &Name) -> Option<Module> {
let loc = self.def_id.loc(db);
let module_tree = db.module_tree(loc.source_root_id);
let child_id = loc.module_id.child(&module_tree, name)?;
Some(Module::from_module_id(db, loc.source_root_id, child_id))
let module_tree = db.module_tree(self.krate);
let child_id = self.module_id.child(&module_tree, name)?;
Some(self.with_module_id(child_id))
}
/// Iterates over all child modules.
pub(crate) fn children_impl(&self, db: &impl HirDatabase) -> impl Iterator<Item = Module> {
// FIXME this should be implementable without collecting into a vec, but
// it's kind of hard since the iterator needs to keep a reference to the
// module tree.
let loc = self.def_id.loc(db);
let module_tree = db.module_tree(loc.source_root_id);
let children = loc
let module_tree = db.module_tree(self.krate);
let children = self
.module_id
.children(&module_tree)
.map(|(_, module_id)| Module::from_module_id(db, loc.source_root_id, module_id))
.map(|(_, module_id)| self.with_module_id(module_id))
.collect::<Vec<_>>();
children.into_iter()
}
pub(crate) fn parent_impl(&self, db: &impl HirDatabase) -> Option<Module> {
let loc = self.def_id.loc(db);
let module_tree = db.module_tree(loc.source_root_id);
let parent_id = loc.module_id.parent(&module_tree)?;
Some(Module::from_module_id(db, loc.source_root_id, parent_id))
let module_tree = db.module_tree(self.krate);
let parent_id = self.module_id.parent(&module_tree)?;
Some(self.with_module_id(parent_id))
}
/// Returns a `ModuleScope`: a set of items, visible in this module.
pub(crate) fn scope_impl(&self, db: &impl HirDatabase) -> ModuleScope {
let loc = self.def_id.loc(db);
let item_map = db.item_map(loc.source_root_id);
item_map.per_module[&loc.module_id].clone()
let item_map = db.item_map(self.krate);
item_map.per_module[&self.module_id].clone()
}
pub(crate) fn resolve_path_impl(&self, db: &impl HirDatabase, path: &Path) -> PerNs<DefId> {
let mut curr_per_ns = PerNs::types(
match path.kind {
PathKind::Crate => self.crate_root(db),
PathKind::Self_ | PathKind::Plain => self.clone(),
PathKind::Super => {
if let Some(p) = self.parent(db) {
p
} else {
return PerNs::none();
}
}
PathKind::Abs => {
// TODO: absolute use is not supported
pub(crate) fn resolve_path_impl(&self, db: &impl HirDatabase, path: &Path) -> PerNs<ModuleDef> {
let mut curr_per_ns: PerNs<ModuleDef> = PerNs::types(match path.kind {
PathKind::Crate => self.crate_root(db).into(),
PathKind::Self_ | PathKind::Plain => self.clone().into(),
PathKind::Super => {
if let Some(p) = self.parent(db) {
p.into()
} else {
return PerNs::none();
}
}
.def_id,
);
PathKind::Abs => {
// TODO: absolute use is not supported
return PerNs::none();
}
});
for segment in path.segments.iter() {
let curr = match curr_per_ns.as_ref().take_types() {
@ -164,32 +126,39 @@ impl Module {
}
};
// resolve segment in curr
curr_per_ns = match curr.resolve(db) {
Def::Module(m) => {
curr_per_ns = match curr {
ModuleDef::Module(m) => {
let scope = m.scope(db);
match scope.get(&segment.name) {
Some(r) => r.def_id,
Some(r) => r.def_id.clone(),
None => PerNs::none(),
}
}
Def::Enum(e) => {
// enum variant
let matching_variant = e
.variants(db)
.into_iter()
.find(|(n, _variant)| n == &segment.name);
ModuleDef::Def(def) => {
match def.resolve(db) {
Def::Enum(e) => {
// enum variant
let matching_variant = e
.variants(db)
.into_iter()
.find(|(n, _variant)| n == &segment.name);
match matching_variant {
Some((_n, variant)) => PerNs::both(variant.def_id(), e.def_id()),
None => PerNs::none(),
match matching_variant {
Some((_n, variant)) => {
PerNs::both(variant.def_id().into(), e.def_id().into())
}
None => PerNs::none(),
}
}
_ => {
// could be an inherent method call in UFCS form
// (`Struct::method`), or some other kind of associated
// item... Which we currently don't handle (TODO)
PerNs::none()
}
}
}
_ => {
// could be an inherent method call in UFCS form
// (`Struct::method`), or some other kind of associated
// item... Which we currently don't handle (TODO)
PerNs::none()
}
};
}
curr_per_ns
@ -199,8 +168,7 @@ impl Module {
&self,
db: &impl HirDatabase,
) -> Vec<(TreeArc<SyntaxNode>, Problem)> {
let loc = self.def_id.loc(db);
let module_tree = db.module_tree(loc.source_root_id);
loc.module_id.problems(&module_tree, db)
let module_tree = db.module_tree(self.krate);
self.module_id.problems(&module_tree, db)
}
}

View File

@ -1,15 +1,15 @@
use std::sync::Arc;
use ra_syntax::{SyntaxNode, TreeArc, SourceFile};
use ra_db::{SourceRootId, SyntaxDatabase, salsa};
use ra_db::{SyntaxDatabase, CrateId, salsa};
use crate::{
HirInterner, DefId, MacroCallId, Name, HirFileId,
SourceFileItems, SourceItemId, Crate,
DefId, MacroCallId, Name, HirFileId,
SourceFileItems, SourceItemId, Crate, Module, HirInterner,
query_definitions,
FnSignature, FnScopes,
macros::MacroExpansion,
module_tree::{ModuleId, ModuleTree},
module_tree::ModuleTree,
nameres::{ItemMap, lower::{LoweredModule, ImportSourceMap}},
ty::{InferenceResult, Ty, method_resolution::CrateImplBlocks},
adt::{StructData, EnumData, EnumVariantData},
@ -56,38 +56,22 @@ pub trait HirDatabase: SyntaxDatabase + AsRef<HirInterner> {
fn submodules(&self, source: SourceItemId) -> Arc<Vec<crate::module_tree::Submodule>>;
#[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_query)]
fn lower_module(
&self,
source_root_id: SourceRootId,
module_id: ModuleId,
) -> (Arc<LoweredModule>, Arc<ImportSourceMap>);
fn lower_module(&self, module: Module) -> (Arc<LoweredModule>, Arc<ImportSourceMap>);
#[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_module_query)]
fn lower_module_module(
&self,
source_root_id: SourceRootId,
module_id: ModuleId,
) -> Arc<LoweredModule>;
fn lower_module_module(&self, module: Module) -> Arc<LoweredModule>;
#[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_source_map_query)]
fn lower_module_source_map(
&self,
source_root_id: SourceRootId,
module_id: ModuleId,
) -> Arc<ImportSourceMap>;
fn lower_module_source_map(&self, module: Module) -> Arc<ImportSourceMap>;
#[salsa::invoke(query_definitions::item_map)]
fn item_map(&self, source_root_id: SourceRootId) -> Arc<ItemMap>;
fn item_map(&self, crate_id: CrateId) -> Arc<ItemMap>;
#[salsa::invoke(crate::module_tree::ModuleTree::module_tree_query)]
fn module_tree(&self, source_root_id: SourceRootId) -> Arc<ModuleTree>;
fn module_tree(&self, crate_id: CrateId) -> Arc<ModuleTree>;
#[salsa::invoke(crate::impl_block::impls_in_module)]
fn impls_in_module(
&self,
source_root_id: SourceRootId,
module_id: ModuleId,
) -> Arc<ModuleImplBlocks>;
fn impls_in_module(&self, module: Module) -> Arc<ModuleImplBlocks>;
#[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)]
fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>;

View File

@ -1,11 +1,10 @@
use ra_db::{SourceRootId, LocationIntener, FileId};
use ra_db::{LocationIntener, FileId};
use ra_syntax::{TreeArc, SyntaxNode, SourceFile, AstNode, ast};
use ra_arena::{Arena, RawId, impl_arena_id};
use crate::{
HirDatabase, Def, Function, Struct, Enum, EnumVariant, ImplBlock, Crate,
Module, Trait, Type, Static, Const,
module_tree::ModuleId,
};
#[derive(Debug, Default)]
@ -110,10 +109,9 @@ impl From<MacroCallId> for HirFileId {
pub struct MacroCallId(RawId);
impl_arena_id!(MacroCallId);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct MacroCallLoc {
pub(crate) source_root_id: SourceRootId,
pub(crate) module_id: ModuleId,
pub(crate) module: Module,
pub(crate) source_item_id: SourceItemId,
}
@ -139,14 +137,12 @@ impl_arena_id!(DefId);
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct DefLoc {
pub(crate) kind: DefKind,
pub(crate) source_root_id: SourceRootId,
pub(crate) module_id: ModuleId,
pub(crate) module: Module,
pub(crate) source_item_id: SourceItemId,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub(crate) enum DefKind {
Module,
Function,
Struct,
Enum,
@ -177,10 +173,6 @@ impl DefId {
pub fn resolve(self, db: &impl HirDatabase) -> Def {
let loc = self.loc(db);
match loc.kind {
DefKind::Module => {
let module = Module::from_module_id(db, loc.source_root_id, loc.module_id);
Def::Module(module)
}
DefKind::Function => {
let function = Function::new(self);
Def::Function(function)
@ -221,8 +213,7 @@ impl DefId {
/// For a module, returns that module; for any other def, returns the containing module.
pub fn module(self, db: &impl HirDatabase) -> Module {
let loc = self.loc(db);
Module::from_module_id(db, loc.source_root_id, loc.module_id)
self.loc(db).module
}
/// Returns the containing crate.
@ -232,8 +223,7 @@ impl DefId {
/// Returns the containing impl block, if this is an impl item.
pub fn impl_block(self, db: &impl HirDatabase) -> Option<ImplBlock> {
let loc = self.loc(db);
let module_impls = db.impls_in_module(loc.source_root_id, loc.module_id);
let module_impls = db.impls_in_module(self.loc(db).module);
ImplBlock::containing(module_impls, self)
}
}

View File

@ -3,14 +3,12 @@ use rustc_hash::FxHashMap;
use ra_arena::{Arena, RawId, impl_arena_id};
use ra_syntax::ast::{self, AstNode};
use ra_db::{SourceRootId};
use crate::{
DefId, DefLoc, DefKind, SourceItemId, SourceFileItems,
Function, HirInterner,
Function, HirFileId, HirInterner,
db::HirDatabase,
type_ref::TypeRef,
module_tree::ModuleId,
};
use crate::code_model_api::{Module, ModuleSource};
@ -67,13 +65,13 @@ pub struct ImplData {
impl ImplData {
pub(crate) fn from_ast(
db: &impl AsRef<HirInterner>,
file_id: HirFileId,
file_items: &SourceFileItems,
module: &Module,
module: Module,
node: &ast::ImplBlock,
) -> Self {
let target_trait = node.target_trait().map(TypeRef::from_ast);
let target_type = TypeRef::from_ast_opt(node.target_type());
let module_loc = module.def_id.loc(db);
let items = if let Some(item_list) = node.item_list() {
item_list
.impl_items()
@ -85,13 +83,13 @@ impl ImplData {
};
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,
file_id,
item_id: Some(item_id),
};
let def_loc = DefLoc {
module,
kind,
source_item_id,
..module_loc
};
let def_id = def_loc.id(db);
match item_node.kind() {
@ -168,6 +166,7 @@ impl ModuleImplBlocks {
fn collect(&mut self, db: &impl HirDatabase, module: Module) {
let (file_id, module_source) = module.definition_source(db);
let file_id: HirFileId = file_id.into();
let node = match &module_source {
ModuleSource::SourceFile(node) => node.syntax(),
ModuleSource::Module(node) => node
@ -176,10 +175,11 @@ impl ModuleImplBlocks {
.syntax(),
};
let source_file_items = db.file_items(file_id.into());
let source_file_items = db.file_items(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);
let impl_block =
ImplData::from_ast(db, file_id, &source_file_items, module, impl_block_ast);
let id = self.impls.alloc(impl_block);
for impl_item in &self.impls[id].items {
self.impls_by_def.insert(impl_item.def_id(), id);
@ -188,13 +188,8 @@ impl ModuleImplBlocks {
}
}
pub(crate) fn impls_in_module(
db: &impl HirDatabase,
source_root_id: SourceRootId,
module_id: ModuleId,
) -> Arc<ModuleImplBlocks> {
pub(crate) fn impls_in_module(db: &impl HirDatabase, module: Module) -> Arc<ModuleImplBlocks> {
let mut result = ModuleImplBlocks::new();
let module = Module::from_module_id(db, source_root_id, module_id);
result.collect(db, module);
Arc::new(result)
}

View File

@ -52,7 +52,7 @@ pub use self::{
pub use self::code_model_api::{
Crate, CrateDependency,
Def,
Module, ModuleSource, Problem,
Module, ModuleDef, ModuleSource, Problem,
Struct, Enum, EnumVariant,
Function, FnSignature, ScopeEntryWithSyntax,
StructField,

View File

@ -35,10 +35,6 @@ impl MockDatabase {
let file_id = db.add_file(WORKSPACE, &mut source_root, "/main.rs", text);
db.query_mut(ra_db::SourceRootQuery)
.set(WORKSPACE, Arc::new(source_root.clone()));
let mut crate_graph = CrateGraph::default();
crate_graph.add_crate_root(file_id);
db.set_crate_graph(crate_graph);
(db, source_root, file_id)
}
@ -97,6 +93,8 @@ impl MockDatabase {
text: &str,
) -> FileId {
assert!(path.starts_with('/'));
let is_crate_root = path == "/lib.rs" || path == "/main.rs";
let path = RelativePathBuf::from_path(&path[1..]).unwrap();
let file_id = FileId(self.file_counter);
self.file_counter += 1;
@ -107,6 +105,12 @@ impl MockDatabase {
self.query_mut(ra_db::FileSourceRootQuery)
.set(file_id, source_root_id);
source_root.files.insert(path, file_id);
if is_crate_root {
let mut crate_graph = CrateGraph::default();
crate_graph.add_crate_root(file_id);
self.set_crate_graph(crate_graph);
}
file_id
}
@ -202,6 +206,7 @@ salsa::database_storage! {
fn file_relative_path() for ra_db::FileRelativePathQuery;
fn file_source_root() for ra_db::FileSourceRootQuery;
fn source_root() for ra_db::SourceRootQuery;
fn source_root_crates() for ra_db::SourceRootCratesQuery;
fn local_roots() for ra_db::LocalRootsQuery;
fn library_roots() for ra_db::LibraryRootsQuery;
fn crate_graph() for ra_db::CrateGraphQuery;

View File

@ -3,7 +3,7 @@ use std::sync::Arc;
use rustc_hash::{FxHashMap, FxHashSet};
use arrayvec::ArrayVec;
use relative_path::RelativePathBuf;
use ra_db::{FileId, SourceRootId, SourceRoot};
use ra_db::{FileId, SourceRoot, CrateId};
use ra_syntax::{
SyntaxNode, TreeArc,
algo::generate,
@ -126,13 +126,10 @@ struct LinkData {
}
impl ModuleTree {
pub(crate) fn module_tree_query(
db: &impl HirDatabase,
source_root: SourceRootId,
) -> Arc<ModuleTree> {
pub(crate) fn module_tree_query(db: &impl HirDatabase, crate_id: CrateId) -> Arc<ModuleTree> {
db.check_canceled();
let mut res = ModuleTree::default();
res.init(db, source_root);
res.init_crate(db, crate_id);
Arc::new(res)
}
@ -145,24 +142,21 @@ impl ModuleTree {
Some(res)
}
fn init(&mut self, db: &impl HirDatabase, source_root: SourceRootId) {
fn init_crate(&mut self, db: &impl HirDatabase, crate_id: CrateId) {
let crate_graph = db.crate_graph();
let file_id = crate_graph.crate_root(crate_id);
let source_root_id = db.file_source_root(file_id);
let mut roots = FxHashMap::default();
let mut visited = FxHashSet::default();
let source_root = db.source_root(source_root);
for &file_id in source_root.files.values() {
let source = SourceItemId {
file_id: file_id.into(),
item_id: None,
};
if visited.contains(&source) {
continue; // TODO: use explicit crate_roots here
}
assert!(!roots.contains_key(&file_id));
let module_id =
self.init_subtree(db, &source_root, &mut visited, &mut roots, None, source);
roots.insert(file_id, module_id);
}
let source_root = db.source_root(source_root_id);
let source = SourceItemId {
file_id: file_id.into(),
item_id: None,
};
let module_id = self.init_subtree(db, &source_root, &mut visited, &mut roots, None, source);
roots.insert(file_id, module_id);
}
fn init_subtree(

View File

@ -16,19 +16,19 @@
//! structure itself is modified.
pub(crate) mod lower;
use crate::nameres::lower::*;
use std::sync::Arc;
use ra_db::CrateId;
use rustc_hash::{FxHashMap, FxHashSet};
use ra_db::SourceRootId;
use crate::{
DefId, DefLoc, DefKind,
Module, ModuleDef,
Path, PathKind,
HirDatabase, Crate,
Name,
module_tree::{ModuleId, ModuleTree},
//FIXME: deglobify
nameres::lower::*,
};
/// `ItemMap` is the result of name resolution. It contains, for each
@ -58,7 +58,7 @@ impl ModuleScope {
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Resolution {
/// None for unresolved
pub def_id: PerNs<DefId>,
pub def_id: PerNs<ModuleDef>,
/// ident by which this is imported into local scope.
pub import: Option<ImportId>,
}
@ -152,7 +152,7 @@ impl<T> PerNs<T> {
pub(crate) struct Resolver<'a, DB> {
db: &'a DB,
input: &'a FxHashMap<ModuleId, Arc<LoweredModule>>,
source_root: SourceRootId,
krate: CrateId,
module_tree: Arc<ModuleTree>,
processed_imports: FxHashSet<(ModuleId, ImportId)>,
result: ItemMap,
@ -165,13 +165,13 @@ where
pub(crate) fn new(
db: &'a DB,
input: &'a FxHashMap<ModuleId, Arc<LoweredModule>>,
source_root: SourceRootId,
module_tree: Arc<ModuleTree>,
krate: CrateId,
) -> Resolver<'a, DB> {
let module_tree = db.module_tree(krate);
Resolver {
db,
input,
source_root,
krate,
module_tree,
processed_imports: FxHashSet::default(),
result: ItemMap::default(),
@ -210,7 +210,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;
let def_id = module.into();
self.add_module_item(
&mut module_items,
dep.name.clone(),
@ -244,20 +244,22 @@ where
// Populate modules
for (name, module_id) in module_id.children(&self.module_tree) {
let def_loc = DefLoc {
kind: DefKind::Module,
source_root_id: self.source_root,
let module = Module {
module_id,
source_item_id: module_id.source(&self.module_tree),
krate: self.krate,
};
let def_id = def_loc.id(self.db);
self.add_module_item(&mut module_items, name, PerNs::types(def_id));
self.add_module_item(&mut module_items, name, PerNs::types(module.into()));
}
self.result.per_module.insert(module_id, module_items);
}
fn add_module_item(&self, module_items: &mut ModuleScope, name: Name, def_id: PerNs<DefId>) {
fn add_module_item(
&self,
module_items: &mut ModuleScope,
name: Name,
def_id: PerNs<ModuleDef>,
) {
let resolution = Resolution {
def_id,
import: None,
@ -329,17 +331,11 @@ where
);
return false;
};
curr = match type_def_id.loc(self.db) {
DefLoc {
kind: DefKind::Module,
module_id: target_module_id,
source_root_id,
..
} => {
if source_root_id == self.source_root {
target_module_id
curr = match type_def_id {
ModuleDef::Module(module) => {
if module.krate == self.krate {
module.module_id
} else {
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,
@ -359,7 +355,7 @@ where
"resolved import {:?} ({:?}) cross-source root to {:?}",
last_segment.name,
import,
def_id.map(|did| did.loc(self.db))
def_id,
);
return true;
} else {
@ -372,7 +368,7 @@ where
log::debug!(
"path segment {:?} resolved to non-module {:?}, but is not last",
segment.name,
type_def_id.loc(self.db)
type_def_id,
);
return true; // this resolved to a non-module, so the path won't ever resolve
}
@ -382,7 +378,7 @@ where
"resolved import {:?} ({:?}) within source root to {:?}",
segment.name,
import,
def_id.map(|did| did.loc(self.db))
def_id,
);
self.update(module_id, |items| {
let res = Resolution {

View File

@ -4,14 +4,13 @@ use ra_syntax::{
SyntaxKind, AstNode, SourceFile, TreeArc, AstPtr,
ast::{self, ModuleItemOwner, NameOwner},
};
use ra_db::SourceRootId;
use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap};
use rustc_hash::FxHashMap;
use crate::{
SourceItemId, Path, ModuleSource, HirDatabase, Name, SourceFileItems,
HirFileId, MacroCallLoc, AsName, PerNs, DefId, DefKind, DefLoc,
module_tree::ModuleId
HirFileId, MacroCallLoc, AsName, PerNs, DefKind, DefLoc,
ModuleDef, Module,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@ -32,7 +31,7 @@ pub(super) struct ImportData {
/// can avoid redoing name resolution.
#[derive(Debug, Default, PartialEq, Eq)]
pub struct LoweredModule {
pub(crate) declarations: FxHashMap<Name, PerNs<DefId>>,
pub(crate) declarations: FxHashMap<Name, PerNs<ModuleDef>>,
pub(super) imports: Arena<ImportId, ImportData>,
}
@ -59,37 +58,31 @@ impl ImportSourceMap {
impl LoweredModule {
pub(crate) fn lower_module_module_query(
db: &impl HirDatabase,
source_root_id: SourceRootId,
module_id: ModuleId,
module: Module,
) -> Arc<LoweredModule> {
db.lower_module(source_root_id, module_id).0
db.lower_module(module).0
}
pub(crate) fn lower_module_source_map_query(
db: &impl HirDatabase,
source_root_id: SourceRootId,
module_id: ModuleId,
module: Module,
) -> Arc<ImportSourceMap> {
db.lower_module(source_root_id, module_id).1
db.lower_module(module).1
}
pub(crate) fn lower_module_query(
db: &impl HirDatabase,
source_root_id: SourceRootId,
module_id: ModuleId,
module: Module,
) -> (Arc<LoweredModule>, Arc<ImportSourceMap>) {
let module_tree = db.module_tree(source_root_id);
let source = module_id.source(&module_tree);
let file_id = source.file_id;
let source = ModuleSource::from_source_item_id(db, source);
let (file_id, source) = module.definition_source(db);
let file_id: HirFileId = file_id.into();
let mut source_map = ImportSourceMap::default();
let mut res = LoweredModule::default();
match source {
ModuleSource::SourceFile(it) => res.fill(
&mut source_map,
db,
source_root_id,
module_id,
module,
file_id,
&mut it.items_with_macros(),
),
@ -98,8 +91,7 @@ impl LoweredModule {
res.fill(
&mut source_map,
db,
source_root_id,
module_id,
module,
file_id,
&mut item_list.items_with_macros(),
)
@ -113,8 +105,7 @@ impl LoweredModule {
&mut self,
source_map: &mut ImportSourceMap,
db: &impl HirDatabase,
source_root_id: SourceRootId,
module_id: ModuleId,
module: Module,
file_id: HirFileId,
items: &mut Iterator<Item = ast::ItemOrMacro>,
) {
@ -123,21 +114,12 @@ impl LoweredModule {
for item in items {
match item {
ast::ItemOrMacro::Item(it) => {
self.add_def_id(
source_map,
db,
source_root_id,
module_id,
file_id,
&file_items,
it,
);
self.add_def_id(source_map, db, module, file_id, &file_items, it);
}
ast::ItemOrMacro::Macro(macro_call) => {
let item_id = file_items.id_of_unchecked(macro_call.syntax());
let loc = MacroCallLoc {
source_root_id,
module_id,
module,
source_item_id: SourceItemId {
file_id,
item_id: Some(item_id),
@ -148,15 +130,7 @@ impl LoweredModule {
let file_items = db.file_items(file_id);
//FIXME: expand recursively
for item in db.hir_source_file(file_id).items() {
self.add_def_id(
source_map,
db,
source_root_id,
module_id,
file_id,
&file_items,
item,
);
self.add_def_id(source_map, db, module, file_id, &file_items, item);
}
}
}
@ -167,8 +141,7 @@ impl LoweredModule {
&mut self,
source_map: &mut ImportSourceMap,
db: &impl HirDatabase,
source_root_id: SourceRootId,
module_id: ModuleId,
module: Module,
file_id: HirFileId,
file_items: &SourceFileItems,
item: &ast::ModuleItem,
@ -199,7 +172,7 @@ impl LoweredModule {
}
};
if let Some(name) = name {
let def_id = assign_def_id(db, source_root_id, module_id, file_id, file_items, item);
let def_id = assign_def_id(db, module, file_id, file_items, item);
self.declarations.insert(name.as_name(), def_id);
}
}
@ -219,12 +192,11 @@ impl LoweredModule {
fn assign_def_id(
db: &impl HirDatabase,
source_root_id: SourceRootId,
module_id: ModuleId,
module: Module,
file_id: HirFileId,
file_items: &SourceFileItems,
item: &ast::ModuleItem,
) -> PerNs<DefId> {
) -> PerNs<ModuleDef> {
// depending on the item kind, the location can define something in
// the values namespace, the types namespace, or both
let kind = DefKind::for_syntax_kind(item.syntax().kind());
@ -232,14 +204,13 @@ fn assign_def_id(
let item_id = file_items.id_of_unchecked(item.syntax());
let def_loc = DefLoc {
kind: k,
source_root_id,
module_id,
module,
source_item_id: SourceItemId {
file_id,
item_id: Some(item_id),
},
};
def_loc.id(db)
def_loc.id(db).into()
});
def_id
}
@ -248,7 +219,6 @@ impl DefKind {
fn for_syntax_kind(kind: SyntaxKind) -> PerNs<DefKind> {
match kind {
SyntaxKind::FN_DEF => PerNs::values(DefKind::Function),
SyntaxKind::MODULE => PerNs::types(DefKind::Module),
SyntaxKind::STRUCT_DEF => PerNs::both(DefKind::Struct, DefKind::StructCtor),
SyntaxKind::ENUM_DEF => PerNs::types(DefKind::Enum),
SyntaxKind::TRAIT_DEF => PerNs::types(DefKind::Trait),

View File

@ -1,6 +1,6 @@
use std::sync::Arc;
use ra_db::{FilesDatabase, CrateGraph, SourceRootId, salsa::Database};
use ra_db::{CrateGraph, SourceRootId, salsa::Database};
use relative_path::RelativePath;
use test_utils::{assert_eq_text, covers};
@ -13,10 +13,10 @@ use crate::{
fn item_map(fixture: &str) -> (Arc<ItemMap>, ModuleId) {
let (db, pos) = MockDatabase::with_position(fixture);
let source_root = db.file_source_root(pos.file_id);
let module = crate::source_binder::module_from_position(&db, pos).unwrap();
let module_id = module.def_id.loc(&db).module_id;
(db.item_map(source_root), module_id)
let krate = module.krate(&db).unwrap();
let module_id = module.module_id;
(db.item_map(krate.crate_id), module_id)
}
fn check_module_item_map(map: &ItemMap, module_id: ModuleId, expected: &str) {
@ -238,14 +238,13 @@ fn item_map_across_crates() {
db.set_crate_graph(crate_graph);
let source_root = db.file_source_root(main_id);
let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap();
let module_id = module.def_id.loc(&db).module_id;
let item_map = db.item_map(source_root);
let krate = module.krate(&db).unwrap();
let item_map = db.item_map(krate.crate_id);
check_module_item_map(
&item_map,
module_id,
module.module_id,
"
Baz: t v
test_crate: t
@ -292,12 +291,12 @@ fn import_across_source_roots() {
db.set_crate_graph(crate_graph);
let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap();
let module_id = module.def_id.loc(&db).module_id;
let item_map = db.item_map(source_root);
let krate = module.krate(&db).unwrap();
let item_map = db.item_map(krate.crate_id);
check_module_item_map(
&item_map,
module_id,
module.module_id,
"
C: t v
test_crate: t
@ -333,14 +332,13 @@ fn reexport_across_crates() {
db.set_crate_graph(crate_graph);
let source_root = db.file_source_root(main_id);
let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap();
let module_id = module.def_id.loc(&db).module_id;
let item_map = db.item_map(source_root);
let krate = module.krate(&db).unwrap();
let item_map = db.item_map(krate.crate_id);
check_module_item_map(
&item_map,
module_id,
module.module_id,
"
Baz: t v
test_crate: t
@ -350,10 +348,11 @@ fn reexport_across_crates() {
fn check_item_map_is_not_recomputed(initial: &str, file_change: &str) {
let (mut db, pos) = MockDatabase::with_position(initial);
let source_root = db.file_source_root(pos.file_id);
let module = crate::source_binder::module_from_file_id(&db, pos.file_id).unwrap();
let krate = module.krate(&db).unwrap();
{
let events = db.log_executed(|| {
db.item_map(source_root);
db.item_map(krate.crate_id);
});
assert!(format!("{:?}", events).contains("item_map"))
}
@ -362,7 +361,7 @@ fn check_item_map_is_not_recomputed(initial: &str, file_change: &str) {
{
let events = db.log_executed(|| {
db.item_map(source_root);
db.item_map(krate.crate_id);
});
assert!(
!format!("{:?}", events).contains("item_map"),

View File

@ -7,11 +7,11 @@ use rustc_hash::FxHashMap;
use ra_syntax::{
AstNode, SyntaxNode, TreeArc,
};
use ra_db::SourceRootId;
use ra_db::{CrateId};
use crate::{
SourceFileItems, SourceItemId, DefId, HirFileId,
FnScopes,
FnScopes, Module,
db::HirDatabase,
nameres::{ItemMap, Resolver},
};
@ -41,15 +41,23 @@ pub(super) fn file_item(
}
}
pub(super) fn item_map(db: &impl HirDatabase, source_root: SourceRootId) -> Arc<ItemMap> {
pub(super) fn item_map(db: &impl HirDatabase, crate_id: CrateId) -> Arc<ItemMap> {
let start = Instant::now();
let module_tree = db.module_tree(source_root);
let module_tree = db.module_tree(crate_id);
let input = module_tree
.modules()
.map(|id| (id, db.lower_module_module(source_root, id)))
.map(|module_id| {
(
module_id,
db.lower_module_module(Module {
krate: crate_id,
module_id,
}),
)
})
.collect::<FxHashMap<_, _>>();
let resolver = Resolver::new(db, &input, source_root, module_tree);
let resolver = Resolver::new(db, &input, crate_id);
let res = resolver.resolve();
let elapsed = start.elapsed();
log::info!("item_map: {:?}", elapsed);

View File

@ -13,7 +13,7 @@ use ra_syntax::{
};
use crate::{
HirDatabase, Function, SourceItemId,
HirDatabase, Function, SourceItemId, ModuleDef,
DefKind, DefLoc, AsName, Module,
};
@ -84,9 +84,13 @@ pub fn module_from_child_node(
fn module_from_source(db: &impl HirDatabase, source: SourceItemId) -> Option<Module> {
let source_root_id = db.file_source_root(source.file_id.as_original_file());
let module_tree = db.module_tree(source_root_id);
let module_id = module_tree.find_module_by_source(source)?;
Some(Module::from_module_id(db, source_root_id, module_id))
db.source_root_crates(source_root_id)
.iter()
.find_map(|&krate| {
let module_tree = db.module_tree(krate);
let module_id = module_tree.find_module_by_source(source)?;
Some(Module { krate, module_id })
})
}
pub fn function_from_position(db: &impl HirDatabase, position: FilePosition) -> Option<Function> {
@ -110,8 +114,8 @@ pub fn function_from_module(
module: &Module,
fn_def: &ast::FnDef,
) -> Function {
let loc = module.def_id.loc(db);
let file_id = loc.source_item_id.file_id;
let (file_id, _) = module.definition_source(db);
let file_id = file_id.into();
let file_items = db.file_items(file_id);
let item_id = file_items.id_of(file_id, fn_def.syntax());
let source_item_id = SourceItemId {
@ -119,9 +123,8 @@ pub fn function_from_module(
item_id: Some(item_id),
};
let def_loc = DefLoc {
module: module.clone(),
kind: DefKind::Function,
source_root_id: loc.source_root_id,
module_id: loc.module_id,
source_item_id,
};
Function::new(def_loc.id(db))
@ -141,14 +144,17 @@ pub fn macro_symbols(db: &impl HirDatabase, file_id: FileId) -> Vec<(SmolStr, Te
Some(it) => it,
None => return Vec::new(),
};
let loc = module.def_id.loc(db);
let items = db.lower_module_module(loc.source_root_id, loc.module_id);
let items = db.lower_module_module(module);
let mut res = Vec::new();
for macro_call_id in items
.declarations
.iter()
.filter_map(|(_, it)| it.take_types())
.filter_map(|(_, it)| it.clone().take_types())
.filter_map(|it| match it {
ModuleDef::Def(it) => Some(it),
_ => None,
})
.filter_map(|it| it.loc(db).source_item_id.file_id.as_macro_call_id())
{
if let Some(exp) = db.expand_macro_invocation(macro_call_id) {

View File

@ -32,7 +32,7 @@ use rustc_hash::FxHashMap;
use crate::{
Def, DefId, Module, Function, Struct, StructField, Enum, EnumVariant, Path, Name, ImplBlock,
FnSignature, FnScopes,
FnSignature, FnScopes, ModuleDef,
db::HirDatabase,
type_ref::{TypeRef, Mutability},
name::KnownName,
@ -382,8 +382,8 @@ impl Ty {
// Resolve in module (in type namespace)
let resolved = match module.resolve_path(db, path).take_types() {
Some(r) => r,
None => return Ty::Unknown,
Some(ModuleDef::Def(r)) => r,
None | Some(ModuleDef::Module(_)) => return Ty::Unknown,
};
let ty = db.type_for_def(resolved);
let substs = Ty::substs_from_path(db, module, impl_block, generics, path, resolved);
@ -663,10 +663,6 @@ pub(crate) fn type_for_enum_variant(db: &impl HirDatabase, ev: EnumVariant) -> T
pub(super) fn type_for_def(db: &impl HirDatabase, def_id: DefId) -> Ty {
let def = def_id.resolve(db);
match def {
Def::Module(..) => {
log::debug!("trying to get type for module {:?}", def_id);
Ty::Unknown
}
Def::Function(f) => type_for_fn(db, f),
Def::Struct(s) => type_for_struct(db, s),
Def::Enum(e) => type_for_enum(db, e),
@ -1063,7 +1059,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
};
// resolve in module
let resolved = self.module.resolve_path(self.db, &path).take_values()?;
let resolved = match self.module.resolve_path(self.db, &path).take_values()? {
ModuleDef::Def(it) => it,
ModuleDef::Module(_) => return None,
};
let ty = self.db.type_for_def(resolved);
let ty = self.insert_type_vars(ty);
Some(ty)
@ -1075,7 +1074,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
None => return (Ty::Unknown, None),
};
let def_id = match self.module.resolve_path(self.db, &path).take_types() {
Some(def_id) => def_id,
Some(ModuleDef::Def(def_id)) => def_id,
_ => return (Ty::Unknown, None),
};
// TODO remove the duplication between here and `Ty::from_path`?
@ -1216,6 +1215,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
.module
.resolve_path(self.db, &path)
.take_values()
.and_then(|module_def| match module_def {
ModuleDef::Def(it) => Some(it),
ModuleDef::Module(_) => None,
})
.map_or(Ty::Unknown, |resolved| self.db.type_for_def(resolved)),
Pat::Bind {
mode,

View File

@ -6,8 +6,6 @@ use std::sync::Arc;
use rustc_hash::FxHashMap;
use ra_db::SourceRootId;
use crate::{
HirDatabase, DefId, module_tree::ModuleId, Module, Crate, Name, Function,
impl_block::{ImplId, ImplBlock, ImplItem},
@ -37,7 +35,7 @@ impl TyFingerprint {
#[derive(Debug, PartialEq, Eq)]
pub struct CrateImplBlocks {
/// To make sense of the ModuleIds, we need the source root.
source_root_id: SourceRootId,
krate: Crate,
impls: FxHashMap<TyFingerprint, Vec<(ModuleId, ImplId)>>,
}
@ -53,14 +51,17 @@ impl CrateImplBlocks {
.into_iter()
.flat_map(|i| i.iter())
.map(move |(module_id, impl_id)| {
let module_impl_blocks = db.impls_in_module(self.source_root_id, *module_id);
let module = Module {
krate: self.krate.crate_id,
module_id: *module_id,
};
let module_impl_blocks = db.impls_in_module(module);
ImplBlock::from_id(module_impl_blocks, *impl_id)
})
}
fn collect_recursive(&mut self, db: &impl HirDatabase, module: Module) {
let module_id = module.def_id.loc(db).module_id;
let module_impl_blocks = db.impls_in_module(self.source_root_id, module_id);
fn collect_recursive(&mut self, db: &impl HirDatabase, module: &Module) {
let module_impl_blocks = db.impls_in_module(module.clone());
for (impl_id, impl_data) in module_impl_blocks.impls.iter() {
let impl_block = ImplBlock::from_id(Arc::clone(&module_impl_blocks), impl_id);
@ -81,13 +82,13 @@ impl CrateImplBlocks {
self.impls
.entry(target_ty_fp)
.or_insert_with(Vec::new)
.push((module_id, impl_id));
.push((module.module_id, impl_id));
}
}
}
for child in module.children(db) {
self.collect_recursive(db, child);
self.collect_recursive(db, &child);
}
}
@ -95,15 +96,12 @@ impl CrateImplBlocks {
db: &impl HirDatabase,
krate: Crate,
) -> Arc<CrateImplBlocks> {
let crate_graph = db.crate_graph();
let file_id = crate_graph.crate_root(krate.crate_id);
let source_root_id = db.file_source_root(file_id);
let mut crate_impl_blocks = CrateImplBlocks {
source_root_id,
krate: krate.clone(),
impls: FxHashMap::default(),
};
if let Some(module) = krate.root_module(db) {
crate_impl_blocks.collect_recursive(db, module);
crate_impl_blocks.collect_recursive(db, &module);
}
Arc::new(crate_impl_blocks)
}

View File

@ -13,8 +13,8 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
Some(it) => it,
None => return,
};
match def_id.resolve(ctx.db) {
hir::Def::Module(module) => {
match def_id {
hir::ModuleDef::Module(module) => {
let module_scope = module.scope(ctx.db);
for (name, res) in module_scope.entries() {
CompletionItem::new(
@ -26,21 +26,24 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
.add_to(acc);
}
}
hir::Def::Enum(e) => {
e.variants(ctx.db)
.into_iter()
.for_each(|(variant_name, variant)| {
CompletionItem::new(
CompletionKind::Reference,
ctx.source_range(),
variant_name.to_string(),
)
.kind(CompletionItemKind::EnumVariant)
.set_documentation(variant.docs(ctx.db))
.add_to(acc)
});
}
_ => return,
hir::ModuleDef::Def(def_id) => match def_id.resolve(ctx.db) {
hir::Def::Enum(e) => {
e.variants(ctx.db)
.into_iter()
.for_each(|(variant_name, variant)| {
CompletionItem::new(
CompletionKind::Reference,
ctx.source_range(),
variant_name.to_string(),
)
.kind(CompletionItemKind::EnumVariant)
.set_documentation(variant.docs(ctx.db))
.add_to(acc)
});
}
_ => return,
},
};
}

View File

@ -1,6 +1,4 @@
use hir::{Docs, Documentation, PerNs};
use crate::completion::completion_context::CompletionContext;
use hir::{Docs, Documentation};
use ra_syntax::{
ast::{self, AstNode},
TextRange,
@ -8,6 +6,8 @@ use ra_syntax::{
use ra_text_edit::TextEdit;
use test_utils::tested_by;
use crate::completion::completion_context::CompletionContext;
/// `CompletionItem` describes a single completion variant in the editor pop-up.
/// It is basically a POD with various properties. To construct a
/// `CompletionItem`, use `new` method and the `Builder` struct.
@ -209,41 +209,26 @@ impl Builder {
ctx: &CompletionContext,
resolution: &hir::Resolution,
) -> Builder {
let resolved = resolution.def_id.map(|d| d.resolve(ctx.db));
let (kind, docs) = match resolved {
PerNs {
types: Some(hir::Def::Module(..)),
..
} => (CompletionItemKind::Module, None),
PerNs {
types: Some(hir::Def::Struct(s)),
..
} => (CompletionItemKind::Struct, s.docs(ctx.db)),
PerNs {
types: Some(hir::Def::Enum(e)),
..
} => (CompletionItemKind::Enum, e.docs(ctx.db)),
PerNs {
types: Some(hir::Def::Trait(t)),
..
} => (CompletionItemKind::Trait, t.docs(ctx.db)),
PerNs {
types: Some(hir::Def::Type(t)),
..
} => (CompletionItemKind::TypeAlias, t.docs(ctx.db)),
PerNs {
values: Some(hir::Def::Const(c)),
..
} => (CompletionItemKind::Const, c.docs(ctx.db)),
PerNs {
values: Some(hir::Def::Static(s)),
..
} => (CompletionItemKind::Static, s.docs(ctx.db)),
PerNs {
values: Some(hir::Def::Function(function)),
..
} => return self.from_function(ctx, function),
_ => return self,
let def = resolution
.def_id
.take_types()
.or(resolution.def_id.take_values());
let def = match def {
None => return self,
Some(it) => it,
};
let (kind, docs) = match def {
hir::ModuleDef::Module(_) => (CompletionItemKind::Module, None),
hir::ModuleDef::Def(def_id) => match def_id.resolve(ctx.db) {
hir::Def::Struct(it) => (CompletionItemKind::Struct, it.docs(ctx.db)),
hir::Def::Enum(it) => (CompletionItemKind::Enum, it.docs(ctx.db)),
hir::Def::Trait(it) => (CompletionItemKind::Trait, it.docs(ctx.db)),
hir::Def::Type(it) => (CompletionItemKind::TypeAlias, it.docs(ctx.db)),
hir::Def::Const(it) => (CompletionItemKind::Const, it.docs(ctx.db)),
hir::Def::Static(it) => (CompletionItemKind::Static, it.docs(ctx.db)),
hir::Def::Function(function) => return self.from_function(ctx, function),
_ => return self,
},
};
self.kind = Some(kind);
self.documentation = docs;

View File

@ -72,6 +72,7 @@ salsa::database_storage! {
fn file_relative_path() for ra_db::FileRelativePathQuery;
fn file_source_root() for ra_db::FileSourceRootQuery;
fn source_root() for ra_db::SourceRootQuery;
fn source_root_crates() for ra_db::SourceRootCratesQuery;
fn local_roots() for ra_db::LocalRootsQuery;
fn library_roots() for ra_db::LibraryRootsQuery;
fn crate_graph() for ra_db::CrateGraphQuery;

View File

@ -67,7 +67,7 @@ pub(crate) fn reference_definition(
.node_expr(expr)
.and_then(|it| infer_result.method_resolution(it))
{
if let Some(target) = NavigationTarget::from_def(db, def_id.resolve(db)) {
if let Some(target) = NavigationTarget::from_def(db, hir::ModuleDef::Def(def_id)) {
return Exact(target);
}
};
@ -84,7 +84,7 @@ pub(crate) fn reference_definition(
{
let resolved = module.resolve_path(db, &path);
if let Some(def_id) = resolved.take_types().or(resolved.take_values()) {
if let Some(target) = NavigationTarget::from_def(db, def_id.resolve(db)) {
if let Some(target) = NavigationTarget::from_def(db, def_id) {
return Exact(target);
}
}

View File

@ -97,7 +97,17 @@ impl NavigationTarget {
}
// TODO once Def::Item is gone, this should be able to always return a NavigationTarget
pub(crate) fn from_def(db: &RootDatabase, def: Def) -> Option<NavigationTarget> {
pub(crate) fn from_def(
db: &RootDatabase,
module_def: hir::ModuleDef,
) -> Option<NavigationTarget> {
let def = match module_def {
hir::ModuleDef::Def(def_id) => def_id.resolve(db),
hir::ModuleDef::Module(module) => {
return Some(NavigationTarget::from_module(db, module));
}
};
let res = match def {
Def::Struct(s) => {
let (file_id, node) = s.source(db);
@ -131,7 +141,6 @@ impl NavigationTarget {
let (file_id, node) = f.source(db);
NavigationTarget::from_named(file_id.original_file(db), &*node)
}
Def::Module(m) => NavigationTarget::from_module(db, m),
Def::Item => return None,
};
Some(res)

View File

@ -57,7 +57,6 @@ fn rename_mod(
) -> Option<SourceChange> {
let mut source_file_edits = Vec::new();
let mut file_system_edits = Vec::new();
if let Some(module) = module_from_declaration(db, position.file_id, &ast_module) {
let (file_id, module_source) = module.definition_source(db);
match module_source {
@ -223,11 +222,15 @@ mod tests {
fn test_rename_mod() {
let (analysis, position) = analysis_and_position(
"
//- /bar.rs
mod fo<|>o;
//- /bar/foo.rs
// emtpy
",
//- /lib.rs
mod bar;
//- /bar.rs
mod foo<|>;
//- /bar/foo.rs
// emtpy
",
);
let new_name = "foo2";
let source_change = analysis.rename(position, new_name).unwrap();
@ -238,11 +241,11 @@ mod tests {
fn test_rename_mod_in_dir() {
let (analysis, position) = analysis_and_position(
"
//- /lib.rs
mod fo<|>o;
//- /foo/mod.rs
// emtpy
",
//- /lib.rs
mod fo<|>o;
//- /foo/mod.rs
// emtpy
",
);
let new_name = "foo2";
let source_change = analysis.rename(position, new_name).unwrap();

View File

@ -1,8 +1,8 @@
---
created: "2019-01-22T14:45:00.975229300+00:00"
creator: insta@0.4.0
created: "2019-01-24T08:39:53.759318522+00:00"
creator: insta@0.5.2
expression: "&source_change"
source: "crates\\ra_ide_api\\src\\rename.rs"
source: crates/ra_ide_api/src/rename.rs
---
Some(
SourceChange {
@ -10,7 +10,7 @@ Some(
source_file_edits: [
SourceFileEdit {
file_id: FileId(
1
2
),
edit: TextEdit {
atoms: [
@ -25,7 +25,7 @@ Some(
file_system_edits: [
MoveFile {
src: FileId(
2
3
),
dst_source_root: SourceRootId(
0