aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis/src/db
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_analysis/src/db')
-rw-r--r--crates/ra_analysis/src/db/input.rs83
-rw-r--r--crates/ra_analysis/src/db/mod.rs107
2 files changed, 190 insertions, 0 deletions
diff --git a/crates/ra_analysis/src/db/input.rs b/crates/ra_analysis/src/db/input.rs
new file mode 100644
index 000000000..957d082f9
--- /dev/null
+++ b/crates/ra_analysis/src/db/input.rs
@@ -0,0 +1,83 @@
1use std::{
2 sync::Arc,
3 hash::{Hasher, Hash},
4};
5
6use salsa;
7use rustc_hash::FxHashSet;
8
9use crate::{FileId, FileResolverImp, CrateGraph, symbol_index::SymbolIndex};
10
11salsa::query_group! {
12 pub(crate) trait FilesDatabase: salsa::Database {
13 fn file_text(file_id: FileId) -> Arc<String> {
14 type FileTextQuery;
15 storage input;
16 }
17 fn file_source_root(file_id: FileId) -> SourceRootId {
18 type FileSourceRootQuery;
19 storage input;
20 }
21 fn source_root(id: SourceRootId) -> Arc<SourceRoot> {
22 type SourceRootQuery;
23 storage input;
24 }
25 fn libraries() -> Arc<Vec<SourceRootId>> {
26 type LibrarieseQuery;
27 storage input;
28 }
29 fn library_symbols(id: SourceRootId) -> Arc<SymbolIndex> {
30 type LibrarySymbolsQuery;
31 storage input;
32 }
33 fn crate_graph() -> Arc<CrateGraph> {
34 type CrateGraphQuery;
35 storage input;
36 }
37 }
38}
39
40#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
41pub(crate) struct SourceRootId(pub(crate) u32);
42
43#[derive(Clone, Default, Debug, Eq)]
44pub(crate) struct SourceRoot {
45 pub(crate) file_resolver: FileResolverImp,
46 pub(crate) files: FxHashSet<FileId>,
47}
48
49impl PartialEq for SourceRoot {
50 fn eq(&self, other: &SourceRoot) -> bool {
51 self.file_resolver == other.file_resolver
52 }
53}
54
55impl Hash for SourceRoot {
56 fn hash<H: Hasher>(&self, hasher: &mut H) {
57 self.file_resolver.hash(hasher);
58 }
59}
60
61pub(crate) const WORKSPACE: SourceRootId = SourceRootId(0);
62
63
64#[derive(Default, Debug, Eq)]
65pub(crate) struct FileSet {
66 pub(crate) files: FxHashSet<FileId>,
67 pub(crate) resolver: FileResolverImp,
68}
69
70impl PartialEq for FileSet {
71 fn eq(&self, other: &FileSet) -> bool {
72 self.files == other.files && self.resolver == other.resolver
73 }
74}
75
76impl Hash for FileSet {
77 fn hash<H: Hasher>(&self, hasher: &mut H) {
78 let mut files = self.files.iter().cloned().collect::<Vec<_>>();
79 files.sort();
80 files.hash(hasher);
81 }
82}
83
diff --git a/crates/ra_analysis/src/db/mod.rs b/crates/ra_analysis/src/db/mod.rs
new file mode 100644
index 000000000..8387118ad
--- /dev/null
+++ b/crates/ra_analysis/src/db/mod.rs
@@ -0,0 +1,107 @@
1pub(crate) mod input;
2
3use std::{
4 fmt,
5 sync::Arc,
6};
7
8use ra_editor::LineIndex;
9use ra_syntax::File;
10use salsa;
11
12use crate::{
13 db,
14 Cancelable, Canceled,
15 descriptors::module::{SubmodulesQuery, ModuleTreeQuery, ModulesDatabase},
16 symbol_index::SymbolIndex,
17 FileId,
18};
19
20#[derive(Default)]
21pub(crate) struct RootDatabase {
22 runtime: salsa::Runtime<RootDatabase>,
23}
24
25impl fmt::Debug for RootDatabase {
26 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
27 fmt.write_str("RootDatabase { ... }")
28 }
29}
30
31impl salsa::Database for RootDatabase {
32 fn salsa_runtime(&self) -> &salsa::Runtime<RootDatabase> {
33 &self.runtime
34 }
35}
36
37pub(crate) fn check_canceled(db: &impl salsa::Database) -> Cancelable<()> {
38 if db.salsa_runtime().is_current_revision_canceled() {
39 Err(Canceled)
40 } else {
41 Ok(())
42 }
43}
44
45impl salsa::ParallelDatabase for RootDatabase {
46 fn fork(&self) -> Self {
47 RootDatabase {
48 runtime: self.runtime.fork(),
49 }
50 }
51}
52
53impl Clone for RootDatabase {
54 fn clone(&self) -> RootDatabase {
55 salsa::ParallelDatabase::fork(self)
56 }
57}
58
59salsa::database_storage! {
60 pub(crate) struct RootDatabaseStorage for RootDatabase {
61 impl input::FilesDatabase {
62 fn file_text() for input::FileTextQuery;
63 fn file_source_root() for input::FileSourceRootQuery;
64 fn source_root() for input::SourceRootQuery;
65 fn libraries() for input::LibrarieseQuery;
66 fn library_symbols() for input::LibrarySymbolsQuery;
67 fn crate_graph() for input::CrateGraphQuery;
68 }
69 impl SyntaxDatabase {
70 fn file_syntax() for FileSyntaxQuery;
71 fn file_lines() for FileLinesQuery;
72 fn file_symbols() for FileSymbolsQuery;
73 }
74 impl ModulesDatabase {
75 fn module_tree() for ModuleTreeQuery;
76 fn module_descriptor() for SubmodulesQuery;
77 }
78 }
79}
80
81salsa::query_group! {
82 pub(crate) trait SyntaxDatabase: input::FilesDatabase {
83 fn file_syntax(file_id: FileId) -> File {
84 type FileSyntaxQuery;
85 }
86 fn file_lines(file_id: FileId) -> Arc<LineIndex> {
87 type FileLinesQuery;
88 }
89 fn file_symbols(file_id: FileId) -> Cancelable<Arc<SymbolIndex>> {
90 type FileSymbolsQuery;
91 }
92 }
93}
94
95fn file_syntax(db: &impl SyntaxDatabase, file_id: FileId) -> File {
96 let text = db.file_text(file_id);
97 File::parse(&*text)
98}
99fn file_lines(db: &impl SyntaxDatabase, file_id: FileId) -> Arc<LineIndex> {
100 let text = db.file_text(file_id);
101 Arc::new(LineIndex::new(&*text))
102}
103fn file_symbols(db: &impl SyntaxDatabase, file_id: FileId) -> Cancelable<Arc<SymbolIndex>> {
104 db::check_canceled(db)?;
105 let syntax = db.file_syntax(file_id);
106 Ok(Arc::new(SymbolIndex::for_file(file_id, syntax)))
107}