diff options
Diffstat (limited to 'crates/ra_analysis/src/db')
-rw-r--r-- | crates/ra_analysis/src/db/input.rs | 83 | ||||
-rw-r--r-- | crates/ra_analysis/src/db/mod.rs | 107 |
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 @@ | |||
1 | use std::{ | ||
2 | sync::Arc, | ||
3 | hash::{Hasher, Hash}, | ||
4 | }; | ||
5 | |||
6 | use salsa; | ||
7 | use rustc_hash::FxHashSet; | ||
8 | |||
9 | use crate::{FileId, FileResolverImp, CrateGraph, symbol_index::SymbolIndex}; | ||
10 | |||
11 | salsa::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)] | ||
41 | pub(crate) struct SourceRootId(pub(crate) u32); | ||
42 | |||
43 | #[derive(Clone, Default, Debug, Eq)] | ||
44 | pub(crate) struct SourceRoot { | ||
45 | pub(crate) file_resolver: FileResolverImp, | ||
46 | pub(crate) files: FxHashSet<FileId>, | ||
47 | } | ||
48 | |||
49 | impl PartialEq for SourceRoot { | ||
50 | fn eq(&self, other: &SourceRoot) -> bool { | ||
51 | self.file_resolver == other.file_resolver | ||
52 | } | ||
53 | } | ||
54 | |||
55 | impl Hash for SourceRoot { | ||
56 | fn hash<H: Hasher>(&self, hasher: &mut H) { | ||
57 | self.file_resolver.hash(hasher); | ||
58 | } | ||
59 | } | ||
60 | |||
61 | pub(crate) const WORKSPACE: SourceRootId = SourceRootId(0); | ||
62 | |||
63 | |||
64 | #[derive(Default, Debug, Eq)] | ||
65 | pub(crate) struct FileSet { | ||
66 | pub(crate) files: FxHashSet<FileId>, | ||
67 | pub(crate) resolver: FileResolverImp, | ||
68 | } | ||
69 | |||
70 | impl PartialEq for FileSet { | ||
71 | fn eq(&self, other: &FileSet) -> bool { | ||
72 | self.files == other.files && self.resolver == other.resolver | ||
73 | } | ||
74 | } | ||
75 | |||
76 | impl 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 @@ | |||
1 | pub(crate) mod input; | ||
2 | |||
3 | use std::{ | ||
4 | fmt, | ||
5 | sync::Arc, | ||
6 | }; | ||
7 | |||
8 | use ra_editor::LineIndex; | ||
9 | use ra_syntax::File; | ||
10 | use salsa; | ||
11 | |||
12 | use crate::{ | ||
13 | db, | ||
14 | Cancelable, Canceled, | ||
15 | descriptors::module::{SubmodulesQuery, ModuleTreeQuery, ModulesDatabase}, | ||
16 | symbol_index::SymbolIndex, | ||
17 | FileId, | ||
18 | }; | ||
19 | |||
20 | #[derive(Default)] | ||
21 | pub(crate) struct RootDatabase { | ||
22 | runtime: salsa::Runtime<RootDatabase>, | ||
23 | } | ||
24 | |||
25 | impl fmt::Debug for RootDatabase { | ||
26 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||
27 | fmt.write_str("RootDatabase { ... }") | ||
28 | } | ||
29 | } | ||
30 | |||
31 | impl salsa::Database for RootDatabase { | ||
32 | fn salsa_runtime(&self) -> &salsa::Runtime<RootDatabase> { | ||
33 | &self.runtime | ||
34 | } | ||
35 | } | ||
36 | |||
37 | pub(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 | |||
45 | impl salsa::ParallelDatabase for RootDatabase { | ||
46 | fn fork(&self) -> Self { | ||
47 | RootDatabase { | ||
48 | runtime: self.runtime.fork(), | ||
49 | } | ||
50 | } | ||
51 | } | ||
52 | |||
53 | impl Clone for RootDatabase { | ||
54 | fn clone(&self) -> RootDatabase { | ||
55 | salsa::ParallelDatabase::fork(self) | ||
56 | } | ||
57 | } | ||
58 | |||
59 | salsa::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 | |||
81 | salsa::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 | |||
95 | fn file_syntax(db: &impl SyntaxDatabase, file_id: FileId) -> File { | ||
96 | let text = db.file_text(file_id); | ||
97 | File::parse(&*text) | ||
98 | } | ||
99 | fn 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 | } | ||
103 | fn 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 | } | ||