diff options
author | Aleksey Kladov <[email protected]> | 2018-11-27 23:49:28 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-11-27 23:49:28 +0000 |
commit | b2de95879a8d48cc4077895376b0aaed1e972169 (patch) | |
tree | 32b7ae7146237d3f861cf58c1dac70ed0d462059 | |
parent | ec45dfea1e37ba40ea3e2c8c6df0991a3d49213f (diff) |
generalize location interner
-rw-r--r-- | crates/ra_analysis/src/db.rs | 18 | ||||
-rw-r--r-- | crates/ra_analysis/src/hir/db.rs | 18 | ||||
-rw-r--r-- | crates/ra_analysis/src/hir/function/mod.rs | 2 | ||||
-rw-r--r-- | crates/ra_analysis/src/hir/mod.rs | 2 | ||||
-rw-r--r-- | crates/ra_analysis/src/hir/module/mod.rs | 4 | ||||
-rw-r--r-- | crates/ra_analysis/src/hir/module/nameres.rs | 6 | ||||
-rw-r--r-- | crates/ra_analysis/src/hir/query_definitions.rs | 2 | ||||
-rw-r--r-- | 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}; | |||
8 | use crate::{ | 8 | use 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 | ||
26 | impl salsa::Database for RootDatabase { | 26 | impl 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 | ||
87 | impl AsRef<LocationIntener<DefLoc, DefId>> for RootDatabase { | ||
88 | fn as_ref(&self) -> &LocationIntener<DefLoc, DefId> { | ||
89 | &self.id_maps.defs | ||
90 | } | ||
91 | } | ||
92 | |||
93 | impl 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)] |
88 | impl RootDatabase { | 100 | impl 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::{ | |||
8 | use crate::{ | 8 | use 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 | ||
22 | salsa::query_group! { | 23 | salsa::query_group! { |
23 | 24 | ||
24 | pub(crate) trait HirDatabase: SyntaxDatabase { | 25 | pub(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 | ||
39 | impl DefId { | 39 | impl 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` |
28 | pub(super) fn fn_syntax(db: &impl HirDatabase, fn_id: FnId) -> FnDefNode { | 28 | pub(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 @@ | |||
1 | use parking_lot::Mutex; | 1 | use parking_lot::Mutex; |
2 | 2 | ||
3 | use std::{ | 3 | use std::hash::Hash; |
4 | hash::Hash, | ||
5 | sync::Arc, | ||
6 | }; | ||
7 | 4 | ||
8 | use rustc_hash::FxHashMap; | 5 | use 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)] |
26 | pub(crate) struct Loc2IdMap<L, ID> | 23 | struct Loc2IdMap<LOC, ID> |
27 | where | 24 | where |
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 | ||
35 | impl<L, ID> Default for Loc2IdMap<L, ID> | 32 | impl<LOC, ID> Default for Loc2IdMap<LOC, ID> |
36 | where | 33 | where |
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 | ||
48 | impl<L, ID> Loc2IdMap<L, ID> | 45 | impl<LOC, ID> Loc2IdMap<LOC, ID> |
49 | where | 46 | where |
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 { | |||
90 | pub(crate) struct FnId(u32); | 87 | pub(crate) struct FnId(u32); |
91 | impl_numeric_id!(FnId); | 88 | impl_numeric_id!(FnId); |
92 | 89 | ||
90 | impl 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)] |
94 | pub(crate) struct DefId(u32); | 103 | pub(crate) struct DefId(u32); |
95 | impl_numeric_id!(DefId); | 104 | impl_numeric_id!(DefId); |
@@ -105,29 +114,54 @@ pub(crate) enum DefLoc { | |||
105 | }, | 114 | }, |
106 | } | 115 | } |
107 | 116 | ||
108 | #[derive(Debug, Default, Clone)] | 117 | impl DefId { |
109 | pub(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 | ||
113 | impl IdMaps { | 123 | impl 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) | 130 | pub(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)] | ||
136 | pub(crate) struct LocationIntener<LOC, ID> | ||
137 | where | ||
138 | ID: NumericId, | ||
139 | LOC: Clone + Eq + Hash, | ||
140 | { | ||
141 | map: Mutex<Loc2IdMap<LOC, ID>>, | ||
142 | } | ||
143 | |||
144 | impl<LOC, ID> Default for LocationIntener<LOC, ID> | ||
145 | where | ||
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)] | 156 | impl<LOC, ID> LocationIntener<LOC, ID> |
130 | struct IdMapsInner { | 157 | where |
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 | } |