diff options
-rw-r--r-- | crates/libanalysis/src/lib.rs | 20 | ||||
-rw-r--r-- | crates/libanalysis/src/symbol_index.rs | 18 | ||||
-rw-r--r-- | crates/server/src/main_loop/handlers.rs | 3 |
3 files changed, 29 insertions, 12 deletions
diff --git a/crates/libanalysis/src/lib.rs b/crates/libanalysis/src/lib.rs index 97b6dfca6..562fab290 100644 --- a/crates/libanalysis/src/lib.rs +++ b/crates/libanalysis/src/lib.rs | |||
@@ -94,12 +94,12 @@ impl World { | |||
94 | Ok(index.clone()) | 94 | Ok(index.clone()) |
95 | } | 95 | } |
96 | 96 | ||
97 | pub fn world_symbols<'a>(&'a self, query: Query) -> impl Iterator<Item=(&'a Path, &'a FileSymbol)> + 'a { | 97 | pub fn world_symbols<'a>(&'a self, mut query: Query) -> impl Iterator<Item=(&'a Path, &'a FileSymbol)> + 'a { |
98 | self.data.file_map.iter() | 98 | self.data.file_map.iter() |
99 | .flat_map(move |(path, data)| { | 99 | .flat_map(move |(path, data)| { |
100 | let path: &'a Path = path.as_path(); | 100 | let path: &'a Path = path.as_path(); |
101 | let symbols = data.symbols(path); | 101 | let symbols = data.symbols(); |
102 | query.process(symbols).map(move |s| (path, s)) | 102 | query.process(symbols).into_iter().map(move |s| (path, s)) |
103 | }) | 103 | }) |
104 | } | 104 | } |
105 | 105 | ||
@@ -125,7 +125,8 @@ impl World { | |||
125 | 125 | ||
126 | let mut query = Query::new(name.to_string()); | 126 | let mut query = Query::new(name.to_string()); |
127 | query.exact(); | 127 | query.exact(); |
128 | Ok(self.world_symbols(query).take(4).collect()) | 128 | query.limit(4); |
129 | Ok(self.world_symbols(query).collect()) | ||
129 | } | 130 | } |
130 | 131 | ||
131 | fn file_data(&self, path: &Path) -> Result<Arc<FileData>> { | 132 | fn file_data(&self, path: &Path) -> Result<Arc<FileData>> { |
@@ -178,9 +179,14 @@ impl FileData { | |||
178 | }) | 179 | }) |
179 | } | 180 | } |
180 | 181 | ||
181 | fn symbols(&self, path: &Path) -> &FileSymbols { | 182 | fn syntax_transient(&self) -> ast::File { |
182 | let syntax = self.syntax(path); | 183 | self.syntax.get().map(|s| s.clone()) |
184 | .unwrap_or_else(|| ast::File::parse(&self.text)) | ||
185 | } | ||
186 | |||
187 | fn symbols(&self) -> &FileSymbols { | ||
188 | let syntax = self.syntax_transient(); | ||
183 | self.symbols | 189 | self.symbols |
184 | .get_or_init(|| FileSymbols::new(syntax)) | 190 | .get_or_init(|| FileSymbols::new(&syntax)) |
185 | } | 191 | } |
186 | } | 192 | } |
diff --git a/crates/libanalysis/src/symbol_index.rs b/crates/libanalysis/src/symbol_index.rs index 88d5c4995..a7ae197e0 100644 --- a/crates/libanalysis/src/symbol_index.rs +++ b/crates/libanalysis/src/symbol_index.rs | |||
@@ -35,6 +35,7 @@ pub struct Query { | |||
35 | lowercased: String, | 35 | lowercased: String, |
36 | only_types: bool, | 36 | only_types: bool, |
37 | exact: bool, | 37 | exact: bool, |
38 | limit: usize, | ||
38 | } | 39 | } |
39 | 40 | ||
40 | impl Query { | 41 | impl Query { |
@@ -45,6 +46,7 @@ impl Query { | |||
45 | lowercased, | 46 | lowercased, |
46 | only_types: false, | 47 | only_types: false, |
47 | exact: false, | 48 | exact: false, |
49 | limit: usize::max_value() | ||
48 | } | 50 | } |
49 | } | 51 | } |
50 | 52 | ||
@@ -56,10 +58,14 @@ impl Query { | |||
56 | self.exact = true; | 58 | self.exact = true; |
57 | } | 59 | } |
58 | 60 | ||
61 | pub fn limit(&mut self, limit: usize) { | ||
62 | self.limit = limit | ||
63 | } | ||
64 | |||
59 | pub(crate) fn process<'a>( | 65 | pub(crate) fn process<'a>( |
60 | &self, | 66 | &mut self, |
61 | file: &'a FileSymbols, | 67 | file: &'a FileSymbols, |
62 | ) -> impl Iterator<Item=&'a FileSymbol> + 'a { | 68 | ) -> Vec<&'a FileSymbol> { |
63 | fn is_type(kind: SyntaxKind) -> bool { | 69 | fn is_type(kind: SyntaxKind) -> bool { |
64 | match kind { | 70 | match kind { |
65 | STRUCT | ENUM | TRAIT | TYPE_ITEM => true, | 71 | STRUCT | ENUM | TRAIT | TYPE_ITEM => true, |
@@ -70,6 +76,9 @@ impl Query { | |||
70 | let mut stream = file.map.search(automaton).into_stream(); | 76 | let mut stream = file.map.search(automaton).into_stream(); |
71 | let mut res = Vec::new(); | 77 | let mut res = Vec::new(); |
72 | while let Some((_, idx)) = stream.next() { | 78 | while let Some((_, idx)) = stream.next() { |
79 | if self.limit == 0 { | ||
80 | break; | ||
81 | } | ||
73 | let idx = idx as usize; | 82 | let idx = idx as usize; |
74 | let symbol = &file.symbols[idx]; | 83 | let symbol = &file.symbols[idx]; |
75 | if self.only_types && !is_type(symbol.kind) { | 84 | if self.only_types && !is_type(symbol.kind) { |
@@ -78,9 +87,10 @@ impl Query { | |||
78 | if self.exact && symbol.name != self.query { | 87 | if self.exact && symbol.name != self.query { |
79 | continue; | 88 | continue; |
80 | } | 89 | } |
81 | res.push(symbol) | 90 | res.push(symbol); |
91 | self.limit -= 1; | ||
82 | } | 92 | } |
83 | res.into_iter() | 93 | res |
84 | } | 94 | } |
85 | } | 95 | } |
86 | 96 | ||
diff --git a/crates/server/src/main_loop/handlers.rs b/crates/server/src/main_loop/handlers.rs index e9dc78420..bfdfcb51e 100644 --- a/crates/server/src/main_loop/handlers.rs +++ b/crates/server/src/main_loop/handlers.rs | |||
@@ -110,10 +110,11 @@ pub fn handle_workspace_symbol( | |||
110 | if !all_symbols { | 110 | if !all_symbols { |
111 | q.only_types(); | 111 | q.only_types(); |
112 | } | 112 | } |
113 | q.limit(128); | ||
113 | q | 114 | q |
114 | }; | 115 | }; |
115 | 116 | ||
116 | for (path, symbol) in world.world_symbols(query).take(128) { | 117 | for (path, symbol) in world.world_symbols(query) { |
117 | let line_index = world.file_line_index(path)?; | 118 | let line_index = world.file_line_index(path)?; |
118 | let info = SymbolInformation { | 119 | let info = SymbolInformation { |
119 | name: symbol.name.to_string(), | 120 | name: symbol.name.to_string(), |