aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis/src/roots.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_analysis/src/roots.rs')
-rw-r--r--crates/ra_analysis/src/roots.rs103
1 files changed, 25 insertions, 78 deletions
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 @@
1use std::{panic, sync::Arc}; 1use std::{sync::Arc};
2 2
3use once_cell::sync::OnceCell;
4use ra_editor::LineIndex; 3use ra_editor::LineIndex;
5use ra_syntax::File; 4use ra_syntax::File;
6use rayon::prelude::*; 5use rustc_hash::FxHashSet;
7use rustc_hash::{FxHashMap, FxHashSet};
8use salsa::Database; 6use salsa::Database;
9 7
10use crate::{ 8use crate::{
11 Cancelable, 9 Cancelable,
12 db::{self, FilesDatabase, SyntaxDatabase}, 10 db::{self, FilesDatabase, SyntaxDatabase},
13 descriptors::{ModuleDescriptor, ModuleTreeDescriptor},
14 imp::FileResolverImp, 11 imp::FileResolverImp,
15 module_map::ModulesDatabase, 12 descriptors::module::{ModulesDatabase, ModuleTree},
16 symbol_index::SymbolIndex, 13 symbol_index::SymbolIndex,
17 FileId, 14 FileId,
18}; 15};
19 16
20pub(crate) trait SourceRoot { 17pub(crate) trait SourceRoot {
21 fn contains(&self, file_id: FileId) -> bool; 18 fn contains(&self, file_id: FileId) -> bool;
22 fn module_tree(&self) -> Cancelable<Arc<ModuleTreeDescriptor>>; 19 fn module_tree(&self) -> Cancelable<Arc<ModuleTree>>;
23 fn lines(&self, file_id: FileId) -> Arc<LineIndex>; 20 fn lines(&self, file_id: FileId) -> Arc<LineIndex>;
24 fn syntax(&self, file_id: FileId) -> File; 21 fn syntax(&self, file_id: FileId) -> File;
25 fn symbols(&self, acc: &mut Vec<Arc<SymbolIndex>>) -> Cancelable<()>; 22 fn symbols(&self, acc: &mut Vec<Arc<SymbolIndex>>) -> Cancelable<()>;
@@ -65,7 +62,7 @@ impl WritableSourceRoot {
65} 62}
66 63
67impl SourceRoot for WritableSourceRoot { 64impl SourceRoot for WritableSourceRoot {
68 fn module_tree(&self) -> Cancelable<Arc<ModuleTreeDescriptor>> { 65 fn module_tree(&self) -> Cancelable<Arc<ModuleTree>> {
69 self.db.module_tree() 66 self.db.module_tree()
70 } 67 }
71 fn contains(&self, file_id: FileId) -> bool { 68 fn contains(&self, file_id: FileId) -> bool {
@@ -86,97 +83,47 @@ impl SourceRoot for WritableSourceRoot {
86 } 83 }
87} 84}
88 85
89#[derive(Debug)] 86#[derive(Debug, Clone)]
90struct FileData {
91 text: String,
92 lines: OnceCell<Arc<LineIndex>>,
93 syntax: OnceCell<File>,
94}
95
96impl FileData {
97 fn new(text: String) -> FileData {
98 FileData {
99 text,
100 syntax: OnceCell::new(),
101 lines: OnceCell::new(),
102 }
103 }
104 fn lines(&self) -> &Arc<LineIndex> {
105 self.lines
106 .get_or_init(|| Arc::new(LineIndex::new(&self.text)))
107 }
108 fn syntax(&self) -> &File {
109 let text = &self.text;
110 let syntax = &self.syntax;
111 match panic::catch_unwind(panic::AssertUnwindSafe(|| {
112 syntax.get_or_init(|| File::parse(text))
113 })) {
114 Ok(file) => file,
115 Err(err) => {
116 error!("Parser paniced on:\n------\n{}\n------\n", text);
117 panic::resume_unwind(err)
118 }
119 }
120 }
121}
122
123#[derive(Debug)]
124pub(crate) struct ReadonlySourceRoot { 87pub(crate) struct ReadonlySourceRoot {
88 db: db::RootDatabase,
125 symbol_index: Arc<SymbolIndex>, 89 symbol_index: Arc<SymbolIndex>,
126 file_map: FxHashMap<FileId, FileData>,
127 module_tree: Arc<ModuleTreeDescriptor>,
128} 90}
129 91
130impl ReadonlySourceRoot { 92impl ReadonlySourceRoot {
131 pub(crate) fn new( 93 pub(crate) fn new(
132 files: Vec<(FileId, String)>, 94 files: Vec<(FileId, String)>,
133 file_resolver: FileResolverImp, 95 resolver: FileResolverImp,
134 ) -> ReadonlySourceRoot { 96 ) -> ReadonlySourceRoot {
135 let modules = files 97 let db = db::RootDatabase::default();
136 .par_iter() 98 let mut file_ids = FxHashSet::default();
137 .map(|(file_id, text)| { 99 for (file_id, text) in files {
138 let syntax = File::parse(text); 100 file_ids.insert(file_id);
139 let mod_descr = ModuleDescriptor::new(syntax.ast()); 101 db.query(db::FileTextQuery).set(file_id, Arc::new(text));
140 (*file_id, syntax, mod_descr) 102 }
141 })
142 .collect::<Vec<_>>();
143 let module_tree =
144 ModuleTreeDescriptor::new(modules.iter().map(|it| (it.0, &it.2)), &file_resolver);
145 103
104 db.query(db::FileSetQuery)
105 .set((), Arc::new(db::FileSet { files: file_ids, resolver }));
106 let file_set = db.file_set();
146 let symbol_index = 107 let symbol_index =
147 SymbolIndex::for_files(modules.par_iter().map(|it| (it.0, it.1.clone()))); 108 SymbolIndex::for_files(file_set.files.iter() // TODO: par iter
148 let file_map: FxHashMap<FileId, FileData> = files 109 .map(|&file_id| (file_id, db.file_syntax(file_id))));
149 .into_iter()
150 .map(|(id, text)| (id, FileData::new(text)))
151 .collect();
152
153 ReadonlySourceRoot {
154 symbol_index: Arc::new(symbol_index),
155 file_map,
156 module_tree: Arc::new(module_tree),
157 }
158 }
159 110
160 fn data(&self, file_id: FileId) -> &FileData { 111 ReadonlySourceRoot { db, symbol_index: Arc::new(symbol_index) }
161 match self.file_map.get(&file_id) {
162 Some(data) => data,
163 None => panic!("unknown file: {:?}", file_id),
164 }
165 } 112 }
166} 113}
167 114
168impl SourceRoot for ReadonlySourceRoot { 115impl SourceRoot for ReadonlySourceRoot {
169 fn module_tree(&self) -> Cancelable<Arc<ModuleTreeDescriptor>> { 116 fn module_tree(&self) -> Cancelable<Arc<ModuleTree>> {
170 Ok(Arc::clone(&self.module_tree)) 117 self.db.module_tree()
171 } 118 }
172 fn contains(&self, file_id: FileId) -> bool { 119 fn contains(&self, file_id: FileId) -> bool {
173 self.file_map.contains_key(&file_id) 120 self.db.file_set().files.contains(&file_id)
174 } 121 }
175 fn lines(&self, file_id: FileId) -> Arc<LineIndex> { 122 fn lines(&self, file_id: FileId) -> Arc<LineIndex> {
176 Arc::clone(self.data(file_id).lines()) 123 self.db.file_lines(file_id)
177 } 124 }
178 fn syntax(&self, file_id: FileId) -> File { 125 fn syntax(&self, file_id: FileId) -> File {
179 self.data(file_id).syntax().clone() 126 self.db.file_syntax(file_id)
180 } 127 }
181 fn symbols(&self, acc: &mut Vec<Arc<SymbolIndex>>) -> Cancelable<()> { 128 fn symbols(&self, acc: &mut Vec<Arc<SymbolIndex>>) -> Cancelable<()> {
182 acc.push(Arc::clone(&self.symbol_index)); 129 acc.push(Arc::clone(&self.symbol_index));