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