aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_batch/src
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2019-02-09 12:06:12 +0000
committerFlorian Diebold <[email protected]>2019-02-10 09:56:58 +0000
commit43e52ac9e2b26ec287b1778823bad10851cfd44e (patch)
tree9e32634c498e0b8ae6d5132b8b0d3e8c17d37788 /crates/ra_batch/src
parent15224dfcd5fc5338844aec5993abf98f7f283e1e (diff)
Implement BatchDatabase construction
Diffstat (limited to 'crates/ra_batch/src')
-rw-r--r--crates/ra_batch/src/lib.rs99
1 files changed, 96 insertions, 3 deletions
diff --git a/crates/ra_batch/src/lib.rs b/crates/ra_batch/src/lib.rs
index 25f1f7357..ea91d88b7 100644
--- a/crates/ra_batch/src/lib.rs
+++ b/crates/ra_batch/src/lib.rs
@@ -1,9 +1,17 @@
1use std::sync::Arc; 1use std::sync::Arc;
2use std::path::Path;
3use std::collections::HashSet;
4
5use rustc_hash::FxHashMap;
2 6
3use ra_db::{ 7use ra_db::{
4 FilePosition, FileId, CrateGraph, SourceRoot, SourceRootId, SourceDatabase, salsa, 8 CrateGraph, FileId, SourceRoot, SourceRootId, SourceDatabase, salsa,
5}; 9};
6use ra_hir::{db, HirInterner}; 10use ra_hir::{db, HirInterner};
11use ra_project_model::ProjectWorkspace;
12use ra_vfs::{Vfs, VfsChange};
13
14type Result<T> = std::result::Result<T, failure::Error>;
7 15
8#[salsa::database( 16#[salsa::database(
9 ra_db::SourceDatabaseStorage, 17 ra_db::SourceDatabaseStorage,
@@ -11,10 +19,10 @@ use ra_hir::{db, HirInterner};
11 db::PersistentHirDatabaseStorage 19 db::PersistentHirDatabaseStorage
12)] 20)]
13#[derive(Debug)] 21#[derive(Debug)]
14pub(crate) struct BatchDatabase { 22pub struct BatchDatabase {
15 runtime: salsa::Runtime<BatchDatabase>, 23 runtime: salsa::Runtime<BatchDatabase>,
16 interner: Arc<HirInterner>, 24 interner: Arc<HirInterner>,
17 file_counter: u32, 25 // file_counter: u32,
18} 26}
19 27
20impl salsa::Database for BatchDatabase { 28impl salsa::Database for BatchDatabase {
@@ -28,3 +36,88 @@ impl AsRef<HirInterner> for BatchDatabase {
28 &self.interner 36 &self.interner
29 } 37 }
30} 38}
39
40fn vfs_file_to_id(f: ra_vfs::VfsFile) -> FileId {
41 FileId(f.0.into())
42}
43fn vfs_root_to_id(r: ra_vfs::VfsRoot) -> SourceRootId {
44 SourceRootId(r.0.into())
45}
46
47impl BatchDatabase {
48 pub fn load(crate_graph: CrateGraph, vfs: &mut Vfs) -> BatchDatabase {
49 let mut db =
50 BatchDatabase { runtime: salsa::Runtime::default(), interner: Default::default() };
51 db.set_crate_graph(Arc::new(crate_graph));
52
53 // wait until Vfs has loaded all roots
54 let receiver = vfs.task_receiver().clone();
55 let mut roots_loaded = HashSet::new();
56 for task in receiver {
57 vfs.handle_task(task);
58 let mut done = false;
59 for change in vfs.commit_changes() {
60 match change {
61 VfsChange::AddRoot { root, files } => {
62 let source_root_id = vfs_root_to_id(root);
63 log::debug!("loaded source root {:?} with path {:?}", source_root_id, vfs.root2path(root));
64 let mut file_map = FxHashMap::default();
65 for (vfs_file, path, text) in files {
66 let file_id = vfs_file_to_id(vfs_file);
67 db.set_file_text(file_id, text);
68 db.set_file_relative_path(file_id, path.clone());
69 db.set_file_source_root(file_id, source_root_id);
70 file_map.insert(path, file_id);
71 }
72 let source_root = SourceRoot { files: file_map };
73 db.set_source_root(source_root_id, Arc::new(source_root));
74 roots_loaded.insert(source_root_id);
75 if roots_loaded.len() == vfs.num_roots() {
76 done = true;
77 }
78 }
79 VfsChange::AddFile { .. }
80 | VfsChange::RemoveFile { .. }
81 | VfsChange::ChangeFile { .. } => {
82 // log::warn!("VFS changed while loading");
83 }
84 }
85 }
86 if done {
87 break;
88 }
89 }
90
91 db
92 }
93
94 pub fn load_cargo(root: impl AsRef<Path>) -> Result<(BatchDatabase, Vec<SourceRootId>)> {
95 let root = root.as_ref().canonicalize()?;
96 let ws = ProjectWorkspace::discover(root.as_ref())?;
97 let mut roots = Vec::new();
98 roots.push(root.clone());
99 for pkg in ws.cargo.packages() {
100 roots.push(pkg.root(&ws.cargo).to_path_buf());
101 }
102 for krate in ws.sysroot.crates() {
103 roots.push(krate.root_dir(&ws.sysroot).to_path_buf())
104 }
105 let (mut vfs, roots) = Vfs::new(roots);
106 let mut load = |path: &Path| {
107 let vfs_file = vfs.load(path);
108 log::debug!("vfs file {:?} -> {:?}", path, vfs_file);
109 vfs_file.map(vfs_file_to_id)
110 };
111 let crate_graph = ws.to_crate_graph(&mut load);
112 log::debug!("crate graph: {:?}", crate_graph);
113
114 let local_roots = roots.into_iter()
115 .filter(|r| vfs.root2path(*r).starts_with(&root))
116 .map(vfs_root_to_id)
117 .collect();
118
119 let db = BatchDatabase::load(crate_graph, &mut vfs);
120 let _ = vfs.shutdown();
121 Ok((db, local_roots))
122 }
123}