aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis/src/loc2id.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_analysis/src/loc2id.rs')
-rw-r--r--crates/ra_analysis/src/loc2id.rs138
1 files changed, 0 insertions, 138 deletions
diff --git a/crates/ra_analysis/src/loc2id.rs b/crates/ra_analysis/src/loc2id.rs
deleted file mode 100644
index e4b55f9b0..000000000
--- a/crates/ra_analysis/src/loc2id.rs
+++ /dev/null
@@ -1,138 +0,0 @@
1use parking_lot::Mutex;
2
3use std::{
4 hash::Hash,
5 sync::Arc,
6};
7
8use rustc_hash::FxHashMap;
9
10use crate::{
11 descriptors::module::ModuleId,
12 syntax_ptr::SyntaxPtr,
13 input::SourceRootId,
14};
15
16/// There are two principle ways to refer to things:
17/// - by their locatinon (module in foo/bar/baz.rs at line 42)
18/// - by their numeric id (module `ModuleId(42)`)
19///
20/// The first one is more powerful (you can actually find the thing in question
21/// by id), but the second one is so much more compact.
22///
23/// `Loc2IdMap` allows us to have a cake an eat it as well: by maintaining a
24/// bidirectional mapping between positional and numeric ids, we can use compact
25/// representation wich still allows us to get the actual item
26#[derive(Debug)]
27pub(crate) struct Loc2IdMap<L, ID>
28where
29 ID: NumericId,
30 L: Clone + Eq + Hash,
31{
32 loc2id: FxHashMap<L, ID>,
33 id2loc: FxHashMap<ID, L>,
34}
35
36impl<L, ID> Default for Loc2IdMap<L, ID>
37where
38 ID: NumericId,
39 L: Clone + Eq + Hash,
40{
41 fn default() -> Self {
42 Loc2IdMap {
43 loc2id: FxHashMap::default(),
44 id2loc: FxHashMap::default(),
45 }
46 }
47}
48
49impl<L, ID> Loc2IdMap<L, ID>
50where
51 ID: NumericId,
52 L: Clone + Eq + Hash,
53{
54 pub fn loc2id(&mut self, loc: &L) -> ID {
55 match self.loc2id.get(loc) {
56 Some(id) => return id.clone(),
57 None => (),
58 }
59 let id = self.loc2id.len();
60 assert!(id < u32::max_value() as usize);
61 let id = ID::from_u32(id as u32);
62 self.loc2id.insert(loc.clone(), id.clone());
63 self.id2loc.insert(id.clone(), loc.clone());
64 id
65 }
66
67 pub fn id2loc(&self, id: ID) -> L {
68 self.id2loc[&id].clone()
69 }
70}
71
72pub(crate) trait NumericId: Clone + Eq + Hash {
73 fn from_u32(id: u32) -> Self;
74 fn to_u32(self) -> u32;
75}
76
77macro_rules! impl_numeric_id {
78 ($id:ident) => {
79 impl NumericId for $id {
80 fn from_u32(id: u32) -> Self {
81 $id(id)
82 }
83 fn to_u32(self) -> u32 {
84 self.0
85 }
86 }
87 };
88}
89
90#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
91pub(crate) struct FnId(u32);
92impl_numeric_id!(FnId);
93
94#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
95pub(crate) struct DefId(u32);
96impl_numeric_id!(DefId);
97
98#[derive(Clone, Debug, PartialEq, Eq, Hash)]
99pub(crate) enum DefLoc {
100 Module {
101 id: ModuleId,
102 source_root: SourceRootId,
103 },
104 Item {
105 ptr: SyntaxPtr,
106 },
107}
108
109pub(crate) trait IdDatabase: salsa::Database {
110 fn id_maps(&self) -> &IdMaps;
111}
112
113#[derive(Debug, Default, Clone)]
114pub(crate) struct IdMaps {
115 inner: Arc<IdMapsInner>,
116}
117
118impl IdMaps {
119 pub(crate) fn fn_id(&self, ptr: SyntaxPtr) -> FnId {
120 self.inner.fns.lock().loc2id(&ptr)
121 }
122 pub(crate) fn fn_ptr(&self, fn_id: FnId) -> SyntaxPtr {
123 self.inner.fns.lock().id2loc(fn_id)
124 }
125
126 pub(crate) fn def_id(&self, loc: DefLoc) -> DefId {
127 self.inner.defs.lock().loc2id(&loc)
128 }
129 pub(crate) fn def_loc(&self, def_id: DefId) -> DefLoc {
130 self.inner.defs.lock().id2loc(def_id)
131 }
132}
133
134#[derive(Debug, Default)]
135struct IdMapsInner {
136 fns: Mutex<Loc2IdMap<SyntaxPtr, FnId>>,
137 defs: Mutex<Loc2IdMap<DefLoc, DefId>>,
138}