mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-21 04:03:11 +00:00
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:
parent
cfb085ded8
commit
3ab1519cb2
@ -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};
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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>;
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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(
|
||||
|
@ -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 {
|
||||
|
@ -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),
|
||||
|
@ -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"),
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user