diff options
Diffstat (limited to 'crates/ra_analysis/src/loc2id.rs')
-rw-r--r-- | crates/ra_analysis/src/loc2id.rs | 98 |
1 files changed, 66 insertions, 32 deletions
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 | } |