diff options
author | Aleksey Kladov <[email protected]> | 2018-08-13 14:07:05 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-08-13 14:07:05 +0100 |
commit | 7fc91f41d8bd948cef3085d7c0d0ec92d1b2bc53 (patch) | |
tree | d671181833c0af18fdfd167998cae1afbe759926 /crates/libanalysis/src | |
parent | 0568e76406fc4869152671a255c5e1efca6611a6 (diff) |
Generalize query
Diffstat (limited to 'crates/libanalysis/src')
-rw-r--r-- | crates/libanalysis/src/lib.rs | 8 | ||||
-rw-r--r-- | crates/libanalysis/src/symbol_index.rs | 56 |
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::{ | |||
21 | use libsyntax2::ast; | 21 | use libsyntax2::ast; |
22 | use libeditor::{LineIndex, FileSymbol}; | 22 | use libeditor::{LineIndex, FileSymbol}; |
23 | 23 | ||
24 | use self::symbol_index::{FileSymbols, Query}; | 24 | use self::symbol_index::{FileSymbols}; |
25 | pub use self::symbol_index::Query; | ||
25 | 26 | ||
26 | pub type Result<T> = ::std::result::Result<T, ::failure::Error>; | 27 | pub 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 | }; |
6 | use fst::{self, IntoStreamer}; | 6 | use fst::{self, IntoStreamer, Streamer}; |
7 | 7 | ||
8 | #[derive(Debug)] | 8 | #[derive(Debug)] |
9 | pub(crate) struct FileSymbols { | 9 | pub(crate) struct FileSymbols { |
@@ -30,19 +30,30 @@ impl FileSymbols { | |||
30 | } | 30 | } |
31 | } | 31 | } |
32 | 32 | ||
33 | pub(crate) struct Query { | 33 | pub 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 | ||
38 | impl Query { | 40 | impl 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 | ||