From b21829f7edd71fb14911fc6ba47fe715757e415f Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 15 Nov 2019 21:28:00 +0300 Subject: Remove old impls infrastructure --- crates/ra_hir/src/impl_block.rs | 260 ++++------------------------------------ 1 file changed, 23 insertions(+), 237 deletions(-) (limited to 'crates/ra_hir/src/impl_block.rs') diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs index b1a014074..0c2bb8fee 100644 --- a/crates/ra_hir/src/impl_block.rs +++ b/crates/ra_hir/src/impl_block.rs @@ -1,88 +1,38 @@ //! FIXME: write short doc here -use rustc_hash::FxHashMap; -use std::sync::Arc; - -use hir_def::{attr::Attr, type_ref::TypeRef}; -use hir_expand::hygiene::Hygiene; -use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId}; -use ra_cfg::CfgOptions; -use ra_syntax::{ - ast::{self, AstNode}, - AstPtr, -}; +use hir_def::{type_ref::TypeRef, AstItemDef}; +use ra_syntax::ast::{self}; use crate::{ - code_model::{Module, ModuleSource}, db::{AstDatabase, DefDatabase, HirDatabase}, generics::HasGenericParams, - ids::LocationCtx, - ids::MacroCallLoc, resolve::Resolver, ty::Ty, - AssocItem, AstId, Const, Function, HasSource, HirFileId, MacroFileKind, Path, Source, TraitRef, - TypeAlias, + AssocItem, Crate, HasSource, ImplBlock, Module, Source, TraitRef, }; -#[derive(Debug, Default, PartialEq, Eq)] -pub struct ImplSourceMap { - map: ArenaMap>>, -} - -impl ImplSourceMap { - fn insert(&mut self, impl_id: ImplId, file_id: HirFileId, impl_block: &ast::ImplBlock) { - let source = Source { file_id, ast: AstPtr::new(impl_block) }; - self.map.insert(impl_id, source) - } - - pub fn get(&self, db: &impl AstDatabase, impl_id: ImplId) -> Source { - let src = self.map[impl_id]; - let root = src.file_syntax(db); - src.map(|ptr| ptr.to_node(&root)) - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct ImplBlock { - module: Module, - impl_id: ImplId, -} - impl HasSource for ImplBlock { type Ast = ast::ImplBlock; fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source { - let source_map = db.impls_in_module_with_source_map(self.module).1; - source_map.get(db, self.impl_id) + self.id.source(db) } } impl ImplBlock { - pub(crate) fn containing( - module_impl_blocks: Arc, - item: AssocItem, - ) -> Option { - let impl_id = *module_impl_blocks.impls_by_def.get(&item)?; - Some(ImplBlock { module: module_impl_blocks.module, impl_id }) - } - - pub(crate) fn from_id(module: Module, impl_id: ImplId) -> ImplBlock { - ImplBlock { module, impl_id } - } - - pub fn id(&self) -> ImplId { - self.impl_id - } - - pub fn module(&self) -> Module { - self.module + pub(crate) fn containing(db: &impl DefDatabase, item: AssocItem) -> Option { + let module = item.module(db); + let crate_def_map = db.crate_def_map(module.id.krate); + crate_def_map[module.id.module_id].impls.iter().copied().map(ImplBlock::from).find(|it| { + db.impl_data(it.id).items().iter().copied().map(AssocItem::from).any(|it| it == item) + }) } pub fn target_trait(&self, db: &impl DefDatabase) -> Option { - db.impls_in_module(self.module).impls[self.impl_id].target_trait().cloned() + db.impl_data(self.id).target_trait().cloned() } pub fn target_type(&self, db: &impl DefDatabase) -> TypeRef { - db.impls_in_module(self.module).impls[self.impl_id].target_type().clone() + db.impl_data(self.id).target_type().clone() } pub fn target_ty(&self, db: &impl HirDatabase) -> Ty { @@ -95,15 +45,23 @@ impl ImplBlock { } pub fn items(&self, db: &impl DefDatabase) -> Vec { - db.impls_in_module(self.module).impls[self.impl_id].items().to_vec() + db.impl_data(self.id).items().iter().map(|it| (*it).into()).collect() } pub fn is_negative(&self, db: &impl DefDatabase) -> bool { - db.impls_in_module(self.module).impls[self.impl_id].negative + db.impl_data(self.id).is_negative() + } + + pub fn module(&self, db: &impl DefDatabase) -> Module { + self.id.module(db).into() + } + + pub fn krate(&self, db: &impl DefDatabase) -> Crate { + Crate { crate_id: self.module(db).id.krate } } pub(crate) fn resolver(&self, db: &impl DefDatabase) -> Resolver { - let r = self.module().resolver(db); + let r = self.module(db).resolver(db); // add generic params, if present let p = self.generic_params(db); let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; @@ -111,175 +69,3 @@ impl ImplBlock { r } } - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ImplData { - target_trait: Option, - target_type: TypeRef, - items: Vec, - negative: bool, -} - -impl ImplData { - pub(crate) fn from_ast( - db: &(impl DefDatabase + AstDatabase), - file_id: HirFileId, - 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 ctx = LocationCtx::new(db, module.id, file_id); - let negative = node.is_negative(); - let items = if let Some(item_list) = node.item_list() { - item_list - .impl_items() - .map(|item_node| match item_node { - ast::ImplItem::FnDef(it) => Function { id: ctx.to_def(&it) }.into(), - ast::ImplItem::ConstDef(it) => Const { id: ctx.to_def(&it) }.into(), - ast::ImplItem::TypeAliasDef(it) => TypeAlias { id: ctx.to_def(&it) }.into(), - }) - .collect() - } else { - Vec::new() - }; - ImplData { target_trait, target_type, items, negative } - } - - 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) -> &[AssocItem] { - &self.items - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct ImplId(pub RawId); -impl_arena_id!(ImplId); - -/// The collection of impl blocks is a two-step process: first we collect the -/// blocks per-module; then we build an index of all impl blocks in the crate. -/// This way, we avoid having to do this process for the whole crate whenever -/// a file is changed; as long as the impl blocks in the file don't change, -/// we don't need to do the second step again. -#[derive(Debug, PartialEq, Eq)] -pub struct ModuleImplBlocks { - pub(crate) module: Module, - pub(crate) impls: Arena, - impls_by_def: FxHashMap, -} - -impl ModuleImplBlocks { - pub(crate) fn impls_in_module_with_source_map_query( - db: &(impl DefDatabase + AstDatabase), - module: Module, - ) -> (Arc, Arc) { - let mut source_map = ImplSourceMap::default(); - let crate_graph = db.crate_graph(); - let cfg_options = crate_graph.cfg_options(module.id.krate); - - let result = ModuleImplBlocks::collect(db, cfg_options, module, &mut source_map); - (Arc::new(result), Arc::new(source_map)) - } - - pub(crate) fn impls_in_module_query( - db: &impl DefDatabase, - module: Module, - ) -> Arc { - db.impls_in_module_with_source_map(module).0 - } - - fn collect( - db: &(impl DefDatabase + AstDatabase), - cfg_options: &CfgOptions, - module: Module, - source_map: &mut ImplSourceMap, - ) -> Self { - let mut m = ModuleImplBlocks { - module, - impls: Arena::default(), - impls_by_def: FxHashMap::default(), - }; - - let src = m.module.definition_source(db); - match &src.ast { - ModuleSource::SourceFile(node) => { - m.collect_from_item_owner(db, cfg_options, source_map, node, src.file_id) - } - ModuleSource::Module(node) => { - let item_list = node.item_list().expect("inline module should have item list"); - m.collect_from_item_owner(db, cfg_options, source_map, &item_list, src.file_id) - } - }; - m - } - - fn collect_from_item_owner( - &mut self, - db: &(impl DefDatabase + AstDatabase), - cfg_options: &CfgOptions, - source_map: &mut ImplSourceMap, - owner: &dyn ast::ModuleItemOwner, - file_id: HirFileId, - ) { - let hygiene = Hygiene::new(db, file_id); - for item in owner.items_with_macros() { - match item { - ast::ItemOrMacro::Item(ast::ModuleItem::ImplBlock(impl_block_ast)) => { - let attrs = Attr::from_attrs_owner(&impl_block_ast, &hygiene); - if attrs.map_or(false, |attrs| { - attrs.iter().any(|attr| attr.is_cfg_enabled(cfg_options) == Some(false)) - }) { - continue; - } - - let impl_block = ImplData::from_ast(db, file_id, self.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, id); - } - - source_map.insert(id, file_id, &impl_block_ast); - } - ast::ItemOrMacro::Item(_) => (), - ast::ItemOrMacro::Macro(macro_call) => { - let attrs = Attr::from_attrs_owner(¯o_call, &hygiene); - if attrs.map_or(false, |attrs| { - attrs.iter().any(|attr| attr.is_cfg_enabled(cfg_options) == Some(false)) - }) { - continue; - } - - //FIXME: we should really cut down on the boilerplate required to process a macro - let ast_id = AstId::new(file_id, db.ast_id_map(file_id).ast_id(¯o_call)); - if let Some(path) = - macro_call.path().and_then(|path| Path::from_src(path, &hygiene)) - { - if let Some(def) = self.module.resolver(db).resolve_path_as_macro(db, &path) - { - let call_id = db.intern_macro(MacroCallLoc { def: def.id, ast_id }); - let file_id = call_id.as_file(MacroFileKind::Items); - if let Some(item_list) = - db.parse_or_expand(file_id).and_then(ast::MacroItems::cast) - { - self.collect_from_item_owner( - db, - cfg_options, - source_map, - &item_list, - file_id, - ) - } - } - } - } - } - } - } -} -- cgit v1.2.3