From 15224dfcd5fc5338844aec5993abf98f7f283e1e Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Tue, 5 Feb 2019 22:54:17 +0100 Subject: Add new crate --- crates/ra_batch/src/lib.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 crates/ra_batch/src/lib.rs (limited to 'crates/ra_batch/src') diff --git a/crates/ra_batch/src/lib.rs b/crates/ra_batch/src/lib.rs new file mode 100644 index 000000000..25f1f7357 --- /dev/null +++ b/crates/ra_batch/src/lib.rs @@ -0,0 +1,30 @@ +use std::sync::Arc; + +use ra_db::{ + FilePosition, FileId, CrateGraph, SourceRoot, SourceRootId, SourceDatabase, salsa, +}; +use ra_hir::{db, HirInterner}; + +#[salsa::database( + ra_db::SourceDatabaseStorage, + db::HirDatabaseStorage, + db::PersistentHirDatabaseStorage +)] +#[derive(Debug)] +pub(crate) struct BatchDatabase { + runtime: salsa::Runtime, + interner: Arc, + file_counter: u32, +} + +impl salsa::Database for BatchDatabase { + fn salsa_runtime(&self) -> &salsa::Runtime { + &self.runtime + } +} + +impl AsRef for BatchDatabase { + fn as_ref(&self) -> &HirInterner { + &self.interner + } +} -- cgit v1.2.3 From 43e52ac9e2b26ec287b1778823bad10851cfd44e Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 9 Feb 2019 13:06:12 +0100 Subject: Implement BatchDatabase construction --- crates/ra_batch/src/lib.rs | 99 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 96 insertions(+), 3 deletions(-) (limited to 'crates/ra_batch/src') 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 @@ use std::sync::Arc; +use std::path::Path; +use std::collections::HashSet; + +use rustc_hash::FxHashMap; use ra_db::{ - FilePosition, FileId, CrateGraph, SourceRoot, SourceRootId, SourceDatabase, salsa, + CrateGraph, FileId, SourceRoot, SourceRootId, SourceDatabase, salsa, }; use ra_hir::{db, HirInterner}; +use ra_project_model::ProjectWorkspace; +use ra_vfs::{Vfs, VfsChange}; + +type Result = std::result::Result; #[salsa::database( ra_db::SourceDatabaseStorage, @@ -11,10 +19,10 @@ use ra_hir::{db, HirInterner}; db::PersistentHirDatabaseStorage )] #[derive(Debug)] -pub(crate) struct BatchDatabase { +pub struct BatchDatabase { runtime: salsa::Runtime, interner: Arc, - file_counter: u32, + // file_counter: u32, } impl salsa::Database for BatchDatabase { @@ -28,3 +36,88 @@ impl AsRef for BatchDatabase { &self.interner } } + +fn vfs_file_to_id(f: ra_vfs::VfsFile) -> FileId { + FileId(f.0.into()) +} +fn vfs_root_to_id(r: ra_vfs::VfsRoot) -> SourceRootId { + SourceRootId(r.0.into()) +} + +impl BatchDatabase { + pub fn load(crate_graph: CrateGraph, vfs: &mut Vfs) -> BatchDatabase { + let mut db = + BatchDatabase { runtime: salsa::Runtime::default(), interner: Default::default() }; + db.set_crate_graph(Arc::new(crate_graph)); + + // wait until Vfs has loaded all roots + let receiver = vfs.task_receiver().clone(); + let mut roots_loaded = HashSet::new(); + for task in receiver { + vfs.handle_task(task); + let mut done = false; + for change in vfs.commit_changes() { + match change { + VfsChange::AddRoot { root, files } => { + let source_root_id = vfs_root_to_id(root); + log::debug!("loaded source root {:?} with path {:?}", source_root_id, vfs.root2path(root)); + let mut file_map = FxHashMap::default(); + for (vfs_file, path, text) in files { + let file_id = vfs_file_to_id(vfs_file); + db.set_file_text(file_id, text); + db.set_file_relative_path(file_id, path.clone()); + db.set_file_source_root(file_id, source_root_id); + file_map.insert(path, file_id); + } + let source_root = SourceRoot { files: file_map }; + db.set_source_root(source_root_id, Arc::new(source_root)); + roots_loaded.insert(source_root_id); + if roots_loaded.len() == vfs.num_roots() { + done = true; + } + } + VfsChange::AddFile { .. } + | VfsChange::RemoveFile { .. } + | VfsChange::ChangeFile { .. } => { + // log::warn!("VFS changed while loading"); + } + } + } + if done { + break; + } + } + + db + } + + pub fn load_cargo(root: impl AsRef) -> Result<(BatchDatabase, Vec)> { + let root = root.as_ref().canonicalize()?; + let ws = ProjectWorkspace::discover(root.as_ref())?; + let mut roots = Vec::new(); + roots.push(root.clone()); + for pkg in ws.cargo.packages() { + roots.push(pkg.root(&ws.cargo).to_path_buf()); + } + for krate in ws.sysroot.crates() { + roots.push(krate.root_dir(&ws.sysroot).to_path_buf()) + } + let (mut vfs, roots) = Vfs::new(roots); + let mut load = |path: &Path| { + let vfs_file = vfs.load(path); + log::debug!("vfs file {:?} -> {:?}", path, vfs_file); + vfs_file.map(vfs_file_to_id) + }; + let crate_graph = ws.to_crate_graph(&mut load); + log::debug!("crate graph: {:?}", crate_graph); + + let local_roots = roots.into_iter() + .filter(|r| vfs.root2path(*r).starts_with(&root)) + .map(vfs_root_to_id) + .collect(); + + let db = BatchDatabase::load(crate_graph, &mut vfs); + let _ = vfs.shutdown(); + Ok((db, local_roots)) + } +} -- cgit v1.2.3 From 6964a88e8c90f06220498d3e9194b7e2073c1e32 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 9 Feb 2019 18:27:11 +0100 Subject: Add an ra_cli command that analyses all crates in the current workspace ... and prints various stats about how many expressions have a type etc. --- crates/ra_batch/src/lib.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'crates/ra_batch/src') diff --git a/crates/ra_batch/src/lib.rs b/crates/ra_batch/src/lib.rs index ea91d88b7..014663546 100644 --- a/crates/ra_batch/src/lib.rs +++ b/crates/ra_batch/src/lib.rs @@ -60,7 +60,11 @@ impl BatchDatabase { match change { VfsChange::AddRoot { root, files } => { let source_root_id = vfs_root_to_id(root); - log::debug!("loaded source root {:?} with path {:?}", source_root_id, vfs.root2path(root)); + log::debug!( + "loaded source root {:?} with path {:?}", + source_root_id, + vfs.root2path(root) + ); let mut file_map = FxHashMap::default(); for (vfs_file, path, text) in files { let file_id = vfs_file_to_id(vfs_file); @@ -111,7 +115,8 @@ impl BatchDatabase { let crate_graph = ws.to_crate_graph(&mut load); log::debug!("crate graph: {:?}", crate_graph); - let local_roots = roots.into_iter() + let local_roots = roots + .into_iter() .filter(|r| vfs.root2path(*r).starts_with(&root)) .map(vfs_root_to_id) .collect(); -- cgit v1.2.3 From 6f81a372db9e402126dcc36a725e9b1d71491955 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sun, 10 Feb 2019 11:44:53 +0100 Subject: Add a smoke test for ra_batch --- crates/ra_batch/src/lib.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'crates/ra_batch/src') diff --git a/crates/ra_batch/src/lib.rs b/crates/ra_batch/src/lib.rs index 014663546..c1cfb76bc 100644 --- a/crates/ra_batch/src/lib.rs +++ b/crates/ra_batch/src/lib.rs @@ -126,3 +126,27 @@ impl BatchDatabase { Ok((db, local_roots)) } } + +#[cfg(test)] +mod tests { + use ra_hir::Crate; + use super::*; + + #[test] + fn test_loading_rust_analyzer() { + let mut path = std::env::current_exe().unwrap(); + while !path.join("Cargo.toml").is_file() { + path = path.parent().unwrap().to_owned(); + } + let (db, roots) = BatchDatabase::load_cargo(path).unwrap(); + let mut num_crates = 0; + for root in roots { + for _krate in Crate::source_root_crates(&db, root) { + num_crates += 1; + } + } + + // RA has quite a few crates, but the exact count doesn't matter + assert!(num_crates > 20); + } +} -- cgit v1.2.3 From b18863f987ef14d44a67c0b8ebaa9c7a7fed7f59 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sun, 10 Feb 2019 11:48:59 +0100 Subject: Clean up a bit --- crates/ra_batch/src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'crates/ra_batch/src') diff --git a/crates/ra_batch/src/lib.rs b/crates/ra_batch/src/lib.rs index c1cfb76bc..837fff4dc 100644 --- a/crates/ra_batch/src/lib.rs +++ b/crates/ra_batch/src/lib.rs @@ -22,7 +22,6 @@ type Result = std::result::Result; pub struct BatchDatabase { runtime: salsa::Runtime, interner: Arc, - // file_counter: u32, } impl salsa::Database for BatchDatabase { @@ -83,7 +82,7 @@ impl BatchDatabase { VfsChange::AddFile { .. } | VfsChange::RemoveFile { .. } | VfsChange::ChangeFile { .. } => { - // log::warn!("VFS changed while loading"); + // We just need the first scan, so just ignore these } } } -- cgit v1.2.3