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