about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--crates/ra_batch/Cargo.toml1
-rw-r--r--crates/ra_batch/src/lib.rs164
-rw-r--r--crates/ra_cli/src/analysis_stats.rs26
-rw-r--r--crates/ra_ide_api/src/lib.rs3
-rw-r--r--crates/ra_lsp_server/src/main.rs2
6 files changed, 89 insertions, 108 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 03b5794fa1b..0579d9d39c1 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1023,6 +1023,7 @@ dependencies = [
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "ra_db 0.1.0",
  "ra_hir 0.1.0",
+ "ra_ide_api 0.1.0",
  "ra_project_model 0.1.0",
  "ra_syntax 0.1.0",
  "ra_vfs 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/crates/ra_batch/Cargo.toml b/crates/ra_batch/Cargo.toml
index 8bf085bbfbc..7d8837fc3a1 100644
--- a/crates/ra_batch/Cargo.toml
+++ b/crates/ra_batch/Cargo.toml
@@ -11,6 +11,7 @@ rustc-hash = "1.0"
 ra_vfs = "0.2.0"
 ra_syntax = { path = "../ra_syntax" }
 ra_db = { path = "../ra_db" }
+ra_ide_api = { path = "../ra_ide_api" }
 ra_hir = { path = "../ra_hir" }
 ra_project_model = { path = "../ra_project_model" }
 
diff --git a/crates/ra_batch/src/lib.rs b/crates/ra_batch/src/lib.rs
index 96b32d9fe46..fa244e86c38 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<T> = std::result::Result<T, Box<dyn Error + Send + Sync>>;
 
-#[salsa::database(
-    ra_db::SourceDatabaseStorage,
-    db::AstDatabaseStorage,
-    db::DefDatabaseStorage,
-    db::HirDatabaseStorage
-)]
-#[derive(Debug)]
-pub struct BatchDatabase {
-    runtime: salsa::Runtime<BatchDatabase>,
-}
-
-impl salsa::Database for BatchDatabase {
-    fn salsa_runtime(&self) -> &salsa::Runtime<BatchDatabase> {
-        &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::<usize>().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<SourceRootId>)> {
+    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::<usize>().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<Path>) -> Result<(BatchDatabase, Vec<SourceRootId>)> {
-        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;
             }
         }
diff --git a/crates/ra_cli/src/analysis_stats.rs b/crates/ra_cli/src/analysis_stats.rs
index c19976bd266..d76c37d847a 100644
--- a/crates/ra_cli/src/analysis_stats.rs
+++ b/crates/ra_cli/src/analysis_stats.rs
@@ -1,7 +1,6 @@
 use std::{collections::HashSet, time::Instant, fmt::Write};
 
 use ra_db::SourceDatabase;
-use ra_batch::BatchDatabase;
 use ra_hir::{Crate, ModuleDef, Ty, ImplItem, HasSource};
 use ra_syntax::AstNode;
 
@@ -9,16 +8,17 @@ use crate::Result;
 
 pub fn run(verbose: bool, path: &str, only: Option<&str>) -> Result<()> {
     let db_load_time = Instant::now();
-    let (db, roots) = BatchDatabase::load_cargo(path)?;
+    let (host, roots) = ra_batch::load_cargo(path.as_ref())?;
+    let db = host.raw_database();
     println!("Database loaded, {} roots, {:?}", roots.len(), db_load_time.elapsed());
     let analysis_time = Instant::now();
     let mut num_crates = 0;
     let mut visited_modules = HashSet::new();
     let mut visit_queue = Vec::new();
     for root in roots {
-        for krate in Crate::source_root_crates(&db, root) {
+        for krate in Crate::source_root_crates(db, root) {
             num_crates += 1;
-            let module = krate.root_module(&db).expect("crate in source root without root module");
+            let module = krate.root_module(db).expect("crate in source root without root module");
             visit_queue.push(module);
         }
     }
@@ -27,17 +27,17 @@ pub fn run(verbose: bool, path: &str, only: Option<&str>) -> Result<()> {
     let mut funcs = Vec::new();
     while let Some(module) = visit_queue.pop() {
         if visited_modules.insert(module) {
-            visit_queue.extend(module.children(&db));
+            visit_queue.extend(module.children(db));
 
-            for decl in module.declarations(&db) {
+            for decl in module.declarations(db) {
                 num_decls += 1;
                 if let ModuleDef::Function(f) = decl {
                     funcs.push(f);
                 }
             }
 
-            for impl_block in module.impl_blocks(&db) {
-                for item in impl_block.items(&db) {
+            for impl_block in module.impl_blocks(db) {
+                for item in impl_block.items(db) {
                     num_decls += 1;
                     if let ImplItem::Method(f) = item {
                         funcs.push(f);
@@ -61,11 +61,11 @@ pub fn run(verbose: bool, path: &str, only: Option<&str>) -> Result<()> {
     let mut num_exprs_unknown = 0;
     let mut num_exprs_partially_unknown = 0;
     for f in funcs {
-        let name = f.name(&db);
+        let name = f.name(db);
         let mut msg = format!("processing: {}", name);
         if verbose {
-            let src = f.source(&db);
-            let original_file = src.file_id.original_file(&db);
+            let src = f.source(db);
+            let original_file = src.file_id.original_file(db);
             let path = db.file_relative_path(original_file);
             let syntax_range = src.ast.syntax().range();
             write!(msg, " ({:?} {})", path, syntax_range).unwrap();
@@ -76,8 +76,8 @@ pub fn run(verbose: bool, path: &str, only: Option<&str>) -> Result<()> {
                 continue;
             }
         }
-        let body = f.body(&db);
-        let inference_result = f.infer(&db);
+        let body = f.body(db);
+        let inference_result = f.infer(db);
         for (expr_id, _) in body.exprs() {
             let ty = &inference_result[expr_id];
             num_exprs += 1;
diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs
index 8741e736f51..a68c5e2a588 100644
--- a/crates/ra_ide_api/src/lib.rs
+++ b/crates/ra_ide_api/src/lib.rs
@@ -276,6 +276,9 @@ impl AnalysisHost {
     pub fn collect_garbage(&mut self) {
         self.db.collect_garbage();
     }
+    pub fn raw_database(&self) -> &impl hir::db::HirDatabase {
+        &self.db
+    }
 }
 
 /// Analysis is a snapshot of a world state at a moment in time. It is the main
diff --git a/crates/ra_lsp_server/src/main.rs b/crates/ra_lsp_server/src/main.rs
index 7ed35c24a80..4aadb5ea87c 100644
--- a/crates/ra_lsp_server/src/main.rs
+++ b/crates/ra_lsp_server/src/main.rs
@@ -17,7 +17,7 @@ fn main() -> Result<()> {
         Err(_) => ra_prof::Filter::disabled(),
     });
     log::info!("lifecycle: server started");
-    match ::std::panic::catch_unwind(main_inner) {
+    match std::panic::catch_unwind(main_inner) {
         Ok(res) => {
             log::info!("lifecycle: terminating process with {:?}", res);
             res