From b0be4207d04b65580e7af10cb256ddd5d9ca006d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 15 Jun 2019 16:29:23 +0300 Subject: reuse AnalysisHost in batch analysis --- crates/ra_batch/src/lib.rs | 164 +++++++++++++++++++-------------------------- 1 file changed, 70 insertions(+), 94 deletions(-) (limited to 'crates/ra_batch/src/lib.rs') diff --git a/crates/ra_batch/src/lib.rs b/crates/ra_batch/src/lib.rs index 96b32d9fe..fa244e86c 100644 --- a/crates/ra_batch/src/lib.rs +++ b/crates/ra_batch/src/lib.rs @@ -1,36 +1,19 @@ mod vfs_filter; -use std::{sync::Arc, path::Path, collections::HashSet, error::Error}; +use std::{path::Path, collections::HashSet, error::Error}; use rustc_hash::FxHashMap; use ra_db::{ - CrateGraph, FileId, SourceRoot, SourceRootId, SourceDatabase, salsa::{self, Database}, + CrateGraph, FileId, SourceRootId, }; -use ra_hir::db; +use ra_ide_api::{AnalysisHost, AnalysisChange}; use ra_project_model::ProjectWorkspace; use ra_vfs::{Vfs, VfsChange}; use vfs_filter::IncludeRustFiles; type Result = std::result::Result>; -#[salsa::database( - ra_db::SourceDatabaseStorage, - db::AstDatabaseStorage, - db::DefDatabaseStorage, - db::HirDatabaseStorage -)] -#[derive(Debug)] -pub struct BatchDatabase { - runtime: salsa::Runtime, -} - -impl salsa::Database for BatchDatabase { - fn salsa_runtime(&self) -> &salsa::Runtime { - &self.runtime - } -} - fn vfs_file_to_id(f: ra_vfs::VfsFile) -> FileId { FileId(f.0) } @@ -38,86 +21,79 @@ fn vfs_root_to_id(r: ra_vfs::VfsRoot) -> SourceRootId { SourceRootId(r.0) } -impl BatchDatabase { - pub fn load(crate_graph: CrateGraph, vfs: &mut Vfs) -> BatchDatabase { - let mut db = BatchDatabase { runtime: salsa::Runtime::default() }; - let lru_cap = std::env::var("RA_LRU_CAP") - .ok() - .and_then(|it| it.parse::().ok()) - .unwrap_or(ra_db::DEFAULT_LRU_CAP); - db.query_mut(ra_db::ParseQuery).set_lru_capacity(lru_cap); - db.query_mut(ra_hir::db::ParseMacroQuery).set_lru_capacity(lru_cap); - db.set_crate_graph(Arc::new(crate_graph)); +pub fn load_cargo(root: &Path) -> Result<(AnalysisHost, Vec)> { + let root = std::env::current_dir()?.join(root); + let ws = ProjectWorkspace::discover(root.as_ref())?; + let mut roots = Vec::new(); + roots.push(IncludeRustFiles::member(root.clone())); + roots.extend(IncludeRustFiles::from_roots(ws.to_roots())); + let (mut vfs, roots) = Vfs::new(roots); + let crate_graph = ws.to_crate_graph(&mut |path: &Path| { + let vfs_file = vfs.load(path); + log::debug!("vfs file {:?} -> {:?}", path, vfs_file); + vfs_file.map(vfs_file_to_id) + }); + 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 host = load(root.as_path(), crate_graph, &mut vfs); + Ok((host, local_roots)) +} - // 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.n_roots() { - done = true; - } +pub fn load(project_root: &Path, crate_graph: CrateGraph, vfs: &mut Vfs) -> AnalysisHost { + let lru_cap = std::env::var("RA_LRU_CAP").ok().and_then(|it| it.parse::().ok()); + let mut host = AnalysisHost::new(lru_cap); + let mut analysis_change = AnalysisChange::new(); + analysis_change.set_crate_graph(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 is_local = vfs.root2path(root).starts_with(&project_root); + let source_root_id = vfs_root_to_id(root); + log::debug!( + "loaded source root {:?} with path {:?}", + source_root_id, + vfs.root2path(root) + ); + analysis_change.add_root(source_root_id, is_local); + + let mut file_map = FxHashMap::default(); + for (vfs_file, path, text) in files { + let file_id = vfs_file_to_id(vfs_file); + analysis_change.add_file(source_root_id, file_id, path.clone(), text); + file_map.insert(path, file_id); } - VfsChange::AddFile { .. } - | VfsChange::RemoveFile { .. } - | VfsChange::ChangeFile { .. } => { - // We just need the first scan, so just ignore these + roots_loaded.insert(source_root_id); + if roots_loaded.len() == vfs.n_roots() { + done = true; } } - } - if done { - break; + VfsChange::AddFile { .. } + | VfsChange::RemoveFile { .. } + | VfsChange::ChangeFile { .. } => { + // We just need the first scan, so just ignore these + } } } - - db + if done { + break; + } } - pub fn load_cargo(root: impl AsRef) -> Result<(BatchDatabase, Vec)> { - let root = std::env::current_dir()?.join(root); - let ws = ProjectWorkspace::discover(root.as_ref())?; - let mut roots = Vec::new(); - roots.push(IncludeRustFiles::member(root.clone())); - roots.extend(IncludeRustFiles::from_roots(ws.to_roots())); - 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); - Ok((db, local_roots)) - } + host.apply_change(analysis_change); + host } #[cfg(test)] @@ -128,10 +104,10 @@ mod tests { #[test] fn test_loading_rust_analyzer() { let path = Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap().parent().unwrap(); - let (db, roots) = BatchDatabase::load_cargo(path).unwrap(); + let (host, roots) = load_cargo(path).unwrap(); let mut n_crates = 0; for root in roots { - for _krate in Crate::source_root_crates(&db, root) { + for _krate in Crate::source_root_crates(host.raw_database(), root) { n_crates += 1; } } -- cgit v1.2.3