diff options
author | Aleksey Kladov <[email protected]> | 2018-08-13 13:35:53 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-08-13 13:35:53 +0100 |
commit | d19f3ac83441420365bff5e4ce21d1d2175bd8c2 (patch) | |
tree | 0523dc698784bb2501998956f8111b31f4e0387b /crates/libanalysis | |
parent | 133d001d8296e51bcb4d0dc0982671f55c2c77d9 (diff) |
workspace symbols
Diffstat (limited to 'crates/libanalysis')
-rw-r--r-- | crates/libanalysis/src/lib.rs | 29 | ||||
-rw-r--r-- | crates/libanalysis/src/symbol_index.rs | 28 |
2 files changed, 29 insertions, 28 deletions
diff --git a/crates/libanalysis/src/lib.rs b/crates/libanalysis/src/lib.rs index f0d0cf0a4..acaadb8a2 100644 --- a/crates/libanalysis/src/lib.rs +++ b/crates/libanalysis/src/lib.rs | |||
@@ -89,14 +89,15 @@ impl World { | |||
89 | Ok(index.clone()) | 89 | Ok(index.clone()) |
90 | } | 90 | } |
91 | 91 | ||
92 | pub fn world_symbols(&self, query: &str, f: &mut FnMut(&Path, &FileSymbol) -> Search) { | 92 | pub fn world_symbols<'a>(&'a self, query: &str) -> impl Iterator<Item=(&'a Path, &'a FileSymbol)> + 'a |
93 | { | ||
93 | let q = Query::new(query); | 94 | let q = Query::new(query); |
94 | for (path, data) in self.data.file_map.iter() { | 95 | self.data.file_map.iter() |
95 | let symbols = data.symbols(path.as_path()); | 96 | .flat_map(move |(path, data)| { |
96 | if q.process(symbols, &mut |symbol| f(path, symbol)) == Search::Break { | 97 | let path: &'a Path = path.as_path(); |
97 | break; | 98 | let symbols = data.symbols(path); |
98 | } | 99 | q.process(symbols).map(move |s| (path, s)) |
99 | } | 100 | }) |
100 | } | 101 | } |
101 | 102 | ||
102 | fn file_data(&self, path: &Path) -> Result<Arc<FileData>> { | 103 | fn file_data(&self, path: &Path) -> Result<Arc<FileData>> { |
@@ -107,11 +108,15 @@ impl World { | |||
107 | } | 108 | } |
108 | } | 109 | } |
109 | 110 | ||
110 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | 111 | |
111 | pub enum Search { | 112 | pub type SearchResult = ::std::result::Result<Continue, Break>; |
112 | Continue, | 113 | |
113 | Break, | 114 | pub struct Continue; |
114 | } | 115 | |
116 | pub struct Break; | ||
117 | |||
118 | pub const CONTINUE: SearchResult = Ok(Continue); | ||
119 | pub const BREAK: SearchResult = Err(Break); | ||
115 | 120 | ||
116 | 121 | ||
117 | #[derive(Default, Debug)] | 122 | #[derive(Default, Debug)] |
diff --git a/crates/libanalysis/src/symbol_index.rs b/crates/libanalysis/src/symbol_index.rs index 1878fae99..4d90aac0c 100644 --- a/crates/libanalysis/src/symbol_index.rs +++ b/crates/libanalysis/src/symbol_index.rs | |||
@@ -5,8 +5,6 @@ use libsyntax2::{ | |||
5 | }; | 5 | }; |
6 | use fst::{self, IntoStreamer}; | 6 | use fst::{self, IntoStreamer}; |
7 | 7 | ||
8 | use Search; | ||
9 | |||
10 | #[derive(Debug)] | 8 | #[derive(Debug)] |
11 | pub(crate) struct FileSymbols { | 9 | pub(crate) struct FileSymbols { |
12 | symbols: Vec<FileSymbol>, | 10 | symbols: Vec<FileSymbol>, |
@@ -47,11 +45,10 @@ impl Query { | |||
47 | Query { query, all_symbols } | 45 | Query { query, all_symbols } |
48 | } | 46 | } |
49 | 47 | ||
50 | pub(crate) fn process( | 48 | pub(crate) fn process<'a>( |
51 | &self, | 49 | &self, |
52 | file: &FileSymbols, | 50 | file: &'a FileSymbols, |
53 | acc: &mut FnMut(&FileSymbol) -> Search, | 51 | ) -> impl Iterator<Item=&'a FileSymbol> + 'a { |
54 | ) -> Search { | ||
55 | fn is_type(kind: SyntaxKind) -> bool { | 52 | fn is_type(kind: SyntaxKind) -> bool { |
56 | match kind { | 53 | match kind { |
57 | STRUCT | ENUM | TRAIT | TYPE_ITEM => true, | 54 | STRUCT | ENUM | TRAIT | TYPE_ITEM => true, |
@@ -59,16 +56,15 @@ impl Query { | |||
59 | } | 56 | } |
60 | } | 57 | } |
61 | let automaton = fst::automaton::Subsequence::new(&self.query); | 58 | let automaton = fst::automaton::Subsequence::new(&self.query); |
62 | for idx in file.map.search(automaton).into_stream().into_values() { | 59 | let all_symbols = self.all_symbols; |
63 | let idx = idx as usize; | 60 | file.map.search(automaton).into_stream() |
64 | let symbol = &file.symbols[idx]; | 61 | .into_values() |
65 | if self.all_symbols || is_type(symbol.kind) { | 62 | .into_iter() |
66 | if acc(&symbol) == Search::Break { | 63 | .map(move |idx| { |
67 | return Search::Break; | 64 | let idx = idx as usize; |
68 | } | 65 | &file.symbols[idx] |
69 | } | 66 | }) |
70 | } | 67 | .filter(move |s| all_symbols || is_type(s.kind)) |
71 | Search::Continue | ||
72 | } | 68 | } |
73 | } | 69 | } |
74 | 70 | ||