aboutsummaryrefslogtreecommitdiff
path: root/crates/libanalysis
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-08-13 13:35:53 +0100
committerAleksey Kladov <[email protected]>2018-08-13 13:35:53 +0100
commitd19f3ac83441420365bff5e4ce21d1d2175bd8c2 (patch)
tree0523dc698784bb2501998956f8111b31f4e0387b /crates/libanalysis
parent133d001d8296e51bcb4d0dc0982671f55c2c77d9 (diff)
workspace symbols
Diffstat (limited to 'crates/libanalysis')
-rw-r--r--crates/libanalysis/src/lib.rs29
-rw-r--r--crates/libanalysis/src/symbol_index.rs28
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
111pub enum Search { 112pub type SearchResult = ::std::result::Result<Continue, Break>;
112 Continue, 113
113 Break, 114pub struct Continue;
114} 115
116pub struct Break;
117
118pub const CONTINUE: SearchResult = Ok(Continue);
119pub 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};
6use fst::{self, IntoStreamer}; 6use fst::{self, IntoStreamer};
7 7
8use Search;
9
10#[derive(Debug)] 8#[derive(Debug)]
11pub(crate) struct FileSymbols { 9pub(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