aboutsummaryrefslogtreecommitdiff
path: root/crates/base_db
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-10-02 14:45:09 +0100
committerAleksey Kladov <[email protected]>2020-10-02 15:45:08 +0100
commit8716c4cec3a05ba891b20b5f28df69d925b913ad (patch)
treee2f073c459e9a1e1c98b98d524565633524b84c2 /crates/base_db
parent700c9bc019346a321d230c51bbea597a497bed84 (diff)
Move ide::AnalysisChange -> base_db::Change
This seems like a better factoring logically; ideally, clients shouldn't touch `set_` methods of the database directly. Additionally, I think this should remove the unfortunate duplication in fixture code.
Diffstat (limited to 'crates/base_db')
-rw-r--r--crates/base_db/src/change.rs97
-rw-r--r--crates/base_db/src/lib.rs2
2 files changed, 99 insertions, 0 deletions
diff --git a/crates/base_db/src/change.rs b/crates/base_db/src/change.rs
new file mode 100644
index 000000000..043e03bba
--- /dev/null
+++ b/crates/base_db/src/change.rs
@@ -0,0 +1,97 @@
1//! Defines a unit of change that can applied to the database to get the next
2//! state. Changes are transactional.
3
4use std::{fmt, sync::Arc};
5
6use rustc_hash::FxHashSet;
7use salsa::Durability;
8use vfs::FileId;
9
10use crate::{CrateGraph, SourceDatabaseExt, SourceRoot, SourceRootId};
11
12/// Encapsulate a bunch of raw `.set` calls on the database.
13#[derive(Default)]
14pub struct Change {
15 pub roots: Option<Vec<SourceRoot>>,
16 pub files_changed: Vec<(FileId, Option<Arc<String>>)>,
17 pub crate_graph: Option<CrateGraph>,
18}
19
20impl fmt::Debug for Change {
21 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
22 let mut d = fmt.debug_struct("AnalysisChange");
23 if let Some(roots) = &self.roots {
24 d.field("roots", roots);
25 }
26 if !self.files_changed.is_empty() {
27 d.field("files_changed", &self.files_changed.len());
28 }
29 if self.crate_graph.is_some() {
30 d.field("crate_graph", &self.crate_graph);
31 }
32 d.finish()
33 }
34}
35
36impl Change {
37 pub fn new() -> Change {
38 Change::default()
39 }
40
41 pub fn set_roots(&mut self, roots: Vec<SourceRoot>) {
42 self.roots = Some(roots);
43 }
44
45 pub fn change_file(&mut self, file_id: FileId, new_text: Option<Arc<String>>) {
46 self.files_changed.push((file_id, new_text))
47 }
48
49 pub fn set_crate_graph(&mut self, graph: CrateGraph) {
50 self.crate_graph = Some(graph);
51 }
52
53 pub fn apply(self, db: &mut dyn SourceDatabaseExt) {
54 let _p = profile::span("RootDatabase::apply_change");
55 // db.request_cancellation();
56 // log::info!("apply_change {:?}", change);
57 if let Some(roots) = self.roots {
58 let mut local_roots = FxHashSet::default();
59 let mut library_roots = FxHashSet::default();
60 for (idx, root) in roots.into_iter().enumerate() {
61 let root_id = SourceRootId(idx as u32);
62 let durability = durability(&root);
63 if root.is_library {
64 library_roots.insert(root_id);
65 } else {
66 local_roots.insert(root_id);
67 }
68 for file_id in root.iter() {
69 db.set_file_source_root_with_durability(file_id, root_id, durability);
70 }
71 db.set_source_root_with_durability(root_id, Arc::new(root), durability);
72 }
73 // db.set_local_roots_with_durability(Arc::new(local_roots), Durability::HIGH);
74 // db.set_library_roots_with_durability(Arc::new(library_roots), Durability::HIGH);
75 }
76
77 for (file_id, text) in self.files_changed {
78 let source_root_id = db.file_source_root(file_id);
79 let source_root = db.source_root(source_root_id);
80 let durability = durability(&source_root);
81 // XXX: can't actually remove the file, just reset the text
82 let text = text.unwrap_or_default();
83 db.set_file_text_with_durability(file_id, text, durability)
84 }
85 if let Some(crate_graph) = self.crate_graph {
86 db.set_crate_graph_with_durability(Arc::new(crate_graph), Durability::HIGH)
87 }
88 }
89}
90
91fn durability(source_root: &SourceRoot) -> Durability {
92 if source_root.is_library {
93 Durability::HIGH
94 } else {
95 Durability::LOW
96 }
97}
diff --git a/crates/base_db/src/lib.rs b/crates/base_db/src/lib.rs
index ee3415850..e38aa7257 100644
--- a/crates/base_db/src/lib.rs
+++ b/crates/base_db/src/lib.rs
@@ -1,6 +1,7 @@
1//! base_db defines basic database traits. The concrete DB is defined by ide. 1//! base_db defines basic database traits. The concrete DB is defined by ide.
2mod cancellation; 2mod cancellation;
3mod input; 3mod input;
4mod change;
4pub mod fixture; 5pub mod fixture;
5 6
6use std::{panic, sync::Arc}; 7use std::{panic, sync::Arc};
@@ -10,6 +11,7 @@ use syntax::{ast, Parse, SourceFile, TextRange, TextSize};
10 11
11pub use crate::{ 12pub use crate::{
12 cancellation::Canceled, 13 cancellation::Canceled,
14 change::Change,
13 input::{ 15 input::{
14 CrateData, CrateGraph, CrateId, CrateName, Dependency, Edition, Env, FileId, ProcMacroId, 16 CrateData, CrateGraph, CrateId, CrateName, Dependency, Edition, Env, FileId, ProcMacroId,
15 SourceRoot, SourceRootId, 17 SourceRoot, SourceRootId,