From 06fa3d8389c833b01f482bf35b0f850e627612b9 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 Nov 2019 14:22:06 +0300 Subject: Move traits to hir_def --- crates/ra_hir_def/src/db.rs | 11 +++++-- crates/ra_hir_def/src/imp.rs | 71 ---------------------------------------- crates/ra_hir_def/src/impls.rs | 71 ++++++++++++++++++++++++++++++++++++++++ crates/ra_hir_def/src/lib.rs | 3 +- crates/ra_hir_def/src/nameres.rs | 8 +++++ crates/ra_hir_def/src/traits.rs | 67 +++++++++++++++++++++++++++++++++++++ 6 files changed, 157 insertions(+), 74 deletions(-) delete mode 100644 crates/ra_hir_def/src/imp.rs create mode 100644 crates/ra_hir_def/src/impls.rs create mode 100644 crates/ra_hir_def/src/traits.rs (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs index 348aca07f..fb4402463 100644 --- a/crates/ra_hir_def/src/db.rs +++ b/crates/ra_hir_def/src/db.rs @@ -8,12 +8,13 @@ use ra_syntax::ast; use crate::{ adt::{EnumData, StructData}, body::{scope::ExprScopes, Body, BodySourceMap}, - imp::ImplData, + impls::ImplData, nameres::{ raw::{ImportSourceMap, RawItems}, CrateDefMap, }, - DefWithBodyId, EnumId, ImplId, ItemLoc, StructOrUnionId, + traits::{TraitData, TraitItemsIndex}, + DefWithBodyId, EnumId, ImplId, ItemLoc, ModuleId, StructOrUnionId, TraitId, }; #[salsa::query_group(InternDatabaseStorage)] @@ -59,6 +60,12 @@ pub trait DefDatabase2: InternDatabase + AstDatabase { #[salsa::invoke(ImplData::impl_data_query)] fn impl_data(&self, e: ImplId) -> Arc; + #[salsa::invoke(TraitData::trait_data_query)] + fn trait_data(&self, e: TraitId) -> Arc; + + #[salsa::invoke(TraitItemsIndex::trait_items_index)] + fn trait_items_index(&self, module: ModuleId) -> TraitItemsIndex; + #[salsa::invoke(Body::body_with_source_map_query)] fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc, Arc); diff --git a/crates/ra_hir_def/src/imp.rs b/crates/ra_hir_def/src/imp.rs deleted file mode 100644 index 4323dfcb6..000000000 --- a/crates/ra_hir_def/src/imp.rs +++ /dev/null @@ -1,71 +0,0 @@ -//! Defines hir-level representation of impls. -//! -//! The handling is similar, but is not quite the same as for other items, -//! because `impl`s don't have names. - -use std::sync::Arc; - -use ra_syntax::ast; - -use crate::{ - db::DefDatabase2, type_ref::TypeRef, AssocItemId, AstItemDef, ConstId, FunctionId, ImplId, - LocationCtx, TypeAliasId, -}; - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ImplData { - target_trait: Option, - target_type: TypeRef, - items: Vec, - negative: bool, -} - -impl ImplData { - pub(crate) fn impl_data_query(db: &impl DefDatabase2, id: ImplId) -> Arc { - let src = id.source(db); - let items = db.ast_id_map(src.file_id); - - let target_trait = src.value.target_trait().map(TypeRef::from_ast); - let target_type = TypeRef::from_ast_opt(src.value.target_type()); - let negative = src.value.is_negative(); - - let items = if let Some(item_list) = src.value.item_list() { - let ctx = LocationCtx::new(db, id.module(db), src.file_id); - item_list - .impl_items() - .map(|item_node| match item_node { - ast::ImplItem::FnDef(it) => { - FunctionId::from_ast_id(ctx, items.ast_id(&it)).into() - } - ast::ImplItem::ConstDef(it) => { - ConstId::from_ast_id(ctx, items.ast_id(&it)).into() - } - ast::ImplItem::TypeAliasDef(it) => { - TypeAliasId::from_ast_id(ctx, items.ast_id(&it)).into() - } - }) - .collect() - } else { - Vec::new() - }; - - let res = ImplData { target_trait, target_type, items, negative }; - Arc::new(res) - } - - pub fn target_trait(&self) -> Option<&TypeRef> { - self.target_trait.as_ref() - } - - pub fn target_type(&self) -> &TypeRef { - &self.target_type - } - - pub fn items(&self) -> &[AssocItemId] { - &self.items - } - - pub fn is_negative(&self) -> bool { - self.negative - } -} diff --git a/crates/ra_hir_def/src/impls.rs b/crates/ra_hir_def/src/impls.rs new file mode 100644 index 000000000..4323dfcb6 --- /dev/null +++ b/crates/ra_hir_def/src/impls.rs @@ -0,0 +1,71 @@ +//! Defines hir-level representation of impls. +//! +//! The handling is similar, but is not quite the same as for other items, +//! because `impl`s don't have names. + +use std::sync::Arc; + +use ra_syntax::ast; + +use crate::{ + db::DefDatabase2, type_ref::TypeRef, AssocItemId, AstItemDef, ConstId, FunctionId, ImplId, + LocationCtx, TypeAliasId, +}; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ImplData { + target_trait: Option, + target_type: TypeRef, + items: Vec, + negative: bool, +} + +impl ImplData { + pub(crate) fn impl_data_query(db: &impl DefDatabase2, id: ImplId) -> Arc { + let src = id.source(db); + let items = db.ast_id_map(src.file_id); + + let target_trait = src.value.target_trait().map(TypeRef::from_ast); + let target_type = TypeRef::from_ast_opt(src.value.target_type()); + let negative = src.value.is_negative(); + + let items = if let Some(item_list) = src.value.item_list() { + let ctx = LocationCtx::new(db, id.module(db), src.file_id); + item_list + .impl_items() + .map(|item_node| match item_node { + ast::ImplItem::FnDef(it) => { + FunctionId::from_ast_id(ctx, items.ast_id(&it)).into() + } + ast::ImplItem::ConstDef(it) => { + ConstId::from_ast_id(ctx, items.ast_id(&it)).into() + } + ast::ImplItem::TypeAliasDef(it) => { + TypeAliasId::from_ast_id(ctx, items.ast_id(&it)).into() + } + }) + .collect() + } else { + Vec::new() + }; + + let res = ImplData { target_trait, target_type, items, negative }; + Arc::new(res) + } + + pub fn target_trait(&self) -> Option<&TypeRef> { + self.target_trait.as_ref() + } + + pub fn target_type(&self) -> &TypeRef { + &self.target_type + } + + pub fn items(&self) -> &[AssocItemId] { + &self.items + } + + pub fn is_negative(&self) -> bool { + self.negative + } +} diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index dffc82ff8..38c110570 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -13,11 +13,12 @@ pub mod path; pub mod type_ref; pub mod builtin_type; pub mod adt; -pub mod imp; +pub mod impls; pub mod diagnostics; pub mod expr; pub mod body; pub mod generics; +pub mod traits; #[cfg(test)] mod test_db; diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index e5b073a0f..c01e020ef 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs @@ -165,6 +165,14 @@ impl ModuleScope { self.items.iter().chain(BUILTIN_SCOPE.iter()) } + pub fn declarations(&self) -> impl Iterator + '_ { + self.entries() + .filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None }) + .flat_map(|per_ns| { + per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter()) + }) + } + /// Iterate over all module scoped macros pub fn macros<'a>(&'a self) -> impl Iterator + 'a { self.items diff --git a/crates/ra_hir_def/src/traits.rs b/crates/ra_hir_def/src/traits.rs new file mode 100644 index 000000000..a8ba31594 --- /dev/null +++ b/crates/ra_hir_def/src/traits.rs @@ -0,0 +1,67 @@ +//! HIR for trait definitions. + +use std::sync::Arc; + +use hir_expand::name::{AsName, Name}; + +use ra_syntax::ast::{self, NameOwner}; +use rustc_hash::FxHashMap; + +use crate::{ + db::DefDatabase2, AssocItemId, AstItemDef, ConstId, FunctionId, LocationCtx, ModuleDefId, + ModuleId, TraitId, TypeAliasId, +}; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct TraitData { + pub name: Option, + pub items: Vec, + pub auto: bool, +} + +impl TraitData { + pub(crate) fn trait_data_query(db: &impl DefDatabase2, tr: TraitId) -> Arc { + let src = tr.source(db); + let name = src.value.name().map(|n| n.as_name()); + let module = tr.module(db); + let ctx = LocationCtx::new(db, module, src.file_id); + let auto = src.value.is_auto(); + let items = if let Some(item_list) = src.value.item_list() { + item_list + .impl_items() + .map(|item_node| match item_node { + ast::ImplItem::FnDef(it) => FunctionId::from_ast(ctx, &it).into(), + ast::ImplItem::ConstDef(it) => ConstId::from_ast(ctx, &it).into(), + ast::ImplItem::TypeAliasDef(it) => TypeAliasId::from_ast(ctx, &it).into(), + }) + .collect() + } else { + Vec::new() + }; + Arc::new(TraitData { name, items, auto }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct TraitItemsIndex { + traits_by_def: FxHashMap, +} + +impl TraitItemsIndex { + pub fn trait_items_index(db: &impl DefDatabase2, module: ModuleId) -> TraitItemsIndex { + let mut index = TraitItemsIndex { traits_by_def: FxHashMap::default() }; + let crate_def_map = db.crate_def_map(module.krate); + for decl in crate_def_map[module.module_id].scope.declarations() { + if let ModuleDefId::TraitId(tr) = decl { + for item in db.trait_data(tr).items.iter() { + index.traits_by_def.insert(*item, tr); + } + } + } + index + } + + pub fn get_parent_trait(&self, item: AssocItemId) -> Option { + self.traits_by_def.get(&item).cloned() + } +} -- cgit v1.2.3