aboutsummaryrefslogtreecommitdiff
path: root/crates/libanalysis/src/symbol_index.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/libanalysis/src/symbol_index.rs')
-rw-r--r--crates/libanalysis/src/symbol_index.rs56
1 files changed, 36 insertions, 20 deletions
diff --git a/crates/libanalysis/src/symbol_index.rs b/crates/libanalysis/src/symbol_index.rs
index 4d90aac0c..88d5c4995 100644
--- a/crates/libanalysis/src/symbol_index.rs
+++ b/crates/libanalysis/src/symbol_index.rs
@@ -3,7 +3,7 @@ use libsyntax2::{
3 ast, 3 ast,
4 SyntaxKind::{self, *}, 4 SyntaxKind::{self, *},
5}; 5};
6use fst::{self, IntoStreamer}; 6use fst::{self, IntoStreamer, Streamer};
7 7
8#[derive(Debug)] 8#[derive(Debug)]
9pub(crate) struct FileSymbols { 9pub(crate) struct FileSymbols {
@@ -30,19 +30,30 @@ impl FileSymbols {
30 } 30 }
31} 31}
32 32
33pub(crate) struct Query { 33pub struct Query {
34 query: String, 34 query: String,
35 all_symbols: bool, 35 lowercased: String,
36 only_types: bool,
37 exact: bool,
36} 38}
37 39
38impl Query { 40impl Query {
39 pub(crate) fn new(query: &str) -> Query { 41 pub fn new(query: String) -> Query {
40 let all_symbols = query.contains("#"); 42 let lowercased = query.to_lowercase();
41 let query: String = query.chars() 43 Query {
42 .filter(|&c| c != '#') 44 query,
43 .flat_map(char::to_lowercase) 45 lowercased,
44 .collect(); 46 only_types: false,
45 Query { query, all_symbols } 47 exact: false,
48 }
49 }
50
51 pub fn only_types(&mut self) {
52 self.only_types = true;
53 }
54
55 pub fn exact(&mut self) {
56 self.exact = true;
46 } 57 }
47 58
48 pub(crate) fn process<'a>( 59 pub(crate) fn process<'a>(
@@ -55,16 +66,21 @@ impl Query {
55 _ => false, 66 _ => false,
56 } 67 }
57 } 68 }
58 let automaton = fst::automaton::Subsequence::new(&self.query); 69 let automaton = fst::automaton::Subsequence::new(&self.lowercased);
59 let all_symbols = self.all_symbols; 70 let mut stream = file.map.search(automaton).into_stream();
60 file.map.search(automaton).into_stream() 71 let mut res = Vec::new();
61 .into_values() 72 while let Some((_, idx)) = stream.next() {
62 .into_iter() 73 let idx = idx as usize;
63 .map(move |idx| { 74 let symbol = &file.symbols[idx];
64 let idx = idx as usize; 75 if self.only_types && !is_type(symbol.kind) {
65 &file.symbols[idx] 76 continue;
66 }) 77 }
67 .filter(move |s| all_symbols || is_type(s.kind)) 78 if self.exact && symbol.name != self.query {
79 continue;
80 }
81 res.push(symbol)
82 }
83 res.into_iter()
68 } 84 }
69} 85}
70 86