aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-11-27 23:49:28 +0000
committerAleksey Kladov <[email protected]>2018-11-27 23:49:28 +0000
commitb2de95879a8d48cc4077895376b0aaed1e972169 (patch)
tree32b7ae7146237d3f861cf58c1dac70ed0d462059
parentec45dfea1e37ba40ea3e2c8c6df0991a3d49213f (diff)
generalize location interner
-rw-r--r--crates/ra_analysis/src/db.rs18
-rw-r--r--crates/ra_analysis/src/hir/db.rs18
-rw-r--r--crates/ra_analysis/src/hir/function/mod.rs2
-rw-r--r--crates/ra_analysis/src/hir/mod.rs2
-rw-r--r--crates/ra_analysis/src/hir/module/mod.rs4
-rw-r--r--crates/ra_analysis/src/hir/module/nameres.rs6
-rw-r--r--crates/ra_analysis/src/hir/query_definitions.rs2
-rw-r--r--crates/ra_analysis/src/loc2id.rs98
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};
8use crate::{ 8use crate::{
9 hir, 9 hir,
10 symbol_index, 10 symbol_index,
11 loc2id::{IdMaps}, 11 loc2id::{IdMaps, LocationIntener, DefId, DefLoc, FnId},
12 Cancelable, Canceled, FileId, 12 Cancelable, Canceled, FileId,
13}; 13};
14 14
@@ -20,7 +20,7 @@ pub(crate) struct RootDatabase {
20 events: (), 20 events: (),
21 21
22 runtime: salsa::Runtime<RootDatabase>, 22 runtime: salsa::Runtime<RootDatabase>,
23 id_maps: IdMaps, 23 id_maps: Arc<IdMaps>,
24} 24}
25 25
26impl salsa::Database for RootDatabase { 26impl salsa::Database for RootDatabase {
@@ -45,7 +45,7 @@ impl Default for RootDatabase {
45 let mut db = RootDatabase { 45 let mut db = RootDatabase {
46 events: Default::default(), 46 events: Default::default(),
47 runtime: salsa::Runtime::default(), 47 runtime: salsa::Runtime::default(),
48 id_maps: IdMaps::default(), 48 id_maps: Default::default(),
49 }; 49 };
50 db.query_mut(crate::input::SourceRootQuery) 50 db.query_mut(crate::input::SourceRootQuery)
51 .set(crate::input::WORKSPACE, Default::default()); 51 .set(crate::input::WORKSPACE, Default::default());
@@ -84,6 +84,18 @@ impl BaseDatabase for RootDatabase {
84 } 84 }
85} 85}
86 86
87impl AsRef<LocationIntener<DefLoc, DefId>> for RootDatabase {
88 fn as_ref(&self) -> &LocationIntener<DefLoc, DefId> {
89 &self.id_maps.defs
90 }
91}
92
93impl AsRef<LocationIntener<hir::SourceItemId, FnId>> for RootDatabase {
94 fn as_ref(&self) -> &LocationIntener<hir::SourceItemId, FnId> {
95 &self.id_maps.fns
96 }
97}
98
87#[cfg(test)] 99#[cfg(test)]
88impl RootDatabase { 100impl RootDatabase {
89 pub(crate) fn log(&self, f: impl FnOnce()) -> Vec<salsa::Event<RootDatabase>> { 101 pub(crate) fn log(&self, f: impl FnOnce()) -> Vec<salsa::Event<RootDatabase>> {
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::{
8use crate::{ 8use crate::{
9 FileId, 9 FileId,
10 db::SyntaxDatabase, 10 db::SyntaxDatabase,
11 hir::{SourceFileItems, SourceItemId}, 11 hir::{
12 hir::query_definitions, 12 SourceFileItems, SourceItemId,
13 hir::function::{FnId, FnScopes}, 13 query_definitions,
14 hir::module::{ 14 function::{FnScopes},
15 ModuleId, ModuleTree, ModuleSource, 15 module::{ModuleId, ModuleTree, ModuleSource,
16 nameres::{ItemMap, InputModuleItems} 16 nameres::{ItemMap, InputModuleItems}},
17 }, 17 },
18 input::SourceRootId, 18 input::SourceRootId,
19 loc2id::{DefLoc, DefId, FnId, LocationIntener},
19 Cancelable, 20 Cancelable,
20}; 21};
21 22
22salsa::query_group! { 23salsa::query_group! {
23 24
24pub(crate) trait HirDatabase: SyntaxDatabase { 25pub(crate) trait HirDatabase: SyntaxDatabase
26 + AsRef<LocationIntener<DefLoc, DefId>>
27 + AsRef<LocationIntener<SourceItemId, FnId>>
28{
25 fn fn_scopes(fn_id: FnId) -> Arc<FnScopes> { 29 fn fn_scopes(fn_id: FnId) -> Arc<FnScopes> {
26 type FnScopesQuery; 30 type FnScopesQuery;
27 use fn query_definitions::fn_scopes; 31 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 {
23 let file_items = db.file_items(file_id); 23 let file_items = db.file_items(file_id);
24 let item_id = file_items.id_of(fn_def.syntax()); 24 let item_id = file_items.id_of(fn_def.syntax());
25 let item_id = SourceItemId { file_id, item_id }; 25 let item_id = SourceItemId { file_id, item_id };
26 db.id_maps().fn_id(item_id) 26 FnId::from_loc(db, &item_id)
27 } 27 }
28} 28}
29 29
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 {
38 38
39impl DefId { 39impl DefId {
40 pub(crate) fn resolve(self, db: &impl HirDatabase) -> Cancelable<Def> { 40 pub(crate) fn resolve(self, db: &impl HirDatabase) -> Cancelable<Def> {
41 let loc = db.id_maps().def_loc(self); 41 let loc = self.loc(db);
42 let res = match loc { 42 let res = match loc {
43 DefLoc::Module { id, source_root } => { 43 DefLoc::Module { id, source_root } => {
44 let descr = Module::new(db, source_root, id)?; 44 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 {
134 id: self.module_id, 134 id: self.module_id,
135 source_root: self.source_root_id, 135 source_root: self.source_root_id,
136 }; 136 };
137 db.id_maps().def_id(def_loc) 137 def_loc.id(db)
138 } 138 }
139 139
140 /// Finds a child module with the specified name. 140 /// Finds a child module with the specified name.
@@ -167,7 +167,7 @@ impl Module {
167 167
168 let segments = path.segments; 168 let segments = path.segments;
169 for name in segments.iter() { 169 for name in segments.iter() {
170 let module = match db.id_maps().def_loc(curr) { 170 let module = match curr.loc(db) {
171 DefLoc::Module { id, source_root } => Module::new(db, source_root, id)?, 171 DefLoc::Module { id, source_root } => Module::new(db, source_root, id)?,
172 _ => return Ok(None), 172 _ => return Ok(None),
173 }; 173 };
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
256 item_id: item.id, 256 item_id: item.id,
257 }, 257 },
258 }; 258 };
259 let def_id = self.db.id_maps().def_id(def_loc); 259 let def_id = def_loc.id(self.db);
260 let resolution = Resolution { 260 let resolution = Resolution {
261 def_id: Some(def_id), 261 def_id: Some(def_id),
262 import: None, 262 import: None,
@@ -269,7 +269,7 @@ where
269 id: mod_id, 269 id: mod_id,
270 source_root: self.source_root, 270 source_root: self.source_root,
271 }; 271 };
272 let def_id = self.db.id_maps().def_id(def_loc); 272 let def_id = def_loc.id(self.db);
273 let resolution = Resolution { 273 let resolution = Resolution {
274 def_id: Some(def_id), 274 def_id: Some(def_id),
275 import: None, 275 import: None,
@@ -318,7 +318,7 @@ where
318 }; 318 };
319 319
320 if !is_last { 320 if !is_last {
321 curr = match self.db.id_maps().def_loc(def_id) { 321 curr = match def_id.loc(self.db) {
322 DefLoc::Module { id, .. } => id, 322 DefLoc::Module { id, .. } => id,
323 _ => return, 323 _ => return,
324 } 324 }
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::{
26 26
27/// Resolve `FnId` to the corresponding `SyntaxNode` 27/// Resolve `FnId` to the corresponding `SyntaxNode`
28pub(super) fn fn_syntax(db: &impl HirDatabase, fn_id: FnId) -> FnDefNode { 28pub(super) fn fn_syntax(db: &impl HirDatabase, fn_id: FnId) -> FnDefNode {
29 let item_id = db.id_maps().fn_item_id(fn_id); 29 let item_id = fn_id.loc(db);
30 let syntax = db.file_item(item_id); 30 let syntax = db.file_item(item_id);
31 FnDef::cast(syntax.borrowed()).unwrap().owned() 31 FnDef::cast(syntax.borrowed()).unwrap().owned()
32} 32}
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 @@
1use parking_lot::Mutex; 1use parking_lot::Mutex;
2 2
3use std::{ 3use std::hash::Hash;
4 hash::Hash,
5 sync::Arc,
6};
7 4
8use rustc_hash::FxHashMap; 5use rustc_hash::FxHashMap;
9 6
@@ -23,19 +20,19 @@ use crate::{
23/// bidirectional mapping between positional and numeric ids, we can use compact 20/// bidirectional mapping between positional and numeric ids, we can use compact
24/// representation wich still allows us to get the actual item 21/// representation wich still allows us to get the actual item
25#[derive(Debug)] 22#[derive(Debug)]
26pub(crate) struct Loc2IdMap<L, ID> 23struct Loc2IdMap<LOC, ID>
27where 24where
28 ID: NumericId, 25 ID: NumericId,
29 L: Clone + Eq + Hash, 26 LOC: Clone + Eq + Hash,
30{ 27{
31 loc2id: FxHashMap<L, ID>, 28 loc2id: FxHashMap<LOC, ID>,
32 id2loc: FxHashMap<ID, L>, 29 id2loc: FxHashMap<ID, LOC>,
33} 30}
34 31
35impl<L, ID> Default for Loc2IdMap<L, ID> 32impl<LOC, ID> Default for Loc2IdMap<LOC, ID>
36where 33where
37 ID: NumericId, 34 ID: NumericId,
38 L: Clone + Eq + Hash, 35 LOC: Clone + Eq + Hash,
39{ 36{
40 fn default() -> Self { 37 fn default() -> Self {
41 Loc2IdMap { 38 Loc2IdMap {
@@ -45,12 +42,12 @@ where
45 } 42 }
46} 43}
47 44
48impl<L, ID> Loc2IdMap<L, ID> 45impl<LOC, ID> Loc2IdMap<LOC, ID>
49where 46where
50 ID: NumericId, 47 ID: NumericId,
51 L: Clone + Eq + Hash, 48 LOC: Clone + Eq + Hash,
52{ 49{
53 pub fn loc2id(&mut self, loc: &L) -> ID { 50 pub fn loc2id(&mut self, loc: &LOC) -> ID {
54 match self.loc2id.get(loc) { 51 match self.loc2id.get(loc) {
55 Some(id) => return id.clone(), 52 Some(id) => return id.clone(),
56 None => (), 53 None => (),
@@ -63,7 +60,7 @@ where
63 id 60 id
64 } 61 }
65 62
66 pub fn id2loc(&self, id: ID) -> L { 63 pub fn id2loc(&self, id: ID) -> LOC {
67 self.id2loc[&id].clone() 64 self.id2loc[&id].clone()
68 } 65 }
69} 66}
@@ -90,6 +87,18 @@ macro_rules! impl_numeric_id {
90pub(crate) struct FnId(u32); 87pub(crate) struct FnId(u32);
91impl_numeric_id!(FnId); 88impl_numeric_id!(FnId);
92 89
90impl FnId {
91 pub(crate) fn from_loc(
92 db: &impl AsRef<LocationIntener<SourceItemId, FnId>>,
93 loc: &SourceItemId,
94 ) -> FnId {
95 db.as_ref().loc2id(loc)
96 }
97 pub(crate) fn loc(self, db: &impl AsRef<LocationIntener<SourceItemId, FnId>>) -> SourceItemId {
98 db.as_ref().id2loc(self)
99 }
100}
101
93#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 102#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
94pub(crate) struct DefId(u32); 103pub(crate) struct DefId(u32);
95impl_numeric_id!(DefId); 104impl_numeric_id!(DefId);
@@ -105,29 +114,54 @@ pub(crate) enum DefLoc {
105 }, 114 },
106} 115}
107 116
108#[derive(Debug, Default, Clone)] 117impl DefId {
109pub(crate) struct IdMaps { 118 pub(crate) fn loc(self, db: &impl AsRef<LocationIntener<DefLoc, DefId>>) -> DefLoc {
110 inner: Arc<IdMapsInner>, 119 db.as_ref().id2loc(self)
120 }
111} 121}
112 122
113impl IdMaps { 123impl DefLoc {
114 pub(crate) fn fn_id(&self, item_id: SourceItemId) -> FnId { 124 pub(crate) fn id(&self, db: &impl AsRef<LocationIntener<DefLoc, DefId>>) -> DefId {
115 self.inner.fns.lock().loc2id(&item_id) 125 db.as_ref().loc2id(&self)
116 }
117 pub(crate) fn fn_item_id(&self, fn_id: FnId) -> SourceItemId {
118 self.inner.fns.lock().id2loc(fn_id)
119 } 126 }
127}
120 128
121 pub(crate) fn def_id(&self, loc: DefLoc) -> DefId { 129#[derive(Debug, Default)]
122 self.inner.defs.lock().loc2id(&loc) 130pub(crate) struct IdMaps {
123 } 131 pub(crate) fns: LocationIntener<SourceItemId, FnId>,
124 pub(crate) fn def_loc(&self, def_id: DefId) -> DefLoc { 132 pub(crate) defs: LocationIntener<DefLoc, DefId>,
125 self.inner.defs.lock().id2loc(def_id) 133}
134
135#[derive(Debug)]
136pub(crate) struct LocationIntener<LOC, ID>
137where
138 ID: NumericId,
139 LOC: Clone + Eq + Hash,
140{
141 map: Mutex<Loc2IdMap<LOC, ID>>,
142}
143
144impl<LOC, ID> Default for LocationIntener<LOC, ID>
145where
146 ID: NumericId,
147 LOC: Clone + Eq + Hash,
148{
149 fn default() -> Self {
150 LocationIntener {
151 map: Default::default(),
152 }
126 } 153 }
127} 154}
128 155
129#[derive(Debug, Default)] 156impl<LOC, ID> LocationIntener<LOC, ID>
130struct IdMapsInner { 157where
131 fns: Mutex<Loc2IdMap<SourceItemId, FnId>>, 158 ID: NumericId,
132 defs: Mutex<Loc2IdMap<DefLoc, DefId>>, 159 LOC: Clone + Eq + Hash,
160{
161 fn loc2id(&self, loc: &LOC) -> ID {
162 self.map.lock().loc2id(loc)
163 }
164 fn id2loc(&self, id: ID) -> LOC {
165 self.map.lock().id2loc(id)
166 }
133} 167}