diff options
Diffstat (limited to 'crates/libanalysis/src/symbol_index.rs')
-rw-r--r-- | crates/libanalysis/src/symbol_index.rs | 58 |
1 files changed, 34 insertions, 24 deletions
diff --git a/crates/libanalysis/src/symbol_index.rs b/crates/libanalysis/src/symbol_index.rs index cb35ab1d1..2cad3f6eb 100644 --- a/crates/libanalysis/src/symbol_index.rs +++ b/crates/libanalysis/src/symbol_index.rs | |||
@@ -3,8 +3,8 @@ use libsyntax2::{ | |||
3 | File, | 3 | File, |
4 | SyntaxKind::{self, *}, | 4 | SyntaxKind::{self, *}, |
5 | }; | 5 | }; |
6 | use fst::{self, IntoStreamer, Streamer}; | 6 | use fst::{self, Streamer}; |
7 | use Query; | 7 | use {Query, FileId, JobToken}; |
8 | 8 | ||
9 | #[derive(Debug)] | 9 | #[derive(Debug)] |
10 | pub(crate) struct FileSymbols { | 10 | pub(crate) struct FileSymbols { |
@@ -32,35 +32,45 @@ impl FileSymbols { | |||
32 | } | 32 | } |
33 | 33 | ||
34 | impl Query { | 34 | impl Query { |
35 | pub(crate) fn process( | 35 | pub(crate) fn search( |
36 | &mut self, | 36 | mut self, |
37 | file: &FileSymbols, | 37 | indices: &[(FileId, &FileSymbols)], |
38 | ) -> Vec<FileSymbol> { | 38 | token: &JobToken, |
39 | fn is_type(kind: SyntaxKind) -> bool { | 39 | ) -> Vec<(FileId, FileSymbol)> { |
40 | match kind { | 40 | |
41 | STRUCT_DEF | ENUM_DEF | TRAIT_DEF | TYPE_DEF => true, | 41 | let mut op = fst::map::OpBuilder::new(); |
42 | _ => false, | 42 | for (_, file_symbols) in indices.iter() { |
43 | } | 43 | let automaton = fst::automaton::Subsequence::new(&self.lowercased); |
44 | op = op.add(file_symbols.map.search(automaton)) | ||
44 | } | 45 | } |
45 | let automaton = fst::automaton::Subsequence::new(&self.lowercased); | 46 | let mut stream = op.union(); |
46 | let mut stream = file.map.search(automaton).into_stream(); | ||
47 | let mut res = Vec::new(); | 47 | let mut res = Vec::new(); |
48 | while let Some((_, idx)) = stream.next() { | 48 | while let Some((_, indexed_values)) = stream.next() { |
49 | if self.limit == 0 { | 49 | if self.limit == 0 || token.is_canceled() { |
50 | break; | 50 | break; |
51 | } | 51 | } |
52 | let idx = idx as usize; | 52 | for indexed_value in indexed_values { |
53 | let symbol = &file.symbols[idx]; | 53 | let (file_id, file_symbols) = &indices[indexed_value.index]; |
54 | if self.only_types && !is_type(symbol.kind) { | 54 | let idx = indexed_value.value as usize; |
55 | continue; | 55 | |
56 | } | 56 | let symbol = &file_symbols.symbols[idx]; |
57 | if self.exact && symbol.name != self.query { | 57 | if self.only_types && !is_type(symbol.kind) { |
58 | continue; | 58 | continue; |
59 | } | ||
60 | if self.exact && symbol.name != self.query { | ||
61 | continue; | ||
62 | } | ||
63 | res.push((*file_id, symbol.clone())); | ||
64 | self.limit -= 1; | ||
59 | } | 65 | } |
60 | res.push(symbol.clone()); | ||
61 | self.limit -= 1; | ||
62 | } | 66 | } |
63 | res | 67 | res |
64 | } | 68 | } |
65 | } | 69 | } |
66 | 70 | ||
71 | fn is_type(kind: SyntaxKind) -> bool { | ||
72 | match kind { | ||
73 | STRUCT_DEF | ENUM_DEF | TRAIT_DEF | TYPE_DEF => true, | ||
74 | _ => false, | ||
75 | } | ||
76 | } | ||