aboutsummaryrefslogtreecommitdiff
path: root/crates/libanalysis/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/libanalysis/src')
-rw-r--r--crates/libanalysis/src/lib.rs8
-rw-r--r--crates/libanalysis/src/symbol_index.rs56
2 files changed, 40 insertions, 24 deletions
diff --git a/crates/libanalysis/src/lib.rs b/crates/libanalysis/src/lib.rs
index acaadb8a2..b2f4bdbb3 100644
--- a/crates/libanalysis/src/lib.rs
+++ b/crates/libanalysis/src/lib.rs
@@ -21,7 +21,8 @@ use std::{
21use libsyntax2::ast; 21use libsyntax2::ast;
22use libeditor::{LineIndex, FileSymbol}; 22use libeditor::{LineIndex, FileSymbol};
23 23
24use self::symbol_index::{FileSymbols, Query}; 24use self::symbol_index::{FileSymbols};
25pub use self::symbol_index::Query;
25 26
26pub type Result<T> = ::std::result::Result<T, ::failure::Error>; 27pub type Result<T> = ::std::result::Result<T, ::failure::Error>;
27 28
@@ -89,14 +90,13 @@ impl World {
89 Ok(index.clone()) 90 Ok(index.clone())
90 } 91 }
91 92
92 pub fn world_symbols<'a>(&'a self, query: &str) -> impl Iterator<Item=(&'a Path, &'a FileSymbol)> + 'a 93 pub fn world_symbols<'a>(&'a self, query: Query) -> impl Iterator<Item=(&'a Path, &'a FileSymbol)> + 'a
93 { 94 {
94 let q = Query::new(query);
95 self.data.file_map.iter() 95 self.data.file_map.iter()
96 .flat_map(move |(path, data)| { 96 .flat_map(move |(path, data)| {
97 let path: &'a Path = path.as_path(); 97 let path: &'a Path = path.as_path();
98 let symbols = data.symbols(path); 98 let symbols = data.symbols(path);
99 q.process(symbols).map(move |s| (path, s)) 99 query.process(symbols).map(move |s| (path, s))
100 }) 100 })
101 } 101 }
102 102
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