aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis/src/loc2id.rs
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 /crates/ra_analysis/src/loc2id.rs
parentec45dfea1e37ba40ea3e2c8c6df0991a3d49213f (diff)
generalize location interner
Diffstat (limited to 'crates/ra_analysis/src/loc2id.rs')
-rw-r--r--crates/ra_analysis/src/loc2id.rs98
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 @@
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}