diff options
Diffstat (limited to 'crates/ra_analysis/src')
-rw-r--r-- | crates/ra_analysis/src/db.rs | 34 | ||||
-rw-r--r-- | crates/ra_analysis/src/descriptors.rs | 5 | ||||
-rw-r--r-- | crates/ra_analysis/src/imp.rs | 78 | ||||
-rw-r--r-- | crates/ra_analysis/src/job.rs | 53 | ||||
-rw-r--r-- | crates/ra_analysis/src/lib.rs | 76 | ||||
-rw-r--r-- | crates/ra_analysis/src/module_map.rs | 22 | ||||
-rw-r--r-- | crates/ra_analysis/src/roots.rs | 30 | ||||
-rw-r--r-- | crates/ra_analysis/src/symbol_index.rs | 14 |
8 files changed, 145 insertions, 167 deletions
diff --git a/crates/ra_analysis/src/db.rs b/crates/ra_analysis/src/db.rs index cce959669..09d74b9e7 100644 --- a/crates/ra_analysis/src/db.rs +++ b/crates/ra_analysis/src/db.rs | |||
@@ -1,17 +1,20 @@ | |||
1 | use crate::{ | 1 | use std::{ |
2 | module_map::{ModuleDescriptorQuery, ModuleTreeQuery, ModulesDatabase}, | 2 | fmt, |
3 | symbol_index::SymbolIndex, | 3 | hash::{Hash, Hasher}, |
4 | FileId, FileResolverImp, | 4 | sync::Arc, |
5 | }; | 5 | }; |
6 | |||
6 | use ra_editor::LineIndex; | 7 | use ra_editor::LineIndex; |
7 | use ra_syntax::File; | 8 | use ra_syntax::File; |
8 | use rustc_hash::FxHashSet; | 9 | use rustc_hash::FxHashSet; |
9 | use salsa; | 10 | use salsa; |
10 | 11 | ||
11 | use std::{ | 12 | use crate::{ |
12 | fmt, | 13 | db, |
13 | hash::{Hash, Hasher}, | 14 | Cancelable, Canceled, |
14 | sync::Arc, | 15 | module_map::{ModuleDescriptorQuery, ModuleTreeQuery, ModulesDatabase}, |
16 | symbol_index::SymbolIndex, | ||
17 | FileId, FileResolverImp, | ||
15 | }; | 18 | }; |
16 | 19 | ||
17 | #[derive(Default)] | 20 | #[derive(Default)] |
@@ -31,6 +34,14 @@ impl salsa::Database for RootDatabase { | |||
31 | } | 34 | } |
32 | } | 35 | } |
33 | 36 | ||
37 | pub(crate) fn check_canceled(db: &impl salsa::Database) -> Cancelable<()> { | ||
38 | if db.salsa_runtime().is_current_revision_canceled() { | ||
39 | Err(Canceled) | ||
40 | } else { | ||
41 | Ok(()) | ||
42 | } | ||
43 | } | ||
44 | |||
34 | impl salsa::ParallelDatabase for RootDatabase { | 45 | impl salsa::ParallelDatabase for RootDatabase { |
35 | fn fork(&self) -> Self { | 46 | fn fork(&self) -> Self { |
36 | RootDatabase { | 47 | RootDatabase { |
@@ -98,7 +109,7 @@ salsa::query_group! { | |||
98 | fn file_lines(file_id: FileId) -> Arc<LineIndex> { | 109 | fn file_lines(file_id: FileId) -> Arc<LineIndex> { |
99 | type FileLinesQuery; | 110 | type FileLinesQuery; |
100 | } | 111 | } |
101 | fn file_symbols(file_id: FileId) -> Arc<SymbolIndex> { | 112 | fn file_symbols(file_id: FileId) -> Cancelable<Arc<SymbolIndex>> { |
102 | type FileSymbolsQuery; | 113 | type FileSymbolsQuery; |
103 | } | 114 | } |
104 | } | 115 | } |
@@ -112,7 +123,8 @@ fn file_lines(db: &impl SyntaxDatabase, file_id: FileId) -> Arc<LineIndex> { | |||
112 | let text = db.file_text(file_id); | 123 | let text = db.file_text(file_id); |
113 | Arc::new(LineIndex::new(&*text)) | 124 | Arc::new(LineIndex::new(&*text)) |
114 | } | 125 | } |
115 | fn file_symbols(db: &impl SyntaxDatabase, file_id: FileId) -> Arc<SymbolIndex> { | 126 | fn file_symbols(db: &impl SyntaxDatabase, file_id: FileId) -> Cancelable<Arc<SymbolIndex>> { |
127 | db::check_canceled(db)?; | ||
116 | let syntax = db.file_syntax(file_id); | 128 | let syntax = db.file_syntax(file_id); |
117 | Arc::new(SymbolIndex::for_file(file_id, syntax)) | 129 | Ok(Arc::new(SymbolIndex::for_file(file_id, syntax))) |
118 | } | 130 | } |
diff --git a/crates/ra_analysis/src/descriptors.rs b/crates/ra_analysis/src/descriptors.rs index 6f26f9935..310bf1585 100644 --- a/crates/ra_analysis/src/descriptors.rs +++ b/crates/ra_analysis/src/descriptors.rs | |||
@@ -1,4 +1,5 @@ | |||
1 | use crate::{imp::FileResolverImp, FileId}; | 1 | use std::collections::BTreeMap; |
2 | |||
2 | use ra_syntax::{ | 3 | use ra_syntax::{ |
3 | ast::{self, AstNode, NameOwner}, | 4 | ast::{self, AstNode, NameOwner}, |
4 | text_utils::is_subrange, | 5 | text_utils::is_subrange, |
@@ -6,7 +7,7 @@ use ra_syntax::{ | |||
6 | }; | 7 | }; |
7 | use relative_path::RelativePathBuf; | 8 | use relative_path::RelativePathBuf; |
8 | 9 | ||
9 | use std::collections::BTreeMap; | 10 | use crate::{imp::FileResolverImp, FileId}; |
10 | 11 | ||
11 | #[derive(Debug, PartialEq, Eq, Hash)] | 12 | #[derive(Debug, PartialEq, Eq, Hash)] |
12 | pub struct ModuleDescriptor { | 13 | pub struct ModuleDescriptor { |
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index a67b1717a..32e9bb6d7 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs | |||
@@ -19,8 +19,8 @@ use rustc_hash::FxHashSet; | |||
19 | use crate::{ | 19 | use crate::{ |
20 | descriptors::{FnDescriptor, ModuleTreeDescriptor, Problem}, | 20 | descriptors::{FnDescriptor, ModuleTreeDescriptor, Problem}, |
21 | roots::{ReadonlySourceRoot, SourceRoot, WritableSourceRoot}, | 21 | roots::{ReadonlySourceRoot, SourceRoot, WritableSourceRoot}, |
22 | CrateGraph, CrateId, Diagnostic, FileId, FileResolver, FileSystemEdit, JobToken, Position, | 22 | CrateGraph, CrateId, Diagnostic, FileId, FileResolver, FileSystemEdit, Position, |
23 | Query, SourceChange, SourceFileEdit, | 23 | Query, SourceChange, SourceFileEdit, Cancelable, |
24 | }; | 24 | }; |
25 | 25 | ||
26 | #[derive(Clone, Debug)] | 26 | #[derive(Clone, Debug)] |
@@ -148,19 +148,21 @@ impl AnalysisImpl { | |||
148 | pub fn file_line_index(&self, file_id: FileId) -> Arc<LineIndex> { | 148 | pub fn file_line_index(&self, file_id: FileId) -> Arc<LineIndex> { |
149 | self.root(file_id).lines(file_id) | 149 | self.root(file_id).lines(file_id) |
150 | } | 150 | } |
151 | pub fn world_symbols(&self, query: Query, token: &JobToken) -> Vec<(FileId, FileSymbol)> { | 151 | pub fn world_symbols(&self, query: Query) -> Cancelable<Vec<(FileId, FileSymbol)>> { |
152 | let mut buf = Vec::new(); | 152 | let mut buf = Vec::new(); |
153 | if query.libs { | 153 | if query.libs { |
154 | self.data.libs.iter().for_each(|it| it.symbols(&mut buf)); | 154 | for lib in self.data.libs.iter() { |
155 | lib.symbols(&mut buf)?; | ||
156 | } | ||
155 | } else { | 157 | } else { |
156 | self.data.root.symbols(&mut buf); | 158 | self.data.root.symbols(&mut buf)?; |
157 | } | 159 | } |
158 | query.search(&buf, token) | 160 | Ok(query.search(&buf)) |
159 | } | 161 | } |
160 | pub fn parent_module(&self, file_id: FileId) -> Vec<(FileId, FileSymbol)> { | 162 | pub fn parent_module(&self, file_id: FileId) -> Cancelable<Vec<(FileId, FileSymbol)>> { |
161 | let root = self.root(file_id); | 163 | let root = self.root(file_id); |
162 | let module_tree = root.module_tree(); | 164 | let module_tree = root.module_tree()?; |
163 | module_tree | 165 | let res = module_tree |
164 | .parent_modules(file_id) | 166 | .parent_modules(file_id) |
165 | .iter() | 167 | .iter() |
166 | .map(|link| { | 168 | .map(|link| { |
@@ -174,10 +176,11 @@ impl AnalysisImpl { | |||
174 | }; | 176 | }; |
175 | (file_id, sym) | 177 | (file_id, sym) |
176 | }) | 178 | }) |
177 | .collect() | 179 | .collect(); |
180 | Ok(res) | ||
178 | } | 181 | } |
179 | pub fn crate_for(&self, file_id: FileId) -> Vec<CrateId> { | 182 | pub fn crate_for(&self, file_id: FileId) -> Cancelable<Vec<CrateId>> { |
180 | let module_tree = self.root(file_id).module_tree(); | 183 | let module_tree = self.root(file_id).module_tree()?; |
181 | let crate_graph = &self.data.crate_graph; | 184 | let crate_graph = &self.data.crate_graph; |
182 | let mut res = Vec::new(); | 185 | let mut res = Vec::new(); |
183 | let mut work = VecDeque::new(); | 186 | let mut work = VecDeque::new(); |
@@ -195,7 +198,7 @@ impl AnalysisImpl { | |||
195 | .filter(|&id| visited.insert(id)); | 198 | .filter(|&id| visited.insert(id)); |
196 | work.extend(parents); | 199 | work.extend(parents); |
197 | } | 200 | } |
198 | res | 201 | Ok(res) |
199 | } | 202 | } |
200 | pub fn crate_root(&self, crate_id: CrateId) -> FileId { | 203 | pub fn crate_root(&self, crate_id: CrateId) -> FileId { |
201 | self.data.crate_graph.crate_roots[&crate_id] | 204 | self.data.crate_graph.crate_roots[&crate_id] |
@@ -204,15 +207,14 @@ impl AnalysisImpl { | |||
204 | &self, | 207 | &self, |
205 | file_id: FileId, | 208 | file_id: FileId, |
206 | offset: TextUnit, | 209 | offset: TextUnit, |
207 | token: &JobToken, | 210 | ) -> Cancelable<Vec<(FileId, FileSymbol)>> { |
208 | ) -> Vec<(FileId, FileSymbol)> { | ||
209 | let root = self.root(file_id); | 211 | let root = self.root(file_id); |
210 | let module_tree = root.module_tree(); | 212 | let module_tree = root.module_tree()?; |
211 | let file = root.syntax(file_id); | 213 | let file = root.syntax(file_id); |
212 | let syntax = file.syntax(); | 214 | let syntax = file.syntax(); |
213 | if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, offset) { | 215 | if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, offset) { |
214 | // First try to resolve the symbol locally | 216 | // First try to resolve the symbol locally |
215 | if let Some((name, range)) = resolve_local_name(&file, offset, name_ref) { | 217 | return if let Some((name, range)) = resolve_local_name(&file, offset, name_ref) { |
216 | let mut vec = vec![]; | 218 | let mut vec = vec![]; |
217 | vec.push(( | 219 | vec.push(( |
218 | file_id, | 220 | file_id, |
@@ -222,12 +224,11 @@ impl AnalysisImpl { | |||
222 | kind: NAME, | 224 | kind: NAME, |
223 | }, | 225 | }, |
224 | )); | 226 | )); |
225 | 227 | Ok(vec) | |
226 | return vec; | ||
227 | } else { | 228 | } else { |
228 | // If that fails try the index based approach. | 229 | // If that fails try the index based approach. |
229 | return self.index_resolve(name_ref, token); | 230 | self.index_resolve(name_ref) |
230 | } | 231 | }; |
231 | } | 232 | } |
232 | if let Some(name) = find_node_at_offset::<ast::Name>(syntax, offset) { | 233 | if let Some(name) = find_node_at_offset::<ast::Name>(syntax, offset) { |
233 | if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) { | 234 | if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) { |
@@ -250,14 +251,14 @@ impl AnalysisImpl { | |||
250 | }) | 251 | }) |
251 | .collect(); | 252 | .collect(); |
252 | 253 | ||
253 | return res; | 254 | return Ok(res); |
254 | } | 255 | } |
255 | } | 256 | } |
256 | } | 257 | } |
257 | vec![] | 258 | Ok(vec![]) |
258 | } | 259 | } |
259 | 260 | ||
260 | pub fn find_all_refs(&self, file_id: FileId, offset: TextUnit, _token: &JobToken) -> Vec<(FileId, TextRange)> { | 261 | pub fn find_all_refs(&self, file_id: FileId, offset: TextUnit) -> Vec<(FileId, TextRange)> { |
261 | let root = self.root(file_id); | 262 | let root = self.root(file_id); |
262 | let file = root.syntax(file_id); | 263 | let file = root.syntax(file_id); |
263 | let syntax = file.syntax(); | 264 | let syntax = file.syntax(); |
@@ -289,9 +290,9 @@ impl AnalysisImpl { | |||
289 | ret | 290 | ret |
290 | } | 291 | } |
291 | 292 | ||
292 | pub fn diagnostics(&self, file_id: FileId) -> Vec<Diagnostic> { | 293 | pub fn diagnostics(&self, file_id: FileId) -> Cancelable<Vec<Diagnostic>> { |
293 | let root = self.root(file_id); | 294 | let root = self.root(file_id); |
294 | let module_tree = root.module_tree(); | 295 | let module_tree = root.module_tree()?; |
295 | let syntax = root.syntax(file_id); | 296 | let syntax = root.syntax(file_id); |
296 | 297 | ||
297 | let mut res = ra_editor::diagnostics(&syntax) | 298 | let mut res = ra_editor::diagnostics(&syntax) |
@@ -346,7 +347,7 @@ impl AnalysisImpl { | |||
346 | }; | 347 | }; |
347 | res.push(diag) | 348 | res.push(diag) |
348 | } | 349 | } |
349 | res | 350 | Ok(res) |
350 | } | 351 | } |
351 | 352 | ||
352 | pub fn assists(&self, file_id: FileId, range: TextRange) -> Vec<SourceChange> { | 353 | pub fn assists(&self, file_id: FileId, range: TextRange) -> Vec<SourceChange> { |
@@ -379,18 +380,23 @@ impl AnalysisImpl { | |||
379 | &self, | 380 | &self, |
380 | file_id: FileId, | 381 | file_id: FileId, |
381 | offset: TextUnit, | 382 | offset: TextUnit, |
382 | token: &JobToken, | 383 | ) -> Cancelable<Option<(FnDescriptor, Option<usize>)>> { |
383 | ) -> Option<(FnDescriptor, Option<usize>)> { | ||
384 | let root = self.root(file_id); | 384 | let root = self.root(file_id); |
385 | let file = root.syntax(file_id); | 385 | let file = root.syntax(file_id); |
386 | let syntax = file.syntax(); | 386 | let syntax = file.syntax(); |
387 | 387 | ||
388 | // Find the calling expression and it's NameRef | 388 | // Find the calling expression and it's NameRef |
389 | let calling_node = FnCallNode::with_node(syntax, offset)?; | 389 | let calling_node = match FnCallNode::with_node(syntax, offset) { |
390 | let name_ref = calling_node.name_ref()?; | 390 | Some(node) => node, |
391 | None => return Ok(None), | ||
392 | }; | ||
393 | let name_ref = match calling_node.name_ref() { | ||
394 | Some(name) => name, | ||
395 | None => return Ok(None), | ||
396 | }; | ||
391 | 397 | ||
392 | // Resolve the function's NameRef (NOTE: this isn't entirely accurate). | 398 | // Resolve the function's NameRef (NOTE: this isn't entirely accurate). |
393 | let file_symbols = self.index_resolve(name_ref, token); | 399 | let file_symbols = self.index_resolve(name_ref)?; |
394 | for (_, fs) in file_symbols { | 400 | for (_, fs) in file_symbols { |
395 | if fs.kind == FN_DEF { | 401 | if fs.kind == FN_DEF { |
396 | if let Some(fn_def) = find_node_at_offset(syntax, fs.node_range.start()) { | 402 | if let Some(fn_def) = find_node_at_offset(syntax, fs.node_range.start()) { |
@@ -432,21 +438,21 @@ impl AnalysisImpl { | |||
432 | } | 438 | } |
433 | } | 439 | } |
434 | 440 | ||
435 | return Some((descriptor, current_parameter)); | 441 | return Ok(Some((descriptor, current_parameter))); |
436 | } | 442 | } |
437 | } | 443 | } |
438 | } | 444 | } |
439 | } | 445 | } |
440 | 446 | ||
441 | None | 447 | Ok(None) |
442 | } | 448 | } |
443 | 449 | ||
444 | fn index_resolve(&self, name_ref: ast::NameRef, token: &JobToken) -> Vec<(FileId, FileSymbol)> { | 450 | fn index_resolve(&self, name_ref: ast::NameRef) -> Cancelable<Vec<(FileId, FileSymbol)>> { |
445 | let name = name_ref.text(); | 451 | let name = name_ref.text(); |
446 | let mut query = Query::new(name.to_string()); | 452 | let mut query = Query::new(name.to_string()); |
447 | query.exact(); | 453 | query.exact(); |
448 | query.limit(4); | 454 | query.limit(4); |
449 | self.world_symbols(query, token) | 455 | self.world_symbols(query) |
450 | } | 456 | } |
451 | 457 | ||
452 | fn resolve_module( | 458 | fn resolve_module( |
diff --git a/crates/ra_analysis/src/job.rs b/crates/ra_analysis/src/job.rs deleted file mode 100644 index 2871f9839..000000000 --- a/crates/ra_analysis/src/job.rs +++ /dev/null | |||
@@ -1,53 +0,0 @@ | |||
1 | use crossbeam_channel::{bounded, Receiver, Sender}; | ||
2 | |||
3 | pub struct JobHandle { | ||
4 | job_alive: Receiver<Never>, | ||
5 | _job_canceled: Sender<Never>, | ||
6 | } | ||
7 | |||
8 | pub struct JobToken { | ||
9 | _job_alive: Sender<Never>, | ||
10 | job_canceled: Receiver<Never>, | ||
11 | } | ||
12 | |||
13 | impl JobHandle { | ||
14 | pub fn new() -> (JobHandle, JobToken) { | ||
15 | let (sender_alive, receiver_alive) = bounded(0); | ||
16 | let (sender_canceled, receiver_canceled) = bounded(0); | ||
17 | let token = JobToken { | ||
18 | _job_alive: sender_alive, | ||
19 | job_canceled: receiver_canceled, | ||
20 | }; | ||
21 | let handle = JobHandle { | ||
22 | job_alive: receiver_alive, | ||
23 | _job_canceled: sender_canceled, | ||
24 | }; | ||
25 | (handle, token) | ||
26 | } | ||
27 | pub fn has_completed(&self) -> bool { | ||
28 | is_closed(&self.job_alive) | ||
29 | } | ||
30 | pub fn cancel(self) {} | ||
31 | } | ||
32 | |||
33 | impl JobToken { | ||
34 | pub fn is_canceled(&self) -> bool { | ||
35 | is_closed(&self.job_canceled) | ||
36 | } | ||
37 | } | ||
38 | |||
39 | // We don't actually send messages through the channels, | ||
40 | // and instead just check if the channel is closed, | ||
41 | // so we use uninhabited enum as a message type | ||
42 | enum Never {} | ||
43 | |||
44 | /// Nonblocking | ||
45 | fn is_closed(chan: &Receiver<Never>) -> bool { | ||
46 | select! { | ||
47 | recv(chan, msg) => match msg { | ||
48 | None => true, | ||
49 | Some(never) => match never {} | ||
50 | } | ||
51 | default => false, | ||
52 | } | ||
53 | } | ||
diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index 46cc0722b..28e0a12b2 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs | |||
@@ -7,8 +7,6 @@ extern crate ra_editor; | |||
7 | extern crate ra_syntax; | 7 | extern crate ra_syntax; |
8 | extern crate rayon; | 8 | extern crate rayon; |
9 | extern crate relative_path; | 9 | extern crate relative_path; |
10 | #[macro_use] | ||
11 | extern crate crossbeam_channel; | ||
12 | extern crate im; | 10 | extern crate im; |
13 | extern crate rustc_hash; | 11 | extern crate rustc_hash; |
14 | extern crate salsa; | 12 | extern crate salsa; |
@@ -16,27 +14,40 @@ extern crate salsa; | |||
16 | mod db; | 14 | mod db; |
17 | mod descriptors; | 15 | mod descriptors; |
18 | mod imp; | 16 | mod imp; |
19 | mod job; | ||
20 | mod module_map; | 17 | mod module_map; |
21 | mod roots; | 18 | mod roots; |
22 | mod symbol_index; | 19 | mod symbol_index; |
23 | 20 | ||
24 | use std::{fmt::Debug, sync::Arc}; | 21 | use std::{fmt::Debug, sync::Arc}; |
25 | 22 | ||
26 | use crate::imp::{AnalysisHostImpl, AnalysisImpl, FileResolverImp}; | ||
27 | use ra_syntax::{AtomEdit, File, TextRange, TextUnit}; | 23 | use ra_syntax::{AtomEdit, File, TextRange, TextUnit}; |
28 | use relative_path::{RelativePath, RelativePathBuf}; | 24 | use relative_path::{RelativePath, RelativePathBuf}; |
29 | use rustc_hash::FxHashMap; | 25 | use rustc_hash::FxHashMap; |
30 | 26 | ||
27 | use crate::imp::{AnalysisHostImpl, AnalysisImpl, FileResolverImp}; | ||
28 | |||
31 | pub use crate::{ | 29 | pub use crate::{ |
32 | descriptors::FnDescriptor, | 30 | descriptors::FnDescriptor, |
33 | job::{JobHandle, JobToken}, | ||
34 | }; | 31 | }; |
35 | pub use ra_editor::{ | 32 | pub use ra_editor::{ |
36 | CompletionItem, FileSymbol, Fold, FoldKind, HighlightedRange, LineIndex, Runnable, | 33 | CompletionItem, FileSymbol, Fold, FoldKind, HighlightedRange, LineIndex, Runnable, |
37 | RunnableKind, StructureNode, | 34 | RunnableKind, StructureNode, |
38 | }; | 35 | }; |
39 | 36 | ||
37 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] | ||
38 | pub struct Canceled; | ||
39 | |||
40 | pub type Cancelable<T> = Result<T, Canceled>; | ||
41 | |||
42 | impl std::fmt::Display for Canceled { | ||
43 | fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
44 | fmt.write_str("Canceled") | ||
45 | } | ||
46 | } | ||
47 | |||
48 | impl std::error::Error for Canceled { | ||
49 | } | ||
50 | |||
40 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | 51 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
41 | pub struct FileId(pub u32); | 52 | pub struct FileId(pub u32); |
42 | 53 | ||
@@ -205,60 +216,57 @@ impl Analysis { | |||
205 | let file = self.imp.file_syntax(file_id); | 216 | let file = self.imp.file_syntax(file_id); |
206 | ra_editor::file_structure(&file) | 217 | ra_editor::file_structure(&file) |
207 | } | 218 | } |
208 | pub fn symbol_search(&self, query: Query, token: &JobToken) -> Vec<(FileId, FileSymbol)> { | 219 | pub fn folding_ranges(&self, file_id: FileId) -> Vec<Fold> { |
209 | self.imp.world_symbols(query, token) | 220 | let file = self.imp.file_syntax(file_id); |
221 | ra_editor::folding_ranges(&file) | ||
222 | } | ||
223 | pub fn symbol_search(&self, query: Query) -> Cancelable<Vec<(FileId, FileSymbol)>> { | ||
224 | self.imp.world_symbols(query) | ||
210 | } | 225 | } |
211 | pub fn approximately_resolve_symbol( | 226 | pub fn approximately_resolve_symbol( |
212 | &self, | 227 | &self, |
213 | file_id: FileId, | 228 | file_id: FileId, |
214 | offset: TextUnit, | 229 | offset: TextUnit |
215 | token: &JobToken, | 230 | ) -> Cancelable<Vec<(FileId, FileSymbol)>> { |
216 | ) -> Vec<(FileId, FileSymbol)> { | ||
217 | self.imp | 231 | self.imp |
218 | .approximately_resolve_symbol(file_id, offset, token) | 232 | .approximately_resolve_symbol(file_id, offset) |
219 | } | 233 | } |
220 | pub fn find_all_refs(&self, file_id: FileId, offset: TextUnit, token: &JobToken) -> Vec<(FileId, TextRange)> { | 234 | pub fn find_all_refs(&self, file_id: FileId, offset: TextUnit, ) -> Cancelable<Vec<(FileId, TextRange)>> { |
221 | self.imp.find_all_refs(file_id, offset, token) | 235 | Ok(self.imp.find_all_refs(file_id, offset)) |
222 | } | 236 | } |
223 | pub fn parent_module(&self, file_id: FileId) -> Vec<(FileId, FileSymbol)> { | 237 | pub fn parent_module(&self, file_id: FileId) -> Cancelable<Vec<(FileId, FileSymbol)>> { |
224 | self.imp.parent_module(file_id) | 238 | self.imp.parent_module(file_id) |
225 | } | 239 | } |
226 | pub fn crate_for(&self, file_id: FileId) -> Vec<CrateId> { | 240 | pub fn crate_for(&self, file_id: FileId) -> Cancelable<Vec<CrateId>> { |
227 | self.imp.crate_for(file_id) | 241 | self.imp.crate_for(file_id) |
228 | } | 242 | } |
229 | pub fn crate_root(&self, crate_id: CrateId) -> FileId { | 243 | pub fn crate_root(&self, crate_id: CrateId) -> Cancelable<FileId> { |
230 | self.imp.crate_root(crate_id) | 244 | Ok(self.imp.crate_root(crate_id)) |
231 | } | 245 | } |
232 | pub fn runnables(&self, file_id: FileId) -> Vec<Runnable> { | 246 | pub fn runnables(&self, file_id: FileId) -> Cancelable<Vec<Runnable>> { |
233 | let file = self.imp.file_syntax(file_id); | 247 | let file = self.imp.file_syntax(file_id); |
234 | ra_editor::runnables(&file) | 248 | Ok(ra_editor::runnables(&file)) |
235 | } | 249 | } |
236 | pub fn highlight(&self, file_id: FileId) -> Vec<HighlightedRange> { | 250 | pub fn highlight(&self, file_id: FileId) -> Cancelable<Vec<HighlightedRange>> { |
237 | let file = self.imp.file_syntax(file_id); | 251 | let file = self.imp.file_syntax(file_id); |
238 | ra_editor::highlight(&file) | 252 | Ok(ra_editor::highlight(&file)) |
239 | } | 253 | } |
240 | pub fn completions(&self, file_id: FileId, offset: TextUnit) -> Option<Vec<CompletionItem>> { | 254 | pub fn completions(&self, file_id: FileId, offset: TextUnit) -> Cancelable<Option<Vec<CompletionItem>>> { |
241 | let file = self.imp.file_syntax(file_id); | 255 | let file = self.imp.file_syntax(file_id); |
242 | ra_editor::scope_completion(&file, offset) | 256 | Ok(ra_editor::scope_completion(&file, offset)) |
243 | } | 257 | } |
244 | pub fn assists(&self, file_id: FileId, range: TextRange) -> Vec<SourceChange> { | 258 | pub fn assists(&self, file_id: FileId, range: TextRange) -> Cancelable<Vec<SourceChange>> { |
245 | self.imp.assists(file_id, range) | 259 | Ok(self.imp.assists(file_id, range)) |
246 | } | 260 | } |
247 | pub fn diagnostics(&self, file_id: FileId) -> Vec<Diagnostic> { | 261 | pub fn diagnostics(&self, file_id: FileId) -> Cancelable<Vec<Diagnostic>> { |
248 | self.imp.diagnostics(file_id) | 262 | self.imp.diagnostics(file_id) |
249 | } | 263 | } |
250 | pub fn folding_ranges(&self, file_id: FileId) -> Vec<Fold> { | ||
251 | let file = self.imp.file_syntax(file_id); | ||
252 | ra_editor::folding_ranges(&file) | ||
253 | } | ||
254 | |||
255 | pub fn resolve_callable( | 264 | pub fn resolve_callable( |
256 | &self, | 265 | &self, |
257 | file_id: FileId, | 266 | file_id: FileId, |
258 | offset: TextUnit, | 267 | offset: TextUnit, |
259 | token: &JobToken, | 268 | ) -> Cancelable<Option<(FnDescriptor, Option<usize>)>> { |
260 | ) -> Option<(FnDescriptor, Option<usize>)> { | 269 | self.imp.resolve_callable(file_id, offset) |
261 | self.imp.resolve_callable(file_id, offset, token) | ||
262 | } | 270 | } |
263 | } | 271 | } |
264 | 272 | ||
diff --git a/crates/ra_analysis/src/module_map.rs b/crates/ra_analysis/src/module_map.rs index b15432498..3c800265a 100644 --- a/crates/ra_analysis/src/module_map.rs +++ b/crates/ra_analysis/src/module_map.rs | |||
@@ -1,37 +1,41 @@ | |||
1 | use std::sync::Arc; | ||
2 | |||
1 | use crate::{ | 3 | use crate::{ |
4 | db, | ||
5 | Cancelable, | ||
2 | db::SyntaxDatabase, | 6 | db::SyntaxDatabase, |
3 | descriptors::{ModuleDescriptor, ModuleTreeDescriptor}, | 7 | descriptors::{ModuleDescriptor, ModuleTreeDescriptor}, |
4 | FileId, | 8 | FileId, |
5 | }; | 9 | }; |
6 | 10 | ||
7 | use std::sync::Arc; | ||
8 | |||
9 | salsa::query_group! { | 11 | salsa::query_group! { |
10 | pub(crate) trait ModulesDatabase: SyntaxDatabase { | 12 | pub(crate) trait ModulesDatabase: SyntaxDatabase { |
11 | fn module_tree() -> Arc<ModuleTreeDescriptor> { | 13 | fn module_tree() -> Cancelable<Arc<ModuleTreeDescriptor>> { |
12 | type ModuleTreeQuery; | 14 | type ModuleTreeQuery; |
13 | } | 15 | } |
14 | fn module_descriptor(file_id: FileId) -> Arc<ModuleDescriptor> { | 16 | fn module_descriptor(file_id: FileId) -> Cancelable<Arc<ModuleDescriptor>> { |
15 | type ModuleDescriptorQuery; | 17 | type ModuleDescriptorQuery; |
16 | } | 18 | } |
17 | } | 19 | } |
18 | } | 20 | } |
19 | 21 | ||
20 | fn module_descriptor(db: &impl ModulesDatabase, file_id: FileId) -> Arc<ModuleDescriptor> { | 22 | fn module_descriptor(db: &impl ModulesDatabase, file_id: FileId) -> Cancelable<Arc<ModuleDescriptor>> { |
23 | db::check_canceled(db)?; | ||
21 | let file = db.file_syntax(file_id); | 24 | let file = db.file_syntax(file_id); |
22 | Arc::new(ModuleDescriptor::new(file.ast())) | 25 | Ok(Arc::new(ModuleDescriptor::new(file.ast()))) |
23 | } | 26 | } |
24 | 27 | ||
25 | fn module_tree(db: &impl ModulesDatabase) -> Arc<ModuleTreeDescriptor> { | 28 | fn module_tree(db: &impl ModulesDatabase) -> Cancelable<Arc<ModuleTreeDescriptor>> { |
29 | db::check_canceled(db)?; | ||
26 | let file_set = db.file_set(); | 30 | let file_set = db.file_set(); |
27 | let mut files = Vec::new(); | 31 | let mut files = Vec::new(); |
28 | for &file_id in file_set.files.iter() { | 32 | for &file_id in file_set.files.iter() { |
29 | let module_descr = db.module_descriptor(file_id); | 33 | let module_descr = db.module_descriptor(file_id)?; |
30 | files.push((file_id, module_descr)); | 34 | files.push((file_id, module_descr)); |
31 | } | 35 | } |
32 | let res = ModuleTreeDescriptor::new( | 36 | let res = ModuleTreeDescriptor::new( |
33 | files.iter().map(|(file_id, descr)| (*file_id, &**descr)), | 37 | files.iter().map(|(file_id, descr)| (*file_id, &**descr)), |
34 | &file_set.resolver, | 38 | &file_set.resolver, |
35 | ); | 39 | ); |
36 | Arc::new(res) | 40 | Ok(Arc::new(res)) |
37 | } | 41 | } |
diff --git a/crates/ra_analysis/src/roots.rs b/crates/ra_analysis/src/roots.rs index 19c84df65..123c4acfa 100644 --- a/crates/ra_analysis/src/roots.rs +++ b/crates/ra_analysis/src/roots.rs | |||
@@ -8,6 +8,7 @@ use rustc_hash::{FxHashMap, FxHashSet}; | |||
8 | use salsa::Database; | 8 | use salsa::Database; |
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | Cancelable, | ||
11 | db::{self, FilesDatabase, SyntaxDatabase}, | 12 | db::{self, FilesDatabase, SyntaxDatabase}, |
12 | descriptors::{ModuleDescriptor, ModuleTreeDescriptor}, | 13 | descriptors::{ModuleDescriptor, ModuleTreeDescriptor}, |
13 | imp::FileResolverImp, | 14 | imp::FileResolverImp, |
@@ -18,10 +19,10 @@ use crate::{ | |||
18 | 19 | ||
19 | pub(crate) trait SourceRoot { | 20 | pub(crate) trait SourceRoot { |
20 | fn contains(&self, file_id: FileId) -> bool; | 21 | fn contains(&self, file_id: FileId) -> bool; |
21 | fn module_tree(&self) -> Arc<ModuleTreeDescriptor>; | 22 | fn module_tree(&self) -> Cancelable<Arc<ModuleTreeDescriptor>>; |
22 | fn lines(&self, file_id: FileId) -> Arc<LineIndex>; | 23 | fn lines(&self, file_id: FileId) -> Arc<LineIndex>; |
23 | fn syntax(&self, file_id: FileId) -> File; | 24 | fn syntax(&self, file_id: FileId) -> File; |
24 | fn symbols(&self, acc: &mut Vec<Arc<SymbolIndex>>); | 25 | fn symbols(&self, acc: &mut Vec<Arc<SymbolIndex>>) -> Cancelable<()>; |
25 | } | 26 | } |
26 | 27 | ||
27 | #[derive(Default, Debug, Clone)] | 28 | #[derive(Default, Debug, Clone)] |
@@ -64,7 +65,7 @@ impl WritableSourceRoot { | |||
64 | } | 65 | } |
65 | 66 | ||
66 | impl SourceRoot for WritableSourceRoot { | 67 | impl SourceRoot for WritableSourceRoot { |
67 | fn module_tree(&self) -> Arc<ModuleTreeDescriptor> { | 68 | fn module_tree(&self) -> Cancelable<Arc<ModuleTreeDescriptor>> { |
68 | self.db.module_tree() | 69 | self.db.module_tree() |
69 | } | 70 | } |
70 | fn contains(&self, file_id: FileId) -> bool { | 71 | fn contains(&self, file_id: FileId) -> bool { |
@@ -76,14 +77,12 @@ impl SourceRoot for WritableSourceRoot { | |||
76 | fn syntax(&self, file_id: FileId) -> File { | 77 | fn syntax(&self, file_id: FileId) -> File { |
77 | self.db.file_syntax(file_id) | 78 | self.db.file_syntax(file_id) |
78 | } | 79 | } |
79 | fn symbols<'a>(&'a self, acc: &mut Vec<Arc<SymbolIndex>>) { | 80 | fn symbols<'a>(&'a self, acc: &mut Vec<Arc<SymbolIndex>>) -> Cancelable<()> { |
80 | let db = &self.db; | 81 | for &file_id in self.db.file_set().files.iter() { |
81 | let symbols = db.file_set(); | 82 | let symbols = self.db.file_symbols(file_id)?; |
82 | let symbols = symbols | 83 | acc.push(symbols) |
83 | .files | 84 | } |
84 | .iter() | 85 | Ok(()) |
85 | .map(|&file_id| db.file_symbols(file_id)); | ||
86 | acc.extend(symbols); | ||
87 | } | 86 | } |
88 | } | 87 | } |
89 | 88 | ||
@@ -167,8 +166,8 @@ impl ReadonlySourceRoot { | |||
167 | } | 166 | } |
168 | 167 | ||
169 | impl SourceRoot for ReadonlySourceRoot { | 168 | impl SourceRoot for ReadonlySourceRoot { |
170 | fn module_tree(&self) -> Arc<ModuleTreeDescriptor> { | 169 | fn module_tree(&self) -> Cancelable<Arc<ModuleTreeDescriptor>> { |
171 | Arc::clone(&self.module_tree) | 170 | Ok(Arc::clone(&self.module_tree)) |
172 | } | 171 | } |
173 | fn contains(&self, file_id: FileId) -> bool { | 172 | fn contains(&self, file_id: FileId) -> bool { |
174 | self.file_map.contains_key(&file_id) | 173 | self.file_map.contains_key(&file_id) |
@@ -179,7 +178,8 @@ impl SourceRoot for ReadonlySourceRoot { | |||
179 | fn syntax(&self, file_id: FileId) -> File { | 178 | fn syntax(&self, file_id: FileId) -> File { |
180 | self.data(file_id).syntax().clone() | 179 | self.data(file_id).syntax().clone() |
181 | } | 180 | } |
182 | fn symbols(&self, acc: &mut Vec<Arc<SymbolIndex>>) { | 181 | fn symbols(&self, acc: &mut Vec<Arc<SymbolIndex>>) -> Cancelable<()> { |
183 | acc.push(Arc::clone(&self.symbol_index)) | 182 | acc.push(Arc::clone(&self.symbol_index)); |
183 | Ok(()) | ||
184 | } | 184 | } |
185 | } | 185 | } |
diff --git a/crates/ra_analysis/src/symbol_index.rs b/crates/ra_analysis/src/symbol_index.rs index 51eef8170..a0f3c0437 100644 --- a/crates/ra_analysis/src/symbol_index.rs +++ b/crates/ra_analysis/src/symbol_index.rs | |||
@@ -1,4 +1,8 @@ | |||
1 | use crate::{FileId, JobToken, Query}; | 1 | use std::{ |
2 | hash::{Hash, Hasher}, | ||
3 | sync::Arc, | ||
4 | }; | ||
5 | |||
2 | use fst::{self, Streamer}; | 6 | use fst::{self, Streamer}; |
3 | use ra_editor::{file_symbols, FileSymbol}; | 7 | use ra_editor::{file_symbols, FileSymbol}; |
4 | use ra_syntax::{ | 8 | use ra_syntax::{ |
@@ -7,10 +11,7 @@ use ra_syntax::{ | |||
7 | }; | 11 | }; |
8 | use rayon::prelude::*; | 12 | use rayon::prelude::*; |
9 | 13 | ||
10 | use std::{ | 14 | use crate::{FileId, Query}; |
11 | hash::{Hash, Hasher}, | ||
12 | sync::Arc, | ||
13 | }; | ||
14 | 15 | ||
15 | #[derive(Debug)] | 16 | #[derive(Debug)] |
16 | pub(crate) struct SymbolIndex { | 17 | pub(crate) struct SymbolIndex { |
@@ -59,7 +60,6 @@ impl Query { | |||
59 | pub(crate) fn search( | 60 | pub(crate) fn search( |
60 | self, | 61 | self, |
61 | indices: &[Arc<SymbolIndex>], | 62 | indices: &[Arc<SymbolIndex>], |
62 | token: &JobToken, | ||
63 | ) -> Vec<(FileId, FileSymbol)> { | 63 | ) -> Vec<(FileId, FileSymbol)> { |
64 | let mut op = fst::map::OpBuilder::new(); | 64 | let mut op = fst::map::OpBuilder::new(); |
65 | for file_symbols in indices.iter() { | 65 | for file_symbols in indices.iter() { |
@@ -69,7 +69,7 @@ impl Query { | |||
69 | let mut stream = op.union(); | 69 | let mut stream = op.union(); |
70 | let mut res = Vec::new(); | 70 | let mut res = Vec::new(); |
71 | while let Some((_, indexed_values)) = stream.next() { | 71 | while let Some((_, indexed_values)) = stream.next() { |
72 | if res.len() >= self.limit || token.is_canceled() { | 72 | if res.len() >= self.limit { |
73 | break; | 73 | break; |
74 | } | 74 | } |
75 | for indexed_value in indexed_values { | 75 | for indexed_value in indexed_values { |