aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock16
-rw-r--r--crates/ra_analysis/Cargo.toml1
-rw-r--r--crates/ra_analysis/src/completion/mod.rs3
-rw-r--r--crates/ra_analysis/src/db.rs69
-rw-r--r--crates/ra_analysis/src/hir/db.rs5
-rw-r--r--crates/ra_analysis/src/hir/function/scope.rs3
-rw-r--r--crates/ra_analysis/src/hir/module/imp.rs4
-rw-r--r--crates/ra_analysis/src/hir/module/mod.rs2
-rw-r--r--crates/ra_analysis/src/hir/module/nameres.rs5
-rw-r--r--crates/ra_analysis/src/hir/query_definitions.rs2
-rw-r--r--crates/ra_analysis/src/imp.rs101
-rw-r--r--crates/ra_analysis/src/lib.rs22
-rw-r--r--crates/ra_analysis/src/loc2id.rs102
-rw-r--r--crates/ra_analysis/src/symbol_index.rs3
-rw-r--r--crates/ra_analysis/tests/tests.rs2
-rw-r--r--crates/ra_db/Cargo.toml16
-rw-r--r--crates/ra_db/src/file_resolver.rs76
-rw-r--r--crates/ra_db/src/input.rs (renamed from crates/ra_analysis/src/input.rs)34
-rw-r--r--crates/ra_db/src/lib.rs69
-rw-r--r--crates/ra_db/src/loc2id.rs100
-rw-r--r--crates/ra_db/src/syntax_ptr.rs (renamed from crates/ra_analysis/src/syntax_ptr.rs)8
-rw-r--r--crates/ra_lsp_server/src/server_world.rs2
22 files changed, 352 insertions, 293 deletions
diff --git a/Cargo.lock b/Cargo.lock
index b4d466fb6..5113317b0 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -607,6 +607,7 @@ dependencies = [
607 "id-arena 1.0.2 (git+https://github.com/fitzgen/id-arena/?rev=43ecd67)", 607 "id-arena 1.0.2 (git+https://github.com/fitzgen/id-arena/?rev=43ecd67)",
608 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 608 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
609 "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", 609 "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
610 "ra_db 0.1.0",
610 "ra_editor 0.1.0", 611 "ra_editor 0.1.0",
611 "ra_syntax 0.1.0", 612 "ra_syntax 0.1.0",
612 "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 613 "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -629,6 +630,21 @@ dependencies = [
629] 630]
630 631
631[[package]] 632[[package]]
633name = "ra_db"
634version = "0.1.0"
635dependencies = [
636 "id-arena 1.0.2 (git+https://github.com/fitzgen/id-arena/?rev=43ecd67)",
637 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
638 "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
639 "ra_editor 0.1.0",
640 "ra_syntax 0.1.0",
641 "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
642 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
643 "salsa 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
644 "test_utils 0.1.0",
645]
646
647[[package]]
632name = "ra_editor" 648name = "ra_editor"
633version = "0.1.0" 649version = "0.1.0"
634dependencies = [ 650dependencies = [
diff --git a/crates/ra_analysis/Cargo.toml b/crates/ra_analysis/Cargo.toml
index 5dae45857..48d8e56e3 100644
--- a/crates/ra_analysis/Cargo.toml
+++ b/crates/ra_analysis/Cargo.toml
@@ -15,4 +15,5 @@ parking_lot = "0.6.4"
15id-arena = { git = "https://github.com/fitzgen/id-arena/", rev = "43ecd67" } 15id-arena = { git = "https://github.com/fitzgen/id-arena/", rev = "43ecd67" }
16ra_syntax = { path = "../ra_syntax" } 16ra_syntax = { path = "../ra_syntax" }
17ra_editor = { path = "../ra_editor" } 17ra_editor = { path = "../ra_editor" }
18ra_db = { path = "../ra_db" }
18test_utils = { path = "../test_utils" } 19test_utils = { path = "../test_utils" }
diff --git a/crates/ra_analysis/src/completion/mod.rs b/crates/ra_analysis/src/completion/mod.rs
index 844dabb19..538b51633 100644
--- a/crates/ra_analysis/src/completion/mod.rs
+++ b/crates/ra_analysis/src/completion/mod.rs
@@ -7,10 +7,11 @@ use ra_syntax::{
7 AstNode, AtomEdit, 7 AstNode, AtomEdit,
8 SyntaxNodeRef, 8 SyntaxNodeRef,
9}; 9};
10use ra_db::SyntaxDatabase;
10use rustc_hash::{FxHashMap}; 11use rustc_hash::{FxHashMap};
11 12
12use crate::{ 13use crate::{
13 db::{self, SyntaxDatabase}, 14 db,
14 hir, 15 hir,
15 Cancelable, FilePosition 16 Cancelable, FilePosition
16}; 17};
diff --git a/crates/ra_analysis/src/db.rs b/crates/ra_analysis/src/db.rs
index e0b7afac5..1b2dd4b3d 100644
--- a/crates/ra_analysis/src/db.rs
+++ b/crates/ra_analysis/src/db.rs
@@ -1,15 +1,13 @@
1use std::sync::Arc; 1use std::sync::Arc;
2#[cfg(test)] 2#[cfg(test)]
3use parking_lot::Mutex; 3use parking_lot::Mutex;
4use ra_editor::LineIndex;
5use ra_syntax::{SourceFileNode};
6use salsa::{self, Database}; 4use salsa::{self, Database};
5use ra_db::{LocationIntener, BaseDatabase};
7 6
8use crate::{ 7use crate::{
9 hir, 8 hir,
10 symbol_index, 9 symbol_index,
11 loc2id::{IdMaps, LocationIntener, DefId, DefLoc, FnId}, 10 loc2id::{IdMaps, DefId, DefLoc, FnId},
12 Cancelable, Canceled, FileId,
13}; 11};
14 12
15#[derive(Debug)] 13#[derive(Debug)]
@@ -47,11 +45,11 @@ impl Default for RootDatabase {
47 runtime: salsa::Runtime::default(), 45 runtime: salsa::Runtime::default(),
48 id_maps: Default::default(), 46 id_maps: Default::default(),
49 }; 47 };
50 db.query_mut(crate::input::SourceRootQuery) 48 db.query_mut(ra_db::SourceRootQuery)
51 .set(crate::input::WORKSPACE, Default::default()); 49 .set(ra_db::WORKSPACE, Default::default());
52 db.query_mut(crate::input::CrateGraphQuery) 50 db.query_mut(ra_db::CrateGraphQuery)
53 .set((), Default::default()); 51 .set((), Default::default());
54 db.query_mut(crate::input::LibrariesQuery) 52 db.query_mut(ra_db::LibrariesQuery)
55 .set((), Default::default()); 53 .set((), Default::default());
56 db 54 db
57 } 55 }
@@ -67,22 +65,7 @@ impl salsa::ParallelDatabase for RootDatabase {
67 } 65 }
68} 66}
69 67
70pub(crate) trait BaseDatabase: salsa::Database { 68impl BaseDatabase for RootDatabase {}
71 fn id_maps(&self) -> &IdMaps;
72 fn check_canceled(&self) -> Cancelable<()> {
73 if self.salsa_runtime().is_current_revision_canceled() {
74 Err(Canceled)
75 } else {
76 Ok(())
77 }
78 }
79}
80
81impl BaseDatabase for RootDatabase {
82 fn id_maps(&self) -> &IdMaps {
83 &self.id_maps
84 }
85}
86 69
87impl AsRef<LocationIntener<DefLoc, DefId>> for RootDatabase { 70impl AsRef<LocationIntener<DefLoc, DefId>> for RootDatabase {
88 fn as_ref(&self) -> &LocationIntener<DefLoc, DefId> { 71 fn as_ref(&self) -> &LocationIntener<DefLoc, DefId> {
@@ -121,16 +104,16 @@ impl RootDatabase {
121 104
122salsa::database_storage! { 105salsa::database_storage! {
123 pub(crate) struct RootDatabaseStorage for RootDatabase { 106 pub(crate) struct RootDatabaseStorage for RootDatabase {
124 impl crate::input::FilesDatabase { 107 impl ra_db::FilesDatabase {
125 fn file_text() for crate::input::FileTextQuery; 108 fn file_text() for ra_db::FileTextQuery;
126 fn file_source_root() for crate::input::FileSourceRootQuery; 109 fn file_source_root() for ra_db::FileSourceRootQuery;
127 fn source_root() for crate::input::SourceRootQuery; 110 fn source_root() for ra_db::SourceRootQuery;
128 fn libraries() for crate::input::LibrariesQuery; 111 fn libraries() for ra_db::LibrariesQuery;
129 fn crate_graph() for crate::input::CrateGraphQuery; 112 fn crate_graph() for ra_db::CrateGraphQuery;
130 } 113 }
131 impl SyntaxDatabase { 114 impl ra_db::SyntaxDatabase {
132 fn source_file() for SourceFileQuery; 115 fn source_file() for ra_db::SourceFileQuery;
133 fn file_lines() for FileLinesQuery; 116 fn file_lines() for ra_db::FileLinesQuery;
134 } 117 }
135 impl symbol_index::SymbolsDatabase { 118 impl symbol_index::SymbolsDatabase {
136 fn file_symbols() for symbol_index::FileSymbolsQuery; 119 fn file_symbols() for symbol_index::FileSymbolsQuery;
@@ -148,23 +131,3 @@ salsa::database_storage! {
148 } 131 }
149 } 132 }
150} 133}
151
152salsa::query_group! {
153 pub(crate) trait SyntaxDatabase: crate::input::FilesDatabase + BaseDatabase {
154 fn source_file(file_id: FileId) -> SourceFileNode {
155 type SourceFileQuery;
156 }
157 fn file_lines(file_id: FileId) -> Arc<LineIndex> {
158 type FileLinesQuery;
159 }
160 }
161}
162
163fn source_file(db: &impl SyntaxDatabase, file_id: FileId) -> SourceFileNode {
164 let text = db.file_text(file_id);
165 SourceFileNode::parse(&*text)
166}
167fn file_lines(db: &impl SyntaxDatabase, file_id: FileId) -> Arc<LineIndex> {
168 let text = db.file_text(file_id);
169 Arc::new(LineIndex::new(&*text))
170}
diff --git a/crates/ra_analysis/src/hir/db.rs b/crates/ra_analysis/src/hir/db.rs
index bf0dc393a..0ae2086ff 100644
--- a/crates/ra_analysis/src/hir/db.rs
+++ b/crates/ra_analysis/src/hir/db.rs
@@ -4,10 +4,10 @@ use ra_syntax::{
4 SyntaxNode, 4 SyntaxNode,
5 ast::FnDefNode, 5 ast::FnDefNode,
6}; 6};
7use ra_db::{SourceRootId, LocationIntener, SyntaxDatabase};
7 8
8use crate::{ 9use crate::{
9 FileId, 10 FileId,
10 db::SyntaxDatabase,
11 hir::{ 11 hir::{
12 SourceFileItems, SourceItemId, 12 SourceFileItems, SourceItemId,
13 query_definitions, 13 query_definitions,
@@ -15,8 +15,7 @@ use crate::{
15 module::{ModuleId, ModuleTree, ModuleSource, 15 module::{ModuleId, ModuleTree, ModuleSource,
16 nameres::{ItemMap, InputModuleItems}}, 16 nameres::{ItemMap, InputModuleItems}},
17 }, 17 },
18 input::SourceRootId, 18 loc2id::{DefLoc, DefId, FnId},
19 loc2id::{DefLoc, DefId, FnId, LocationIntener},
20 Cancelable, 19 Cancelable,
21}; 20};
22 21
diff --git a/crates/ra_analysis/src/hir/function/scope.rs b/crates/ra_analysis/src/hir/function/scope.rs
index 76b2fea68..ed789fede 100644
--- a/crates/ra_analysis/src/hir/function/scope.rs
+++ b/crates/ra_analysis/src/hir/function/scope.rs
@@ -5,9 +5,10 @@ use ra_syntax::{
5 algo::generate, 5 algo::generate,
6 ast::{self, ArgListOwner, LoopBodyOwner, NameOwner}, 6 ast::{self, ArgListOwner, LoopBodyOwner, NameOwner},
7}; 7};
8use ra_db::LocalSyntaxPtr;
8 9
9use crate::{ 10use crate::{
10 syntax_ptr::LocalSyntaxPtr, 11
11 arena::{Arena, Id}, 12 arena::{Arena, Id},
12}; 13};
13 14
diff --git a/crates/ra_analysis/src/hir/module/imp.rs b/crates/ra_analysis/src/hir/module/imp.rs
index d51ca2d59..c8f7ed58d 100644
--- a/crates/ra_analysis/src/hir/module/imp.rs
+++ b/crates/ra_analysis/src/hir/module/imp.rs
@@ -6,11 +6,11 @@ use ra_syntax::{
6}; 6};
7use relative_path::RelativePathBuf; 7use relative_path::RelativePathBuf;
8use rustc_hash::{FxHashMap, FxHashSet}; 8use rustc_hash::{FxHashMap, FxHashSet};
9use ra_db::{SourceRoot, SourceRootId, FileResolverImp};
9 10
10use crate::{ 11use crate::{
11 hir::HirDatabase, 12 hir::HirDatabase,
12 input::{SourceRoot, SourceRootId}, 13 Cancelable, FileId,
13 Cancelable, FileId, FileResolverImp,
14}; 14};
15 15
16use super::{ 16use super::{
diff --git a/crates/ra_analysis/src/hir/module/mod.rs b/crates/ra_analysis/src/hir/module/mod.rs
index 893ec3a10..683cb5d4c 100644
--- a/crates/ra_analysis/src/hir/module/mod.rs
+++ b/crates/ra_analysis/src/hir/module/mod.rs
@@ -10,12 +10,12 @@ use ra_syntax::{
10 ast::{self, AstNode, NameOwner}, 10 ast::{self, AstNode, NameOwner},
11 SmolStr, SyntaxNode, 11 SmolStr, SyntaxNode,
12}; 12};
13use ra_db::SourceRootId;
13use relative_path::RelativePathBuf; 14use relative_path::RelativePathBuf;
14 15
15use crate::{ 16use crate::{
16 FileId, FilePosition, Cancelable, 17 FileId, FilePosition, Cancelable,
17 hir::{Path, PathKind, HirDatabase, SourceItemId}, 18 hir::{Path, PathKind, HirDatabase, SourceItemId},
18 input::SourceRootId,
19 arena::{Arena, Id}, 19 arena::{Arena, Id},
20 loc2id::{DefLoc, DefId}, 20 loc2id::{DefLoc, DefId},
21}; 21};
diff --git a/crates/ra_analysis/src/hir/module/nameres.rs b/crates/ra_analysis/src/hir/module/nameres.rs
index f48f51c8d..5c87e7af2 100644
--- a/crates/ra_analysis/src/hir/module/nameres.rs
+++ b/crates/ra_analysis/src/hir/module/nameres.rs
@@ -19,12 +19,12 @@ use std::{
19}; 19};
20 20
21use rustc_hash::FxHashMap; 21use rustc_hash::FxHashMap;
22
23use ra_syntax::{ 22use ra_syntax::{
24 TextRange, 23 TextRange,
25 SmolStr, SyntaxKind::{self, *}, 24 SmolStr, SyntaxKind::{self, *},
26 ast::{self, AstNode} 25 ast::{self, AstNode}
27}; 26};
27use ra_db::SourceRootId;
28 28
29use crate::{ 29use crate::{
30 Cancelable, FileId, 30 Cancelable, FileId,
@@ -35,7 +35,6 @@ use crate::{
35 HirDatabase, 35 HirDatabase,
36 module::{ModuleId, ModuleTree}, 36 module::{ModuleId, ModuleTree},
37 }, 37 },
38 input::SourceRootId,
39}; 38};
40 39
41/// Item map is the result of the name resolution. Item map contains, for each 40/// Item map is the result of the name resolution. Item map contains, for each
@@ -342,11 +341,11 @@ where
342 341
343#[cfg(test)] 342#[cfg(test)]
344mod tests { 343mod tests {
344 use ra_db::FilesDatabase;
345 use crate::{ 345 use crate::{
346 AnalysisChange, 346 AnalysisChange,
347 mock_analysis::{MockAnalysis, analysis_and_position}, 347 mock_analysis::{MockAnalysis, analysis_and_position},
348 hir::{self, HirDatabase}, 348 hir::{self, HirDatabase},
349 input::FilesDatabase,
350}; 349};
351 use super::*; 350 use super::*;
352 351
diff --git a/crates/ra_analysis/src/hir/query_definitions.rs b/crates/ra_analysis/src/hir/query_definitions.rs
index 6570ca994..fbdf8eb67 100644
--- a/crates/ra_analysis/src/hir/query_definitions.rs
+++ b/crates/ra_analysis/src/hir/query_definitions.rs
@@ -8,6 +8,7 @@ use ra_syntax::{
8 AstNode, SyntaxNode, SmolStr, 8 AstNode, SyntaxNode, SmolStr,
9 ast::{self, FnDef, FnDefNode, NameOwner, ModuleItemOwner} 9 ast::{self, FnDef, FnDefNode, NameOwner, ModuleItemOwner}
10}; 10};
11use ra_db::SourceRootId;
11 12
12use crate::{ 13use crate::{
13 FileId, Cancelable, 14 FileId, Cancelable,
@@ -21,7 +22,6 @@ use crate::{
21 nameres::{InputModuleItems, ItemMap, Resolver}, 22 nameres::{InputModuleItems, ItemMap, Resolver},
22 }, 23 },
23 }, 24 },
24 input::SourceRootId,
25}; 25};
26 26
27/// Resolve `FnId` to the corresponding `SyntaxNode` 27/// Resolve `FnId` to the corresponding `SyntaxNode`
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs
index c86bc111a..9a8694221 100644
--- a/crates/ra_analysis/src/imp.rs
+++ b/crates/ra_analysis/src/imp.rs
@@ -1,6 +1,5 @@
1use std::{ 1use std::{
2 fmt, 2 fmt,
3 hash::{Hash, Hasher},
4 sync::Arc, 3 sync::Arc,
5}; 4};
6 5
@@ -11,84 +10,24 @@ use ra_syntax::{
11 SyntaxKind::*, 10 SyntaxKind::*,
12 SyntaxNodeRef, TextRange, TextUnit, 11 SyntaxNodeRef, TextRange, TextUnit,
13}; 12};
13use ra_db::{FilesDatabase, SourceRoot, SourceRootId, WORKSPACE, SyntaxDatabase, SourceFileQuery};
14use rayon::prelude::*; 14use rayon::prelude::*;
15use relative_path::RelativePath;
16use rustc_hash::FxHashSet; 15use rustc_hash::FxHashSet;
17use salsa::{Database, ParallelDatabase}; 16use salsa::{Database, ParallelDatabase};
18 17
19use crate::{ 18use crate::{
20 completion::{completions, CompletionItem}, 19 completion::{completions, CompletionItem},
21 db::{self, SourceFileQuery, SyntaxDatabase}, 20 db,
22 hir::{ 21 hir::{
23 self, 22 self,
24 FnSignatureInfo, 23 FnSignatureInfo,
25 Problem, 24 Problem,
26 }, 25 },
27 input::{FilesDatabase, SourceRoot, SourceRootId, WORKSPACE},
28 symbol_index::{SymbolIndex, SymbolsDatabase}, 26 symbol_index::{SymbolIndex, SymbolsDatabase},
29 AnalysisChange, Cancelable, CrateGraph, CrateId, Diagnostic, FileId, FileResolver, 27 AnalysisChange, Cancelable, CrateId, Diagnostic, FileId,
30 FileSystemEdit, FilePosition, Query, SourceChange, SourceFileNodeEdit, 28 FileSystemEdit, FilePosition, Query, SourceChange, SourceFileNodeEdit,
31}; 29};
32 30
33#[derive(Clone, Debug)]
34pub(crate) struct FileResolverImp {
35 inner: Arc<FileResolver>,
36}
37
38impl PartialEq for FileResolverImp {
39 fn eq(&self, other: &FileResolverImp) -> bool {
40 self.inner() == other.inner()
41 }
42}
43
44impl Eq for FileResolverImp {}
45
46impl Hash for FileResolverImp {
47 fn hash<H: Hasher>(&self, hasher: &mut H) {
48 self.inner().hash(hasher);
49 }
50}
51
52impl FileResolverImp {
53 pub(crate) fn new(inner: Arc<FileResolver>) -> FileResolverImp {
54 FileResolverImp { inner }
55 }
56 pub(crate) fn file_stem(&self, file_id: FileId) -> String {
57 self.inner.file_stem(file_id)
58 }
59 pub(crate) fn resolve(&self, file_id: FileId, path: &RelativePath) -> Option<FileId> {
60 self.inner.resolve(file_id, path)
61 }
62 pub(crate) fn debug_path(&self, file_id: FileId) -> Option<std::path::PathBuf> {
63 self.inner.debug_path(file_id)
64 }
65 fn inner(&self) -> *const FileResolver {
66 &*self.inner
67 }
68}
69
70impl Default for FileResolverImp {
71 fn default() -> FileResolverImp {
72 #[derive(Debug)]
73 struct DummyResolver;
74 impl FileResolver for DummyResolver {
75 fn file_stem(&self, _file_: FileId) -> String {
76 panic!("file resolver not set")
77 }
78 fn resolve(
79 &self,
80 _file_id: FileId,
81 _path: &::relative_path::RelativePath,
82 ) -> Option<FileId> {
83 panic!("file resolver not set")
84 }
85 }
86 FileResolverImp {
87 inner: Arc::new(DummyResolver),
88 }
89 }
90}
91
92#[derive(Debug, Default)] 31#[derive(Debug, Default)]
93pub(crate) struct AnalysisHostImpl { 32pub(crate) struct AnalysisHostImpl {
94 db: db::RootDatabase, 33 db: db::RootDatabase,
@@ -105,7 +44,7 @@ impl AnalysisHostImpl {
105 44
106 for (file_id, text) in change.files_changed { 45 for (file_id, text) in change.files_changed {
107 self.db 46 self.db
108 .query_mut(crate::input::FileTextQuery) 47 .query_mut(ra_db::FileTextQuery)
109 .set(file_id, Arc::new(text)) 48 .set(file_id, Arc::new(text))
110 } 49 }
111 if !(change.files_added.is_empty() && change.files_removed.is_empty()) { 50 if !(change.files_added.is_empty() && change.files_removed.is_empty()) {
@@ -115,22 +54,22 @@ impl AnalysisHostImpl {
115 let mut source_root = SourceRoot::clone(&self.db.source_root(WORKSPACE)); 54 let mut source_root = SourceRoot::clone(&self.db.source_root(WORKSPACE));
116 for (file_id, text) in change.files_added { 55 for (file_id, text) in change.files_added {
117 self.db 56 self.db
118 .query_mut(crate::input::FileTextQuery) 57 .query_mut(ra_db::FileTextQuery)
119 .set(file_id, Arc::new(text)); 58 .set(file_id, Arc::new(text));
120 self.db 59 self.db
121 .query_mut(crate::input::FileSourceRootQuery) 60 .query_mut(ra_db::FileSourceRootQuery)
122 .set(file_id, crate::input::WORKSPACE); 61 .set(file_id, ra_db::WORKSPACE);
123 source_root.files.insert(file_id); 62 source_root.files.insert(file_id);
124 } 63 }
125 for file_id in change.files_removed { 64 for file_id in change.files_removed {
126 self.db 65 self.db
127 .query_mut(crate::input::FileTextQuery) 66 .query_mut(ra_db::FileTextQuery)
128 .set(file_id, Arc::new(String::new())); 67 .set(file_id, Arc::new(String::new()));
129 source_root.files.remove(&file_id); 68 source_root.files.remove(&file_id);
130 } 69 }
131 source_root.file_resolver = file_resolver; 70 source_root.file_resolver = file_resolver;
132 self.db 71 self.db
133 .query_mut(crate::input::SourceRootQuery) 72 .query_mut(ra_db::SourceRootQuery)
134 .set(WORKSPACE, Arc::new(source_root)) 73 .set(WORKSPACE, Arc::new(source_root))
135 } 74 }
136 if !change.libraries_added.is_empty() { 75 if !change.libraries_added.is_empty() {
@@ -147,10 +86,10 @@ impl AnalysisHostImpl {
147 library.file_resolver.debug_path(file_id) 86 library.file_resolver.debug_path(file_id)
148 ); 87 );
149 self.db 88 self.db
150 .query_mut(crate::input::FileSourceRootQuery) 89 .query_mut(ra_db::FileSourceRootQuery)
151 .set_constant(file_id, source_root_id); 90 .set_constant(file_id, source_root_id);
152 self.db 91 self.db
153 .query_mut(crate::input::FileTextQuery) 92 .query_mut(ra_db::FileTextQuery)
154 .set_constant(file_id, Arc::new(text)); 93 .set_constant(file_id, Arc::new(text));
155 } 94 }
156 let source_root = SourceRoot { 95 let source_root = SourceRoot {
@@ -158,19 +97,19 @@ impl AnalysisHostImpl {
158 file_resolver: library.file_resolver, 97 file_resolver: library.file_resolver,
159 }; 98 };
160 self.db 99 self.db
161 .query_mut(crate::input::SourceRootQuery) 100 .query_mut(ra_db::SourceRootQuery)
162 .set(source_root_id, Arc::new(source_root)); 101 .set(source_root_id, Arc::new(source_root));
163 self.db 102 self.db
164 .query_mut(crate::symbol_index::LibrarySymbolsQuery) 103 .query_mut(crate::symbol_index::LibrarySymbolsQuery)
165 .set(source_root_id, Arc::new(library.symbol_index)); 104 .set(source_root_id, Arc::new(library.symbol_index));
166 } 105 }
167 self.db 106 self.db
168 .query_mut(crate::input::LibrariesQuery) 107 .query_mut(ra_db::LibrariesQuery)
169 .set((), Arc::new(libraries)); 108 .set((), Arc::new(libraries));
170 } 109 }
171 if let Some(crate_graph) = change.crate_graph { 110 if let Some(crate_graph) = change.crate_graph {
172 self.db 111 self.db
173 .query_mut(crate::input::CrateGraphQuery) 112 .query_mut(ra_db::CrateGraphQuery)
174 .set((), Arc::new(crate_graph)) 113 .set((), Arc::new(crate_graph))
175 } 114 }
176 } 115 }
@@ -261,7 +200,7 @@ impl AnalysisImpl {
261 Ok(crate_id.into_iter().collect()) 200 Ok(crate_id.into_iter().collect())
262 } 201 }
263 pub fn crate_root(&self, crate_id: CrateId) -> FileId { 202 pub fn crate_root(&self, crate_id: CrateId) -> FileId {
264 self.db.crate_graph().crate_roots[&crate_id] 203 self.db.crate_graph().crate_root(crate_id)
265 } 204 }
266 pub fn completions(&self, position: FilePosition) -> Cancelable<Option<Vec<CompletionItem>>> { 205 pub fn completions(&self, position: FilePosition) -> Cancelable<Option<Vec<CompletionItem>>> {
267 completions(&self.db, position) 206 completions(&self.db, position)
@@ -546,16 +485,6 @@ impl SourceChange {
546 } 485 }
547} 486}
548 487
549impl CrateGraph {
550 fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> {
551 let (&crate_id, _) = self
552 .crate_roots
553 .iter()
554 .find(|(_crate_id, &root_id)| root_id == file_id)?;
555 Some(crate_id)
556 }
557}
558
559enum FnCallNode<'a> { 488enum FnCallNode<'a> {
560 CallExpr(ast::CallExpr<'a>), 489 CallExpr(ast::CallExpr<'a>),
561 MethodCallExpr(ast::MethodCallExpr<'a>), 490 MethodCallExpr(ast::MethodCallExpr<'a>),
diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs
index c0e43544e..012d36b8e 100644
--- a/crates/ra_analysis/src/lib.rs
+++ b/crates/ra_analysis/src/lib.rs
@@ -19,8 +19,6 @@ macro_rules! ctry {
19} 19}
20 20
21mod arena; 21mod arena;
22mod syntax_ptr;
23mod input;
24mod db; 22mod db;
25mod loc2id; 23mod loc2id;
26mod imp; 24mod imp;
@@ -32,35 +30,27 @@ pub mod mock_analysis;
32use std::{fmt, sync::Arc}; 30use std::{fmt, sync::Arc};
33 31
34use ra_syntax::{AtomEdit, SourceFileNode, TextRange, TextUnit}; 32use ra_syntax::{AtomEdit, SourceFileNode, TextRange, TextUnit};
33use ra_db::FileResolverImp;
35use rayon::prelude::*; 34use rayon::prelude::*;
36use relative_path::RelativePathBuf; 35use relative_path::RelativePathBuf;
37 36
38use crate::{ 37use crate::{
39 imp::{AnalysisHostImpl, AnalysisImpl, FileResolverImp}, 38 imp::{AnalysisHostImpl, AnalysisImpl},
40 symbol_index::SymbolIndex, 39 symbol_index::SymbolIndex,
41}; 40};
42 41
43pub use crate::{ 42pub use crate::{
44 completion::CompletionItem, 43 completion::CompletionItem,
45 hir::FnSignatureInfo, 44 hir::FnSignatureInfo,
46 input::{CrateGraph, CrateId, FileId, FileResolver},
47}; 45};
48pub use ra_editor::{ 46pub use ra_editor::{
49 FileSymbol, Fold, FoldKind, HighlightedRange, LineIndex, Runnable, RunnableKind, StructureNode, 47 FileSymbol, Fold, FoldKind, HighlightedRange, LineIndex, Runnable, RunnableKind, StructureNode,
50}; 48};
51 49
52#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] 50pub use ra_db::{
53pub struct Canceled; 51 Canceled, Cancelable,
54 52 CrateGraph, CrateId, FileId, FileResolver
55pub type Cancelable<T> = Result<T, Canceled>; 53};
56
57impl std::fmt::Display for Canceled {
58 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59 fmt.write_str("Canceled")
60 }
61}
62
63impl std::error::Error for Canceled {}
64 54
65#[derive(Default)] 55#[derive(Default)]
66pub struct AnalysisChange { 56pub struct AnalysisChange {
diff --git a/crates/ra_analysis/src/loc2id.rs b/crates/ra_analysis/src/loc2id.rs
index 2aa141130..7956431ab 100644
--- a/crates/ra_analysis/src/loc2id.rs
+++ b/crates/ra_analysis/src/loc2id.rs
@@ -1,74 +1,10 @@
1use parking_lot::Mutex; 1use ra_db::SourceRootId;
2
3use std::hash::Hash;
4
5use rustc_hash::FxHashMap;
6 2
7use crate::{ 3use crate::{
8 hir::{SourceItemId, ModuleId}, 4 hir::{SourceItemId, ModuleId},
9 input::SourceRootId,
10}; 5};
11 6
12/// There are two principle ways to refer to things: 7use ra_db::{NumericId, LocationIntener};
13/// - by their locatinon (module in foo/bar/baz.rs at line 42)
14/// - by their numeric id (module `ModuleId(42)`)
15///
16/// The first one is more powerful (you can actually find the thing in question
17/// by id), but the second one is so much more compact.
18///
19/// `Loc2IdMap` allows us to have a cake an eat it as well: by maintaining a
20/// bidirectional mapping between positional and numeric ids, we can use compact
21/// representation wich still allows us to get the actual item
22#[derive(Debug)]
23struct Loc2IdMap<LOC, ID>
24where
25 ID: NumericId,
26 LOC: Clone + Eq + Hash,
27{
28 loc2id: FxHashMap<LOC, ID>,
29 id2loc: FxHashMap<ID, LOC>,
30}
31
32impl<LOC, ID> Default for Loc2IdMap<LOC, ID>
33where
34 ID: NumericId,
35 LOC: Clone + Eq + Hash,
36{
37 fn default() -> Self {
38 Loc2IdMap {
39 loc2id: FxHashMap::default(),
40 id2loc: FxHashMap::default(),
41 }
42 }
43}
44
45impl<LOC, ID> Loc2IdMap<LOC, ID>
46where
47 ID: NumericId,
48 LOC: Clone + Eq + Hash,
49{
50 pub fn loc2id(&mut self, loc: &LOC) -> ID {
51 match self.loc2id.get(loc) {
52 Some(id) => return id.clone(),
53 None => (),
54 }
55 let id = self.loc2id.len();
56 assert!(id < u32::max_value() as usize);
57 let id = ID::from_u32(id as u32);
58 self.loc2id.insert(loc.clone(), id.clone());
59 self.id2loc.insert(id.clone(), loc.clone());
60 id
61 }
62
63 pub fn id2loc(&self, id: ID) -> LOC {
64 self.id2loc[&id].clone()
65 }
66}
67
68pub(crate) trait NumericId: Clone + Eq + Hash {
69 fn from_u32(id: u32) -> Self;
70 fn to_u32(self) -> u32;
71}
72 8
73macro_rules! impl_numeric_id { 9macro_rules! impl_numeric_id {
74 ($id:ident) => { 10 ($id:ident) => {
@@ -131,37 +67,3 @@ pub(crate) struct IdMaps {
131 pub(crate) fns: LocationIntener<SourceItemId, FnId>, 67 pub(crate) fns: LocationIntener<SourceItemId, FnId>,
132 pub(crate) defs: LocationIntener<DefLoc, DefId>, 68 pub(crate) defs: LocationIntener<DefLoc, DefId>,
133} 69}
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 }
153 }
154}
155
156impl<LOC, ID> LocationIntener<LOC, ID>
157where
158 ID: NumericId,
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 }
167}
diff --git a/crates/ra_analysis/src/symbol_index.rs b/crates/ra_analysis/src/symbol_index.rs
index 747b34e38..b48a37229 100644
--- a/crates/ra_analysis/src/symbol_index.rs
+++ b/crates/ra_analysis/src/symbol_index.rs
@@ -9,13 +9,12 @@ use ra_syntax::{
9 SourceFileNode, 9 SourceFileNode,
10 SyntaxKind::{self, *}, 10 SyntaxKind::{self, *},
11}; 11};
12use ra_db::{SyntaxDatabase, SourceRootId};
12use rayon::prelude::*; 13use rayon::prelude::*;
13 14
14use crate::{ 15use crate::{
15 Cancelable, 16 Cancelable,
16 FileId, Query, 17 FileId, Query,
17 db::SyntaxDatabase,
18 input::SourceRootId,
19}; 18};
20 19
21salsa::query_group! { 20salsa::query_group! {
diff --git a/crates/ra_analysis/tests/tests.rs b/crates/ra_analysis/tests/tests.rs
index 8e7856027..fbe89f444 100644
--- a/crates/ra_analysis/tests/tests.rs
+++ b/crates/ra_analysis/tests/tests.rs
@@ -126,7 +126,7 @@ fn test_resolve_crate_root() {
126 let mut host = mock.analysis_host(); 126 let mut host = mock.analysis_host();
127 assert!(host.analysis().crate_for(mod_file).unwrap().is_empty()); 127 assert!(host.analysis().crate_for(mod_file).unwrap().is_empty());
128 128
129 let mut crate_graph = CrateGraph::new(); 129 let mut crate_graph = CrateGraph::default();
130 let crate_id = crate_graph.add_crate_root(root_file); 130 let crate_id = crate_graph.add_crate_root(root_file);
131 let mut change = AnalysisChange::new(); 131 let mut change = AnalysisChange::new();
132 change.set_crate_graph(crate_graph); 132 change.set_crate_graph(crate_graph);
diff --git a/crates/ra_db/Cargo.toml b/crates/ra_db/Cargo.toml
new file mode 100644
index 000000000..3bf2f635e
--- /dev/null
+++ b/crates/ra_db/Cargo.toml
@@ -0,0 +1,16 @@
1[package]
2edition = "2018"
3name = "ra_db"
4version = "0.1.0"
5authors = ["Aleksey Kladov <[email protected]>"]
6
7[dependencies]
8log = "0.4.5"
9relative-path = "0.4.0"
10salsa = "0.8.0"
11rustc-hash = "1.0"
12parking_lot = "0.6.4"
13id-arena = { git = "https://github.com/fitzgen/id-arena/", rev = "43ecd67" }
14ra_syntax = { path = "../ra_syntax" }
15ra_editor = { path = "../ra_editor" }
16test_utils = { path = "../test_utils" }
diff --git a/crates/ra_db/src/file_resolver.rs b/crates/ra_db/src/file_resolver.rs
new file mode 100644
index 000000000..f849ac752
--- /dev/null
+++ b/crates/ra_db/src/file_resolver.rs
@@ -0,0 +1,76 @@
1use std::{
2 sync::Arc,
3 hash::{Hash, Hasher},
4 fmt,
5};
6
7use relative_path::RelativePath;
8
9use crate::input::FileId;
10
11pub trait FileResolver: fmt::Debug + Send + Sync + 'static {
12 fn file_stem(&self, file_id: FileId) -> String;
13 fn resolve(&self, file_id: FileId, path: &RelativePath) -> Option<FileId>;
14 fn debug_path(&self, _1file_id: FileId) -> Option<std::path::PathBuf> {
15 None
16 }
17}
18
19#[derive(Clone, Debug)]
20pub struct FileResolverImp {
21 inner: Arc<FileResolver>,
22}
23
24impl PartialEq for FileResolverImp {
25 fn eq(&self, other: &FileResolverImp) -> bool {
26 self.inner() == other.inner()
27 }
28}
29
30impl Eq for FileResolverImp {}
31
32impl Hash for FileResolverImp {
33 fn hash<H: Hasher>(&self, hasher: &mut H) {
34 self.inner().hash(hasher);
35 }
36}
37
38impl FileResolverImp {
39 pub fn new(inner: Arc<FileResolver>) -> FileResolverImp {
40 FileResolverImp { inner }
41 }
42 pub fn file_stem(&self, file_id: FileId) -> String {
43 self.inner.file_stem(file_id)
44 }
45 pub fn resolve(&self, file_id: FileId, path: &RelativePath) -> Option<FileId> {
46 self.inner.resolve(file_id, path)
47 }
48 pub fn debug_path(&self, file_id: FileId) -> Option<std::path::PathBuf> {
49 self.inner.debug_path(file_id)
50 }
51 fn inner(&self) -> *const FileResolver {
52 &*self.inner
53 }
54}
55
56impl Default for FileResolverImp {
57 fn default() -> FileResolverImp {
58 #[derive(Debug)]
59 struct DummyResolver;
60 impl FileResolver for DummyResolver {
61 fn file_stem(&self, _file_: FileId) -> String {
62 panic!("file resolver not set")
63 }
64 fn resolve(
65 &self,
66 _file_id: FileId,
67 _path: &::relative_path::RelativePath,
68 ) -> Option<FileId> {
69 panic!("file resolver not set")
70 }
71 }
72 FileResolverImp {
73 inner: Arc::new(DummyResolver),
74 }
75 }
76}
diff --git a/crates/ra_analysis/src/input.rs b/crates/ra_db/src/input.rs
index e601cd58a..9101ac7a8 100644
--- a/crates/ra_analysis/src/input.rs
+++ b/crates/ra_db/src/input.rs
@@ -1,11 +1,10 @@
1use std::{fmt, sync::Arc}; 1use std::sync::Arc;
2 2
3use relative_path::RelativePath;
4use rustc_hash::FxHashMap; 3use rustc_hash::FxHashMap;
5use rustc_hash::FxHashSet; 4use rustc_hash::FxHashSet;
6use salsa; 5use salsa;
7 6
8use crate::FileResolverImp; 7use crate::file_resolver::FileResolverImp;
9 8
10#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] 9#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
11pub struct FileId(pub u32); 10pub struct FileId(pub u32);
@@ -19,8 +18,8 @@ pub struct CrateGraph {
19} 18}
20 19
21impl CrateGraph { 20impl CrateGraph {
22 pub fn new() -> CrateGraph { 21 pub fn crate_root(&self, crate_id: CrateId) -> FileId {
23 CrateGraph::default() 22 self.crate_roots[&crate_id]
24 } 23 }
25 pub fn add_crate_root(&mut self, file_id: FileId) -> CrateId { 24 pub fn add_crate_root(&mut self, file_id: FileId) -> CrateId {
26 let crate_id = CrateId(self.crate_roots.len() as u32); 25 let crate_id = CrateId(self.crate_roots.len() as u32);
@@ -28,18 +27,17 @@ impl CrateGraph {
28 assert!(prev.is_none()); 27 assert!(prev.is_none());
29 crate_id 28 crate_id
30 } 29 }
31} 30 pub fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> {
32 31 let (&crate_id, _) = self
33pub trait FileResolver: fmt::Debug + Send + Sync + 'static { 32 .crate_roots
34 fn file_stem(&self, file_id: FileId) -> String; 33 .iter()
35 fn resolve(&self, file_id: FileId, path: &RelativePath) -> Option<FileId>; 34 .find(|(_crate_id, &root_id)| root_id == file_id)?;
36 fn debug_path(&self, _1file_id: FileId) -> Option<std::path::PathBuf> { 35 Some(crate_id)
37 None
38 } 36 }
39} 37}
40 38
41salsa::query_group! { 39salsa::query_group! {
42 pub(crate) trait FilesDatabase: salsa::Database { 40 pub trait FilesDatabase: salsa::Database {
43 fn file_text(file_id: FileId) -> Arc<String> { 41 fn file_text(file_id: FileId) -> Arc<String> {
44 type FileTextQuery; 42 type FileTextQuery;
45 storage input; 43 storage input;
@@ -64,12 +62,12 @@ salsa::query_group! {
64} 62}
65 63
66#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] 64#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
67pub(crate) struct SourceRootId(pub(crate) u32); 65pub struct SourceRootId(pub u32);
68 66
69#[derive(Default, Clone, Debug, PartialEq, Eq)] 67#[derive(Default, Clone, Debug, PartialEq, Eq)]
70pub(crate) struct SourceRoot { 68pub struct SourceRoot {
71 pub(crate) file_resolver: FileResolverImp, 69 pub file_resolver: FileResolverImp,
72 pub(crate) files: FxHashSet<FileId>, 70 pub files: FxHashSet<FileId>,
73} 71}
74 72
75pub(crate) const WORKSPACE: SourceRootId = SourceRootId(0); 73pub const WORKSPACE: SourceRootId = SourceRootId(0);
diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs
new file mode 100644
index 000000000..833f95eeb
--- /dev/null
+++ b/crates/ra_db/src/lib.rs
@@ -0,0 +1,69 @@
1//! ra_db defines basic database traits. Concrete DB is defined by ra_analysis.
2
3extern crate ra_editor;
4extern crate ra_syntax;
5extern crate relative_path;
6extern crate rustc_hash;
7extern crate salsa;
8
9mod syntax_ptr;
10mod file_resolver;
11mod input;
12mod loc2id;
13
14use std::sync::Arc;
15use ra_editor::LineIndex;
16use ra_syntax::SourceFileNode;
17
18#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
19pub struct Canceled;
20
21pub type Cancelable<T> = Result<T, Canceled>;
22
23impl std::fmt::Display for Canceled {
24 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25 fmt.write_str("Canceled")
26 }
27}
28
29impl std::error::Error for Canceled {}
30
31pub use crate::{
32 syntax_ptr::LocalSyntaxPtr,
33 file_resolver::{FileResolver, FileResolverImp},
34 input::{
35 FilesDatabase, FileId, CrateId, SourceRoot, SourceRootId, CrateGraph, WORKSPACE,
36 FileTextQuery, FileSourceRootQuery, SourceRootQuery, LibrariesQuery, CrateGraphQuery,
37 },
38 loc2id::{LocationIntener, NumericId},
39};
40
41pub trait BaseDatabase: salsa::Database {
42 fn check_canceled(&self) -> Cancelable<()> {
43 if self.salsa_runtime().is_current_revision_canceled() {
44 Err(Canceled)
45 } else {
46 Ok(())
47 }
48 }
49}
50
51salsa::query_group! {
52 pub trait SyntaxDatabase: crate::input::FilesDatabase + BaseDatabase {
53 fn source_file(file_id: FileId) -> SourceFileNode {
54 type SourceFileQuery;
55 }
56 fn file_lines(file_id: FileId) -> Arc<LineIndex> {
57 type FileLinesQuery;
58 }
59 }
60}
61
62fn source_file(db: &impl SyntaxDatabase, file_id: FileId) -> SourceFileNode {
63 let text = db.file_text(file_id);
64 SourceFileNode::parse(&*text)
65}
66fn file_lines(db: &impl SyntaxDatabase, file_id: FileId) -> Arc<LineIndex> {
67 let text = db.file_text(file_id);
68 Arc::new(LineIndex::new(&*text))
69}
diff --git a/crates/ra_db/src/loc2id.rs b/crates/ra_db/src/loc2id.rs
new file mode 100644
index 000000000..69ba43d0f
--- /dev/null
+++ b/crates/ra_db/src/loc2id.rs
@@ -0,0 +1,100 @@
1use parking_lot::Mutex;
2
3use std::hash::Hash;
4
5use rustc_hash::FxHashMap;
6
7/// There are two principle ways to refer to things:
8/// - by their locatinon (module in foo/bar/baz.rs at line 42)
9/// - by their numeric id (module `ModuleId(42)`)
10///
11/// The first one is more powerful (you can actually find the thing in question
12/// by id), but the second one is so much more compact.
13///
14/// `Loc2IdMap` allows us to have a cake an eat it as well: by maintaining a
15/// bidirectional mapping between positional and numeric ids, we can use compact
16/// representation wich still allows us to get the actual item
17#[derive(Debug)]
18struct Loc2IdMap<LOC, ID>
19where
20 ID: NumericId,
21 LOC: Clone + Eq + Hash,
22{
23 loc2id: FxHashMap<LOC, ID>,
24 id2loc: FxHashMap<ID, LOC>,
25}
26
27impl<LOC, ID> Default for Loc2IdMap<LOC, ID>
28where
29 ID: NumericId,
30 LOC: Clone + Eq + Hash,
31{
32 fn default() -> Self {
33 Loc2IdMap {
34 loc2id: FxHashMap::default(),
35 id2loc: FxHashMap::default(),
36 }
37 }
38}
39
40impl<LOC, ID> Loc2IdMap<LOC, ID>
41where
42 ID: NumericId,
43 LOC: Clone + Eq + Hash,
44{
45 pub fn loc2id(&mut self, loc: &LOC) -> ID {
46 match self.loc2id.get(loc) {
47 Some(id) => return id.clone(),
48 None => (),
49 }
50 let id = self.loc2id.len();
51 assert!(id < u32::max_value() as usize);
52 let id = ID::from_u32(id as u32);
53 self.loc2id.insert(loc.clone(), id.clone());
54 self.id2loc.insert(id.clone(), loc.clone());
55 id
56 }
57
58 pub fn id2loc(&self, id: ID) -> LOC {
59 self.id2loc[&id].clone()
60 }
61}
62
63pub trait NumericId: Clone + Eq + Hash {
64 fn from_u32(id: u32) -> Self;
65 fn to_u32(self) -> u32;
66}
67
68#[derive(Debug)]
69pub struct LocationIntener<LOC, ID>
70where
71 ID: NumericId,
72 LOC: Clone + Eq + Hash,
73{
74 map: Mutex<Loc2IdMap<LOC, ID>>,
75}
76
77impl<LOC, ID> Default for LocationIntener<LOC, ID>
78where
79 ID: NumericId,
80 LOC: Clone + Eq + Hash,
81{
82 fn default() -> Self {
83 LocationIntener {
84 map: Default::default(),
85 }
86 }
87}
88
89impl<LOC, ID> LocationIntener<LOC, ID>
90where
91 ID: NumericId,
92 LOC: Clone + Eq + Hash,
93{
94 pub fn loc2id(&self, loc: &LOC) -> ID {
95 self.map.lock().loc2id(loc)
96 }
97 pub fn id2loc(&self, id: ID) -> LOC {
98 self.map.lock().id2loc(id)
99 }
100}
diff --git a/crates/ra_analysis/src/syntax_ptr.rs b/crates/ra_db/src/syntax_ptr.rs
index f4b05fc19..dac94dd36 100644
--- a/crates/ra_analysis/src/syntax_ptr.rs
+++ b/crates/ra_db/src/syntax_ptr.rs
@@ -2,20 +2,20 @@ use ra_syntax::{SourceFileNode, SyntaxKind, SyntaxNode, SyntaxNodeRef, TextRange
2 2
3/// A pionter to a syntax node inside a file. 3/// A pionter to a syntax node inside a file.
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 4#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5pub(crate) struct LocalSyntaxPtr { 5pub struct LocalSyntaxPtr {
6 range: TextRange, 6 range: TextRange,
7 kind: SyntaxKind, 7 kind: SyntaxKind,
8} 8}
9 9
10impl LocalSyntaxPtr { 10impl LocalSyntaxPtr {
11 pub(crate) fn new(node: SyntaxNodeRef) -> LocalSyntaxPtr { 11 pub fn new(node: SyntaxNodeRef) -> LocalSyntaxPtr {
12 LocalSyntaxPtr { 12 LocalSyntaxPtr {
13 range: node.range(), 13 range: node.range(),
14 kind: node.kind(), 14 kind: node.kind(),
15 } 15 }
16 } 16 }
17 17
18 pub(crate) fn resolve(self, file: &SourceFileNode) -> SyntaxNode { 18 pub fn resolve(self, file: &SourceFileNode) -> SyntaxNode {
19 let mut curr = file.syntax(); 19 let mut curr = file.syntax();
20 loop { 20 loop {
21 if curr.range() == self.range && curr.kind() == self.kind { 21 if curr.range() == self.range && curr.kind() == self.kind {
@@ -28,7 +28,7 @@ impl LocalSyntaxPtr {
28 } 28 }
29 } 29 }
30 30
31 pub(crate) fn range(self) -> TextRange { 31 pub fn range(self) -> TextRange {
32 self.range 32 self.range
33 } 33 }
34} 34}
diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/server_world.rs
index 3e7670fcc..12faeb93a 100644
--- a/crates/ra_lsp_server/src/server_world.rs
+++ b/crates/ra_lsp_server/src/server_world.rs
@@ -140,7 +140,7 @@ impl ServerWorldState {
140 Ok(file_id) 140 Ok(file_id)
141 } 141 }
142 pub fn set_workspaces(&mut self, ws: Vec<CargoWorkspace>) { 142 pub fn set_workspaces(&mut self, ws: Vec<CargoWorkspace>) {
143 let mut crate_graph = CrateGraph::new(); 143 let mut crate_graph = CrateGraph::default();
144 ws.iter() 144 ws.iter()
145 .flat_map(|ws| { 145 .flat_map(|ws| {
146 ws.packages() 146 ws.packages()