From ee4d904cfb1b604bc8627491e05980ac43cd59e3 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 25 Oct 2018 10:57:55 +0300 Subject: Store all the data in the Salsa Database --- crates/ra_analysis/src/imp.rs | 179 +++++++++++++++++++++++------------------- 1 file changed, 98 insertions(+), 81 deletions(-) (limited to 'crates/ra_analysis/src/imp.rs') diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index f3e5b2887..97ed55465 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs @@ -1,7 +1,5 @@ use std::{ - fmt, hash::{Hash, Hasher}, - iter, sync::Arc, }; @@ -14,12 +12,16 @@ use ra_syntax::{ }; use relative_path::RelativePath; use rustc_hash::FxHashSet; +use salsa::{ParallelDatabase, Database}; use crate::{ - db::SyntaxDatabase, + AnalysisChange, + db::{ + self, SyntaxDatabase, + input::{SourceRootId, FilesDatabase, SourceRoot, WORKSPACE} + }, descriptors::module::{ModulesDatabase, ModuleTree, Problem}, descriptors::{FnDescriptor}, - roots::{ReadonlySourceRoot, SourceRoot, WritableSourceRoot}, CrateGraph, CrateId, Diagnostic, FileId, FileResolver, FileSystemEdit, Position, Query, SourceChange, SourceFileEdit, Cancelable, }; @@ -80,96 +82,123 @@ impl Default for FileResolverImp { } } -#[derive(Debug)] +#[derive(Debug, Default)] pub(crate) struct AnalysisHostImpl { - data: WorldData, + db: db::RootDatabase, } + impl AnalysisHostImpl { pub fn new() -> AnalysisHostImpl { - AnalysisHostImpl { - data: WorldData::default(), - } + AnalysisHostImpl::default() } pub fn analysis(&self) -> AnalysisImpl { AnalysisImpl { - data: self.data.clone(), + db: self.db.fork() // freeze revision here } } - pub fn change_files(&mut self, changes: &mut dyn Iterator)>) { - self.data_mut().root.apply_changes(changes, None); - } - pub fn set_file_resolver(&mut self, resolver: FileResolverImp) { - self.data_mut() - .root - .apply_changes(&mut iter::empty(), Some(resolver)); - } - pub fn set_crate_graph(&mut self, graph: CrateGraph) { - let mut visited = FxHashSet::default(); - for &file_id in graph.crate_roots.values() { - if !visited.insert(file_id) { - panic!("duplicate crate root: {:?}", file_id); + pub fn apply_change(&mut self, change: AnalysisChange) { + for (file_id, text) in change.files_changed { + self.db + .query(db::input::FileTextQuery) + .set(file_id, Arc::new(text)) + } + if !(change.files_added.is_empty() && change.files_removed.is_empty()) { + let file_resolver = change.file_resolver + .expect("change resolver when changing set of files"); + let mut source_root = SourceRoot::clone(&self.db.source_root(WORKSPACE)); + for (file_id, text) in change.files_added { + self.db + .query(db::input::FileTextQuery) + .set(file_id, Arc::new(text)); + self.db + .query(db::input::FileSourceRootQuery) + .set(file_id, db::input::WORKSPACE); + source_root.files.insert(file_id); + } + for file_id in change.files_removed { + self.db + .query(db::input::FileTextQuery) + .set(file_id, Arc::new(String::new())); + source_root.files.remove(&file_id); } + source_root.file_resolver = file_resolver; + self.db + .query(db::input::SourceRootQuery) + .set(WORKSPACE, Arc::new(source_root)) + } + if !change.libraries_added.is_empty() { + let mut libraries = Vec::clone(&self.db.libraries()); + for library in change.libraries_added { + let source_root_id = SourceRootId(1 + libraries.len() as u32); + libraries.push(source_root_id); + let mut files = FxHashSet::default(); + for (file_id, text) in library.files { + files.insert(file_id); + self.db + .query(db::input::FileSourceRootQuery) + .set_constant(file_id, source_root_id); + self.db + .query(db::input::FileTextQuery) + .set_constant(file_id, Arc::new(text)); + } + let source_root = SourceRoot { + files, + file_resolver: library.file_resolver, + }; + self.db + .query(db::input::SourceRootQuery) + .set(source_root_id, Arc::new(source_root)); + self.db + .query(db::input::LibrarySymbolsQuery) + .set(source_root_id, Arc::new(library.symbol_index)); + } + self.db + .query(db::input::LibrarieseQuery) + .set((), Arc::new(libraries)); + } + if let Some(crate_graph) = change.crate_graph { + self.db.query(db::input::CrateGraphQuery) + .set((), Arc::new(crate_graph)) } - self.data_mut().crate_graph = graph; - } - pub fn add_library(&mut self, root: ReadonlySourceRoot) { - self.data_mut().libs.push(root); - } - fn data_mut(&mut self) -> &mut WorldData { - &mut self.data } } +#[derive(Debug)] pub(crate) struct AnalysisImpl { - data: WorldData, -} - -impl fmt::Debug for AnalysisImpl { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.data.fmt(f) - } + db: db::RootDatabase, } impl AnalysisImpl { - fn root(&self, file_id: FileId) -> &SourceRoot { - if self.data.root.contains(file_id) { - return &self.data.root; - } - self - .data - .libs - .iter() - .find(|it| it.contains(file_id)) - .unwrap() - } pub fn file_syntax(&self, file_id: FileId) -> File { - self.root(file_id).db().file_syntax(file_id) + self.db.file_syntax(file_id) } pub fn file_line_index(&self, file_id: FileId) -> Arc { - self.root(file_id).db().file_lines(file_id) + self.db.file_lines(file_id) } pub fn world_symbols(&self, query: Query) -> Cancelable> { let mut buf = Vec::new(); - if query.libs { - for lib in self.data.libs.iter() { - lib.symbols(&mut buf)?; - } - } else { - self.data.root.symbols(&mut buf)?; + for &lib_id in self.db.libraries().iter() { + buf.push(self.db.library_symbols(lib_id)); + } + for &file_id in self.db.source_root(WORKSPACE).files.iter() { + buf.push(self.db.file_symbols(file_id)?); } Ok(query.search(&buf)) } + fn module_tree(&self, file_id: FileId) -> Cancelable> { + let source_root = self.db.file_source_root(file_id); + self.db.module_tree(source_root) + } pub fn parent_module(&self, file_id: FileId) -> Cancelable> { - let root = self.root(file_id); - let module_tree = root.db().module_tree()?; + let module_tree = self.module_tree(file_id)?; let res = module_tree.modules_for_file(file_id) .into_iter() .filter_map(|module_id| { let link = module_id.parent_link(&module_tree)?; let file_id = link.owner(&module_tree).file_id(&module_tree); - let syntax = root.db().file_syntax(file_id); + let syntax = self.db.file_syntax(file_id); let decl = link.bind_source(&module_tree, syntax.ast()); let sym = FileSymbol { @@ -183,8 +212,8 @@ impl AnalysisImpl { Ok(res) } pub fn crate_for(&self, file_id: FileId) -> Cancelable> { - let module_tree = self.root(file_id).db().module_tree()?; - let crate_graph = &self.data.crate_graph; + let module_tree = self.module_tree(file_id)?; + let crate_graph = self.db.crate_graph(); let res = module_tree.modules_for_file(file_id) .into_iter() .map(|it| it.root(&module_tree)) @@ -195,7 +224,7 @@ impl AnalysisImpl { Ok(res) } pub fn crate_root(&self, crate_id: CrateId) -> FileId { - self.data.crate_graph.crate_roots[&crate_id] + self.db.crate_graph().crate_roots[&crate_id] } pub fn completions(&self, file_id: FileId, offset: TextUnit) -> Cancelable>> { let mut res = Vec::new(); @@ -205,8 +234,7 @@ impl AnalysisImpl { res.extend(scope_based); has_completions = true; } - let root = self.root(file_id); - if let Some(scope_based) = crate::completion::resolve_based_completion(root.db(), file_id, offset)? { + if let Some(scope_based) = crate::completion::resolve_based_completion(&self.db, file_id, offset)? { res.extend(scope_based); has_completions = true; } @@ -222,9 +250,8 @@ impl AnalysisImpl { file_id: FileId, offset: TextUnit, ) -> Cancelable> { - let root = self.root(file_id); - let module_tree = root.db().module_tree()?; - let file = root.db().file_syntax(file_id); + let module_tree = self.module_tree(file_id)?; + let file = self.db.file_syntax(file_id); let syntax = file.syntax(); if let Some(name_ref) = find_node_at_offset::(syntax, offset) { // First try to resolve the symbol locally @@ -273,8 +300,7 @@ impl AnalysisImpl { } pub fn find_all_refs(&self, file_id: FileId, offset: TextUnit) -> Vec<(FileId, TextRange)> { - let root = self.root(file_id); - let file = root.db().file_syntax(file_id); + let file = self.db.file_syntax(file_id); let syntax = file.syntax(); let mut ret = vec![]; @@ -305,9 +331,8 @@ impl AnalysisImpl { } pub fn diagnostics(&self, file_id: FileId) -> Cancelable> { - let root = self.root(file_id); - let module_tree = root.db().module_tree()?; - let syntax = root.db().file_syntax(file_id); + let module_tree = self.module_tree(file_id)?; + let syntax = self.db.file_syntax(file_id); let mut res = ra_editor::diagnostics(&syntax) .into_iter() @@ -396,8 +421,7 @@ impl AnalysisImpl { file_id: FileId, offset: TextUnit, ) -> Cancelable)>> { - let root = self.root(file_id); - let file = root.db().file_syntax(file_id); + let file = self.db.file_syntax(file_id); let syntax = file.syntax(); // Find the calling expression and it's NameRef @@ -491,13 +515,6 @@ impl AnalysisImpl { } } -#[derive(Default, Clone, Debug)] -struct WorldData { - crate_graph: CrateGraph, - root: WritableSourceRoot, - libs: Vec, -} - impl SourceChange { pub(crate) fn from_local_edit(file_id: FileId, label: &str, edit: LocalEdit) -> SourceChange { let file_edit = SourceFileEdit { -- cgit v1.2.3 From 56df0fc83c753b7fb8829438c8d3017ef1bf450c Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 25 Oct 2018 16:03:49 +0300 Subject: Improve logging --- crates/ra_analysis/src/imp.rs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'crates/ra_analysis/src/imp.rs') diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index 97ed55465..6c1a4749a 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs @@ -98,6 +98,8 @@ impl AnalysisHostImpl { } } pub fn apply_change(&mut self, change: AnalysisChange) { + log::info!("apply_change {:?}", change); + for (file_id, text) in change.files_changed { self.db .query(db::input::FileTextQuery) -- cgit v1.2.3 From 772acb53f2d7568ff1cc2ba4ca84a47110f13b3a Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 25 Oct 2018 16:25:24 +0300 Subject: use correct file when resolving callables --- crates/ra_analysis/src/imp.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'crates/ra_analysis/src/imp.rs') diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index 6c1a4749a..b24b5cfdc 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs @@ -438,9 +438,10 @@ impl AnalysisImpl { // Resolve the function's NameRef (NOTE: this isn't entirely accurate). let file_symbols = self.index_resolve(name_ref)?; - for (_, fs) in file_symbols { + for (fn_fiel_id, fs) in file_symbols { if fs.kind == FN_DEF { - if let Some(fn_def) = find_node_at_offset(syntax, fs.node_range.start()) { + let fn_file = self.db.file_syntax(fn_fiel_id); + if let Some(fn_def) = find_node_at_offset(fn_file.syntax(), fs.node_range.start()) { if let Some(descriptor) = FnDescriptor::new(fn_def) { // If we have a calling expression let's find which argument we are on let mut current_parameter = None; -- cgit v1.2.3 From d19001957172287afee90bd4fc3d037d2ce6f5dd Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 25 Oct 2018 17:52:50 +0300 Subject: Move input to top-level --- crates/ra_analysis/src/imp.rs | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'crates/ra_analysis/src/imp.rs') diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index b24b5cfdc..69f5ed330 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs @@ -18,8 +18,9 @@ use crate::{ AnalysisChange, db::{ self, SyntaxDatabase, - input::{SourceRootId, FilesDatabase, SourceRoot, WORKSPACE} + }, + input::{SourceRootId, FilesDatabase, SourceRoot, WORKSPACE}, descriptors::module::{ModulesDatabase, ModuleTree, Problem}, descriptors::{FnDescriptor}, CrateGraph, CrateId, Diagnostic, FileId, FileResolver, FileSystemEdit, Position, @@ -102,7 +103,7 @@ impl AnalysisHostImpl { for (file_id, text) in change.files_changed { self.db - .query(db::input::FileTextQuery) + .query(crate::input::FileTextQuery) .set(file_id, Arc::new(text)) } if !(change.files_added.is_empty() && change.files_removed.is_empty()) { @@ -111,22 +112,22 @@ impl AnalysisHostImpl { let mut source_root = SourceRoot::clone(&self.db.source_root(WORKSPACE)); for (file_id, text) in change.files_added { self.db - .query(db::input::FileTextQuery) + .query(crate::input::FileTextQuery) .set(file_id, Arc::new(text)); self.db - .query(db::input::FileSourceRootQuery) - .set(file_id, db::input::WORKSPACE); + .query(crate::input::FileSourceRootQuery) + .set(file_id, crate::input::WORKSPACE); source_root.files.insert(file_id); } for file_id in change.files_removed { self.db - .query(db::input::FileTextQuery) + .query(crate::input::FileTextQuery) .set(file_id, Arc::new(String::new())); source_root.files.remove(&file_id); } source_root.file_resolver = file_resolver; self.db - .query(db::input::SourceRootQuery) + .query(crate::input::SourceRootQuery) .set(WORKSPACE, Arc::new(source_root)) } if !change.libraries_added.is_empty() { @@ -138,10 +139,10 @@ impl AnalysisHostImpl { for (file_id, text) in library.files { files.insert(file_id); self.db - .query(db::input::FileSourceRootQuery) + .query(crate::input::FileSourceRootQuery) .set_constant(file_id, source_root_id); self.db - .query(db::input::FileTextQuery) + .query(crate::input::FileTextQuery) .set_constant(file_id, Arc::new(text)); } let source_root = SourceRoot { @@ -149,18 +150,18 @@ impl AnalysisHostImpl { file_resolver: library.file_resolver, }; self.db - .query(db::input::SourceRootQuery) + .query(crate::input::SourceRootQuery) .set(source_root_id, Arc::new(source_root)); self.db - .query(db::input::LibrarySymbolsQuery) + .query(crate::input::LibrarySymbolsQuery) .set(source_root_id, Arc::new(library.symbol_index)); } self.db - .query(db::input::LibrarieseQuery) + .query(crate::input::LibrarieseQuery) .set((), Arc::new(libraries)); } if let Some(crate_graph) = change.crate_graph { - self.db.query(db::input::CrateGraphQuery) + self.db.query(crate::input::CrateGraphQuery) .set((), Arc::new(crate_graph)) } } -- cgit v1.2.3 From 363adf07b7763cfe7e13fac0ee148361d51834e4 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 25 Oct 2018 17:59:03 +0300 Subject: restore symbols filtering --- crates/ra_analysis/src/imp.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'crates/ra_analysis/src/imp.rs') diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index 69f5ed330..5a6e2450d 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs @@ -181,11 +181,14 @@ impl AnalysisImpl { } pub fn world_symbols(&self, query: Query) -> Cancelable> { let mut buf = Vec::new(); - for &lib_id in self.db.libraries().iter() { - buf.push(self.db.library_symbols(lib_id)); - } - for &file_id in self.db.source_root(WORKSPACE).files.iter() { - buf.push(self.db.file_symbols(file_id)?); + if query.libs { + for &lib_id in self.db.libraries().iter() { + buf.push(self.db.library_symbols(lib_id)); + } + } else { + for &file_id in self.db.source_root(WORKSPACE).files.iter() { + buf.push(self.db.file_symbols(file_id)?); + } } Ok(query.search(&buf)) } -- cgit v1.2.3