diff options
Diffstat (limited to 'crates/ra_analysis/src/db')
-rw-r--r-- | crates/ra_analysis/src/db/imp.rs | 153 | ||||
-rw-r--r-- | crates/ra_analysis/src/db/mod.rs | 189 |
2 files changed, 0 insertions, 342 deletions
diff --git a/crates/ra_analysis/src/db/imp.rs b/crates/ra_analysis/src/db/imp.rs deleted file mode 100644 index 7669b6184..000000000 --- a/crates/ra_analysis/src/db/imp.rs +++ /dev/null | |||
@@ -1,153 +0,0 @@ | |||
1 | use std::{ | ||
2 | sync::Arc, | ||
3 | any::Any, | ||
4 | hash::{Hash, Hasher}, | ||
5 | collections::hash_map::{DefaultHasher}, | ||
6 | iter, | ||
7 | }; | ||
8 | use rustc_hash::FxHashMap; | ||
9 | use salsa; | ||
10 | use crate::{FileId, imp::FileResolverImp}; | ||
11 | use super::{State, Query, QueryCtx}; | ||
12 | |||
13 | pub(super) type Data = Arc<Any + Send + Sync + 'static>; | ||
14 | |||
15 | #[derive(Debug)] | ||
16 | pub(super) struct Db { | ||
17 | names: Arc<FxHashMap<salsa::QueryTypeId, &'static str>>, | ||
18 | pub(super) imp: salsa::Db<State, Data>, | ||
19 | } | ||
20 | |||
21 | impl Db { | ||
22 | pub(super) fn new(mut reg: QueryRegistry) -> Db { | ||
23 | let config = reg.config.take().unwrap(); | ||
24 | Db { | ||
25 | names: Arc::new(reg.names), | ||
26 | imp: salsa::Db::new(config, State::default()) | ||
27 | } | ||
28 | } | ||
29 | pub(crate) fn with_changes(&self, new_state: State, changed_files: &[FileId], resolver_changed: bool) -> Db { | ||
30 | let names = self.names.clone(); | ||
31 | let mut invalidations = salsa::Invalidations::new(); | ||
32 | invalidations.invalidate(FILE_TEXT, changed_files.iter().map(hash).map(salsa::InputFingerprint)); | ||
33 | if resolver_changed { | ||
34 | invalidations.invalidate(FILE_SET, iter::once(salsa::InputFingerprint(hash(&())))); | ||
35 | } else { | ||
36 | invalidations.invalidate(FILE_SET, iter::empty()); | ||
37 | } | ||
38 | let imp = self.imp.with_ground_data( | ||
39 | new_state, | ||
40 | invalidations, | ||
41 | ); | ||
42 | Db { names, imp } | ||
43 | } | ||
44 | pub(super) fn extract_trace(&self, ctx: &salsa::QueryCtx<State, Data>) -> Vec<&'static str> { | ||
45 | ctx.trace().into_iter().map(|it| self.names[&it]).collect() | ||
46 | } | ||
47 | } | ||
48 | |||
49 | pub(crate) trait EvalQuery { | ||
50 | type Params; | ||
51 | type Output; | ||
52 | fn query_type(&self) -> salsa::QueryTypeId; | ||
53 | fn f(&self) -> salsa::QueryFn<State, Data>; | ||
54 | fn get(&self, ctx: &QueryCtx, params: Self::Params) -> Arc<Self::Output>; | ||
55 | } | ||
56 | |||
57 | impl<T, R> EvalQuery for Query<T, R> | ||
58 | where | ||
59 | T: Hash + Send + Sync + 'static, | ||
60 | R: Hash + Send + Sync + 'static, | ||
61 | { | ||
62 | type Params = T; | ||
63 | type Output = R; | ||
64 | fn query_type(&self) -> salsa::QueryTypeId { | ||
65 | salsa::QueryTypeId(self.0) | ||
66 | } | ||
67 | fn f(&self) -> salsa::QueryFn<State, Data> { | ||
68 | let f = self.1; | ||
69 | Box::new(move |ctx, data| { | ||
70 | let ctx = QueryCtx { imp: ctx }; | ||
71 | let data: &T = data.downcast_ref().unwrap(); | ||
72 | let res = f(ctx, data); | ||
73 | let h = hash(&res); | ||
74 | (Arc::new(res), salsa::OutputFingerprint(h)) | ||
75 | }) | ||
76 | } | ||
77 | fn get(&self, ctx: &QueryCtx, params: Self::Params) -> Arc<Self::Output> { | ||
78 | let query_id = salsa::QueryId( | ||
79 | self.query_type(), | ||
80 | salsa::InputFingerprint(hash(¶ms)), | ||
81 | ); | ||
82 | let res = ctx.imp.get(query_id, Arc::new(params)); | ||
83 | res.downcast().unwrap() | ||
84 | } | ||
85 | } | ||
86 | |||
87 | pub(super) struct QueryRegistry { | ||
88 | config: Option<salsa::QueryConfig<State, Data>>, | ||
89 | names: FxHashMap<salsa::QueryTypeId, &'static str>, | ||
90 | } | ||
91 | |||
92 | impl QueryRegistry { | ||
93 | pub(super) fn new() -> QueryRegistry { | ||
94 | let mut config = salsa::QueryConfig::<State, Data>::new(); | ||
95 | config = config.with_ground_query( | ||
96 | FILE_TEXT, Box::new(|state, params| { | ||
97 | let file_id: &FileId = params.downcast_ref().unwrap(); | ||
98 | let res = state.file_map[file_id].clone(); | ||
99 | let fingerprint = salsa::OutputFingerprint(hash(&res)); | ||
100 | (res, fingerprint) | ||
101 | }) | ||
102 | ); | ||
103 | config = config.with_ground_query( | ||
104 | FILE_SET, Box::new(|state, _params| { | ||
105 | let file_ids: Vec<FileId> = state.file_map.keys().cloned().collect(); | ||
106 | let hash = hash(&file_ids); | ||
107 | let file_resolver = state.file_resolver.clone(); | ||
108 | let res = (file_ids, file_resolver); | ||
109 | let fingerprint = salsa::OutputFingerprint(hash); | ||
110 | (Arc::new(res), fingerprint) | ||
111 | }) | ||
112 | ); | ||
113 | let mut names = FxHashMap::default(); | ||
114 | names.insert(FILE_TEXT, "FILE_TEXT"); | ||
115 | names.insert(FILE_SET, "FILE_SET"); | ||
116 | QueryRegistry { config: Some(config), names } | ||
117 | } | ||
118 | pub(super) fn add<Q: EvalQuery>(&mut self, q: Q, name: &'static str) { | ||
119 | let id = q.query_type(); | ||
120 | let prev = self.names.insert(id, name); | ||
121 | assert!(prev.is_none(), "duplicate query: {:?}", id); | ||
122 | let config = self.config.take().unwrap(); | ||
123 | let config = config.with_query(id, q.f()); | ||
124 | self.config= Some(config); | ||
125 | } | ||
126 | } | ||
127 | |||
128 | fn hash<T: Hash>(x: &T) -> u64 { | ||
129 | let mut hasher = DefaultHasher::new(); | ||
130 | x.hash(&mut hasher); | ||
131 | hasher.finish() | ||
132 | } | ||
133 | |||
134 | const FILE_TEXT: salsa::QueryTypeId = salsa::QueryTypeId(0); | ||
135 | pub(super) fn file_text(ctx: QueryCtx, file_id: FileId) -> Arc<String> { | ||
136 | let query_id = salsa::QueryId( | ||
137 | FILE_TEXT, | ||
138 | salsa::InputFingerprint(hash(&file_id)), | ||
139 | ); | ||
140 | let res = ctx.imp.get(query_id, Arc::new(file_id)); | ||
141 | res.downcast().unwrap() | ||
142 | } | ||
143 | |||
144 | const FILE_SET: salsa::QueryTypeId = salsa::QueryTypeId(1); | ||
145 | pub(super) fn file_set(ctx: QueryCtx) -> Arc<(Vec<FileId>, FileResolverImp)> { | ||
146 | let query_id = salsa::QueryId( | ||
147 | FILE_SET, | ||
148 | salsa::InputFingerprint(hash(&())), | ||
149 | ); | ||
150 | let res = ctx.imp.get(query_id, Arc::new(())); | ||
151 | res.downcast().unwrap() | ||
152 | } | ||
153 | |||
diff --git a/crates/ra_analysis/src/db/mod.rs b/crates/ra_analysis/src/db/mod.rs deleted file mode 100644 index 081510daa..000000000 --- a/crates/ra_analysis/src/db/mod.rs +++ /dev/null | |||
@@ -1,189 +0,0 @@ | |||
1 | use std::{ | ||
2 | fmt, | ||
3 | sync::Arc, | ||
4 | hash::{Hash, Hasher}, | ||
5 | }; | ||
6 | use salsa; | ||
7 | use rustc_hash::FxHashSet; | ||
8 | use ra_syntax::File; | ||
9 | use ra_editor::{LineIndex}; | ||
10 | use crate::{ | ||
11 | symbol_index::SymbolIndex, | ||
12 | module_map::{ModulesDatabase, ModuleTreeQuery, ModuleDescriptorQuery}, | ||
13 | FileId, FileResolverImp, | ||
14 | }; | ||
15 | |||
16 | #[derive(Default)] | ||
17 | pub(crate) struct RootDatabase { | ||
18 | runtime: salsa::runtime::Runtime<RootDatabase>, | ||
19 | } | ||
20 | |||
21 | impl fmt::Debug for RootDatabase { | ||
22 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||
23 | fmt.write_str("RootDatabase { ... }") | ||
24 | } | ||
25 | } | ||
26 | |||
27 | impl salsa::Database for RootDatabase { | ||
28 | fn salsa_runtime(&self) -> &salsa::runtime::Runtime<RootDatabase> { | ||
29 | &self.runtime | ||
30 | } | ||
31 | } | ||
32 | |||
33 | salsa::database_storage! { | ||
34 | pub(crate) struct RootDatabaseStorage for RootDatabase { | ||
35 | impl FilesDatabase { | ||
36 | fn file_text() for FileTextQuery; | ||
37 | fn file_set() for FileSetQuery; | ||
38 | } | ||
39 | impl SyntaxDatabase { | ||
40 | fn file_syntax() for FileSyntaxQuery; | ||
41 | fn file_lines() for FileLinesQuery; | ||
42 | fn file_symbols() for FileSymbolsQuery; | ||
43 | } | ||
44 | impl ModulesDatabase { | ||
45 | fn module_tree() for ModuleTreeQuery; | ||
46 | fn module_descriptor() for ModuleDescriptorQuery; | ||
47 | } | ||
48 | } | ||
49 | } | ||
50 | |||
51 | salsa::query_group! { | ||
52 | pub(crate) trait FilesDatabase: salsa::Database { | ||
53 | fn file_text(file_id: FileId) -> Arc<String> { | ||
54 | type FileTextQuery; | ||
55 | storage input; | ||
56 | } | ||
57 | fn file_set(key: ()) -> Arc<FileSet> { | ||
58 | type FileSetQuery; | ||
59 | storage input; | ||
60 | } | ||
61 | } | ||
62 | } | ||
63 | |||
64 | #[derive(Default, Debug, PartialEq, Eq)] | ||
65 | pub(crate) struct FileSet { | ||
66 | pub(crate) files: FxHashSet<FileId>, | ||
67 | pub(crate) resolver: FileResolverImp, | ||
68 | } | ||
69 | |||
70 | impl Hash for FileSet { | ||
71 | fn hash<H: Hasher>(&self, hasher: &mut H) { | ||
72 | let mut files = self.files.iter().cloned().collect::<Vec<_>>(); | ||
73 | files.sort(); | ||
74 | files.hash(hasher); | ||
75 | } | ||
76 | } | ||
77 | |||
78 | salsa::query_group! { | ||
79 | pub(crate) trait SyntaxDatabase: FilesDatabase { | ||
80 | fn file_syntax(file_id: FileId) -> File { | ||
81 | type FileSyntaxQuery; | ||
82 | } | ||
83 | fn file_lines(file_id: FileId) -> Arc<LineIndex> { | ||
84 | type FileLinesQuery; | ||
85 | } | ||
86 | fn file_symbols(file_id: FileId) -> Arc<SymbolIndex> { | ||
87 | type FileSymbolsQuery; | ||
88 | } | ||
89 | } | ||
90 | } | ||
91 | |||
92 | fn file_syntax(db: &impl SyntaxDatabase, file_id: FileId) -> File { | ||
93 | let text = db.file_text(file_id); | ||
94 | File::parse(&*text) | ||
95 | } | ||
96 | fn file_lines(db: &impl SyntaxDatabase, file_id: FileId) -> Arc<LineIndex> { | ||
97 | let text = db.file_text(file_id); | ||
98 | Arc::new(LineIndex::new(&*text)) | ||
99 | } | ||
100 | fn file_symbols(db: &impl SyntaxDatabase, file_id: FileId) -> Arc<SymbolIndex> { | ||
101 | let syntax = db.file_syntax(file_id); | ||
102 | Arc::new(SymbolIndex::for_file(file_id, syntax)) | ||
103 | } | ||
104 | |||
105 | // mod imp; | ||
106 | |||
107 | // use std::{ | ||
108 | // sync::Arc, | ||
109 | // }; | ||
110 | // use im; | ||
111 | // use salsa; | ||
112 | // use {FileId, imp::FileResolverImp}; | ||
113 | |||
114 | // #[derive(Debug, Default, Clone)] | ||
115 | // pub(crate) struct State { | ||
116 | // pub(crate) file_map: im::HashMap<FileId, Arc<String>>, | ||
117 | // pub(crate) file_resolver: FileResolverImp | ||
118 | // } | ||
119 | |||
120 | // #[derive(Debug)] | ||
121 | // pub(crate) struct Db { | ||
122 | // imp: imp::Db, | ||
123 | // } | ||
124 | |||
125 | // #[derive(Clone, Copy)] | ||
126 | // pub(crate) struct QueryCtx<'a> { | ||
127 | // imp: &'a salsa::QueryCtx<State, imp::Data>, | ||
128 | // } | ||
129 | |||
130 | // pub(crate) struct Query<T, R>(pub(crate) u16, pub(crate) fn(QueryCtx, &T) -> R); | ||
131 | |||
132 | // pub(crate) struct QueryRegistry { | ||
133 | // imp: imp::QueryRegistry, | ||
134 | // } | ||
135 | |||
136 | // impl Default for Db { | ||
137 | // fn default() -> Db { | ||
138 | // Db::new() | ||
139 | // } | ||
140 | // } | ||
141 | |||
142 | // impl Db { | ||
143 | // pub(crate) fn new() -> Db { | ||
144 | // let reg = QueryRegistry::new(); | ||
145 | // Db { imp: imp::Db::new(reg.imp) } | ||
146 | // } | ||
147 | // pub(crate) fn state(&self) -> &State { | ||
148 | // self.imp.imp.ground_data() | ||
149 | // } | ||
150 | // pub(crate) fn with_changes(&self, new_state: State, changed_files: &[FileId], resolver_changed: bool) -> Db { | ||
151 | // Db { imp: self.imp.with_changes(new_state, changed_files, resolver_changed) } | ||
152 | // } | ||
153 | // pub(crate) fn make_query<F: FnOnce(QueryCtx) -> R, R>(&self, f: F) -> R { | ||
154 | // let ctx = QueryCtx { imp: &self.imp.imp.query_ctx() }; | ||
155 | // f(ctx) | ||
156 | // } | ||
157 | // #[allow(unused)] | ||
158 | // pub(crate) fn trace_query<F: FnOnce(QueryCtx) -> R, R>(&self, f: F) -> (R, Vec<&'static str>) { | ||
159 | // let ctx = QueryCtx { imp: &self.imp.imp.query_ctx() }; | ||
160 | // let res = f(ctx); | ||
161 | // let trace = self.imp.extract_trace(ctx.imp); | ||
162 | // (res, trace) | ||
163 | // } | ||
164 | // } | ||
165 | |||
166 | // impl<'a> QueryCtx<'a> { | ||
167 | // pub(crate) fn get<Q: imp::EvalQuery>(&self, q: Q, params: Q::Params) -> Arc<Q::Output> { | ||
168 | // q.get(self, params) | ||
169 | // } | ||
170 | // } | ||
171 | |||
172 | // pub(crate) fn file_text(ctx: QueryCtx, file_id: FileId) -> Arc<String> { | ||
173 | // imp::file_text(ctx, file_id) | ||
174 | // } | ||
175 | |||
176 | // pub(crate) fn file_set(ctx: QueryCtx) -> Arc<(Vec<FileId>, FileResolverImp)> { | ||
177 | // imp::file_set(ctx) | ||
178 | // } | ||
179 | // impl QueryRegistry { | ||
180 | // fn new() -> QueryRegistry { | ||
181 | // let mut reg = QueryRegistry { imp: imp::QueryRegistry::new() }; | ||
182 | // ::queries::register_queries(&mut reg); | ||
183 | // ::module_map::register_queries(&mut reg); | ||
184 | // reg | ||
185 | // } | ||
186 | // pub(crate) fn add<Q: imp::EvalQuery>(&mut self, q: Q, name: &'static str) { | ||
187 | // self.imp.add(q, name) | ||
188 | // } | ||
189 | // } | ||