From b2de95879a8d48cc4077895376b0aaed1e972169 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 28 Nov 2018 02:49:28 +0300 Subject: generalize location interner --- crates/ra_analysis/src/db.rs | 18 ++++- crates/ra_analysis/src/hir/db.rs | 18 +++-- crates/ra_analysis/src/hir/function/mod.rs | 2 +- crates/ra_analysis/src/hir/mod.rs | 2 +- crates/ra_analysis/src/hir/module/mod.rs | 4 +- crates/ra_analysis/src/hir/module/nameres.rs | 6 +- crates/ra_analysis/src/hir/query_definitions.rs | 2 +- crates/ra_analysis/src/loc2id.rs | 98 +++++++++++++++++-------- 8 files changed, 100 insertions(+), 50 deletions(-) diff --git a/crates/ra_analysis/src/db.rs b/crates/ra_analysis/src/db.rs index 11154cc65..e0b7afac5 100644 --- a/crates/ra_analysis/src/db.rs +++ b/crates/ra_analysis/src/db.rs @@ -8,7 +8,7 @@ use salsa::{self, Database}; use crate::{ hir, symbol_index, - loc2id::{IdMaps}, + loc2id::{IdMaps, LocationIntener, DefId, DefLoc, FnId}, Cancelable, Canceled, FileId, }; @@ -20,7 +20,7 @@ pub(crate) struct RootDatabase { events: (), runtime: salsa::Runtime, - id_maps: IdMaps, + id_maps: Arc, } impl salsa::Database for RootDatabase { @@ -45,7 +45,7 @@ impl Default for RootDatabase { let mut db = RootDatabase { events: Default::default(), runtime: salsa::Runtime::default(), - id_maps: IdMaps::default(), + id_maps: Default::default(), }; db.query_mut(crate::input::SourceRootQuery) .set(crate::input::WORKSPACE, Default::default()); @@ -84,6 +84,18 @@ impl BaseDatabase for RootDatabase { } } +impl AsRef> for RootDatabase { + fn as_ref(&self) -> &LocationIntener { + &self.id_maps.defs + } +} + +impl AsRef> for RootDatabase { + fn as_ref(&self) -> &LocationIntener { + &self.id_maps.fns + } +} + #[cfg(test)] impl RootDatabase { pub(crate) fn log(&self, f: impl FnOnce()) -> Vec> { diff --git a/crates/ra_analysis/src/hir/db.rs b/crates/ra_analysis/src/hir/db.rs index 0998295f5..bf0dc393a 100644 --- a/crates/ra_analysis/src/hir/db.rs +++ b/crates/ra_analysis/src/hir/db.rs @@ -8,20 +8,24 @@ use ra_syntax::{ use crate::{ FileId, db::SyntaxDatabase, - hir::{SourceFileItems, SourceItemId}, - hir::query_definitions, - hir::function::{FnId, FnScopes}, - hir::module::{ - ModuleId, ModuleTree, ModuleSource, - nameres::{ItemMap, InputModuleItems} + hir::{ + SourceFileItems, SourceItemId, + query_definitions, + function::{FnScopes}, + module::{ModuleId, ModuleTree, ModuleSource, + nameres::{ItemMap, InputModuleItems}}, }, input::SourceRootId, + loc2id::{DefLoc, DefId, FnId, LocationIntener}, Cancelable, }; salsa::query_group! { -pub(crate) trait HirDatabase: SyntaxDatabase { +pub(crate) trait HirDatabase: SyntaxDatabase + + AsRef> + + AsRef> +{ fn fn_scopes(fn_id: FnId) -> Arc { type FnScopesQuery; use fn query_definitions::fn_scopes; diff --git a/crates/ra_analysis/src/hir/function/mod.rs b/crates/ra_analysis/src/hir/function/mod.rs index 280218fd4..e64a9f045 100644 --- a/crates/ra_analysis/src/hir/function/mod.rs +++ b/crates/ra_analysis/src/hir/function/mod.rs @@ -23,7 +23,7 @@ impl FnId { let file_items = db.file_items(file_id); let item_id = file_items.id_of(fn_def.syntax()); let item_id = SourceItemId { file_id, item_id }; - db.id_maps().fn_id(item_id) + FnId::from_loc(db, &item_id) } } diff --git a/crates/ra_analysis/src/hir/mod.rs b/crates/ra_analysis/src/hir/mod.rs index 9527cc33f..61e6c9913 100644 --- a/crates/ra_analysis/src/hir/mod.rs +++ b/crates/ra_analysis/src/hir/mod.rs @@ -38,7 +38,7 @@ pub(crate) enum Def { impl DefId { pub(crate) fn resolve(self, db: &impl HirDatabase) -> Cancelable { - let loc = db.id_maps().def_loc(self); + let loc = self.loc(db); let res = match loc { DefLoc::Module { id, source_root } => { let descr = Module::new(db, source_root, id)?; diff --git a/crates/ra_analysis/src/hir/module/mod.rs b/crates/ra_analysis/src/hir/module/mod.rs index 83f176b32..893ec3a10 100644 --- a/crates/ra_analysis/src/hir/module/mod.rs +++ b/crates/ra_analysis/src/hir/module/mod.rs @@ -134,7 +134,7 @@ impl Module { id: self.module_id, source_root: self.source_root_id, }; - db.id_maps().def_id(def_loc) + def_loc.id(db) } /// Finds a child module with the specified name. @@ -167,7 +167,7 @@ impl Module { let segments = path.segments; for name in segments.iter() { - let module = match db.id_maps().def_loc(curr) { + let module = match curr.loc(db) { DefLoc::Module { id, source_root } => Module::new(db, source_root, id)?, _ => return Ok(None), }; diff --git a/crates/ra_analysis/src/hir/module/nameres.rs b/crates/ra_analysis/src/hir/module/nameres.rs index f22832eda..f48f51c8d 100644 --- a/crates/ra_analysis/src/hir/module/nameres.rs +++ b/crates/ra_analysis/src/hir/module/nameres.rs @@ -256,7 +256,7 @@ where item_id: item.id, }, }; - let def_id = self.db.id_maps().def_id(def_loc); + let def_id = def_loc.id(self.db); let resolution = Resolution { def_id: Some(def_id), import: None, @@ -269,7 +269,7 @@ where id: mod_id, source_root: self.source_root, }; - let def_id = self.db.id_maps().def_id(def_loc); + let def_id = def_loc.id(self.db); let resolution = Resolution { def_id: Some(def_id), import: None, @@ -318,7 +318,7 @@ where }; if !is_last { - curr = match self.db.id_maps().def_loc(def_id) { + curr = match def_id.loc(self.db) { DefLoc::Module { id, .. } => id, _ => return, } diff --git a/crates/ra_analysis/src/hir/query_definitions.rs b/crates/ra_analysis/src/hir/query_definitions.rs index e7fba5d72..6570ca994 100644 --- a/crates/ra_analysis/src/hir/query_definitions.rs +++ b/crates/ra_analysis/src/hir/query_definitions.rs @@ -26,7 +26,7 @@ use crate::{ /// Resolve `FnId` to the corresponding `SyntaxNode` pub(super) fn fn_syntax(db: &impl HirDatabase, fn_id: FnId) -> FnDefNode { - let item_id = db.id_maps().fn_item_id(fn_id); + let item_id = fn_id.loc(db); let syntax = db.file_item(item_id); FnDef::cast(syntax.borrowed()).unwrap().owned() } diff --git a/crates/ra_analysis/src/loc2id.rs b/crates/ra_analysis/src/loc2id.rs index 204708942..2aa141130 100644 --- a/crates/ra_analysis/src/loc2id.rs +++ b/crates/ra_analysis/src/loc2id.rs @@ -1,9 +1,6 @@ use parking_lot::Mutex; -use std::{ - hash::Hash, - sync::Arc, -}; +use std::hash::Hash; use rustc_hash::FxHashMap; @@ -23,19 +20,19 @@ use crate::{ /// bidirectional mapping between positional and numeric ids, we can use compact /// representation wich still allows us to get the actual item #[derive(Debug)] -pub(crate) struct Loc2IdMap +struct Loc2IdMap where ID: NumericId, - L: Clone + Eq + Hash, + LOC: Clone + Eq + Hash, { - loc2id: FxHashMap, - id2loc: FxHashMap, + loc2id: FxHashMap, + id2loc: FxHashMap, } -impl Default for Loc2IdMap +impl Default for Loc2IdMap where ID: NumericId, - L: Clone + Eq + Hash, + LOC: Clone + Eq + Hash, { fn default() -> Self { Loc2IdMap { @@ -45,12 +42,12 @@ where } } -impl Loc2IdMap +impl Loc2IdMap where ID: NumericId, - L: Clone + Eq + Hash, + LOC: Clone + Eq + Hash, { - pub fn loc2id(&mut self, loc: &L) -> ID { + pub fn loc2id(&mut self, loc: &LOC) -> ID { match self.loc2id.get(loc) { Some(id) => return id.clone(), None => (), @@ -63,7 +60,7 @@ where id } - pub fn id2loc(&self, id: ID) -> L { + pub fn id2loc(&self, id: ID) -> LOC { self.id2loc[&id].clone() } } @@ -90,6 +87,18 @@ macro_rules! impl_numeric_id { pub(crate) struct FnId(u32); impl_numeric_id!(FnId); +impl FnId { + pub(crate) fn from_loc( + db: &impl AsRef>, + loc: &SourceItemId, + ) -> FnId { + db.as_ref().loc2id(loc) + } + pub(crate) fn loc(self, db: &impl AsRef>) -> SourceItemId { + db.as_ref().id2loc(self) + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub(crate) struct DefId(u32); impl_numeric_id!(DefId); @@ -105,29 +114,54 @@ pub(crate) enum DefLoc { }, } -#[derive(Debug, Default, Clone)] -pub(crate) struct IdMaps { - inner: Arc, +impl DefId { + pub(crate) fn loc(self, db: &impl AsRef>) -> DefLoc { + db.as_ref().id2loc(self) + } } -impl IdMaps { - pub(crate) fn fn_id(&self, item_id: SourceItemId) -> FnId { - self.inner.fns.lock().loc2id(&item_id) - } - pub(crate) fn fn_item_id(&self, fn_id: FnId) -> SourceItemId { - self.inner.fns.lock().id2loc(fn_id) +impl DefLoc { + pub(crate) fn id(&self, db: &impl AsRef>) -> DefId { + db.as_ref().loc2id(&self) } +} - pub(crate) fn def_id(&self, loc: DefLoc) -> DefId { - self.inner.defs.lock().loc2id(&loc) - } - pub(crate) fn def_loc(&self, def_id: DefId) -> DefLoc { - self.inner.defs.lock().id2loc(def_id) +#[derive(Debug, Default)] +pub(crate) struct IdMaps { + pub(crate) fns: LocationIntener, + pub(crate) defs: LocationIntener, +} + +#[derive(Debug)] +pub(crate) struct LocationIntener +where + ID: NumericId, + LOC: Clone + Eq + Hash, +{ + map: Mutex>, +} + +impl Default for LocationIntener +where + ID: NumericId, + LOC: Clone + Eq + Hash, +{ + fn default() -> Self { + LocationIntener { + map: Default::default(), + } } } -#[derive(Debug, Default)] -struct IdMapsInner { - fns: Mutex>, - defs: Mutex>, +impl LocationIntener +where + ID: NumericId, + LOC: Clone + Eq + Hash, +{ + fn loc2id(&self, loc: &LOC) -> ID { + self.map.lock().loc2id(loc) + } + fn id2loc(&self, id: ID) -> LOC { + self.map.lock().id2loc(id) + } } -- cgit v1.2.3