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. /// Contents of the source root.
#[salsa::input] #[salsa::input]
fn source_root(&self, id: SourceRootId) -> Arc<SourceRoot>; 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. /// The set of "local" (that is, from the current workspace) roots.
/// Files in local roots are assumed to change frequently. /// Files in local roots are assumed to change frequently.
#[salsa::input] #[salsa::input]
@ -173,6 +174,17 @@ pub trait FilesDatabase: salsa::Database {
fn crate_graph(&self) -> Arc<CrateGraph>; 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)] #[cfg(test)]
mod tests { mod tests {
use super::{CrateGraph, FileId, SmolStr}; use super::{CrateGraph, FileId, SmolStr};

View File

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

View File

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

View File

@ -14,13 +14,14 @@ use crate::{
adt::VariantData, adt::VariantData,
generics::GenericParams, generics::GenericParams,
code_model_impl::def_id_to_ast, 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 /// 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 /// a crate's dependencies interact. Mostly, it should be just a proxy for the
/// root module. /// root module.
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Crate { pub struct Crate {
pub(crate) crate_id: CrateId, pub(crate) crate_id: CrateId,
} }
@ -45,7 +46,6 @@ impl Crate {
#[derive(Debug)] #[derive(Debug)]
pub enum Def { pub enum Def {
Module(Module),
Struct(Struct), Struct(Struct),
Enum(Enum), Enum(Enum),
EnumVariant(EnumVariant), EnumVariant(EnumVariant),
@ -57,9 +57,29 @@ pub enum Def {
Item, Item,
} }
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Module { 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 { pub enum ModuleSource {
@ -149,7 +169,7 @@ impl Module {
self.scope_impl(db) 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) self.resolve_path_impl(db, path)
} }

View File

@ -1,7 +1,7 @@
use ra_db::CrateId; use ra_db::CrateId;
use crate::{ use crate::{
HirFileId, Crate, CrateDependency, AsName, DefLoc, DefKind, Module, SourceItemId, Crate, CrateDependency, AsName, Module,
db::HirDatabase, db::HirDatabase,
}; };
@ -21,27 +21,13 @@ impl Crate {
.collect() .collect()
} }
pub(crate) fn root_module_impl(&self, db: &impl HirDatabase) -> Option<Module> { pub(crate) fn root_module_impl(&self, db: &impl HirDatabase) -> Option<Module> {
let crate_graph = db.crate_graph(); let module_tree = db.module_tree(self.crate_id);
let file_id = crate_graph.crate_root(self.crate_id); let module_id = module_tree.modules().next()?;
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 def_loc = DefLoc { let module = Module {
kind: DefKind::Module, krate: self.crate_id,
source_root_id,
module_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) Some(module)
} }
} }

View File

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

View File

@ -1,15 +1,15 @@
use std::sync::Arc; use std::sync::Arc;
use ra_syntax::{SyntaxNode, TreeArc, SourceFile}; use ra_syntax::{SyntaxNode, TreeArc, SourceFile};
use ra_db::{SourceRootId, SyntaxDatabase, salsa}; use ra_db::{SyntaxDatabase, CrateId, salsa};
use crate::{ use crate::{
HirInterner, DefId, MacroCallId, Name, HirFileId, DefId, MacroCallId, Name, HirFileId,
SourceFileItems, SourceItemId, Crate, SourceFileItems, SourceItemId, Crate, Module, HirInterner,
query_definitions, query_definitions,
FnSignature, FnScopes, FnSignature, FnScopes,
macros::MacroExpansion, macros::MacroExpansion,
module_tree::{ModuleId, ModuleTree}, module_tree::ModuleTree,
nameres::{ItemMap, lower::{LoweredModule, ImportSourceMap}}, nameres::{ItemMap, lower::{LoweredModule, ImportSourceMap}},
ty::{InferenceResult, Ty, method_resolution::CrateImplBlocks}, ty::{InferenceResult, Ty, method_resolution::CrateImplBlocks},
adt::{StructData, EnumData, EnumVariantData}, 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>>; fn submodules(&self, source: SourceItemId) -> Arc<Vec<crate::module_tree::Submodule>>;
#[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_query)] #[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_query)]
fn lower_module( fn lower_module(&self, module: Module) -> (Arc<LoweredModule>, Arc<ImportSourceMap>);
&self,
source_root_id: SourceRootId,
module_id: ModuleId,
) -> (Arc<LoweredModule>, Arc<ImportSourceMap>);
#[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_module_query)] #[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_module_query)]
fn lower_module_module( fn lower_module_module(&self, module: Module) -> Arc<LoweredModule>;
&self,
source_root_id: SourceRootId,
module_id: ModuleId,
) -> Arc<LoweredModule>;
#[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_source_map_query)] #[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_source_map_query)]
fn lower_module_source_map( fn lower_module_source_map(&self, module: Module) -> Arc<ImportSourceMap>;
&self,
source_root_id: SourceRootId,
module_id: ModuleId,
) -> Arc<ImportSourceMap>;
#[salsa::invoke(query_definitions::item_map)] #[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)] #[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)] #[salsa::invoke(crate::impl_block::impls_in_module)]
fn impls_in_module( fn impls_in_module(&self, module: Module) -> Arc<ModuleImplBlocks>;
&self,
source_root_id: SourceRootId,
module_id: ModuleId,
) -> Arc<ModuleImplBlocks>;
#[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)] #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)]
fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>; 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_syntax::{TreeArc, SyntaxNode, SourceFile, AstNode, ast};
use ra_arena::{Arena, RawId, impl_arena_id}; use ra_arena::{Arena, RawId, impl_arena_id};
use crate::{ use crate::{
HirDatabase, Def, Function, Struct, Enum, EnumVariant, ImplBlock, Crate, HirDatabase, Def, Function, Struct, Enum, EnumVariant, ImplBlock, Crate,
Module, Trait, Type, Static, Const, Module, Trait, Type, Static, Const,
module_tree::ModuleId,
}; };
#[derive(Debug, Default)] #[derive(Debug, Default)]
@ -110,10 +109,9 @@ impl From<MacroCallId> for HirFileId {
pub struct MacroCallId(RawId); pub struct MacroCallId(RawId);
impl_arena_id!(MacroCallId); impl_arena_id!(MacroCallId);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct MacroCallLoc { pub struct MacroCallLoc {
pub(crate) source_root_id: SourceRootId, pub(crate) module: Module,
pub(crate) module_id: ModuleId,
pub(crate) source_item_id: SourceItemId, pub(crate) source_item_id: SourceItemId,
} }
@ -139,14 +137,12 @@ impl_arena_id!(DefId);
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct DefLoc { pub struct DefLoc {
pub(crate) kind: DefKind, pub(crate) kind: DefKind,
pub(crate) source_root_id: SourceRootId, pub(crate) module: Module,
pub(crate) module_id: ModuleId,
pub(crate) source_item_id: SourceItemId, pub(crate) source_item_id: SourceItemId,
} }
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub(crate) enum DefKind { pub(crate) enum DefKind {
Module,
Function, Function,
Struct, Struct,
Enum, Enum,
@ -177,10 +173,6 @@ impl DefId {
pub fn resolve(self, db: &impl HirDatabase) -> Def { pub fn resolve(self, db: &impl HirDatabase) -> Def {
let loc = self.loc(db); let loc = self.loc(db);
match loc.kind { match loc.kind {
DefKind::Module => {
let module = Module::from_module_id(db, loc.source_root_id, loc.module_id);
Def::Module(module)
}
DefKind::Function => { DefKind::Function => {
let function = Function::new(self); let function = Function::new(self);
Def::Function(function) Def::Function(function)
@ -221,8 +213,7 @@ impl DefId {
/// For a module, returns that module; for any other def, returns the containing module. /// For a module, returns that module; for any other def, returns the containing module.
pub fn module(self, db: &impl HirDatabase) -> Module { pub fn module(self, db: &impl HirDatabase) -> Module {
let loc = self.loc(db); self.loc(db).module
Module::from_module_id(db, loc.source_root_id, loc.module_id)
} }
/// Returns the containing crate. /// Returns the containing crate.
@ -232,8 +223,7 @@ impl DefId {
/// Returns the containing impl block, if this is an impl item. /// Returns the containing impl block, if this is an impl item.
pub fn impl_block(self, db: &impl HirDatabase) -> Option<ImplBlock> { pub fn impl_block(self, db: &impl HirDatabase) -> Option<ImplBlock> {
let loc = self.loc(db); let module_impls = db.impls_in_module(self.loc(db).module);
let module_impls = db.impls_in_module(loc.source_root_id, loc.module_id);
ImplBlock::containing(module_impls, self) 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_arena::{Arena, RawId, impl_arena_id};
use ra_syntax::ast::{self, AstNode}; use ra_syntax::ast::{self, AstNode};
use ra_db::{SourceRootId};
use crate::{ use crate::{
DefId, DefLoc, DefKind, SourceItemId, SourceFileItems, DefId, DefLoc, DefKind, SourceItemId, SourceFileItems,
Function, HirInterner, Function, HirFileId, HirInterner,
db::HirDatabase, db::HirDatabase,
type_ref::TypeRef, type_ref::TypeRef,
module_tree::ModuleId,
}; };
use crate::code_model_api::{Module, ModuleSource}; use crate::code_model_api::{Module, ModuleSource};
@ -67,13 +65,13 @@ pub struct ImplData {
impl ImplData { impl ImplData {
pub(crate) fn from_ast( pub(crate) fn from_ast(
db: &impl AsRef<HirInterner>, db: &impl AsRef<HirInterner>,
file_id: HirFileId,
file_items: &SourceFileItems, file_items: &SourceFileItems,
module: &Module, module: Module,
node: &ast::ImplBlock, node: &ast::ImplBlock,
) -> Self { ) -> Self {
let target_trait = node.target_trait().map(TypeRef::from_ast); let target_trait = node.target_trait().map(TypeRef::from_ast);
let target_type = TypeRef::from_ast_opt(node.target_type()); 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() { let items = if let Some(item_list) = node.item_list() {
item_list item_list
.impl_items() .impl_items()
@ -85,13 +83,13 @@ impl ImplData {
}; };
let item_id = file_items.id_of_unchecked(item_node.syntax()); let item_id = file_items.id_of_unchecked(item_node.syntax());
let source_item_id = SourceItemId { let source_item_id = SourceItemId {
file_id: module_loc.source_item_id.file_id, file_id,
item_id: Some(item_id), item_id: Some(item_id),
}; };
let def_loc = DefLoc { let def_loc = DefLoc {
module,
kind, kind,
source_item_id, source_item_id,
..module_loc
}; };
let def_id = def_loc.id(db); let def_id = def_loc.id(db);
match item_node.kind() { match item_node.kind() {
@ -168,6 +166,7 @@ impl ModuleImplBlocks {
fn collect(&mut self, db: &impl HirDatabase, module: Module) { fn collect(&mut self, db: &impl HirDatabase, module: Module) {
let (file_id, module_source) = module.definition_source(db); let (file_id, module_source) = module.definition_source(db);
let file_id: HirFileId = file_id.into();
let node = match &module_source { let node = match &module_source {
ModuleSource::SourceFile(node) => node.syntax(), ModuleSource::SourceFile(node) => node.syntax(),
ModuleSource::Module(node) => node ModuleSource::Module(node) => node
@ -176,10 +175,11 @@ impl ModuleImplBlocks {
.syntax(), .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) { 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); let id = self.impls.alloc(impl_block);
for impl_item in &self.impls[id].items { for impl_item in &self.impls[id].items {
self.impls_by_def.insert(impl_item.def_id(), id); self.impls_by_def.insert(impl_item.def_id(), id);
@ -188,13 +188,8 @@ impl ModuleImplBlocks {
} }
} }
pub(crate) fn impls_in_module( pub(crate) fn impls_in_module(db: &impl HirDatabase, module: Module) -> Arc<ModuleImplBlocks> {
db: &impl HirDatabase,
source_root_id: SourceRootId,
module_id: ModuleId,
) -> Arc<ModuleImplBlocks> {
let mut result = ModuleImplBlocks::new(); let mut result = ModuleImplBlocks::new();
let module = Module::from_module_id(db, source_root_id, module_id);
result.collect(db, module); result.collect(db, module);
Arc::new(result) Arc::new(result)
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -7,11 +7,11 @@ use rustc_hash::FxHashMap;
use ra_syntax::{ use ra_syntax::{
AstNode, SyntaxNode, TreeArc, AstNode, SyntaxNode, TreeArc,
}; };
use ra_db::SourceRootId; use ra_db::{CrateId};
use crate::{ use crate::{
SourceFileItems, SourceItemId, DefId, HirFileId, SourceFileItems, SourceItemId, DefId, HirFileId,
FnScopes, FnScopes, Module,
db::HirDatabase, db::HirDatabase,
nameres::{ItemMap, Resolver}, 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 start = Instant::now();
let module_tree = db.module_tree(source_root); let module_tree = db.module_tree(crate_id);
let input = module_tree let input = module_tree
.modules() .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<_, _>>(); .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 res = resolver.resolve();
let elapsed = start.elapsed(); let elapsed = start.elapsed();
log::info!("item_map: {:?}", elapsed); log::info!("item_map: {:?}", elapsed);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -67,7 +67,7 @@ pub(crate) fn reference_definition(
.node_expr(expr) .node_expr(expr)
.and_then(|it| infer_result.method_resolution(it)) .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); return Exact(target);
} }
}; };
@ -84,7 +84,7 @@ pub(crate) fn reference_definition(
{ {
let resolved = module.resolve_path(db, &path); let resolved = module.resolve_path(db, &path);
if let Some(def_id) = resolved.take_types().or(resolved.take_values()) { 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); 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 // 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 { let res = match def {
Def::Struct(s) => { Def::Struct(s) => {
let (file_id, node) = s.source(db); let (file_id, node) = s.source(db);
@ -131,7 +141,6 @@ impl NavigationTarget {
let (file_id, node) = f.source(db); let (file_id, node) = f.source(db);
NavigationTarget::from_named(file_id.original_file(db), &*node) NavigationTarget::from_named(file_id.original_file(db), &*node)
} }
Def::Module(m) => NavigationTarget::from_module(db, m),
Def::Item => return None, Def::Item => return None,
}; };
Some(res) Some(res)

View File

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

View File

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