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/completion.rs | 5 +- crates/ra_analysis/src/db.rs | 136 ----------------- crates/ra_analysis/src/db/input.rs | 83 +++++++++++ crates/ra_analysis/src/db/mod.rs | 107 ++++++++++++++ crates/ra_analysis/src/descriptors/module/imp.rs | 22 +-- crates/ra_analysis/src/descriptors/module/mod.rs | 10 +- crates/ra_analysis/src/imp.rs | 179 +++++++++++++---------- crates/ra_analysis/src/lib.rs | 81 +++++++--- crates/ra_analysis/src/symbol_index.rs | 2 +- crates/ra_analysis/tests/tests.rs | 20 ++- crates/ra_lsp_server/src/path_map.rs | 13 +- crates/ra_lsp_server/src/server_world.rs | 70 ++++++--- 12 files changed, 433 insertions(+), 295 deletions(-) delete mode 100644 crates/ra_analysis/src/db.rs create mode 100644 crates/ra_analysis/src/db/input.rs create mode 100644 crates/ra_analysis/src/db/mod.rs diff --git a/crates/ra_analysis/src/completion.rs b/crates/ra_analysis/src/completion.rs index a0fd6828d..04bb82c18 100644 --- a/crates/ra_analysis/src/completion.rs +++ b/crates/ra_analysis/src/completion.rs @@ -6,13 +6,14 @@ use ra_syntax::{ use crate::{ FileId, Cancelable, - db::{self, SyntaxDatabase}, + db::{self, SyntaxDatabase, input::FilesDatabase}, descriptors::module::{ModulesDatabase, ModuleTree, ModuleId}, }; pub(crate) fn resolve_based_completion(db: &db::RootDatabase, file_id: FileId, offset: TextUnit) -> Cancelable>> { + let source_root_id = db.file_source_root(file_id); let file = db.file_syntax(file_id); - let module_tree = db.module_tree()?; + let module_tree = db.module_tree(source_root_id)?; let file = { let edit = AtomEdit::insert(offset, "intellijRulezz".to_string()); file.reparse(&edit) diff --git a/crates/ra_analysis/src/db.rs b/crates/ra_analysis/src/db.rs deleted file mode 100644 index b527cde61..000000000 --- a/crates/ra_analysis/src/db.rs +++ /dev/null @@ -1,136 +0,0 @@ -use std::{ - fmt, - hash::{Hash, Hasher}, - sync::Arc, -}; - -use ra_editor::LineIndex; -use ra_syntax::File; -use rustc_hash::FxHashSet; -use salsa; - -use crate::{ - db, - Cancelable, Canceled, - descriptors::module::{SubmodulesQuery, ModuleTreeQuery, ModulesDatabase}, - symbol_index::SymbolIndex, - FileId, FileResolverImp, -}; - -#[derive(Default)] -pub(crate) struct RootDatabase { - runtime: salsa::Runtime, -} - -impl fmt::Debug for RootDatabase { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.write_str("RootDatabase { ... }") - } -} - -impl salsa::Database for RootDatabase { - fn salsa_runtime(&self) -> &salsa::Runtime { - &self.runtime - } -} - -pub(crate) fn check_canceled(db: &impl salsa::Database) -> Cancelable<()> { - if db.salsa_runtime().is_current_revision_canceled() { - Err(Canceled) - } else { - Ok(()) - } -} - -impl salsa::ParallelDatabase for RootDatabase { - fn fork(&self) -> Self { - RootDatabase { - runtime: self.runtime.fork(), - } - } -} - -impl Clone for RootDatabase { - fn clone(&self) -> RootDatabase { - salsa::ParallelDatabase::fork(self) - } -} - -salsa::database_storage! { - pub(crate) struct RootDatabaseStorage for RootDatabase { - impl FilesDatabase { - fn file_text() for FileTextQuery; - fn file_set() for FileSetQuery; - } - impl SyntaxDatabase { - fn file_syntax() for FileSyntaxQuery; - fn file_lines() for FileLinesQuery; - fn file_symbols() for FileSymbolsQuery; - } - impl ModulesDatabase { - fn module_tree() for ModuleTreeQuery; - fn module_descriptor() for SubmodulesQuery; - } - } -} - -salsa::query_group! { - pub(crate) trait FilesDatabase: salsa::Database { - fn file_text(file_id: FileId) -> Arc { - type FileTextQuery; - storage input; - } - fn file_set() -> Arc { - type FileSetQuery; - storage input; - } - } -} - -#[derive(Default, Debug, Eq)] -pub(crate) struct FileSet { - pub(crate) files: FxHashSet, - pub(crate) resolver: FileResolverImp, -} - -impl PartialEq for FileSet { - fn eq(&self, other: &FileSet) -> bool { - self.files == other.files && self.resolver == other.resolver - } -} - -impl Hash for FileSet { - fn hash(&self, hasher: &mut H) { - let mut files = self.files.iter().cloned().collect::>(); - files.sort(); - files.hash(hasher); - } -} - -salsa::query_group! { - pub(crate) trait SyntaxDatabase: FilesDatabase { - fn file_syntax(file_id: FileId) -> File { - type FileSyntaxQuery; - } - fn file_lines(file_id: FileId) -> Arc { - type FileLinesQuery; - } - fn file_symbols(file_id: FileId) -> Cancelable> { - type FileSymbolsQuery; - } - } -} - -fn file_syntax(db: &impl SyntaxDatabase, file_id: FileId) -> File { - let text = db.file_text(file_id); - File::parse(&*text) -} -fn file_lines(db: &impl SyntaxDatabase, file_id: FileId) -> Arc { - let text = db.file_text(file_id); - Arc::new(LineIndex::new(&*text)) -} -fn file_symbols(db: &impl SyntaxDatabase, file_id: FileId) -> Cancelable> { - db::check_canceled(db)?; - let syntax = db.file_syntax(file_id); - Ok(Arc::new(SymbolIndex::for_file(file_id, syntax))) -} diff --git a/crates/ra_analysis/src/db/input.rs b/crates/ra_analysis/src/db/input.rs new file mode 100644 index 000000000..957d082f9 --- /dev/null +++ b/crates/ra_analysis/src/db/input.rs @@ -0,0 +1,83 @@ +use std::{ + sync::Arc, + hash::{Hasher, Hash}, +}; + +use salsa; +use rustc_hash::FxHashSet; + +use crate::{FileId, FileResolverImp, CrateGraph, symbol_index::SymbolIndex}; + +salsa::query_group! { + pub(crate) trait FilesDatabase: salsa::Database { + fn file_text(file_id: FileId) -> Arc { + type FileTextQuery; + storage input; + } + fn file_source_root(file_id: FileId) -> SourceRootId { + type FileSourceRootQuery; + storage input; + } + fn source_root(id: SourceRootId) -> Arc { + type SourceRootQuery; + storage input; + } + fn libraries() -> Arc> { + type LibrarieseQuery; + storage input; + } + fn library_symbols(id: SourceRootId) -> Arc { + type LibrarySymbolsQuery; + storage input; + } + fn crate_graph() -> Arc { + type CrateGraphQuery; + storage input; + } + } +} + +#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub(crate) struct SourceRootId(pub(crate) u32); + +#[derive(Clone, Default, Debug, Eq)] +pub(crate) struct SourceRoot { + pub(crate) file_resolver: FileResolverImp, + pub(crate) files: FxHashSet, +} + +impl PartialEq for SourceRoot { + fn eq(&self, other: &SourceRoot) -> bool { + self.file_resolver == other.file_resolver + } +} + +impl Hash for SourceRoot { + fn hash(&self, hasher: &mut H) { + self.file_resolver.hash(hasher); + } +} + +pub(crate) const WORKSPACE: SourceRootId = SourceRootId(0); + + +#[derive(Default, Debug, Eq)] +pub(crate) struct FileSet { + pub(crate) files: FxHashSet, + pub(crate) resolver: FileResolverImp, +} + +impl PartialEq for FileSet { + fn eq(&self, other: &FileSet) -> bool { + self.files == other.files && self.resolver == other.resolver + } +} + +impl Hash for FileSet { + fn hash(&self, hasher: &mut H) { + let mut files = self.files.iter().cloned().collect::>(); + files.sort(); + files.hash(hasher); + } +} + diff --git a/crates/ra_analysis/src/db/mod.rs b/crates/ra_analysis/src/db/mod.rs new file mode 100644 index 000000000..8387118ad --- /dev/null +++ b/crates/ra_analysis/src/db/mod.rs @@ -0,0 +1,107 @@ +pub(crate) mod input; + +use std::{ + fmt, + sync::Arc, +}; + +use ra_editor::LineIndex; +use ra_syntax::File; +use salsa; + +use crate::{ + db, + Cancelable, Canceled, + descriptors::module::{SubmodulesQuery, ModuleTreeQuery, ModulesDatabase}, + symbol_index::SymbolIndex, + FileId, +}; + +#[derive(Default)] +pub(crate) struct RootDatabase { + runtime: salsa::Runtime, +} + +impl fmt::Debug for RootDatabase { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.write_str("RootDatabase { ... }") + } +} + +impl salsa::Database for RootDatabase { + fn salsa_runtime(&self) -> &salsa::Runtime { + &self.runtime + } +} + +pub(crate) fn check_canceled(db: &impl salsa::Database) -> Cancelable<()> { + if db.salsa_runtime().is_current_revision_canceled() { + Err(Canceled) + } else { + Ok(()) + } +} + +impl salsa::ParallelDatabase for RootDatabase { + fn fork(&self) -> Self { + RootDatabase { + runtime: self.runtime.fork(), + } + } +} + +impl Clone for RootDatabase { + fn clone(&self) -> RootDatabase { + salsa::ParallelDatabase::fork(self) + } +} + +salsa::database_storage! { + pub(crate) struct RootDatabaseStorage for RootDatabase { + impl input::FilesDatabase { + fn file_text() for input::FileTextQuery; + fn file_source_root() for input::FileSourceRootQuery; + fn source_root() for input::SourceRootQuery; + fn libraries() for input::LibrarieseQuery; + fn library_symbols() for input::LibrarySymbolsQuery; + fn crate_graph() for input::CrateGraphQuery; + } + impl SyntaxDatabase { + fn file_syntax() for FileSyntaxQuery; + fn file_lines() for FileLinesQuery; + fn file_symbols() for FileSymbolsQuery; + } + impl ModulesDatabase { + fn module_tree() for ModuleTreeQuery; + fn module_descriptor() for SubmodulesQuery; + } + } +} + +salsa::query_group! { + pub(crate) trait SyntaxDatabase: input::FilesDatabase { + fn file_syntax(file_id: FileId) -> File { + type FileSyntaxQuery; + } + fn file_lines(file_id: FileId) -> Arc { + type FileLinesQuery; + } + fn file_symbols(file_id: FileId) -> Cancelable> { + type FileSymbolsQuery; + } + } +} + +fn file_syntax(db: &impl SyntaxDatabase, file_id: FileId) -> File { + let text = db.file_text(file_id); + File::parse(&*text) +} +fn file_lines(db: &impl SyntaxDatabase, file_id: FileId) -> Arc { + let text = db.file_text(file_id); + Arc::new(LineIndex::new(&*text)) +} +fn file_symbols(db: &impl SyntaxDatabase, file_id: FileId) -> Cancelable> { + db::check_canceled(db)?; + let syntax = db.file_syntax(file_id); + Ok(Arc::new(SymbolIndex::for_file(file_id, syntax))) +} diff --git a/crates/ra_analysis/src/descriptors/module/imp.rs b/crates/ra_analysis/src/descriptors/module/imp.rs index 22e4bd785..6a408dc89 100644 --- a/crates/ra_analysis/src/descriptors/module/imp.rs +++ b/crates/ra_analysis/src/descriptors/module/imp.rs @@ -9,7 +9,7 @@ use ra_syntax::{ use crate::{ FileId, Cancelable, FileResolverImp, - db, + db::{self, input::{SourceRoot, SourceRootId}}, }; use super::{ @@ -35,9 +35,12 @@ pub(super) fn modules(root: ast::Root<'_>) -> impl Iterator Cancelable> { +pub(super) fn module_tree( + db: &impl ModulesDatabase, + source_root: SourceRootId, +) -> Cancelable> { db::check_canceled(db)?; - let res = create_module_tree(db)?; + let res = create_module_tree(db, source_root)?; Ok(Arc::new(res)) } @@ -50,6 +53,7 @@ pub struct Submodule { fn create_module_tree<'a>( db: &impl ModulesDatabase, + source_root: SourceRootId, ) -> Cancelable { let mut tree = ModuleTree { mods: Vec::new(), @@ -59,12 +63,13 @@ fn create_module_tree<'a>( let mut roots = FxHashMap::default(); let mut visited = FxHashSet::default(); - for &file_id in db.file_set().files.iter() { + let source_root = db.source_root(source_root); + for &file_id in source_root.files.iter() { if visited.contains(&file_id) { continue; // TODO: use explicit crate_roots here } assert!(!roots.contains_key(&file_id)); - let module_id = build_subtree(db, &mut tree, &mut visited, &mut roots, None, file_id)?; + let module_id = build_subtree(db, &source_root, &mut tree, &mut visited, &mut roots, None, file_id)?; roots.insert(file_id, module_id); } Ok(tree) @@ -72,6 +77,7 @@ fn create_module_tree<'a>( fn build_subtree( db: &impl ModulesDatabase, + source_root: &SourceRoot, tree: &mut ModuleTree, visited: &mut FxHashSet, roots: &mut FxHashMap, @@ -84,10 +90,8 @@ fn build_subtree( parent, children: Vec::new(), }); - let file_set = db.file_set(); - let file_resolver = &file_set.resolver; for name in db.submodules(file_id)?.iter() { - let (points_to, problem) = resolve_submodule(file_id, name, file_resolver); + let (points_to, problem) = resolve_submodule(file_id, name, &source_root.file_resolver); let link = tree.push_link(LinkData { name: name.clone(), owner: id, @@ -102,7 +106,7 @@ fn build_subtree( tree.module_mut(module_id).parent = Some(link); Ok(module_id) } - None => build_subtree(db, tree, visited, roots, Some(link), file_id), + None => build_subtree(db, source_root, tree, visited, roots, Some(link), file_id), }) .collect::>>()?; tree.link_mut(link).points_to = points_to; diff --git a/crates/ra_analysis/src/descriptors/module/mod.rs b/crates/ra_analysis/src/descriptors/module/mod.rs index 52da650b3..98024cc15 100644 --- a/crates/ra_analysis/src/descriptors/module/mod.rs +++ b/crates/ra_analysis/src/descriptors/module/mod.rs @@ -7,12 +7,12 @@ use ra_syntax::{ast::{self, NameOwner, AstNode}, SmolStr, SyntaxNode}; use crate::{ FileId, Cancelable, - db::SyntaxDatabase, + db::{SyntaxDatabase, input::SourceRootId}, }; salsa::query_group! { pub(crate) trait ModulesDatabase: SyntaxDatabase { - fn module_tree() -> Cancelable> { + fn module_tree(source_root_id: SourceRootId) -> Cancelable> { type ModuleTreeQuery; use fn imp::module_tree; } @@ -110,15 +110,9 @@ impl ModuleId { } impl LinkId { - pub(crate) fn name(self, tree: &ModuleTree) -> SmolStr { - tree.link(self).name.clone() - } pub(crate) fn owner(self, tree: &ModuleTree) -> ModuleId { tree.link(self).owner } - fn points_to(self, tree: &ModuleTree) -> &[ModuleId] { - &tree.link(self).points_to - } pub(crate) fn bind_source<'a>( self, tree: &ModuleTree, 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 { diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index 7078e2d31..4a1ae3b64 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs @@ -9,17 +9,23 @@ extern crate salsa; mod db; mod descriptors; mod imp; -mod roots; mod symbol_index; mod completion; -use std::{fmt::Debug, sync::Arc}; +use std::{ + fmt::Debug, + sync::Arc, + collections::BTreeMap, +}; use ra_syntax::{AtomEdit, File, TextRange, TextUnit}; use relative_path::{RelativePath, RelativePathBuf}; -use rustc_hash::FxHashMap; +use rayon::prelude::*; -use crate::imp::{AnalysisHostImpl, AnalysisImpl, FileResolverImp}; +use crate::{ + imp::{AnalysisHostImpl, AnalysisImpl, FileResolverImp}, + symbol_index::SymbolIndex, +}; pub use crate::{ descriptors::FnDescriptor, @@ -49,9 +55,9 @@ pub struct FileId(pub u32); #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct CrateId(pub u32); -#[derive(Debug, Clone, Default)] +#[derive(Debug, Clone, Default, PartialEq, Eq, Hash)] pub struct CrateGraph { - pub crate_roots: FxHashMap, + pub crate_roots: BTreeMap, } pub trait FileResolver: Debug + Send + Sync + 'static { @@ -59,6 +65,41 @@ pub trait FileResolver: Debug + Send + Sync + 'static { fn resolve(&self, file_id: FileId, path: &RelativePath) -> Option; } +#[derive(Debug, Default)] +pub struct AnalysisChange { + files_added: Vec<(FileId, String)>, + files_changed: Vec<(FileId, String)>, + files_removed: Vec<(FileId)>, + libraries_added: Vec, + crate_graph: Option, + file_resolver: Option, +} + + +impl AnalysisChange { + pub fn new() -> AnalysisChange { + AnalysisChange::default() + } + pub fn add_file(&mut self, file_id: FileId, text: String) { + self.files_added.push((file_id, text)) + } + pub fn change_file(&mut self, file_id: FileId, new_text: String) { + self.files_changed.push((file_id, new_text)) + } + pub fn remove_file(&mut self, file_id: FileId) { + self.files_removed.push(file_id) + } + pub fn add_library(&mut self, data: LibraryData) { + self.libraries_added.push(data) + } + pub fn set_crate_graph(&mut self, graph: CrateGraph) { + self.crate_graph = Some(graph); + } + pub fn set_file_resolver(&mut self, file_resolver: Arc) { + self.file_resolver = Some(FileResolverImp::new(file_resolver)); + } +} + #[derive(Debug)] pub struct AnalysisHost { imp: AnalysisHostImpl, @@ -75,20 +116,8 @@ impl AnalysisHost { imp: self.imp.analysis(), } } - pub fn change_file(&mut self, file_id: FileId, text: Option) { - self.change_files(::std::iter::once((file_id, text))); - } - pub fn change_files(&mut self, mut changes: impl Iterator)>) { - self.imp.change_files(&mut changes) - } - pub fn set_file_resolver(&mut self, resolver: Arc) { - self.imp.set_file_resolver(FileResolverImp::new(resolver)); - } - pub fn set_crate_graph(&mut self, graph: CrateGraph) { - self.imp.set_crate_graph(graph) - } - pub fn add_library(&mut self, data: LibraryData) { - self.imp.add_library(data.root) + pub fn apply_change(&mut self, change: AnalysisChange) { + self.imp.apply_change(change) } } @@ -266,14 +295,18 @@ impl Analysis { #[derive(Debug)] pub struct LibraryData { - root: roots::ReadonlySourceRoot, + files: Vec<(FileId, String)>, + file_resolver: FileResolverImp, + symbol_index: SymbolIndex, } impl LibraryData { pub fn prepare(files: Vec<(FileId, String)>, file_resolver: Arc) -> LibraryData { - let file_resolver = FileResolverImp::new(file_resolver); - let root = roots::ReadonlySourceRoot::new(files, file_resolver); - LibraryData { root } + let symbol_index = SymbolIndex::for_files(files.par_iter().map(|(file_id, text)| { + let file = File::parse(text); + (*file_id, file) + })); + LibraryData { files, file_resolver: FileResolverImp::new(file_resolver), symbol_index } } } diff --git a/crates/ra_analysis/src/symbol_index.rs b/crates/ra_analysis/src/symbol_index.rs index e5c8d8870..5f302cbda 100644 --- a/crates/ra_analysis/src/symbol_index.rs +++ b/crates/ra_analysis/src/symbol_index.rs @@ -13,7 +13,7 @@ use rayon::prelude::*; use crate::{FileId, Query}; -#[derive(Debug)] +#[derive(Default, Debug)] pub(crate) struct SymbolIndex { symbols: Vec<(FileId, FileSymbol)>, map: fst::Map, diff --git a/crates/ra_analysis/tests/tests.rs b/crates/ra_analysis/tests/tests.rs index 52fae71ae..198d6a263 100644 --- a/crates/ra_analysis/tests/tests.rs +++ b/crates/ra_analysis/tests/tests.rs @@ -5,15 +5,17 @@ extern crate relative_path; extern crate rustc_hash; extern crate test_utils; -use std::sync::Arc; +use std::{ + sync::Arc, + collections::BTreeMap, +}; use ra_syntax::TextRange; use relative_path::{RelativePath, RelativePathBuf}; -use rustc_hash::FxHashMap; use test_utils::{assert_eq_dbg, extract_offset}; use ra_analysis::{ - Analysis, AnalysisHost, CrateGraph, CrateId, FileId, FileResolver, FnDescriptor, + AnalysisChange, Analysis, AnalysisHost, CrateGraph, CrateId, FileId, FileResolver, FnDescriptor, }; #[derive(Debug)] @@ -45,14 +47,16 @@ impl FileResolver for FileMap { fn analysis_host(files: &[(&str, &str)]) -> AnalysisHost { let mut host = AnalysisHost::new(); let mut file_map = Vec::new(); + let mut change = AnalysisChange::new(); for (id, &(path, contents)) in files.iter().enumerate() { let file_id = FileId((id + 1) as u32); assert!(path.starts_with('/')); let path = RelativePathBuf::from_path(&path[1..]).unwrap(); - host.change_file(file_id, Some(contents.to_string())); + change.add_file(file_id, contents.to_string()); file_map.push((file_id, path)); } - host.set_file_resolver(Arc::new(FileMap(file_map))); + change.set_file_resolver(Arc::new(FileMap(file_map))); + host.apply_change(change); host } @@ -128,12 +132,14 @@ fn test_resolve_crate_root() { let crate_graph = CrateGraph { crate_roots: { - let mut m = FxHashMap::default(); + let mut m = BTreeMap::default(); m.insert(CrateId(1), FileId(1)); m }, }; - host.set_crate_graph(crate_graph); + let mut change = AnalysisChange::new(); + change.set_crate_graph(crate_graph); + host.apply_change(change); let snap = host.analysis(); assert_eq!(snap.crate_for(FileId(2)).unwrap(), vec![CrateId(1)],); diff --git a/crates/ra_lsp_server/src/path_map.rs b/crates/ra_lsp_server/src/path_map.rs index d32829382..b3d1dc3db 100644 --- a/crates/ra_lsp_server/src/path_map.rs +++ b/crates/ra_lsp_server/src/path_map.rs @@ -22,15 +22,18 @@ impl PathMap { pub fn new() -> PathMap { Default::default() } - pub fn get_or_insert(&mut self, path: PathBuf, root: Root) -> FileId { - self.path2id + pub fn get_or_insert(&mut self, path: PathBuf, root: Root) -> (bool, FileId) { + let mut inserted = false; + let file_id = self.path2id .get(path.as_path()) .map(|&id| id) .unwrap_or_else(|| { + inserted = true; let id = self.new_file_id(); self.insert(path, id, root); id - }) + }); + (inserted, file_id) } pub fn get_id(&self, path: &Path) -> Option { self.path2id.get(path).map(|&id| id) @@ -105,8 +108,8 @@ mod test { #[test] fn test_resolve() { let mut m = PathMap::new(); - let id1 = m.get_or_insert(PathBuf::from("/foo"), Root::Workspace); - let id2 = m.get_or_insert(PathBuf::from("/foo/bar.rs"), Root::Workspace); + let (_, id1) = m.get_or_insert(PathBuf::from("/foo"), Root::Workspace); + let (_, id2) = m.get_or_insert(PathBuf::from("/foo/bar.rs"), Root::Workspace); assert_eq!(m.resolve(id1, &RelativePath::new("bar.rs")), Some(id2),) } } diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/server_world.rs index 69b2a1cd1..555de66ff 100644 --- a/crates/ra_lsp_server/src/server_world.rs +++ b/crates/ra_lsp_server/src/server_world.rs @@ -2,10 +2,11 @@ use std::{ fs, path::{Path, PathBuf}, sync::Arc, + collections::BTreeMap, }; use languageserver_types::Url; -use ra_analysis::{Analysis, AnalysisHost, CrateGraph, CrateId, FileId, FileResolver, LibraryData}; +use ra_analysis::{Analysis, AnalysisHost, AnalysisChange, CrateGraph, CrateId, FileId, FileResolver, LibraryData}; use rustc_hash::FxHashMap; use crate::{ @@ -39,30 +40,40 @@ impl ServerWorldState { } } pub fn apply_fs_changes(&mut self, events: Vec) { + let mut change = AnalysisChange::new(); + let mut inserted = false; { let pm = &mut self.path_map; let mm = &mut self.mem_map; - let changes = events + events .into_iter() .map(|event| { let text = match event.kind { - FileEventKind::Add(text) => Some(text), + FileEventKind::Add(text) => text, }; (event.path, text) }) - .map(|(path, text)| (pm.get_or_insert(path, Root::Workspace), text)) - .filter_map(|(id, text)| { - if mm.contains_key(&id) { - mm.insert(id, text); + .map(|(path, text)| { + let (ins, file_id) = pm.get_or_insert(path, Root::Workspace); + inserted |= ins; + (file_id, text) + }) + .filter_map(|(file_id, text)| { + if mm.contains_key(&file_id) { + mm.insert(file_id, Some(text)); None } else { - Some((id, text)) + Some((file_id, text)) } + }) + .for_each(|(file_id, text)| { + change.add_file(file_id, text) }); - self.analysis_host.change_files(changes); } - self.analysis_host - .set_file_resolver(Arc::new(self.path_map.clone())); + if inserted { + change.set_file_resolver(Arc::new(self.path_map.clone())) + } + self.analysis_host.apply_change(change); } pub fn events_to_files( &mut self, @@ -76,24 +87,31 @@ impl ServerWorldState { let FileEventKind::Add(text) = event.kind; (event.path, text) }) - .map(|(path, text)| (pm.get_or_insert(path, Root::Lib), text)) + .map(|(path, text)| (pm.get_or_insert(path, Root::Lib).1, text)) .collect() }; let resolver = Arc::new(self.path_map.clone()); (files, resolver) } pub fn add_lib(&mut self, data: LibraryData) { - self.analysis_host.add_library(data); + let mut change = AnalysisChange::new(); + change.add_library(data); + self.analysis_host.apply_change(change); } pub fn add_mem_file(&mut self, path: PathBuf, text: String) -> FileId { - let file_id = self.path_map.get_or_insert(path, Root::Workspace); - self.analysis_host - .set_file_resolver(Arc::new(self.path_map.clone())); - self.mem_map.insert(file_id, None); + let (inserted, file_id) = self.path_map.get_or_insert(path, Root::Workspace); if self.path_map.get_root(file_id) != Root::Lib { - self.analysis_host.change_file(file_id, Some(text)); + let mut change = AnalysisChange::new(); + if inserted { + change.add_file(file_id, text); + change.set_file_resolver(Arc::new(self.path_map.clone())); + } else { + change.change_file(file_id, text); + } + self.analysis_host.apply_change(change); } + self.mem_map.insert(file_id, None); file_id } @@ -103,7 +121,9 @@ impl ServerWorldState { .get_id(path) .ok_or_else(|| format_err!("change to unknown file: {}", path.display()))?; if self.path_map.get_root(file_id) != Root::Lib { - self.analysis_host.change_file(file_id, Some(text)); + let mut change = AnalysisChange::new(); + change.change_file(file_id, text); + self.analysis_host.apply_change(change); } Ok(()) } @@ -120,12 +140,16 @@ impl ServerWorldState { // Do this via file watcher ideally. let text = fs::read_to_string(path).ok(); if self.path_map.get_root(file_id) != Root::Lib { - self.analysis_host.change_file(file_id, text); + let mut change = AnalysisChange::new(); + if let Some(text) = text { + change.change_file(file_id, text); + } + self.analysis_host.apply_change(change); } Ok(file_id) } pub fn set_workspaces(&mut self, ws: Vec) { - let mut crate_roots = FxHashMap::default(); + let mut crate_roots = BTreeMap::default(); ws.iter() .flat_map(|ws| { ws.packages() @@ -140,7 +164,9 @@ impl ServerWorldState { }); let crate_graph = CrateGraph { crate_roots }; self.workspaces = Arc::new(ws); - self.analysis_host.set_crate_graph(crate_graph); + let mut change = AnalysisChange::new(); + change.set_crate_graph(crate_graph); + self.analysis_host.apply_change(change); } pub fn snapshot(&self) -> ServerWorld { ServerWorld { -- 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 --- Cargo.lock | 8 +++++--- crates/ra_analysis/Cargo.toml | 1 + crates/ra_analysis/src/db/mod.rs | 9 +-------- crates/ra_analysis/src/imp.rs | 2 ++ crates/ra_analysis/src/lib.rs | 19 ++++++++++++++++--- crates/ra_lsp_server/src/main_loop/mod.rs | 20 ++++++++++++++++---- 6 files changed, 41 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d1a294c30..982463f0b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -602,12 +602,13 @@ name = "ra_analysis" version = "0.1.0" dependencies = [ "fst 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "ra_editor 0.1.0", "ra_syntax 0.1.0", "rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "salsa 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "salsa 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "test_utils 0.1.0", ] @@ -833,11 +834,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "salsa" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "derive-new 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lock_api 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1348,7 +1350,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7153dd96dade874ab973e098cb62fcdbb89a03682e46b144fd09550998d4a4a7" "checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" -"checksum salsa 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6c8f8b59428c040fbac0f6a2e698ae892e33d23d7519713ba8b243edb3082dad" +"checksum salsa 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9fc085b9e4a2cf422e798387d0dc1091c6dae97411b2b177755950db9a26dace" "checksum same-file 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "10f7794e2fda7f594866840e95f5c5962e886e228e68b6505885811a94dd728c" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" diff --git a/crates/ra_analysis/Cargo.toml b/crates/ra_analysis/Cargo.toml index 75a9dc844..b9f9cd7a7 100644 --- a/crates/ra_analysis/Cargo.toml +++ b/crates/ra_analysis/Cargo.toml @@ -5,6 +5,7 @@ version = "0.1.0" authors = ["Aleksey Kladov "] [dependencies] +log = "0.4.5" relative-path = "0.4.0" rayon = "1.0.2" fst = "0.3.1" diff --git a/crates/ra_analysis/src/db/mod.rs b/crates/ra_analysis/src/db/mod.rs index 8387118ad..1a9023697 100644 --- a/crates/ra_analysis/src/db/mod.rs +++ b/crates/ra_analysis/src/db/mod.rs @@ -1,7 +1,6 @@ pub(crate) mod input; use std::{ - fmt, sync::Arc, }; @@ -17,17 +16,11 @@ use crate::{ FileId, }; -#[derive(Default)] +#[derive(Default, Debug)] pub(crate) struct RootDatabase { runtime: salsa::Runtime, } -impl fmt::Debug for RootDatabase { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.write_str("RootDatabase { ... }") - } -} - impl salsa::Database for RootDatabase { fn salsa_runtime(&self) -> &salsa::Runtime { &self.runtime 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) diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index 4a1ae3b64..703938cf9 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs @@ -13,7 +13,7 @@ mod symbol_index; mod completion; use std::{ - fmt::Debug, + fmt, sync::Arc, collections::BTreeMap, }; @@ -60,12 +60,12 @@ pub struct CrateGraph { pub crate_roots: BTreeMap, } -pub trait FileResolver: Debug + Send + Sync + 'static { +pub trait FileResolver: fmt::Debug + Send + Sync + 'static { fn file_stem(&self, file_id: FileId) -> String; fn resolve(&self, file_id: FileId, path: &RelativePath) -> Option; } -#[derive(Debug, Default)] +#[derive(Default)] pub struct AnalysisChange { files_added: Vec<(FileId, String)>, files_changed: Vec<(FileId, String)>, @@ -75,6 +75,19 @@ pub struct AnalysisChange { file_resolver: Option, } +impl fmt::Debug for AnalysisChange { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_struct("AnalysisChange") + .field("files_added", &self.files_added.len()) + .field("files_changed", &self.files_changed.len()) + .field("files_removed", &self.files_removed.len()) + .field("libraries_added", &self.libraries_added.len()) + .field("crate_graph", &self.crate_graph) + .field("file_resolver", &self.file_resolver) + .finish() + } +} + impl AnalysisChange { pub fn new() -> AnalysisChange { diff --git a/crates/ra_lsp_server/src/main_loop/mod.rs b/crates/ra_lsp_server/src/main_loop/mod.rs index e681062ca..9ddc3fd0b 100644 --- a/crates/ra_lsp_server/src/main_loop/mod.rs +++ b/crates/ra_lsp_server/src/main_loop/mod.rs @@ -8,7 +8,7 @@ use gen_lsp_server::{ handle_shutdown, ErrorCode, RawMessage, RawNotification, RawRequest, RawResponse, }; use languageserver_types::NumberOrString; -use ra_analysis::{FileId, LibraryData}; +use ra_analysis::{Canceled, FileId, LibraryData}; use rayon::{self, ThreadPool}; use rustc_hash::FxHashSet; use serde::{de::DeserializeOwned, Serialize}; @@ -376,7 +376,7 @@ impl<'a> PoolDispatcher<'a> { Err(e) => { match e.downcast::() { Ok(lsp_error) => RawResponse::err(id, lsp_error.code, lsp_error.message), - Err(e) => RawResponse::err(id, ErrorCode::InternalError as i32, e.to_string()) + Err(e) => RawResponse::err(id, ErrorCode::InternalError as i32, format!("{}\n{}", e, e.backtrace())) } } }; @@ -408,14 +408,22 @@ fn update_file_notifications_on_threadpool( pool.spawn(move || { for file_id in subscriptions { match handlers::publish_diagnostics(&world, file_id) { - Err(e) => error!("failed to compute diagnostics: {:?}", e), + Err(e) => { + if !is_canceled(&e) { + error!("failed to compute diagnostics: {:?}", e); + } + }, Ok(params) => { let not = RawNotification::new::(¶ms); sender.send(Task::Notify(not)); } } match handlers::publish_decorations(&world, file_id) { - Err(e) => error!("failed to compute decorations: {:?}", e), + Err(e) => { + if !is_canceled(&e) { + error!("failed to compute decorations: {:?}", e); + } + }, Ok(params) => { let not = RawNotification::new::(¶ms); sender.send(Task::Notify(not)) @@ -432,3 +440,7 @@ fn feedback(intrnal_mode: bool, msg: &str, sender: &Sender) { let not = RawNotification::new::(&msg.to_string()); sender.send(RawMessage::Notification(not)); } + +fn is_canceled(e: &failure::Error) -> bool { + e.downcast_ref::().is_some() +} -- cgit v1.2.3 From 171acad15b1eacdfb12612a7615f4f6b21e5bf99 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 25 Oct 2018 16:04:42 +0300 Subject: disable cancelation --- crates/ra_analysis/src/db/mod.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/crates/ra_analysis/src/db/mod.rs b/crates/ra_analysis/src/db/mod.rs index 1a9023697..a922995de 100644 --- a/crates/ra_analysis/src/db/mod.rs +++ b/crates/ra_analysis/src/db/mod.rs @@ -27,12 +27,14 @@ impl salsa::Database for RootDatabase { } } -pub(crate) fn check_canceled(db: &impl salsa::Database) -> Cancelable<()> { - if db.salsa_runtime().is_current_revision_canceled() { - Err(Canceled) - } else { - Ok(()) - } +pub(crate) fn check_canceled(_db: &impl salsa::Database) -> Cancelable<()> { + // Disabled due to https://github.com/salsa-rs/salsa/issues/66 + Ok(()) + // if db.salsa_runtime().is_current_revision_canceled() { + // Err(Canceled) + // } else { + // Ok(()) + // } } impl salsa::ParallelDatabase for RootDatabase { -- 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 +++-- crates/ra_lsp_server/src/path_map.rs | 13 +++++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) 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; diff --git a/crates/ra_lsp_server/src/path_map.rs b/crates/ra_lsp_server/src/path_map.rs index b3d1dc3db..d5957d673 100644 --- a/crates/ra_lsp_server/src/path_map.rs +++ b/crates/ra_lsp_server/src/path_map.rs @@ -1,4 +1,7 @@ -use std::path::{Component, Path, PathBuf}; +use std::{ + fmt, + path::{Component, Path, PathBuf}, +}; use im; use ra_analysis::{FileId, FileResolver}; @@ -10,7 +13,7 @@ pub enum Root { Lib, } -#[derive(Debug, Default, Clone)] +#[derive(Default, Clone)] pub struct PathMap { next_id: u32, path2id: im::HashMap, @@ -18,6 +21,12 @@ pub struct PathMap { id2root: im::HashMap, } +impl fmt::Debug for PathMap { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("PathMap { ... }") + } +} + impl PathMap { pub fn new() -> PathMap { Default::default() -- cgit v1.2.3 From 75d9cbd7c22b09a0bc2731731228c95ae60573c3 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 25 Oct 2018 17:22:31 +0300 Subject: re-enable cancelation --- crates/ra_analysis/Cargo.toml | 2 +- crates/ra_analysis/src/db/mod.rs | 14 ++++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/crates/ra_analysis/Cargo.toml b/crates/ra_analysis/Cargo.toml index b9f9cd7a7..5d7915fa5 100644 --- a/crates/ra_analysis/Cargo.toml +++ b/crates/ra_analysis/Cargo.toml @@ -11,7 +11,7 @@ rayon = "1.0.2" fst = "0.3.1" ra_syntax = { path = "../ra_syntax" } ra_editor = { path = "../ra_editor" } -salsa = "0.6.0" +salsa = "0.6.2" rustc-hash = "1.0" [dev-dependencies] diff --git a/crates/ra_analysis/src/db/mod.rs b/crates/ra_analysis/src/db/mod.rs index a922995de..1a9023697 100644 --- a/crates/ra_analysis/src/db/mod.rs +++ b/crates/ra_analysis/src/db/mod.rs @@ -27,14 +27,12 @@ impl salsa::Database for RootDatabase { } } -pub(crate) fn check_canceled(_db: &impl salsa::Database) -> Cancelable<()> { - // Disabled due to https://github.com/salsa-rs/salsa/issues/66 - Ok(()) - // if db.salsa_runtime().is_current_revision_canceled() { - // Err(Canceled) - // } else { - // Ok(()) - // } +pub(crate) fn check_canceled(db: &impl salsa::Database) -> Cancelable<()> { + if db.salsa_runtime().is_current_revision_canceled() { + Err(Canceled) + } else { + Ok(()) + } } impl salsa::ParallelDatabase for RootDatabase { -- cgit v1.2.3 From e0eb33605a917d2e7289debe0c915e75286b834f Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 25 Oct 2018 17:40:24 +0300 Subject: Encapsulate CrateGraph a bit --- crates/ra_analysis/Cargo.toml | 2 +- crates/ra_analysis/src/lib.rs | 18 +++++++++++++++--- crates/ra_analysis/tests/tests.rs | 13 +++++-------- crates/ra_lsp_server/src/server_world.rs | 9 +++------ 4 files changed, 24 insertions(+), 18 deletions(-) diff --git a/crates/ra_analysis/Cargo.toml b/crates/ra_analysis/Cargo.toml index 5d7915fa5..ff56a3c34 100644 --- a/crates/ra_analysis/Cargo.toml +++ b/crates/ra_analysis/Cargo.toml @@ -11,7 +11,7 @@ rayon = "1.0.2" fst = "0.3.1" ra_syntax = { path = "../ra_syntax" } ra_editor = { path = "../ra_editor" } -salsa = "0.6.2" +salsa = "0.6.1" rustc-hash = "1.0" [dev-dependencies] diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index 703938cf9..af7894cd0 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs @@ -15,9 +15,9 @@ mod completion; use std::{ fmt, sync::Arc, - collections::BTreeMap, }; +use rustc_hash::FxHashMap; use ra_syntax::{AtomEdit, File, TextRange, TextUnit}; use relative_path::{RelativePath, RelativePathBuf}; use rayon::prelude::*; @@ -55,9 +55,21 @@ pub struct FileId(pub u32); #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct CrateId(pub u32); -#[derive(Debug, Clone, Default, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Default, PartialEq, Eq)] pub struct CrateGraph { - pub crate_roots: BTreeMap, + crate_roots: FxHashMap, +} + +impl CrateGraph { + pub fn new() -> CrateGraph { + CrateGraph::default() + } + pub fn add_crate_root(&mut self, file_id: FileId) -> CrateId{ + let crate_id = CrateId(self.crate_roots.len() as u32); + let prev = self.crate_roots.insert(crate_id, file_id); + assert!(prev.is_none()); + crate_id + } } pub trait FileResolver: fmt::Debug + Send + Sync + 'static { diff --git a/crates/ra_analysis/tests/tests.rs b/crates/ra_analysis/tests/tests.rs index 198d6a263..806e1fb34 100644 --- a/crates/ra_analysis/tests/tests.rs +++ b/crates/ra_analysis/tests/tests.rs @@ -7,7 +7,6 @@ extern crate test_utils; use std::{ sync::Arc, - collections::BTreeMap, }; use ra_syntax::TextRange; @@ -130,19 +129,17 @@ fn test_resolve_crate_root() { let snap = host.analysis(); assert!(snap.crate_for(FileId(2)).unwrap().is_empty()); - let crate_graph = CrateGraph { - crate_roots: { - let mut m = BTreeMap::default(); - m.insert(CrateId(1), FileId(1)); - m - }, + let crate_graph = { + let mut g = CrateGraph::new(); + g.add_crate_root(FileId(1)); + g }; let mut change = AnalysisChange::new(); change.set_crate_graph(crate_graph); host.apply_change(change); let snap = host.analysis(); - assert_eq!(snap.crate_for(FileId(2)).unwrap(), vec![CrateId(1)],); + assert_eq!(snap.crate_for(FileId(2)).unwrap(), vec![CrateId(0)],); } #[test] diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/server_world.rs index 555de66ff..25986e230 100644 --- a/crates/ra_lsp_server/src/server_world.rs +++ b/crates/ra_lsp_server/src/server_world.rs @@ -2,11 +2,10 @@ use std::{ fs, path::{Path, PathBuf}, sync::Arc, - collections::BTreeMap, }; use languageserver_types::Url; -use ra_analysis::{Analysis, AnalysisHost, AnalysisChange, CrateGraph, CrateId, FileId, FileResolver, LibraryData}; +use ra_analysis::{Analysis, AnalysisHost, AnalysisChange, CrateGraph, FileId, FileResolver, LibraryData}; use rustc_hash::FxHashMap; use crate::{ @@ -149,7 +148,7 @@ impl ServerWorldState { Ok(file_id) } pub fn set_workspaces(&mut self, ws: Vec) { - let mut crate_roots = BTreeMap::default(); + let mut crate_graph = CrateGraph::new(); ws.iter() .flat_map(|ws| { ws.packages() @@ -158,11 +157,9 @@ impl ServerWorldState { }) .for_each(|root| { if let Some(file_id) = self.path_map.get_id(root) { - let crate_id = CrateId(crate_roots.len() as u32); - crate_roots.insert(crate_id, file_id); + crate_graph.add_crate_root(file_id); } }); - let crate_graph = CrateGraph { crate_roots }; self.workspaces = Arc::new(ws); let mut change = AnalysisChange::new(); change.set_crate_graph(crate_graph); -- cgit v1.2.3 From 3c024d6c62d9add4051b4d8a863b402c07e8c984 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 25 Oct 2018 17:41:17 +0300 Subject: dead code --- crates/ra_analysis/src/db/input.rs | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/crates/ra_analysis/src/db/input.rs b/crates/ra_analysis/src/db/input.rs index 957d082f9..25b9935cb 100644 --- a/crates/ra_analysis/src/db/input.rs +++ b/crates/ra_analysis/src/db/input.rs @@ -59,25 +59,3 @@ impl Hash for SourceRoot { } pub(crate) const WORKSPACE: SourceRootId = SourceRootId(0); - - -#[derive(Default, Debug, Eq)] -pub(crate) struct FileSet { - pub(crate) files: FxHashSet, - pub(crate) resolver: FileResolverImp, -} - -impl PartialEq for FileSet { - fn eq(&self, other: &FileSet) -> bool { - self.files == other.files && self.resolver == other.resolver - } -} - -impl Hash for FileSet { - fn hash(&self, hasher: &mut H) { - let mut files = self.files.iter().cloned().collect::>(); - files.sort(); - files.hash(hasher); - } -} - -- cgit v1.2.3 From e7217e1a01e4b2c5b136d8f38f21b5ade0ddcf86 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 25 Oct 2018 17:42:29 +0300 Subject: dead code --- crates/ra_analysis/src/roots.rs | 116 ---------------------------------------- 1 file changed, 116 deletions(-) delete mode 100644 crates/ra_analysis/src/roots.rs diff --git a/crates/ra_analysis/src/roots.rs b/crates/ra_analysis/src/roots.rs deleted file mode 100644 index 1e9e613ac..000000000 --- a/crates/ra_analysis/src/roots.rs +++ /dev/null @@ -1,116 +0,0 @@ -use std::{sync::Arc}; - -use rustc_hash::FxHashSet; -use rayon::prelude::*; -use salsa::Database; - -use crate::{ - Cancelable, - db::{self, FilesDatabase, SyntaxDatabase}, - imp::FileResolverImp, - symbol_index::SymbolIndex, - FileId, -}; - -pub(crate) trait SourceRoot { - fn contains(&self, file_id: FileId) -> bool; - fn db(&self) -> &db::RootDatabase; - fn symbols(&self, acc: &mut Vec>) -> Cancelable<()>; -} - -#[derive(Default, Debug, Clone)] -pub(crate) struct WritableSourceRoot { - db: db::RootDatabase, -} - -impl WritableSourceRoot { - pub fn apply_changes( - &mut self, - changes: &mut dyn Iterator)>, - file_resolver: Option, - ) { - let mut changed = FxHashSet::default(); - let mut removed = FxHashSet::default(); - for (file_id, text) in changes { - match text { - None => { - removed.insert(file_id); - } - Some(text) => { - self.db - .query(db::FileTextQuery) - .set(file_id, Arc::new(text)); - changed.insert(file_id); - } - } - } - let file_set = self.db.file_set(); - let mut files: FxHashSet = file_set.files.clone(); - for file_id in removed { - files.remove(&file_id); - } - files.extend(changed); - let resolver = file_resolver.unwrap_or_else(|| file_set.resolver.clone()); - self.db - .query(db::FileSetQuery) - .set((), Arc::new(db::FileSet { files, resolver })); - } -} - -impl SourceRoot for WritableSourceRoot { - fn contains(&self, file_id: FileId) -> bool { - self.db.file_set().files.contains(&file_id) - } - fn db(&self) -> &db::RootDatabase { - &self.db - } - fn symbols<'a>(&'a self, acc: &mut Vec>) -> Cancelable<()> { - for &file_id in self.db.file_set().files.iter() { - let symbols = self.db.file_symbols(file_id)?; - acc.push(symbols) - } - Ok(()) - } -} - -#[derive(Debug, Clone)] -pub(crate) struct ReadonlySourceRoot { - db: db::RootDatabase, - symbol_index: Arc, -} - -impl ReadonlySourceRoot { - pub(crate) fn new( - files: Vec<(FileId, String)>, - resolver: FileResolverImp, - ) -> ReadonlySourceRoot { - let db = db::RootDatabase::default(); - let mut file_ids = FxHashSet::default(); - for (file_id, text) in files { - file_ids.insert(file_id); - db.query(db::FileTextQuery).set(file_id, Arc::new(text)); - } - - db.query(db::FileSetQuery) - .set((), Arc::new(db::FileSet { files: file_ids, resolver })); - let file_set = db.file_set(); - let symbol_index = - SymbolIndex::for_files(file_set.files.par_iter() - .map_with(db.clone(), |db, &file_id| (file_id, db.file_syntax(file_id)))); - - ReadonlySourceRoot { db, symbol_index: Arc::new(symbol_index) } - } -} - -impl SourceRoot for ReadonlySourceRoot { - fn contains(&self, file_id: FileId) -> bool { - self.db.file_set().files.contains(&file_id) - } - fn db(&self) -> &db::RootDatabase { - &self.db - } - fn symbols(&self, acc: &mut Vec>) -> Cancelable<()> { - acc.push(Arc::clone(&self.symbol_index)); - Ok(()) - } -} -- cgit v1.2.3 From 5ef3fda5e165cbc079f731e459635df0a714b778 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 25 Oct 2018 17:43:17 +0300 Subject: Remove unneded Hash --- crates/ra_analysis/src/db/input.rs | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/crates/ra_analysis/src/db/input.rs b/crates/ra_analysis/src/db/input.rs index 25b9935cb..9baf7474c 100644 --- a/crates/ra_analysis/src/db/input.rs +++ b/crates/ra_analysis/src/db/input.rs @@ -1,6 +1,5 @@ use std::{ sync::Arc, - hash::{Hasher, Hash}, }; use salsa; @@ -40,22 +39,10 @@ salsa::query_group! { #[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] pub(crate) struct SourceRootId(pub(crate) u32); -#[derive(Clone, Default, Debug, Eq)] +#[derive(Clone, Default, Debug, PartialEq, Eq)] pub(crate) struct SourceRoot { pub(crate) file_resolver: FileResolverImp, pub(crate) files: FxHashSet, } -impl PartialEq for SourceRoot { - fn eq(&self, other: &SourceRoot) -> bool { - self.file_resolver == other.file_resolver - } -} - -impl Hash for SourceRoot { - fn hash(&self, hasher: &mut H) { - self.file_resolver.hash(hasher); - } -} - pub(crate) const WORKSPACE: SourceRootId = SourceRootId(0); -- 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 --- Cargo.lock | 6 +- crates/ra_analysis/Cargo.toml | 2 +- crates/ra_analysis/src/completion.rs | 3 +- crates/ra_analysis/src/db.rs | 98 ++++++++++++++++++++++ crates/ra_analysis/src/db/input.rs | 48 ----------- crates/ra_analysis/src/db/mod.rs | 100 ----------------------- crates/ra_analysis/src/descriptors/module/imp.rs | 4 +- crates/ra_analysis/src/descriptors/module/mod.rs | 3 +- crates/ra_analysis/src/imp.rs | 27 +++--- crates/ra_analysis/src/input.rs | 79 ++++++++++++++++++ crates/ra_analysis/src/lib.rs | 33 +------- 11 files changed, 204 insertions(+), 199 deletions(-) create mode 100644 crates/ra_analysis/src/db.rs delete mode 100644 crates/ra_analysis/src/db/input.rs delete mode 100644 crates/ra_analysis/src/db/mod.rs create mode 100644 crates/ra_analysis/src/input.rs diff --git a/Cargo.lock b/Cargo.lock index 982463f0b..ea4275e63 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -608,7 +608,7 @@ dependencies = [ "rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "salsa 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "salsa 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "test_utils 0.1.0", ] @@ -834,7 +834,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "salsa" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "derive-new 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1350,7 +1350,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7153dd96dade874ab973e098cb62fcdbb89a03682e46b144fd09550998d4a4a7" "checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" -"checksum salsa 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9fc085b9e4a2cf422e798387d0dc1091c6dae97411b2b177755950db9a26dace" +"checksum salsa 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ba7fe802c02c7b0074b0b4794442d73e3c7d071967300a98bb0f5dfc25e9f1ef" "checksum same-file 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "10f7794e2fda7f594866840e95f5c5962e886e228e68b6505885811a94dd728c" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" diff --git a/crates/ra_analysis/Cargo.toml b/crates/ra_analysis/Cargo.toml index ff56a3c34..5d7915fa5 100644 --- a/crates/ra_analysis/Cargo.toml +++ b/crates/ra_analysis/Cargo.toml @@ -11,7 +11,7 @@ rayon = "1.0.2" fst = "0.3.1" ra_syntax = { path = "../ra_syntax" } ra_editor = { path = "../ra_editor" } -salsa = "0.6.1" +salsa = "0.6.2" rustc-hash = "1.0" [dev-dependencies] diff --git a/crates/ra_analysis/src/completion.rs b/crates/ra_analysis/src/completion.rs index 04bb82c18..0a2f99575 100644 --- a/crates/ra_analysis/src/completion.rs +++ b/crates/ra_analysis/src/completion.rs @@ -6,7 +6,8 @@ use ra_syntax::{ use crate::{ FileId, Cancelable, - db::{self, SyntaxDatabase, input::FilesDatabase}, + input::FilesDatabase, + db::{self, SyntaxDatabase}, descriptors::module::{ModulesDatabase, ModuleTree, ModuleId}, }; diff --git a/crates/ra_analysis/src/db.rs b/crates/ra_analysis/src/db.rs new file mode 100644 index 000000000..3ca14af79 --- /dev/null +++ b/crates/ra_analysis/src/db.rs @@ -0,0 +1,98 @@ +use std::{ + sync::Arc, +}; + +use ra_editor::LineIndex; +use ra_syntax::File; +use salsa; + +use crate::{ + db, + Cancelable, Canceled, + descriptors::module::{SubmodulesQuery, ModuleTreeQuery, ModulesDatabase}, + symbol_index::SymbolIndex, + FileId, +}; + +#[derive(Default, Debug)] +pub(crate) struct RootDatabase { + runtime: salsa::Runtime, +} + +impl salsa::Database for RootDatabase { + fn salsa_runtime(&self) -> &salsa::Runtime { + &self.runtime + } +} + +pub(crate) fn check_canceled(db: &impl salsa::Database) -> Cancelable<()> { + if db.salsa_runtime().is_current_revision_canceled() { + Err(Canceled) + } else { + Ok(()) + } +} + +impl salsa::ParallelDatabase for RootDatabase { + fn fork(&self) -> Self { + RootDatabase { + runtime: self.runtime.fork(), + } + } +} + +impl Clone for RootDatabase { + fn clone(&self) -> RootDatabase { + salsa::ParallelDatabase::fork(self) + } +} + +salsa::database_storage! { + pub(crate) struct RootDatabaseStorage for RootDatabase { + impl crate::input::FilesDatabase { + fn file_text() for crate::input::FileTextQuery; + fn file_source_root() for crate::input::FileSourceRootQuery; + fn source_root() for crate::input::SourceRootQuery; + fn libraries() for crate::input::LibrarieseQuery; + fn library_symbols() for crate::input::LibrarySymbolsQuery; + fn crate_graph() for crate::input::CrateGraphQuery; + } + impl SyntaxDatabase { + fn file_syntax() for FileSyntaxQuery; + fn file_lines() for FileLinesQuery; + fn file_symbols() for FileSymbolsQuery; + } + impl ModulesDatabase { + fn module_tree() for ModuleTreeQuery; + fn module_descriptor() for SubmodulesQuery; + } + } +} + +salsa::query_group! { + pub(crate) trait SyntaxDatabase: crate::input::FilesDatabase { + fn file_syntax(file_id: FileId) -> File { + type FileSyntaxQuery; + } + fn file_lines(file_id: FileId) -> Arc { + type FileLinesQuery; + } + fn file_symbols(file_id: FileId) -> Cancelable> { + type FileSymbolsQuery; + } + } +} + +fn file_syntax(db: &impl SyntaxDatabase, file_id: FileId) -> File { + let text = db.file_text(file_id); + File::parse(&*text) +} +fn file_lines(db: &impl SyntaxDatabase, file_id: FileId) -> Arc { + let text = db.file_text(file_id); + Arc::new(LineIndex::new(&*text)) +} +fn file_symbols(db: &impl SyntaxDatabase, file_id: FileId) -> Cancelable> { + db::check_canceled(db)?; + let syntax = db.file_syntax(file_id); + Ok(Arc::new(SymbolIndex::for_file(file_id, syntax))) +} diff --git a/crates/ra_analysis/src/db/input.rs b/crates/ra_analysis/src/db/input.rs deleted file mode 100644 index 9baf7474c..000000000 --- a/crates/ra_analysis/src/db/input.rs +++ /dev/null @@ -1,48 +0,0 @@ -use std::{ - sync::Arc, -}; - -use salsa; -use rustc_hash::FxHashSet; - -use crate::{FileId, FileResolverImp, CrateGraph, symbol_index::SymbolIndex}; - -salsa::query_group! { - pub(crate) trait FilesDatabase: salsa::Database { - fn file_text(file_id: FileId) -> Arc { - type FileTextQuery; - storage input; - } - fn file_source_root(file_id: FileId) -> SourceRootId { - type FileSourceRootQuery; - storage input; - } - fn source_root(id: SourceRootId) -> Arc { - type SourceRootQuery; - storage input; - } - fn libraries() -> Arc> { - type LibrarieseQuery; - storage input; - } - fn library_symbols(id: SourceRootId) -> Arc { - type LibrarySymbolsQuery; - storage input; - } - fn crate_graph() -> Arc { - type CrateGraphQuery; - storage input; - } - } -} - -#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub(crate) struct SourceRootId(pub(crate) u32); - -#[derive(Clone, Default, Debug, PartialEq, Eq)] -pub(crate) struct SourceRoot { - pub(crate) file_resolver: FileResolverImp, - pub(crate) files: FxHashSet, -} - -pub(crate) const WORKSPACE: SourceRootId = SourceRootId(0); diff --git a/crates/ra_analysis/src/db/mod.rs b/crates/ra_analysis/src/db/mod.rs deleted file mode 100644 index 1a9023697..000000000 --- a/crates/ra_analysis/src/db/mod.rs +++ /dev/null @@ -1,100 +0,0 @@ -pub(crate) mod input; - -use std::{ - sync::Arc, -}; - -use ra_editor::LineIndex; -use ra_syntax::File; -use salsa; - -use crate::{ - db, - Cancelable, Canceled, - descriptors::module::{SubmodulesQuery, ModuleTreeQuery, ModulesDatabase}, - symbol_index::SymbolIndex, - FileId, -}; - -#[derive(Default, Debug)] -pub(crate) struct RootDatabase { - runtime: salsa::Runtime, -} - -impl salsa::Database for RootDatabase { - fn salsa_runtime(&self) -> &salsa::Runtime { - &self.runtime - } -} - -pub(crate) fn check_canceled(db: &impl salsa::Database) -> Cancelable<()> { - if db.salsa_runtime().is_current_revision_canceled() { - Err(Canceled) - } else { - Ok(()) - } -} - -impl salsa::ParallelDatabase for RootDatabase { - fn fork(&self) -> Self { - RootDatabase { - runtime: self.runtime.fork(), - } - } -} - -impl Clone for RootDatabase { - fn clone(&self) -> RootDatabase { - salsa::ParallelDatabase::fork(self) - } -} - -salsa::database_storage! { - pub(crate) struct RootDatabaseStorage for RootDatabase { - impl input::FilesDatabase { - fn file_text() for input::FileTextQuery; - fn file_source_root() for input::FileSourceRootQuery; - fn source_root() for input::SourceRootQuery; - fn libraries() for input::LibrarieseQuery; - fn library_symbols() for input::LibrarySymbolsQuery; - fn crate_graph() for input::CrateGraphQuery; - } - impl SyntaxDatabase { - fn file_syntax() for FileSyntaxQuery; - fn file_lines() for FileLinesQuery; - fn file_symbols() for FileSymbolsQuery; - } - impl ModulesDatabase { - fn module_tree() for ModuleTreeQuery; - fn module_descriptor() for SubmodulesQuery; - } - } -} - -salsa::query_group! { - pub(crate) trait SyntaxDatabase: input::FilesDatabase { - fn file_syntax(file_id: FileId) -> File { - type FileSyntaxQuery; - } - fn file_lines(file_id: FileId) -> Arc { - type FileLinesQuery; - } - fn file_symbols(file_id: FileId) -> Cancelable> { - type FileSymbolsQuery; - } - } -} - -fn file_syntax(db: &impl SyntaxDatabase, file_id: FileId) -> File { - let text = db.file_text(file_id); - File::parse(&*text) -} -fn file_lines(db: &impl SyntaxDatabase, file_id: FileId) -> Arc { - let text = db.file_text(file_id); - Arc::new(LineIndex::new(&*text)) -} -fn file_symbols(db: &impl SyntaxDatabase, file_id: FileId) -> Cancelable> { - db::check_canceled(db)?; - let syntax = db.file_syntax(file_id); - Ok(Arc::new(SymbolIndex::for_file(file_id, syntax))) -} diff --git a/crates/ra_analysis/src/descriptors/module/imp.rs b/crates/ra_analysis/src/descriptors/module/imp.rs index 6a408dc89..aecf6e29a 100644 --- a/crates/ra_analysis/src/descriptors/module/imp.rs +++ b/crates/ra_analysis/src/descriptors/module/imp.rs @@ -8,8 +8,8 @@ use ra_syntax::{ }; use crate::{ - FileId, Cancelable, FileResolverImp, - db::{self, input::{SourceRoot, SourceRootId}}, + FileId, Cancelable, FileResolverImp, db, + input::{SourceRoot, SourceRootId}, }; use super::{ diff --git a/crates/ra_analysis/src/descriptors/module/mod.rs b/crates/ra_analysis/src/descriptors/module/mod.rs index 98024cc15..8968c4afd 100644 --- a/crates/ra_analysis/src/descriptors/module/mod.rs +++ b/crates/ra_analysis/src/descriptors/module/mod.rs @@ -7,7 +7,8 @@ use ra_syntax::{ast::{self, NameOwner, AstNode}, SmolStr, SyntaxNode}; use crate::{ FileId, Cancelable, - db::{SyntaxDatabase, input::SourceRootId}, + db::SyntaxDatabase, + input::SourceRootId, }; salsa::query_group! { 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)) } } diff --git a/crates/ra_analysis/src/input.rs b/crates/ra_analysis/src/input.rs new file mode 100644 index 000000000..e64fad40c --- /dev/null +++ b/crates/ra_analysis/src/input.rs @@ -0,0 +1,79 @@ +use std::{ + sync::Arc, + fmt, +}; + +use salsa; +use rustc_hash::FxHashSet; +use relative_path::RelativePath; +use rustc_hash::FxHashMap; + +use crate::{symbol_index::SymbolIndex, FileResolverImp}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct FileId(pub u32); + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct CrateId(pub u32); + +#[derive(Debug, Clone, Default, PartialEq, Eq)] +pub struct CrateGraph { + pub(crate) crate_roots: FxHashMap, +} + +impl CrateGraph { + pub fn new() -> CrateGraph { + CrateGraph::default() + } + pub fn add_crate_root(&mut self, file_id: FileId) -> CrateId{ + let crate_id = CrateId(self.crate_roots.len() as u32); + let prev = self.crate_roots.insert(crate_id, file_id); + assert!(prev.is_none()); + crate_id + } +} + +pub trait FileResolver: fmt::Debug + Send + Sync + 'static { + fn file_stem(&self, file_id: FileId) -> String; + fn resolve(&self, file_id: FileId, path: &RelativePath) -> Option; +} + +salsa::query_group! { + pub(crate) trait FilesDatabase: salsa::Database { + fn file_text(file_id: FileId) -> Arc { + type FileTextQuery; + storage input; + } + fn file_source_root(file_id: FileId) -> SourceRootId { + type FileSourceRootQuery; + storage input; + } + fn source_root(id: SourceRootId) -> Arc { + type SourceRootQuery; + storage input; + } + fn libraries() -> Arc> { + type LibrarieseQuery; + storage input; + } + fn library_symbols(id: SourceRootId) -> Arc { + type LibrarySymbolsQuery; + storage input; + } + fn crate_graph() -> Arc { + type CrateGraphQuery; + storage input; + } + } +} + +#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub(crate) struct SourceRootId(pub(crate) u32); + +#[derive(Clone, Default, Debug, PartialEq, Eq)] +pub(crate) struct SourceRoot { + pub(crate) file_resolver: FileResolverImp, + pub(crate) files: FxHashSet, +} + +pub(crate) const WORKSPACE: SourceRootId = SourceRootId(0); diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index af7894cd0..a67cac21e 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs @@ -6,6 +6,7 @@ extern crate relative_path; extern crate rustc_hash; extern crate salsa; +mod input; mod db; mod descriptors; mod imp; @@ -17,9 +18,8 @@ use std::{ sync::Arc, }; -use rustc_hash::FxHashMap; use ra_syntax::{AtomEdit, File, TextRange, TextUnit}; -use relative_path::{RelativePath, RelativePathBuf}; +use relative_path::RelativePathBuf; use rayon::prelude::*; use crate::{ @@ -29,6 +29,7 @@ use crate::{ pub use crate::{ descriptors::FnDescriptor, + input::{FileId, FileResolver, CrateGraph, CrateId} }; pub use ra_editor::{ CompletionItem, FileSymbol, Fold, FoldKind, HighlightedRange, LineIndex, Runnable, @@ -49,34 +50,6 @@ impl std::fmt::Display for Canceled { impl std::error::Error for Canceled { } -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct FileId(pub u32); - -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct CrateId(pub u32); - -#[derive(Debug, Clone, Default, PartialEq, Eq)] -pub struct CrateGraph { - crate_roots: FxHashMap, -} - -impl CrateGraph { - pub fn new() -> CrateGraph { - CrateGraph::default() - } - pub fn add_crate_root(&mut self, file_id: FileId) -> CrateId{ - let crate_id = CrateId(self.crate_roots.len() as u32); - let prev = self.crate_roots.insert(crate_id, file_id); - assert!(prev.is_none()); - crate_id - } -} - -pub trait FileResolver: fmt::Debug + Send + Sync + 'static { - fn file_stem(&self, file_id: FileId) -> String; - fn resolve(&self, file_id: FileId, path: &RelativePath) -> Option; -} - #[derive(Default)] pub struct AnalysisChange { files_added: Vec<(FileId, String)>, -- 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(-) 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