From dc477db757247d5184250bffe9dd0c38dd867778 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 23 Oct 2018 19:15:31 +0300 Subject: Introduce ModuleId Previously, module was synonym with a file, and so a module could have had several parents. This commit introduces a separate module concept, such that each module has only one parent, but a single file can correspond to different modules. --- crates/ra_analysis/src/roots.rs | 103 ++++++++++------------------------------ 1 file changed, 25 insertions(+), 78 deletions(-) (limited to 'crates/ra_analysis/src/roots.rs') diff --git a/crates/ra_analysis/src/roots.rs b/crates/ra_analysis/src/roots.rs index 123c4acfa..7100f7c71 100644 --- a/crates/ra_analysis/src/roots.rs +++ b/crates/ra_analysis/src/roots.rs @@ -1,25 +1,22 @@ -use std::{panic, sync::Arc}; +use std::{sync::Arc}; -use once_cell::sync::OnceCell; use ra_editor::LineIndex; use ra_syntax::File; -use rayon::prelude::*; -use rustc_hash::{FxHashMap, FxHashSet}; +use rustc_hash::FxHashSet; use salsa::Database; use crate::{ Cancelable, db::{self, FilesDatabase, SyntaxDatabase}, - descriptors::{ModuleDescriptor, ModuleTreeDescriptor}, imp::FileResolverImp, - module_map::ModulesDatabase, + descriptors::module::{ModulesDatabase, ModuleTree}, symbol_index::SymbolIndex, FileId, }; pub(crate) trait SourceRoot { fn contains(&self, file_id: FileId) -> bool; - fn module_tree(&self) -> Cancelable>; + fn module_tree(&self) -> Cancelable>; fn lines(&self, file_id: FileId) -> Arc; fn syntax(&self, file_id: FileId) -> File; fn symbols(&self, acc: &mut Vec>) -> Cancelable<()>; @@ -65,7 +62,7 @@ impl WritableSourceRoot { } impl SourceRoot for WritableSourceRoot { - fn module_tree(&self) -> Cancelable> { + fn module_tree(&self) -> Cancelable> { self.db.module_tree() } fn contains(&self, file_id: FileId) -> bool { @@ -86,97 +83,47 @@ impl SourceRoot for WritableSourceRoot { } } -#[derive(Debug)] -struct FileData { - text: String, - lines: OnceCell>, - syntax: OnceCell, -} - -impl FileData { - fn new(text: String) -> FileData { - FileData { - text, - syntax: OnceCell::new(), - lines: OnceCell::new(), - } - } - fn lines(&self) -> &Arc { - self.lines - .get_or_init(|| Arc::new(LineIndex::new(&self.text))) - } - fn syntax(&self) -> &File { - let text = &self.text; - let syntax = &self.syntax; - match panic::catch_unwind(panic::AssertUnwindSafe(|| { - syntax.get_or_init(|| File::parse(text)) - })) { - Ok(file) => file, - Err(err) => { - error!("Parser paniced on:\n------\n{}\n------\n", text); - panic::resume_unwind(err) - } - } - } -} - -#[derive(Debug)] +#[derive(Debug, Clone)] pub(crate) struct ReadonlySourceRoot { + db: db::RootDatabase, symbol_index: Arc, - file_map: FxHashMap, - module_tree: Arc, } impl ReadonlySourceRoot { pub(crate) fn new( files: Vec<(FileId, String)>, - file_resolver: FileResolverImp, + resolver: FileResolverImp, ) -> ReadonlySourceRoot { - let modules = files - .par_iter() - .map(|(file_id, text)| { - let syntax = File::parse(text); - let mod_descr = ModuleDescriptor::new(syntax.ast()); - (*file_id, syntax, mod_descr) - }) - .collect::>(); - let module_tree = - ModuleTreeDescriptor::new(modules.iter().map(|it| (it.0, &it.2)), &file_resolver); + 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(modules.par_iter().map(|it| (it.0, it.1.clone()))); - let file_map: FxHashMap = files - .into_iter() - .map(|(id, text)| (id, FileData::new(text))) - .collect(); - - ReadonlySourceRoot { - symbol_index: Arc::new(symbol_index), - file_map, - module_tree: Arc::new(module_tree), - } - } + SymbolIndex::for_files(file_set.files.iter() // TODO: par iter + .map(|&file_id| (file_id, db.file_syntax(file_id)))); - fn data(&self, file_id: FileId) -> &FileData { - match self.file_map.get(&file_id) { - Some(data) => data, - None => panic!("unknown file: {:?}", file_id), - } + ReadonlySourceRoot { db, symbol_index: Arc::new(symbol_index) } } } impl SourceRoot for ReadonlySourceRoot { - fn module_tree(&self) -> Cancelable> { - Ok(Arc::clone(&self.module_tree)) + fn module_tree(&self) -> Cancelable> { + self.db.module_tree() } fn contains(&self, file_id: FileId) -> bool { - self.file_map.contains_key(&file_id) + self.db.file_set().files.contains(&file_id) } fn lines(&self, file_id: FileId) -> Arc { - Arc::clone(self.data(file_id).lines()) + self.db.file_lines(file_id) } fn syntax(&self, file_id: FileId) -> File { - self.data(file_id).syntax().clone() + self.db.file_syntax(file_id) } fn symbols(&self, acc: &mut Vec>) -> Cancelable<()> { acc.push(Arc::clone(&self.symbol_index)); -- cgit v1.2.3