aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-11-18 12:44:24 +0000
committerAleksey Kladov <[email protected]>2018-11-18 12:44:24 +0000
commitcb22a799d60c6c5f81ad0f3d0361f575264f3bc2 (patch)
tree738b06fae809d32f76776d27c71fa869f5dd2544
parentf1d8558cd5fe20a351496c39dbb8e15aa028803c (diff)
Add Loc2IdMap
-rw-r--r--Cargo.lock1
-rw-r--r--crates/ra_analysis/Cargo.toml1
-rw-r--r--crates/ra_analysis/src/db.rs8
-rw-r--r--crates/ra_analysis/src/descriptors/module/mod.rs9
-rw-r--r--crates/ra_analysis/src/lib.rs1
-rw-r--r--crates/ra_analysis/src/loc2id.rs64
6 files changed, 84 insertions, 0 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 18aac79ab..c6ed5107c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -600,6 +600,7 @@ version = "0.1.0"
600dependencies = [ 600dependencies = [
601 "fst 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 601 "fst 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
602 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 602 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
603 "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
603 "ra_editor 0.1.0", 604 "ra_editor 0.1.0",
604 "ra_syntax 0.1.0", 605 "ra_syntax 0.1.0",
605 "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 606 "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/crates/ra_analysis/Cargo.toml b/crates/ra_analysis/Cargo.toml
index 908ee1c81..b4a1a09b5 100644
--- a/crates/ra_analysis/Cargo.toml
+++ b/crates/ra_analysis/Cargo.toml
@@ -11,6 +11,7 @@ rayon = "1.0.2"
11fst = "0.3.1" 11fst = "0.3.1"
12salsa = "0.8.0" 12salsa = "0.8.0"
13rustc-hash = "1.0" 13rustc-hash = "1.0"
14parking_lot = "0.6.4"
14ra_syntax = { path = "../ra_syntax" } 15ra_syntax = { path = "../ra_syntax" }
15ra_editor = { path = "../ra_editor" } 16ra_editor = { path = "../ra_editor" }
16test_utils = { path = "../test_utils" } 17test_utils = { path = "../test_utils" }
diff --git a/crates/ra_analysis/src/db.rs b/crates/ra_analysis/src/db.rs
index 194f1a6b0..baf6d915a 100644
--- a/crates/ra_analysis/src/db.rs
+++ b/crates/ra_analysis/src/db.rs
@@ -1,5 +1,7 @@
1use std::sync::Arc; 1use std::sync::Arc;
2 2
3use parking_lot::Mutex;
4
3use ra_editor::LineIndex; 5use ra_editor::LineIndex;
4use ra_syntax::{SourceFileNode, SyntaxNode}; 6use ra_syntax::{SourceFileNode, SyntaxNode};
5use salsa::{self, Database}; 7use salsa::{self, Database};
@@ -9,15 +11,19 @@ use crate::{
9 descriptors::{ 11 descriptors::{
10 DescriptorDatabase, FnScopesQuery, FnSyntaxQuery, ModuleScopeQuery, ModuleTreeQuery, 12 DescriptorDatabase, FnScopesQuery, FnSyntaxQuery, ModuleScopeQuery, ModuleTreeQuery,
11 SubmodulesQuery, 13 SubmodulesQuery,
14 module::{ModuleSource, ModuleId},
12 }, 15 },
16 input::SourceRootId,
13 symbol_index::SymbolIndex, 17 symbol_index::SymbolIndex,
14 syntax_ptr::SyntaxPtr, 18 syntax_ptr::SyntaxPtr,
19 loc2id::Loc2IdMap,
15 Cancelable, Canceled, FileId, 20 Cancelable, Canceled, FileId,
16}; 21};
17 22
18#[derive(Debug)] 23#[derive(Debug)]
19pub(crate) struct RootDatabase { 24pub(crate) struct RootDatabase {
20 runtime: salsa::Runtime<RootDatabase>, 25 runtime: salsa::Runtime<RootDatabase>,
26 loc2id: Arc<Mutex<Loc2IdMap<(SourceRootId, ModuleSource), ModuleId>>>,
21} 27}
22 28
23impl salsa::Database for RootDatabase { 29impl salsa::Database for RootDatabase {
@@ -30,6 +36,7 @@ impl Default for RootDatabase {
30 fn default() -> RootDatabase { 36 fn default() -> RootDatabase {
31 let mut db = RootDatabase { 37 let mut db = RootDatabase {
32 runtime: Default::default(), 38 runtime: Default::default(),
39 loc2id: Default::default(),
33 }; 40 };
34 db.query_mut(crate::input::SourceRootQuery) 41 db.query_mut(crate::input::SourceRootQuery)
35 .set(crate::input::WORKSPACE, Default::default()); 42 .set(crate::input::WORKSPACE, Default::default());
@@ -53,6 +60,7 @@ impl salsa::ParallelDatabase for RootDatabase {
53 fn snapshot(&self) -> salsa::Snapshot<RootDatabase> { 60 fn snapshot(&self) -> salsa::Snapshot<RootDatabase> {
54 salsa::Snapshot::new(RootDatabase { 61 salsa::Snapshot::new(RootDatabase {
55 runtime: self.runtime.snapshot(self), 62 runtime: self.runtime.snapshot(self),
63 loc2id: Arc::clone(&self.loc2id),
56 }) 64 })
57 } 65 }
58} 66}
diff --git a/crates/ra_analysis/src/descriptors/module/mod.rs b/crates/ra_analysis/src/descriptors/module/mod.rs
index bc1148b22..055a56b54 100644
--- a/crates/ra_analysis/src/descriptors/module/mod.rs
+++ b/crates/ra_analysis/src/descriptors/module/mod.rs
@@ -58,6 +58,15 @@ enum ModuleSourceNode {
58#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)] 58#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
59pub(crate) struct ModuleId(u32); 59pub(crate) struct ModuleId(u32);
60 60
61impl crate::loc2id::NumericId for ModuleId {
62 fn from_u32(id: u32) -> Self {
63 ModuleId(id)
64 }
65 fn to_u32(self) -> u32 {
66 self.0
67 }
68}
69
61#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] 70#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
62pub(crate) struct LinkId(u32); 71pub(crate) struct LinkId(u32);
63 72
diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs
index ab0e3cb0c..eccda84a7 100644
--- a/crates/ra_analysis/src/lib.rs
+++ b/crates/ra_analysis/src/lib.rs
@@ -10,6 +10,7 @@ extern crate rustc_hash;
10extern crate salsa; 10extern crate salsa;
11 11
12mod db; 12mod db;
13mod loc2id;
13mod input; 14mod input;
14mod imp; 15mod imp;
15mod completion; 16mod completion;
diff --git a/crates/ra_analysis/src/loc2id.rs b/crates/ra_analysis/src/loc2id.rs
new file mode 100644
index 000000000..a53ce8348
--- /dev/null
+++ b/crates/ra_analysis/src/loc2id.rs
@@ -0,0 +1,64 @@
1use std::hash::Hash;
2
3use rustc_hash::FxHashMap;
4
5/// There are two principle ways to refer to things:
6/// - by their locatinon (module in foo/bar/baz.rs at line 42)
7/// - by their numeric id (module `ModuleId(42)`)
8///
9/// The first one is more powerful (you can actually find the thing in question
10/// by id), but the second one is so much more compact.
11///
12/// `Loc2IdMap` allows us to have a cake an eat it as well: by maintaining a
13/// bidirectional mapping between positional and numeric ids, we can use compact
14/// representation wich still allows us to get the actual item
15#[derive(Debug)]
16pub(crate) struct Loc2IdMap<L, ID>
17where
18 ID: NumericId,
19 L: Clone + Eq + Hash,
20{
21 loc2id: FxHashMap<L, ID>,
22 id2loc: FxHashMap<ID, L>,
23}
24
25impl<L, ID> Default for Loc2IdMap<L, ID>
26where
27 ID: NumericId,
28 L: Clone + Eq + Hash,
29{
30 fn default() -> Self {
31 Loc2IdMap {
32 loc2id: FxHashMap::default(),
33 id2loc: FxHashMap::default(),
34 }
35 }
36}
37
38impl<L, ID> Loc2IdMap<L, ID>
39where
40 ID: NumericId,
41 L: Clone + Eq + Hash,
42{
43 pub fn loc2id(&mut self, loc: &L) -> ID {
44 match self.loc2id.get(loc) {
45 Some(id) => return id.clone(),
46 None => (),
47 }
48 let id = self.loc2id.len();
49 assert!(id < u32::max_value() as usize);
50 let id = ID::from_u32(id as u32);
51 self.loc2id.insert(loc.clone(), id.clone());
52 self.id2loc.insert(id.clone(), loc.clone());
53 id
54 }
55
56 pub fn id2loc(&self, id: &ID) -> L {
57 self.id2loc[id].clone()
58 }
59}
60
61pub(crate) trait NumericId: Clone + Eq + Hash {
62 fn from_u32(id: u32) -> Self;
63 fn to_u32(self) -> u32;
64}