diff options
author | Mikhail Rakhmanov <[email protected]> | 2020-06-03 18:26:01 +0100 |
---|---|---|
committer | Mikhail Rakhmanov <[email protected]> | 2020-06-03 18:26:01 +0100 |
commit | 6a0083a519680e8d16bde5d7c1940c8dd6d4e9d4 (patch) | |
tree | 2b377141d722257cfea18e74b955aea1a8f6cc1a /crates/rust-analyzer/src/main_loop/handlers.rs | |
parent | 1f7de306f547ecb394a34445fd6ac1d6bc8ab439 (diff) | |
parent | 794f6da821c5d6e2490b996baffe162e4753262d (diff) |
Merge branch 'master' into compute-lazy-assits
# Conflicts:
# crates/rust-analyzer/src/main_loop/handlers.rs
# crates/rust-analyzer/src/to_proto.rs
Diffstat (limited to 'crates/rust-analyzer/src/main_loop/handlers.rs')
-rw-r--r-- | crates/rust-analyzer/src/main_loop/handlers.rs | 390 |
1 files changed, 197 insertions, 193 deletions
diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs index fab82ff7e..a3361d6dc 100644 --- a/crates/rust-analyzer/src/main_loop/handlers.rs +++ b/crates/rust-analyzer/src/main_loop/handlers.rs | |||
@@ -32,17 +32,16 @@ use crate::{ | |||
32 | config::RustfmtConfig, | 32 | config::RustfmtConfig, |
33 | diagnostics::DiagnosticTask, | 33 | diagnostics::DiagnosticTask, |
34 | from_json, from_proto, | 34 | from_json, from_proto, |
35 | global_state::GlobalStateSnapshot, | ||
35 | lsp_ext::{self, InlayHint, InlayHintsParams}, | 36 | lsp_ext::{self, InlayHint, InlayHintsParams}, |
36 | to_proto, | 37 | to_proto, LspError, Result, |
37 | world::WorldSnapshot, | ||
38 | LspError, Result, | ||
39 | }; | 38 | }; |
40 | 39 | ||
41 | pub fn handle_analyzer_status(world: WorldSnapshot, _: ()) -> Result<String> { | 40 | pub fn handle_analyzer_status(snap: GlobalStateSnapshot, _: ()) -> Result<String> { |
42 | let _p = profile("handle_analyzer_status"); | 41 | let _p = profile("handle_analyzer_status"); |
43 | let mut buf = world.status(); | 42 | let mut buf = snap.status(); |
44 | format_to!(buf, "\n\nrequests:\n"); | 43 | format_to!(buf, "\n\nrequests:\n"); |
45 | let requests = world.latest_requests.read(); | 44 | let requests = snap.latest_requests.read(); |
46 | for (is_last, r) in requests.iter() { | 45 | for (is_last, r) in requests.iter() { |
47 | let mark = if is_last { "*" } else { " " }; | 46 | let mark = if is_last { "*" } else { " " }; |
48 | format_to!(buf, "{}{:4} {:<36}{}ms\n", mark, r.id, r.method, r.duration.as_millis()); | 47 | format_to!(buf, "{}{:4} {:<36}{}ms\n", mark, r.id, r.method, r.duration.as_millis()); |
@@ -51,37 +50,37 @@ pub fn handle_analyzer_status(world: WorldSnapshot, _: ()) -> Result<String> { | |||
51 | } | 50 | } |
52 | 51 | ||
53 | pub fn handle_syntax_tree( | 52 | pub fn handle_syntax_tree( |
54 | world: WorldSnapshot, | 53 | snap: GlobalStateSnapshot, |
55 | params: lsp_ext::SyntaxTreeParams, | 54 | params: lsp_ext::SyntaxTreeParams, |
56 | ) -> Result<String> { | 55 | ) -> Result<String> { |
57 | let _p = profile("handle_syntax_tree"); | 56 | let _p = profile("handle_syntax_tree"); |
58 | let id = from_proto::file_id(&world, ¶ms.text_document.uri)?; | 57 | let id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; |
59 | let line_index = world.analysis().file_line_index(id)?; | 58 | let line_index = snap.analysis().file_line_index(id)?; |
60 | let text_range = params.range.map(|r| from_proto::text_range(&line_index, r)); | 59 | let text_range = params.range.map(|r| from_proto::text_range(&line_index, r)); |
61 | let res = world.analysis().syntax_tree(id, text_range)?; | 60 | let res = snap.analysis().syntax_tree(id, text_range)?; |
62 | Ok(res) | 61 | Ok(res) |
63 | } | 62 | } |
64 | 63 | ||
65 | pub fn handle_expand_macro( | 64 | pub fn handle_expand_macro( |
66 | world: WorldSnapshot, | 65 | snap: GlobalStateSnapshot, |
67 | params: lsp_ext::ExpandMacroParams, | 66 | params: lsp_ext::ExpandMacroParams, |
68 | ) -> Result<Option<lsp_ext::ExpandedMacro>> { | 67 | ) -> Result<Option<lsp_ext::ExpandedMacro>> { |
69 | let _p = profile("handle_expand_macro"); | 68 | let _p = profile("handle_expand_macro"); |
70 | let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; | 69 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; |
71 | let line_index = world.analysis().file_line_index(file_id)?; | 70 | let line_index = snap.analysis().file_line_index(file_id)?; |
72 | let offset = from_proto::offset(&line_index, params.position); | 71 | let offset = from_proto::offset(&line_index, params.position); |
73 | 72 | ||
74 | let res = world.analysis().expand_macro(FilePosition { file_id, offset })?; | 73 | let res = snap.analysis().expand_macro(FilePosition { file_id, offset })?; |
75 | Ok(res.map(|it| lsp_ext::ExpandedMacro { name: it.name, expansion: it.expansion })) | 74 | Ok(res.map(|it| lsp_ext::ExpandedMacro { name: it.name, expansion: it.expansion })) |
76 | } | 75 | } |
77 | 76 | ||
78 | pub fn handle_selection_range( | 77 | pub fn handle_selection_range( |
79 | world: WorldSnapshot, | 78 | snap: GlobalStateSnapshot, |
80 | params: lsp_types::SelectionRangeParams, | 79 | params: lsp_types::SelectionRangeParams, |
81 | ) -> Result<Option<Vec<lsp_types::SelectionRange>>> { | 80 | ) -> Result<Option<Vec<lsp_types::SelectionRange>>> { |
82 | let _p = profile("handle_selection_range"); | 81 | let _p = profile("handle_selection_range"); |
83 | let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; | 82 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; |
84 | let line_index = world.analysis().file_line_index(file_id)?; | 83 | let line_index = snap.analysis().file_line_index(file_id)?; |
85 | let res: Result<Vec<lsp_types::SelectionRange>> = params | 84 | let res: Result<Vec<lsp_types::SelectionRange>> = params |
86 | .positions | 85 | .positions |
87 | .into_iter() | 86 | .into_iter() |
@@ -93,7 +92,7 @@ pub fn handle_selection_range( | |||
93 | loop { | 92 | loop { |
94 | ranges.push(range); | 93 | ranges.push(range); |
95 | let frange = FileRange { file_id, range }; | 94 | let frange = FileRange { file_id, range }; |
96 | let next = world.analysis().extend_selection(frange)?; | 95 | let next = snap.analysis().extend_selection(frange)?; |
97 | if next == range { | 96 | if next == range { |
98 | break; | 97 | break; |
99 | } else { | 98 | } else { |
@@ -119,18 +118,18 @@ pub fn handle_selection_range( | |||
119 | } | 118 | } |
120 | 119 | ||
121 | pub fn handle_matching_brace( | 120 | pub fn handle_matching_brace( |
122 | world: WorldSnapshot, | 121 | snap: GlobalStateSnapshot, |
123 | params: lsp_ext::MatchingBraceParams, | 122 | params: lsp_ext::MatchingBraceParams, |
124 | ) -> Result<Vec<Position>> { | 123 | ) -> Result<Vec<Position>> { |
125 | let _p = profile("handle_matching_brace"); | 124 | let _p = profile("handle_matching_brace"); |
126 | let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; | 125 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; |
127 | let line_index = world.analysis().file_line_index(file_id)?; | 126 | let line_index = snap.analysis().file_line_index(file_id)?; |
128 | let res = params | 127 | let res = params |
129 | .positions | 128 | .positions |
130 | .into_iter() | 129 | .into_iter() |
131 | .map(|position| { | 130 | .map(|position| { |
132 | let offset = from_proto::offset(&line_index, position); | 131 | let offset = from_proto::offset(&line_index, position); |
133 | let offset = match world.analysis().matching_brace(FilePosition { file_id, offset }) { | 132 | let offset = match snap.analysis().matching_brace(FilePosition { file_id, offset }) { |
134 | Ok(Some(matching_brace_offset)) => matching_brace_offset, | 133 | Ok(Some(matching_brace_offset)) => matching_brace_offset, |
135 | Err(_) | Ok(None) => offset, | 134 | Err(_) | Ok(None) => offset, |
136 | }; | 135 | }; |
@@ -141,17 +140,17 @@ pub fn handle_matching_brace( | |||
141 | } | 140 | } |
142 | 141 | ||
143 | pub fn handle_join_lines( | 142 | pub fn handle_join_lines( |
144 | world: WorldSnapshot, | 143 | snap: GlobalStateSnapshot, |
145 | params: lsp_ext::JoinLinesParams, | 144 | params: lsp_ext::JoinLinesParams, |
146 | ) -> Result<Vec<lsp_types::TextEdit>> { | 145 | ) -> Result<Vec<lsp_types::TextEdit>> { |
147 | let _p = profile("handle_join_lines"); | 146 | let _p = profile("handle_join_lines"); |
148 | let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; | 147 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; |
149 | let line_index = world.analysis().file_line_index(file_id)?; | 148 | let line_index = snap.analysis().file_line_index(file_id)?; |
150 | let line_endings = world.file_line_endings(file_id); | 149 | let line_endings = snap.file_line_endings(file_id); |
151 | let mut res = TextEdit::default(); | 150 | let mut res = TextEdit::default(); |
152 | for range in params.ranges { | 151 | for range in params.ranges { |
153 | let range = from_proto::text_range(&line_index, range); | 152 | let range = from_proto::text_range(&line_index, range); |
154 | let edit = world.analysis().join_lines(FileRange { file_id, range })?; | 153 | let edit = snap.analysis().join_lines(FileRange { file_id, range })?; |
155 | match res.union(edit) { | 154 | match res.union(edit) { |
156 | Ok(()) => (), | 155 | Ok(()) => (), |
157 | Err(_edit) => { | 156 | Err(_edit) => { |
@@ -164,37 +163,37 @@ pub fn handle_join_lines( | |||
164 | } | 163 | } |
165 | 164 | ||
166 | pub fn handle_on_enter( | 165 | pub fn handle_on_enter( |
167 | world: WorldSnapshot, | 166 | snap: GlobalStateSnapshot, |
168 | params: lsp_types::TextDocumentPositionParams, | 167 | params: lsp_types::TextDocumentPositionParams, |
169 | ) -> Result<Option<Vec<lsp_ext::SnippetTextEdit>>> { | 168 | ) -> Result<Option<Vec<lsp_ext::SnippetTextEdit>>> { |
170 | let _p = profile("handle_on_enter"); | 169 | let _p = profile("handle_on_enter"); |
171 | let position = from_proto::file_position(&world, params)?; | 170 | let position = from_proto::file_position(&snap, params)?; |
172 | let edit = match world.analysis().on_enter(position)? { | 171 | let edit = match snap.analysis().on_enter(position)? { |
173 | None => return Ok(None), | 172 | None => return Ok(None), |
174 | Some(it) => it, | 173 | Some(it) => it, |
175 | }; | 174 | }; |
176 | let line_index = world.analysis().file_line_index(position.file_id)?; | 175 | let line_index = snap.analysis().file_line_index(position.file_id)?; |
177 | let line_endings = world.file_line_endings(position.file_id); | 176 | let line_endings = snap.file_line_endings(position.file_id); |
178 | let edit = to_proto::snippet_text_edit_vec(&line_index, line_endings, true, edit); | 177 | let edit = to_proto::snippet_text_edit_vec(&line_index, line_endings, true, edit); |
179 | Ok(Some(edit)) | 178 | Ok(Some(edit)) |
180 | } | 179 | } |
181 | 180 | ||
182 | // Don't forget to add new trigger characters to `ServerCapabilities` in `caps.rs`. | 181 | // Don't forget to add new trigger characters to `ServerCapabilities` in `caps.rs`. |
183 | pub fn handle_on_type_formatting( | 182 | pub fn handle_on_type_formatting( |
184 | world: WorldSnapshot, | 183 | snap: GlobalStateSnapshot, |
185 | params: lsp_types::DocumentOnTypeFormattingParams, | 184 | params: lsp_types::DocumentOnTypeFormattingParams, |
186 | ) -> Result<Option<Vec<lsp_types::TextEdit>>> { | 185 | ) -> Result<Option<Vec<lsp_types::TextEdit>>> { |
187 | let _p = profile("handle_on_type_formatting"); | 186 | let _p = profile("handle_on_type_formatting"); |
188 | let mut position = from_proto::file_position(&world, params.text_document_position)?; | 187 | let mut position = from_proto::file_position(&snap, params.text_document_position)?; |
189 | let line_index = world.analysis().file_line_index(position.file_id)?; | 188 | let line_index = snap.analysis().file_line_index(position.file_id)?; |
190 | let line_endings = world.file_line_endings(position.file_id); | 189 | let line_endings = snap.file_line_endings(position.file_id); |
191 | 190 | ||
192 | // in `ra_ide`, the `on_type` invariant is that | 191 | // in `ra_ide`, the `on_type` invariant is that |
193 | // `text.char_at(position) == typed_char`. | 192 | // `text.char_at(position) == typed_char`. |
194 | position.offset -= TextSize::of('.'); | 193 | position.offset -= TextSize::of('.'); |
195 | let char_typed = params.ch.chars().next().unwrap_or('\0'); | 194 | let char_typed = params.ch.chars().next().unwrap_or('\0'); |
196 | assert!({ | 195 | assert!({ |
197 | let text = world.analysis().file_text(position.file_id)?; | 196 | let text = snap.analysis().file_text(position.file_id)?; |
198 | text[usize::from(position.offset)..].starts_with(char_typed) | 197 | text[usize::from(position.offset)..].starts_with(char_typed) |
199 | }); | 198 | }); |
200 | 199 | ||
@@ -206,7 +205,7 @@ pub fn handle_on_type_formatting( | |||
206 | return Ok(None); | 205 | return Ok(None); |
207 | } | 206 | } |
208 | 207 | ||
209 | let edit = world.analysis().on_char_typed(position, char_typed)?; | 208 | let edit = snap.analysis().on_char_typed(position, char_typed)?; |
210 | let mut edit = match edit { | 209 | let mut edit = match edit { |
211 | Some(it) => it, | 210 | Some(it) => it, |
212 | None => return Ok(None), | 211 | None => return Ok(None), |
@@ -220,16 +219,16 @@ pub fn handle_on_type_formatting( | |||
220 | } | 219 | } |
221 | 220 | ||
222 | pub fn handle_document_symbol( | 221 | pub fn handle_document_symbol( |
223 | world: WorldSnapshot, | 222 | snap: GlobalStateSnapshot, |
224 | params: lsp_types::DocumentSymbolParams, | 223 | params: lsp_types::DocumentSymbolParams, |
225 | ) -> Result<Option<lsp_types::DocumentSymbolResponse>> { | 224 | ) -> Result<Option<lsp_types::DocumentSymbolResponse>> { |
226 | let _p = profile("handle_document_symbol"); | 225 | let _p = profile("handle_document_symbol"); |
227 | let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; | 226 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; |
228 | let line_index = world.analysis().file_line_index(file_id)?; | 227 | let line_index = snap.analysis().file_line_index(file_id)?; |
229 | 228 | ||
230 | let mut parents: Vec<(DocumentSymbol, Option<usize>)> = Vec::new(); | 229 | let mut parents: Vec<(DocumentSymbol, Option<usize>)> = Vec::new(); |
231 | 230 | ||
232 | for symbol in world.analysis().file_structure(file_id)? { | 231 | for symbol in snap.analysis().file_structure(file_id)? { |
233 | let doc_symbol = DocumentSymbol { | 232 | let doc_symbol = DocumentSymbol { |
234 | name: symbol.label, | 233 | name: symbol.label, |
235 | detail: symbol.detail, | 234 | detail: symbol.detail, |
@@ -255,10 +254,10 @@ pub fn handle_document_symbol( | |||
255 | } | 254 | } |
256 | } | 255 | } |
257 | 256 | ||
258 | let res = if world.config.client_caps.hierarchical_symbols { | 257 | let res = if snap.config.client_caps.hierarchical_symbols { |
259 | document_symbols.into() | 258 | document_symbols.into() |
260 | } else { | 259 | } else { |
261 | let url = to_proto::url(&world, file_id)?; | 260 | let url = to_proto::url(&snap, file_id)?; |
262 | let mut symbol_information = Vec::<SymbolInformation>::new(); | 261 | let mut symbol_information = Vec::<SymbolInformation>::new(); |
263 | for symbol in document_symbols { | 262 | for symbol in document_symbols { |
264 | flatten_document_symbol(&symbol, None, &url, &mut symbol_information); | 263 | flatten_document_symbol(&symbol, None, &url, &mut symbol_information); |
@@ -288,7 +287,7 @@ pub fn handle_document_symbol( | |||
288 | } | 287 | } |
289 | 288 | ||
290 | pub fn handle_workspace_symbol( | 289 | pub fn handle_workspace_symbol( |
291 | world: WorldSnapshot, | 290 | snap: GlobalStateSnapshot, |
292 | params: lsp_types::WorkspaceSymbolParams, | 291 | params: lsp_types::WorkspaceSymbolParams, |
293 | ) -> Result<Option<Vec<SymbolInformation>>> { | 292 | ) -> Result<Option<Vec<SymbolInformation>>> { |
294 | let _p = profile("handle_workspace_symbol"); | 293 | let _p = profile("handle_workspace_symbol"); |
@@ -306,22 +305,22 @@ pub fn handle_workspace_symbol( | |||
306 | q.limit(128); | 305 | q.limit(128); |
307 | q | 306 | q |
308 | }; | 307 | }; |
309 | let mut res = exec_query(&world, query)?; | 308 | let mut res = exec_query(&snap, query)?; |
310 | if res.is_empty() && !all_symbols { | 309 | if res.is_empty() && !all_symbols { |
311 | let mut query = Query::new(params.query); | 310 | let mut query = Query::new(params.query); |
312 | query.limit(128); | 311 | query.limit(128); |
313 | res = exec_query(&world, query)?; | 312 | res = exec_query(&snap, query)?; |
314 | } | 313 | } |
315 | 314 | ||
316 | return Ok(Some(res)); | 315 | return Ok(Some(res)); |
317 | 316 | ||
318 | fn exec_query(world: &WorldSnapshot, query: Query) -> Result<Vec<SymbolInformation>> { | 317 | fn exec_query(snap: &GlobalStateSnapshot, query: Query) -> Result<Vec<SymbolInformation>> { |
319 | let mut res = Vec::new(); | 318 | let mut res = Vec::new(); |
320 | for nav in world.analysis().symbol_search(query)? { | 319 | for nav in snap.analysis().symbol_search(query)? { |
321 | let info = SymbolInformation { | 320 | let info = SymbolInformation { |
322 | name: nav.name().to_string(), | 321 | name: nav.name().to_string(), |
323 | kind: to_proto::symbol_kind(nav.kind()), | 322 | kind: to_proto::symbol_kind(nav.kind()), |
324 | location: to_proto::location(world, nav.file_range())?, | 323 | location: to_proto::location(snap, nav.file_range())?, |
325 | container_name: nav.container_name().map(|v| v.to_string()), | 324 | container_name: nav.container_name().map(|v| v.to_string()), |
326 | deprecated: None, | 325 | deprecated: None, |
327 | }; | 326 | }; |
@@ -332,73 +331,73 @@ pub fn handle_workspace_symbol( | |||
332 | } | 331 | } |
333 | 332 | ||
334 | pub fn handle_goto_definition( | 333 | pub fn handle_goto_definition( |
335 | world: WorldSnapshot, | 334 | snap: GlobalStateSnapshot, |
336 | params: lsp_types::GotoDefinitionParams, | 335 | params: lsp_types::GotoDefinitionParams, |
337 | ) -> Result<Option<lsp_types::GotoDefinitionResponse>> { | 336 | ) -> Result<Option<lsp_types::GotoDefinitionResponse>> { |
338 | let _p = profile("handle_goto_definition"); | 337 | let _p = profile("handle_goto_definition"); |
339 | let position = from_proto::file_position(&world, params.text_document_position_params)?; | 338 | let position = from_proto::file_position(&snap, params.text_document_position_params)?; |
340 | let nav_info = match world.analysis().goto_definition(position)? { | 339 | let nav_info = match snap.analysis().goto_definition(position)? { |
341 | None => return Ok(None), | 340 | None => return Ok(None), |
342 | Some(it) => it, | 341 | Some(it) => it, |
343 | }; | 342 | }; |
344 | let src = FileRange { file_id: position.file_id, range: nav_info.range }; | 343 | let src = FileRange { file_id: position.file_id, range: nav_info.range }; |
345 | let res = to_proto::goto_definition_response(&world, Some(src), nav_info.info)?; | 344 | let res = to_proto::goto_definition_response(&snap, Some(src), nav_info.info)?; |
346 | Ok(Some(res)) | 345 | Ok(Some(res)) |
347 | } | 346 | } |
348 | 347 | ||
349 | pub fn handle_goto_implementation( | 348 | pub fn handle_goto_implementation( |
350 | world: WorldSnapshot, | 349 | snap: GlobalStateSnapshot, |
351 | params: lsp_types::request::GotoImplementationParams, | 350 | params: lsp_types::request::GotoImplementationParams, |
352 | ) -> Result<Option<lsp_types::request::GotoImplementationResponse>> { | 351 | ) -> Result<Option<lsp_types::request::GotoImplementationResponse>> { |
353 | let _p = profile("handle_goto_implementation"); | 352 | let _p = profile("handle_goto_implementation"); |
354 | let position = from_proto::file_position(&world, params.text_document_position_params)?; | 353 | let position = from_proto::file_position(&snap, params.text_document_position_params)?; |
355 | let nav_info = match world.analysis().goto_implementation(position)? { | 354 | let nav_info = match snap.analysis().goto_implementation(position)? { |
356 | None => return Ok(None), | 355 | None => return Ok(None), |
357 | Some(it) => it, | 356 | Some(it) => it, |
358 | }; | 357 | }; |
359 | let src = FileRange { file_id: position.file_id, range: nav_info.range }; | 358 | let src = FileRange { file_id: position.file_id, range: nav_info.range }; |
360 | let res = to_proto::goto_definition_response(&world, Some(src), nav_info.info)?; | 359 | let res = to_proto::goto_definition_response(&snap, Some(src), nav_info.info)?; |
361 | Ok(Some(res)) | 360 | Ok(Some(res)) |
362 | } | 361 | } |
363 | 362 | ||
364 | pub fn handle_goto_type_definition( | 363 | pub fn handle_goto_type_definition( |
365 | world: WorldSnapshot, | 364 | snap: GlobalStateSnapshot, |
366 | params: lsp_types::request::GotoTypeDefinitionParams, | 365 | params: lsp_types::request::GotoTypeDefinitionParams, |
367 | ) -> Result<Option<lsp_types::request::GotoTypeDefinitionResponse>> { | 366 | ) -> Result<Option<lsp_types::request::GotoTypeDefinitionResponse>> { |
368 | let _p = profile("handle_goto_type_definition"); | 367 | let _p = profile("handle_goto_type_definition"); |
369 | let position = from_proto::file_position(&world, params.text_document_position_params)?; | 368 | let position = from_proto::file_position(&snap, params.text_document_position_params)?; |
370 | let nav_info = match world.analysis().goto_type_definition(position)? { | 369 | let nav_info = match snap.analysis().goto_type_definition(position)? { |
371 | None => return Ok(None), | 370 | None => return Ok(None), |
372 | Some(it) => it, | 371 | Some(it) => it, |
373 | }; | 372 | }; |
374 | let src = FileRange { file_id: position.file_id, range: nav_info.range }; | 373 | let src = FileRange { file_id: position.file_id, range: nav_info.range }; |
375 | let res = to_proto::goto_definition_response(&world, Some(src), nav_info.info)?; | 374 | let res = to_proto::goto_definition_response(&snap, Some(src), nav_info.info)?; |
376 | Ok(Some(res)) | 375 | Ok(Some(res)) |
377 | } | 376 | } |
378 | 377 | ||
379 | pub fn handle_parent_module( | 378 | pub fn handle_parent_module( |
380 | world: WorldSnapshot, | 379 | snap: GlobalStateSnapshot, |
381 | params: lsp_types::TextDocumentPositionParams, | 380 | params: lsp_types::TextDocumentPositionParams, |
382 | ) -> Result<Option<lsp_types::GotoDefinitionResponse>> { | 381 | ) -> Result<Option<lsp_types::GotoDefinitionResponse>> { |
383 | let _p = profile("handle_parent_module"); | 382 | let _p = profile("handle_parent_module"); |
384 | let position = from_proto::file_position(&world, params)?; | 383 | let position = from_proto::file_position(&snap, params)?; |
385 | let navs = world.analysis().parent_module(position)?; | 384 | let navs = snap.analysis().parent_module(position)?; |
386 | let res = to_proto::goto_definition_response(&world, None, navs)?; | 385 | let res = to_proto::goto_definition_response(&snap, None, navs)?; |
387 | Ok(Some(res)) | 386 | Ok(Some(res)) |
388 | } | 387 | } |
389 | 388 | ||
390 | pub fn handle_runnables( | 389 | pub fn handle_runnables( |
391 | world: WorldSnapshot, | 390 | snap: GlobalStateSnapshot, |
392 | params: lsp_ext::RunnablesParams, | 391 | params: lsp_ext::RunnablesParams, |
393 | ) -> Result<Vec<lsp_ext::Runnable>> { | 392 | ) -> Result<Vec<lsp_ext::Runnable>> { |
394 | let _p = profile("handle_runnables"); | 393 | let _p = profile("handle_runnables"); |
395 | let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; | 394 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; |
396 | let line_index = world.analysis().file_line_index(file_id)?; | 395 | let line_index = snap.analysis().file_line_index(file_id)?; |
397 | let offset = params.position.map(|it| from_proto::offset(&line_index, it)); | 396 | let offset = params.position.map(|it| from_proto::offset(&line_index, it)); |
398 | let mut res = Vec::new(); | 397 | let mut res = Vec::new(); |
399 | let workspace_root = world.workspace_root_for(file_id); | 398 | let workspace_root = snap.workspace_root_for(file_id); |
400 | let cargo_spec = CargoTargetSpec::for_file(&world, file_id)?; | 399 | let cargo_spec = CargoTargetSpec::for_file(&snap, file_id)?; |
401 | for runnable in world.analysis().runnables(file_id)? { | 400 | for runnable in snap.analysis().runnables(file_id)? { |
402 | if let Some(offset) = offset { | 401 | if let Some(offset) = offset { |
403 | if !runnable.nav.full_range().contains_inclusive(offset) { | 402 | if !runnable.nav.full_range().contains_inclusive(offset) { |
404 | continue; | 403 | continue; |
@@ -413,7 +412,7 @@ pub fn handle_runnables( | |||
413 | } | 412 | } |
414 | } | 413 | } |
415 | } | 414 | } |
416 | res.push(to_proto::runnable(&world, file_id, runnable)?); | 415 | res.push(to_proto::runnable(&snap, file_id, runnable)?); |
417 | } | 416 | } |
418 | 417 | ||
419 | // Add `cargo check` and `cargo test` for the whole package | 418 | // Add `cargo check` and `cargo test` for the whole package |
@@ -453,16 +452,16 @@ pub fn handle_runnables( | |||
453 | } | 452 | } |
454 | 453 | ||
455 | pub fn handle_completion( | 454 | pub fn handle_completion( |
456 | world: WorldSnapshot, | 455 | snap: GlobalStateSnapshot, |
457 | params: lsp_types::CompletionParams, | 456 | params: lsp_types::CompletionParams, |
458 | ) -> Result<Option<lsp_types::CompletionResponse>> { | 457 | ) -> Result<Option<lsp_types::CompletionResponse>> { |
459 | let _p = profile("handle_completion"); | 458 | let _p = profile("handle_completion"); |
460 | let position = from_proto::file_position(&world, params.text_document_position)?; | 459 | let position = from_proto::file_position(&snap, params.text_document_position)?; |
461 | let completion_triggered_after_single_colon = { | 460 | let completion_triggered_after_single_colon = { |
462 | let mut res = false; | 461 | let mut res = false; |
463 | if let Some(ctx) = params.context { | 462 | if let Some(ctx) = params.context { |
464 | if ctx.trigger_character.unwrap_or_default() == ":" { | 463 | if ctx.trigger_character.unwrap_or_default() == ":" { |
465 | let source_file = world.analysis().parse(position.file_id)?; | 464 | let source_file = snap.analysis().parse(position.file_id)?; |
466 | let syntax = source_file.syntax(); | 465 | let syntax = source_file.syntax(); |
467 | let text = syntax.text(); | 466 | let text = syntax.text(); |
468 | if let Some(next_char) = text.char_at(position.offset) { | 467 | if let Some(next_char) = text.char_at(position.offset) { |
@@ -480,12 +479,12 @@ pub fn handle_completion( | |||
480 | return Ok(None); | 479 | return Ok(None); |
481 | } | 480 | } |
482 | 481 | ||
483 | let items = match world.analysis().completions(&world.config.completion, position)? { | 482 | let items = match snap.analysis().completions(&snap.config.completion, position)? { |
484 | None => return Ok(None), | 483 | None => return Ok(None), |
485 | Some(items) => items, | 484 | Some(items) => items, |
486 | }; | 485 | }; |
487 | let line_index = world.analysis().file_line_index(position.file_id)?; | 486 | let line_index = snap.analysis().file_line_index(position.file_id)?; |
488 | let line_endings = world.file_line_endings(position.file_id); | 487 | let line_endings = snap.file_line_endings(position.file_id); |
489 | let items: Vec<CompletionItem> = items | 488 | let items: Vec<CompletionItem> = items |
490 | .into_iter() | 489 | .into_iter() |
491 | .map(|item| to_proto::completion_item(&line_index, line_endings, item)) | 490 | .map(|item| to_proto::completion_item(&line_index, line_endings, item)) |
@@ -495,15 +494,15 @@ pub fn handle_completion( | |||
495 | } | 494 | } |
496 | 495 | ||
497 | pub fn handle_folding_range( | 496 | pub fn handle_folding_range( |
498 | world: WorldSnapshot, | 497 | snap: GlobalStateSnapshot, |
499 | params: FoldingRangeParams, | 498 | params: FoldingRangeParams, |
500 | ) -> Result<Option<Vec<FoldingRange>>> { | 499 | ) -> Result<Option<Vec<FoldingRange>>> { |
501 | let _p = profile("handle_folding_range"); | 500 | let _p = profile("handle_folding_range"); |
502 | let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; | 501 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; |
503 | let folds = world.analysis().folding_ranges(file_id)?; | 502 | let folds = snap.analysis().folding_ranges(file_id)?; |
504 | let text = world.analysis().file_text(file_id)?; | 503 | let text = snap.analysis().file_text(file_id)?; |
505 | let line_index = world.analysis().file_line_index(file_id)?; | 504 | let line_index = snap.analysis().file_line_index(file_id)?; |
506 | let line_folding_only = world.config.client_caps.line_folding_only; | 505 | let line_folding_only = snap.config.client_caps.line_folding_only; |
507 | let res = folds | 506 | let res = folds |
508 | .into_iter() | 507 | .into_iter() |
509 | .map(|it| to_proto::folding_range(&*text, &line_index, line_folding_only, it)) | 508 | .map(|it| to_proto::folding_range(&*text, &line_index, line_folding_only, it)) |
@@ -512,16 +511,16 @@ pub fn handle_folding_range( | |||
512 | } | 511 | } |
513 | 512 | ||
514 | pub fn handle_signature_help( | 513 | pub fn handle_signature_help( |
515 | world: WorldSnapshot, | 514 | snap: GlobalStateSnapshot, |
516 | params: lsp_types::SignatureHelpParams, | 515 | params: lsp_types::SignatureHelpParams, |
517 | ) -> Result<Option<lsp_types::SignatureHelp>> { | 516 | ) -> Result<Option<lsp_types::SignatureHelp>> { |
518 | let _p = profile("handle_signature_help"); | 517 | let _p = profile("handle_signature_help"); |
519 | let position = from_proto::file_position(&world, params.text_document_position_params)?; | 518 | let position = from_proto::file_position(&snap, params.text_document_position_params)?; |
520 | let call_info = match world.analysis().call_info(position)? { | 519 | let call_info = match snap.analysis().call_info(position)? { |
521 | None => return Ok(None), | 520 | None => return Ok(None), |
522 | Some(it) => it, | 521 | Some(it) => it, |
523 | }; | 522 | }; |
524 | let concise = !world.config.call_info_full; | 523 | let concise = !snap.config.call_info_full; |
525 | let mut active_parameter = call_info.active_parameter.map(|it| it as i64); | 524 | let mut active_parameter = call_info.active_parameter.map(|it| it as i64); |
526 | if concise && call_info.signature.has_self_param { | 525 | if concise && call_info.signature.has_self_param { |
527 | active_parameter = active_parameter.map(|it| it.saturating_sub(1)); | 526 | active_parameter = active_parameter.map(|it| it.saturating_sub(1)); |
@@ -535,14 +534,17 @@ pub fn handle_signature_help( | |||
535 | })) | 534 | })) |
536 | } | 535 | } |
537 | 536 | ||
538 | pub fn handle_hover(world: WorldSnapshot, params: lsp_types::HoverParams) -> Result<Option<Hover>> { | 537 | pub fn handle_hover( |
538 | snap: GlobalStateSnapshot, | ||
539 | params: lsp_types::HoverParams, | ||
540 | ) -> Result<Option<Hover>> { | ||
539 | let _p = profile("handle_hover"); | 541 | let _p = profile("handle_hover"); |
540 | let position = from_proto::file_position(&world, params.text_document_position_params)?; | 542 | let position = from_proto::file_position(&snap, params.text_document_position_params)?; |
541 | let info = match world.analysis().hover(position)? { | 543 | let info = match snap.analysis().hover(position)? { |
542 | None => return Ok(None), | 544 | None => return Ok(None), |
543 | Some(info) => info, | 545 | Some(info) => info, |
544 | }; | 546 | }; |
545 | let line_index = world.analysis.file_line_index(position.file_id)?; | 547 | let line_index = snap.analysis.file_line_index(position.file_id)?; |
546 | let range = to_proto::range(&line_index, info.range); | 548 | let range = to_proto::range(&line_index, info.range); |
547 | let res = Hover { | 549 | let res = Hover { |
548 | contents: HoverContents::Markup(MarkupContent { | 550 | contents: HoverContents::Markup(MarkupContent { |
@@ -555,26 +557,29 @@ pub fn handle_hover(world: WorldSnapshot, params: lsp_types::HoverParams) -> Res | |||
555 | } | 557 | } |
556 | 558 | ||
557 | pub fn handle_prepare_rename( | 559 | pub fn handle_prepare_rename( |
558 | world: WorldSnapshot, | 560 | snap: GlobalStateSnapshot, |
559 | params: lsp_types::TextDocumentPositionParams, | 561 | params: lsp_types::TextDocumentPositionParams, |
560 | ) -> Result<Option<PrepareRenameResponse>> { | 562 | ) -> Result<Option<PrepareRenameResponse>> { |
561 | let _p = profile("handle_prepare_rename"); | 563 | let _p = profile("handle_prepare_rename"); |
562 | let position = from_proto::file_position(&world, params)?; | 564 | let position = from_proto::file_position(&snap, params)?; |
563 | 565 | ||
564 | let optional_change = world.analysis().rename(position, "dummy")?; | 566 | let optional_change = snap.analysis().rename(position, "dummy")?; |
565 | let range = match optional_change { | 567 | let range = match optional_change { |
566 | None => return Ok(None), | 568 | None => return Ok(None), |
567 | Some(it) => it.range, | 569 | Some(it) => it.range, |
568 | }; | 570 | }; |
569 | 571 | ||
570 | let line_index = world.analysis().file_line_index(position.file_id)?; | 572 | let line_index = snap.analysis().file_line_index(position.file_id)?; |
571 | let range = to_proto::range(&line_index, range); | 573 | let range = to_proto::range(&line_index, range); |
572 | Ok(Some(PrepareRenameResponse::Range(range))) | 574 | Ok(Some(PrepareRenameResponse::Range(range))) |
573 | } | 575 | } |
574 | 576 | ||
575 | pub fn handle_rename(world: WorldSnapshot, params: RenameParams) -> Result<Option<WorkspaceEdit>> { | 577 | pub fn handle_rename( |
578 | snap: GlobalStateSnapshot, | ||
579 | params: RenameParams, | ||
580 | ) -> Result<Option<WorkspaceEdit>> { | ||
576 | let _p = profile("handle_rename"); | 581 | let _p = profile("handle_rename"); |
577 | let position = from_proto::file_position(&world, params.text_document_position)?; | 582 | let position = from_proto::file_position(&snap, params.text_document_position)?; |
578 | 583 | ||
579 | if params.new_name.is_empty() { | 584 | if params.new_name.is_empty() { |
580 | return Err(LspError::new( | 585 | return Err(LspError::new( |
@@ -584,36 +589,36 @@ pub fn handle_rename(world: WorldSnapshot, params: RenameParams) -> Result<Optio | |||
584 | .into()); | 589 | .into()); |
585 | } | 590 | } |
586 | 591 | ||
587 | let optional_change = world.analysis().rename(position, &*params.new_name)?; | 592 | let optional_change = snap.analysis().rename(position, &*params.new_name)?; |
588 | let source_change = match optional_change { | 593 | let source_change = match optional_change { |
589 | None => return Ok(None), | 594 | None => return Ok(None), |
590 | Some(it) => it.info, | 595 | Some(it) => it.info, |
591 | }; | 596 | }; |
592 | let workspace_edit = to_proto::workspace_edit(&world, source_change)?; | 597 | let workspace_edit = to_proto::workspace_edit(&snap, source_change)?; |
593 | Ok(Some(workspace_edit)) | 598 | Ok(Some(workspace_edit)) |
594 | } | 599 | } |
595 | 600 | ||
596 | pub fn handle_references( | 601 | pub fn handle_references( |
597 | world: WorldSnapshot, | 602 | snap: GlobalStateSnapshot, |
598 | params: lsp_types::ReferenceParams, | 603 | params: lsp_types::ReferenceParams, |
599 | ) -> Result<Option<Vec<Location>>> { | 604 | ) -> Result<Option<Vec<Location>>> { |
600 | let _p = profile("handle_references"); | 605 | let _p = profile("handle_references"); |
601 | let position = from_proto::file_position(&world, params.text_document_position)?; | 606 | let position = from_proto::file_position(&snap, params.text_document_position)?; |
602 | 607 | ||
603 | let refs = match world.analysis().find_all_refs(position, None)? { | 608 | let refs = match snap.analysis().find_all_refs(position, None)? { |
604 | None => return Ok(None), | 609 | None => return Ok(None), |
605 | Some(refs) => refs, | 610 | Some(refs) => refs, |
606 | }; | 611 | }; |
607 | 612 | ||
608 | let locations = if params.context.include_declaration { | 613 | let locations = if params.context.include_declaration { |
609 | refs.into_iter() | 614 | refs.into_iter() |
610 | .filter_map(|reference| to_proto::location(&world, reference.file_range).ok()) | 615 | .filter_map(|reference| to_proto::location(&snap, reference.file_range).ok()) |
611 | .collect() | 616 | .collect() |
612 | } else { | 617 | } else { |
613 | // Only iterate over the references if include_declaration was false | 618 | // Only iterate over the references if include_declaration was false |
614 | refs.references() | 619 | refs.references() |
615 | .iter() | 620 | .iter() |
616 | .filter_map(|reference| to_proto::location(&world, reference.file_range).ok()) | 621 | .filter_map(|reference| to_proto::location(&snap, reference.file_range).ok()) |
617 | .collect() | 622 | .collect() |
618 | }; | 623 | }; |
619 | 624 | ||
@@ -621,24 +626,24 @@ pub fn handle_references( | |||
621 | } | 626 | } |
622 | 627 | ||
623 | pub fn handle_formatting( | 628 | pub fn handle_formatting( |
624 | world: WorldSnapshot, | 629 | snap: GlobalStateSnapshot, |
625 | params: DocumentFormattingParams, | 630 | params: DocumentFormattingParams, |
626 | ) -> Result<Option<Vec<lsp_types::TextEdit>>> { | 631 | ) -> Result<Option<Vec<lsp_types::TextEdit>>> { |
627 | let _p = profile("handle_formatting"); | 632 | let _p = profile("handle_formatting"); |
628 | let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; | 633 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; |
629 | let file = world.analysis().file_text(file_id)?; | 634 | let file = snap.analysis().file_text(file_id)?; |
630 | let crate_ids = world.analysis().crate_for(file_id)?; | 635 | let crate_ids = snap.analysis().crate_for(file_id)?; |
631 | 636 | ||
632 | let file_line_index = world.analysis().file_line_index(file_id)?; | 637 | let file_line_index = snap.analysis().file_line_index(file_id)?; |
633 | let end_position = to_proto::position(&file_line_index, TextSize::of(file.as_str())); | 638 | let end_position = to_proto::position(&file_line_index, TextSize::of(file.as_str())); |
634 | 639 | ||
635 | let mut rustfmt = match &world.config.rustfmt { | 640 | let mut rustfmt = match &snap.config.rustfmt { |
636 | RustfmtConfig::Rustfmt { extra_args } => { | 641 | RustfmtConfig::Rustfmt { extra_args } => { |
637 | let mut cmd = process::Command::new("rustfmt"); | 642 | let mut cmd = process::Command::new("rustfmt"); |
638 | cmd.args(extra_args); | 643 | cmd.args(extra_args); |
639 | if let Some(&crate_id) = crate_ids.first() { | 644 | if let Some(&crate_id) = crate_ids.first() { |
640 | // Assume all crates are in the same edition | 645 | // Assume all crates are in the same edition |
641 | let edition = world.analysis().crate_edition(crate_id)?; | 646 | let edition = snap.analysis().crate_edition(crate_id)?; |
642 | cmd.arg("--edition"); | 647 | cmd.arg("--edition"); |
643 | cmd.arg(edition.to_string()); | 648 | cmd.arg(edition.to_string()); |
644 | } | 649 | } |
@@ -697,15 +702,14 @@ pub fn handle_formatting( | |||
697 | } | 702 | } |
698 | 703 | ||
699 | fn handle_fixes( | 704 | fn handle_fixes( |
700 | world: &WorldSnapshot, | 705 | snap: &GlobalStateSnapshot, |
701 | params: &lsp_types::CodeActionParams, | 706 | params: &lsp_types::CodeActionParams, |
702 | res: &mut Vec<lsp_ext::CodeAction>, | 707 | res: &mut Vec<lsp_ext::CodeAction>, |
703 | ) -> Result<()> { | 708 | ) -> Result<()> { |
704 | let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; | 709 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; |
705 | let line_index = world.analysis().file_line_index(file_id)?; | 710 | let line_index = snap.analysis().file_line_index(file_id)?; |
706 | let range = from_proto::text_range(&line_index, params.range); | 711 | let range = from_proto::text_range(&line_index, params.range); |
707 | 712 | let diagnostics = snap.analysis().diagnostics(file_id)?; | |
708 | let diagnostics = world.analysis().diagnostics(file_id)?; | ||
709 | 713 | ||
710 | let fixes_from_diagnostics = diagnostics | 714 | let fixes_from_diagnostics = diagnostics |
711 | .into_iter() | 715 | .into_iter() |
@@ -714,18 +718,19 @@ fn handle_fixes( | |||
714 | .map(|(_range, fix)| fix); | 718 | .map(|(_range, fix)| fix); |
715 | for fix in fixes_from_diagnostics { | 719 | for fix in fixes_from_diagnostics { |
716 | let title = fix.label; | 720 | let title = fix.label; |
717 | let edit = to_proto::snippet_workspace_edit(&world, fix.source_change)?; | 721 | let edit = to_proto::snippet_workspace_edit(&snap, fix.source_change)?; |
718 | let action = lsp_ext::CodeAction { | 722 | let action = lsp_ext::CodeAction { |
719 | title, | 723 | title, |
720 | id: None, | 724 | id: None, |
721 | group: None, | 725 | group: None, |
722 | kind: None, | 726 | kind: Some(lsp_types::code_action_kind::QUICKFIX.into()), |
723 | edit: Some(edit), | 727 | edit: Some(edit), |
724 | command: None, | 728 | command: None, |
725 | }; | 729 | }; |
726 | res.push(action); | 730 | res.push(action); |
727 | } | 731 | } |
728 | for fix in world.check_fixes.get(&file_id).into_iter().flatten() { | 732 | |
733 | for fix in snap.check_fixes.get(&file_id).into_iter().flatten() { | ||
729 | let fix_range = from_proto::text_range(&line_index, fix.range); | 734 | let fix_range = from_proto::text_range(&line_index, fix.range); |
730 | if fix_range.intersect(range).is_none() { | 735 | if fix_range.intersect(range).is_none() { |
731 | continue; | 736 | continue; |
@@ -736,37 +741,34 @@ fn handle_fixes( | |||
736 | } | 741 | } |
737 | 742 | ||
738 | pub fn handle_code_action( | 743 | pub fn handle_code_action( |
739 | world: WorldSnapshot, | 744 | snap: GlobalStateSnapshot, |
740 | params: lsp_types::CodeActionParams, | 745 | params: lsp_types::CodeActionParams, |
741 | ) -> Result<Option<Vec<lsp_ext::CodeAction>>> { | 746 | ) -> Result<Option<Vec<lsp_ext::CodeAction>>> { |
742 | let _p = profile("handle_code_action"); | 747 | let _p = profile("handle_code_action"); |
743 | // We intentionally don't support command-based actions, as those either | 748 | // We intentionally don't support command-based actions, as those either |
744 | // requires custom client-code anyway, or requires server-initiated edits. | 749 | // requires custom client-code anyway, or requires server-initiated edits. |
745 | // Server initiated edits break causality, so we avoid those as well. | 750 | // Server initiated edits break causality, so we avoid those as well. |
746 | if !world.config.client_caps.code_action_literals { | 751 | if !snap.config.client_caps.code_action_literals { |
747 | return Ok(None); | 752 | return Ok(None); |
748 | } | 753 | } |
749 | 754 | ||
750 | let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; | 755 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; |
751 | let line_index = world.analysis().file_line_index(file_id)?; | 756 | let line_index = snap.analysis().file_line_index(file_id)?; |
752 | let range = from_proto::text_range(&line_index, params.range); | 757 | let range = from_proto::text_range(&line_index, params.range); |
753 | let frange = FileRange { file_id, range }; | 758 | let frange = FileRange { file_id, range }; |
754 | let mut res: Vec<lsp_ext::CodeAction> = Vec::new(); | 759 | let mut res: Vec<lsp_ext::CodeAction> = Vec::new(); |
755 | 760 | ||
756 | handle_fixes(&world, ¶ms, &mut res)?; | 761 | handle_fixes(&snap, ¶ms, &mut res)?; |
757 | 762 | ||
758 | if world.config.client_caps.resolve_code_action { | 763 | if snap.config.client_caps.resolve_code_action { |
759 | for (index, assist) in world | 764 | for (index, assist) in |
760 | .analysis() | 765 | snap.analysis().unresolved_assists(&snap.config.assist, frange)?.into_iter().enumerate() |
761 | .unresolved_assists(&world.config.assist, frange)? | ||
762 | .into_iter() | ||
763 | .enumerate() | ||
764 | { | 766 | { |
765 | res.push(to_proto::unresolved_code_action(&world, assist, index)?); | 767 | res.push(to_proto::unresolved_code_action(&snap, assist, index)?); |
766 | } | 768 | } |
767 | } else { | 769 | } else { |
768 | for assist in world.analysis().resolved_assists(&world.config.assist, frange)?.into_iter() { | 770 | for assist in snap.analysis().resolved_assists(&snap.config.assist, frange)?.into_iter() { |
769 | res.push(to_proto::resolved_code_action(&world, assist)?); | 771 | res.push(to_proto::resolved_code_action(&snap, assist)?); |
770 | } | 772 | } |
771 | } | 773 | } |
772 | 774 | ||
@@ -774,43 +776,43 @@ pub fn handle_code_action( | |||
774 | } | 776 | } |
775 | 777 | ||
776 | pub fn handle_resolve_code_action( | 778 | pub fn handle_resolve_code_action( |
777 | world: WorldSnapshot, | 779 | snap: GlobalStateSnapshot, |
778 | params: lsp_ext::ResolveCodeActionParams, | 780 | params: lsp_ext::ResolveCodeActionParams, |
779 | ) -> Result<Option<lsp_ext::SnippetWorkspaceEdit>> { | 781 | ) -> Result<Option<lsp_ext::SnippetWorkspaceEdit>> { |
780 | let _p = profile("handle_resolve_code_action"); | 782 | let _p = profile("handle_resolve_code_action"); |
781 | let file_id = from_proto::file_id(&world, ¶ms.code_action_params.text_document.uri)?; | 783 | let file_id = from_proto::file_id(&snap, ¶ms.code_action_params.text_document.uri)?; |
782 | let line_index = world.analysis().file_line_index(file_id)?; | 784 | let line_index = snap.analysis().file_line_index(file_id)?; |
783 | let range = from_proto::text_range(&line_index, params.code_action_params.range); | 785 | let range = from_proto::text_range(&line_index, params.code_action_params.range); |
784 | let frange = FileRange { file_id, range }; | 786 | let frange = FileRange { file_id, range }; |
785 | 787 | ||
786 | let assists = world.analysis().resolved_assists(&world.config.assist, frange)?; | 788 | let assists = snap.analysis().resolved_assists(&snap.config.assist, frange)?; |
787 | let id_components = params.id.split(":").collect::<Vec<&str>>(); | 789 | let id_components = params.id.split(":").collect::<Vec<&str>>(); |
788 | let index = id_components.last().unwrap().parse::<usize>().unwrap(); | 790 | let index = id_components.last().unwrap().parse::<usize>().unwrap(); |
789 | let id_string = id_components.first().unwrap(); | 791 | let id_string = id_components.first().unwrap(); |
790 | let assist = &assists[index]; | 792 | let assist = &assists[index]; |
791 | assert!(assist.assist.id.0 == *id_string); | 793 | assert!(assist.assist.id.0 == *id_string); |
792 | Ok(to_proto::resolved_code_action(&world, assist.clone())?.edit) | 794 | Ok(to_proto::resolved_code_action(&snap, assist.clone())?.edit) |
793 | } | 795 | } |
794 | 796 | ||
795 | pub fn handle_code_lens( | 797 | pub fn handle_code_lens( |
796 | world: WorldSnapshot, | 798 | snap: GlobalStateSnapshot, |
797 | params: lsp_types::CodeLensParams, | 799 | params: lsp_types::CodeLensParams, |
798 | ) -> Result<Option<Vec<CodeLens>>> { | 800 | ) -> Result<Option<Vec<CodeLens>>> { |
799 | let _p = profile("handle_code_lens"); | 801 | let _p = profile("handle_code_lens"); |
800 | let mut lenses: Vec<CodeLens> = Default::default(); | 802 | let mut lenses: Vec<CodeLens> = Default::default(); |
801 | 803 | ||
802 | if world.config.lens.none() { | 804 | if snap.config.lens.none() { |
803 | // early return before any db query! | 805 | // early return before any db query! |
804 | return Ok(Some(lenses)); | 806 | return Ok(Some(lenses)); |
805 | } | 807 | } |
806 | 808 | ||
807 | let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; | 809 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; |
808 | let line_index = world.analysis().file_line_index(file_id)?; | 810 | let line_index = snap.analysis().file_line_index(file_id)?; |
809 | let cargo_spec = CargoTargetSpec::for_file(&world, file_id)?; | 811 | let cargo_spec = CargoTargetSpec::for_file(&snap, file_id)?; |
810 | 812 | ||
811 | if world.config.lens.runnable() { | 813 | if snap.config.lens.runnable() { |
812 | // Gather runnables | 814 | // Gather runnables |
813 | for runnable in world.analysis().runnables(file_id)? { | 815 | for runnable in snap.analysis().runnables(file_id)? { |
814 | let (run_title, debugee) = match &runnable.kind { | 816 | let (run_title, debugee) = match &runnable.kind { |
815 | RunnableKind::Test { .. } | RunnableKind::TestMod { .. } => { | 817 | RunnableKind::Test { .. } | RunnableKind::TestMod { .. } => { |
816 | ("â–¶\u{fe0e} Run Test", true) | 818 | ("â–¶\u{fe0e} Run Test", true) |
@@ -836,8 +838,8 @@ pub fn handle_code_lens( | |||
836 | }; | 838 | }; |
837 | 839 | ||
838 | let range = to_proto::range(&line_index, runnable.nav.range()); | 840 | let range = to_proto::range(&line_index, runnable.nav.range()); |
839 | let r = to_proto::runnable(&world, file_id, runnable)?; | 841 | let r = to_proto::runnable(&snap, file_id, runnable)?; |
840 | if world.config.lens.run { | 842 | if snap.config.lens.run { |
841 | let lens = CodeLens { | 843 | let lens = CodeLens { |
842 | range, | 844 | range, |
843 | command: Some(Command { | 845 | command: Some(Command { |
@@ -850,7 +852,7 @@ pub fn handle_code_lens( | |||
850 | lenses.push(lens); | 852 | lenses.push(lens); |
851 | } | 853 | } |
852 | 854 | ||
853 | if debugee && world.config.lens.debug { | 855 | if debugee && snap.config.lens.debug { |
854 | let debug_lens = CodeLens { | 856 | let debug_lens = CodeLens { |
855 | range, | 857 | range, |
856 | command: Some(Command { | 858 | command: Some(Command { |
@@ -865,11 +867,10 @@ pub fn handle_code_lens( | |||
865 | } | 867 | } |
866 | } | 868 | } |
867 | 869 | ||
868 | if world.config.lens.impementations { | 870 | if snap.config.lens.impementations { |
869 | // Handle impls | 871 | // Handle impls |
870 | lenses.extend( | 872 | lenses.extend( |
871 | world | 873 | snap.analysis() |
872 | .analysis() | ||
873 | .file_structure(file_id)? | 874 | .file_structure(file_id)? |
874 | .into_iter() | 875 | .into_iter() |
875 | .filter(|it| match it.kind { | 876 | .filter(|it| match it.kind { |
@@ -904,14 +905,17 @@ enum CodeLensResolveData { | |||
904 | Impls(lsp_types::request::GotoImplementationParams), | 905 | Impls(lsp_types::request::GotoImplementationParams), |
905 | } | 906 | } |
906 | 907 | ||
907 | pub fn handle_code_lens_resolve(world: WorldSnapshot, code_lens: CodeLens) -> Result<CodeLens> { | 908 | pub fn handle_code_lens_resolve( |
909 | snap: GlobalStateSnapshot, | ||
910 | code_lens: CodeLens, | ||
911 | ) -> Result<CodeLens> { | ||
908 | let _p = profile("handle_code_lens_resolve"); | 912 | let _p = profile("handle_code_lens_resolve"); |
909 | let data = code_lens.data.unwrap(); | 913 | let data = code_lens.data.unwrap(); |
910 | let resolve = from_json::<Option<CodeLensResolveData>>("CodeLensResolveData", data)?; | 914 | let resolve = from_json::<Option<CodeLensResolveData>>("CodeLensResolveData", data)?; |
911 | match resolve { | 915 | match resolve { |
912 | Some(CodeLensResolveData::Impls(lens_params)) => { | 916 | Some(CodeLensResolveData::Impls(lens_params)) => { |
913 | let locations: Vec<Location> = | 917 | let locations: Vec<Location> = |
914 | match handle_goto_implementation(world, lens_params.clone())? { | 918 | match handle_goto_implementation(snap, lens_params.clone())? { |
915 | Some(lsp_types::GotoDefinitionResponse::Scalar(loc)) => vec![loc], | 919 | Some(lsp_types::GotoDefinitionResponse::Scalar(loc)) => vec![loc], |
916 | Some(lsp_types::GotoDefinitionResponse::Array(locs)) => locs, | 920 | Some(lsp_types::GotoDefinitionResponse::Array(locs)) => locs, |
917 | Some(lsp_types::GotoDefinitionResponse::Link(links)) => links | 921 | Some(lsp_types::GotoDefinitionResponse::Link(links)) => links |
@@ -950,14 +954,14 @@ pub fn handle_code_lens_resolve(world: WorldSnapshot, code_lens: CodeLens) -> Re | |||
950 | } | 954 | } |
951 | 955 | ||
952 | pub fn handle_document_highlight( | 956 | pub fn handle_document_highlight( |
953 | world: WorldSnapshot, | 957 | snap: GlobalStateSnapshot, |
954 | params: lsp_types::DocumentHighlightParams, | 958 | params: lsp_types::DocumentHighlightParams, |
955 | ) -> Result<Option<Vec<DocumentHighlight>>> { | 959 | ) -> Result<Option<Vec<DocumentHighlight>>> { |
956 | let _p = profile("handle_document_highlight"); | 960 | let _p = profile("handle_document_highlight"); |
957 | let position = from_proto::file_position(&world, params.text_document_position_params)?; | 961 | let position = from_proto::file_position(&snap, params.text_document_position_params)?; |
958 | let line_index = world.analysis().file_line_index(position.file_id)?; | 962 | let line_index = snap.analysis().file_line_index(position.file_id)?; |
959 | 963 | ||
960 | let refs = match world | 964 | let refs = match snap |
961 | .analysis() | 965 | .analysis() |
962 | .find_all_refs(position, Some(SearchScope::single_file(position.file_id)))? | 966 | .find_all_refs(position, Some(SearchScope::single_file(position.file_id)))? |
963 | { | 967 | { |
@@ -977,19 +981,19 @@ pub fn handle_document_highlight( | |||
977 | } | 981 | } |
978 | 982 | ||
979 | pub fn handle_ssr( | 983 | pub fn handle_ssr( |
980 | world: WorldSnapshot, | 984 | snap: GlobalStateSnapshot, |
981 | params: lsp_ext::SsrParams, | 985 | params: lsp_ext::SsrParams, |
982 | ) -> Result<lsp_types::WorkspaceEdit> { | 986 | ) -> Result<lsp_types::WorkspaceEdit> { |
983 | let _p = profile("handle_ssr"); | 987 | let _p = profile("handle_ssr"); |
984 | let source_change = | 988 | let source_change = |
985 | world.analysis().structural_search_replace(¶ms.query, params.parse_only)??; | 989 | snap.analysis().structural_search_replace(¶ms.query, params.parse_only)??; |
986 | to_proto::workspace_edit(&world, source_change) | 990 | to_proto::workspace_edit(&snap, source_change) |
987 | } | 991 | } |
988 | 992 | ||
989 | pub fn publish_diagnostics(world: &WorldSnapshot, file_id: FileId) -> Result<DiagnosticTask> { | 993 | pub fn publish_diagnostics(snap: &GlobalStateSnapshot, file_id: FileId) -> Result<DiagnosticTask> { |
990 | let _p = profile("publish_diagnostics"); | 994 | let _p = profile("publish_diagnostics"); |
991 | let line_index = world.analysis().file_line_index(file_id)?; | 995 | let line_index = snap.analysis().file_line_index(file_id)?; |
992 | let diagnostics: Vec<Diagnostic> = world | 996 | let diagnostics: Vec<Diagnostic> = snap |
993 | .analysis() | 997 | .analysis() |
994 | .diagnostics(file_id)? | 998 | .diagnostics(file_id)? |
995 | .into_iter() | 999 | .into_iter() |
@@ -1007,28 +1011,28 @@ pub fn publish_diagnostics(world: &WorldSnapshot, file_id: FileId) -> Result<Dia | |||
1007 | } | 1011 | } |
1008 | 1012 | ||
1009 | pub fn handle_inlay_hints( | 1013 | pub fn handle_inlay_hints( |
1010 | world: WorldSnapshot, | 1014 | snap: GlobalStateSnapshot, |
1011 | params: InlayHintsParams, | 1015 | params: InlayHintsParams, |
1012 | ) -> Result<Vec<InlayHint>> { | 1016 | ) -> Result<Vec<InlayHint>> { |
1013 | let _p = profile("handle_inlay_hints"); | 1017 | let _p = profile("handle_inlay_hints"); |
1014 | let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; | 1018 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; |
1015 | let analysis = world.analysis(); | 1019 | let analysis = snap.analysis(); |
1016 | let line_index = analysis.file_line_index(file_id)?; | 1020 | let line_index = analysis.file_line_index(file_id)?; |
1017 | Ok(analysis | 1021 | Ok(analysis |
1018 | .inlay_hints(file_id, &world.config.inlay_hints)? | 1022 | .inlay_hints(file_id, &snap.config.inlay_hints)? |
1019 | .into_iter() | 1023 | .into_iter() |
1020 | .map(|it| to_proto::inlay_int(&line_index, it)) | 1024 | .map(|it| to_proto::inlay_int(&line_index, it)) |
1021 | .collect()) | 1025 | .collect()) |
1022 | } | 1026 | } |
1023 | 1027 | ||
1024 | pub fn handle_call_hierarchy_prepare( | 1028 | pub fn handle_call_hierarchy_prepare( |
1025 | world: WorldSnapshot, | 1029 | snap: GlobalStateSnapshot, |
1026 | params: CallHierarchyPrepareParams, | 1030 | params: CallHierarchyPrepareParams, |
1027 | ) -> Result<Option<Vec<CallHierarchyItem>>> { | 1031 | ) -> Result<Option<Vec<CallHierarchyItem>>> { |
1028 | let _p = profile("handle_call_hierarchy_prepare"); | 1032 | let _p = profile("handle_call_hierarchy_prepare"); |
1029 | let position = from_proto::file_position(&world, params.text_document_position_params)?; | 1033 | let position = from_proto::file_position(&snap, params.text_document_position_params)?; |
1030 | 1034 | ||
1031 | let nav_info = match world.analysis().call_hierarchy(position)? { | 1035 | let nav_info = match snap.analysis().call_hierarchy(position)? { |
1032 | None => return Ok(None), | 1036 | None => return Ok(None), |
1033 | Some(it) => it, | 1037 | Some(it) => it, |
1034 | }; | 1038 | }; |
@@ -1037,24 +1041,24 @@ pub fn handle_call_hierarchy_prepare( | |||
1037 | let res = navs | 1041 | let res = navs |
1038 | .into_iter() | 1042 | .into_iter() |
1039 | .filter(|it| it.kind() == SyntaxKind::FN_DEF) | 1043 | .filter(|it| it.kind() == SyntaxKind::FN_DEF) |
1040 | .map(|it| to_proto::call_hierarchy_item(&world, it)) | 1044 | .map(|it| to_proto::call_hierarchy_item(&snap, it)) |
1041 | .collect::<Result<Vec<_>>>()?; | 1045 | .collect::<Result<Vec<_>>>()?; |
1042 | 1046 | ||
1043 | Ok(Some(res)) | 1047 | Ok(Some(res)) |
1044 | } | 1048 | } |
1045 | 1049 | ||
1046 | pub fn handle_call_hierarchy_incoming( | 1050 | pub fn handle_call_hierarchy_incoming( |
1047 | world: WorldSnapshot, | 1051 | snap: GlobalStateSnapshot, |
1048 | params: CallHierarchyIncomingCallsParams, | 1052 | params: CallHierarchyIncomingCallsParams, |
1049 | ) -> Result<Option<Vec<CallHierarchyIncomingCall>>> { | 1053 | ) -> Result<Option<Vec<CallHierarchyIncomingCall>>> { |
1050 | let _p = profile("handle_call_hierarchy_incoming"); | 1054 | let _p = profile("handle_call_hierarchy_incoming"); |
1051 | let item = params.item; | 1055 | let item = params.item; |
1052 | 1056 | ||
1053 | let doc = TextDocumentIdentifier::new(item.uri); | 1057 | let doc = TextDocumentIdentifier::new(item.uri); |
1054 | let frange = from_proto::file_range(&world, doc, item.range)?; | 1058 | let frange = from_proto::file_range(&snap, doc, item.range)?; |
1055 | let fpos = FilePosition { file_id: frange.file_id, offset: frange.range.start() }; | 1059 | let fpos = FilePosition { file_id: frange.file_id, offset: frange.range.start() }; |
1056 | 1060 | ||
1057 | let call_items = match world.analysis().incoming_calls(fpos)? { | 1061 | let call_items = match snap.analysis().incoming_calls(fpos)? { |
1058 | None => return Ok(None), | 1062 | None => return Ok(None), |
1059 | Some(it) => it, | 1063 | Some(it) => it, |
1060 | }; | 1064 | }; |
@@ -1063,8 +1067,8 @@ pub fn handle_call_hierarchy_incoming( | |||
1063 | 1067 | ||
1064 | for call_item in call_items.into_iter() { | 1068 | for call_item in call_items.into_iter() { |
1065 | let file_id = call_item.target.file_id(); | 1069 | let file_id = call_item.target.file_id(); |
1066 | let line_index = world.analysis().file_line_index(file_id)?; | 1070 | let line_index = snap.analysis().file_line_index(file_id)?; |
1067 | let item = to_proto::call_hierarchy_item(&world, call_item.target)?; | 1071 | let item = to_proto::call_hierarchy_item(&snap, call_item.target)?; |
1068 | res.push(CallHierarchyIncomingCall { | 1072 | res.push(CallHierarchyIncomingCall { |
1069 | from: item, | 1073 | from: item, |
1070 | from_ranges: call_item | 1074 | from_ranges: call_item |
@@ -1079,17 +1083,17 @@ pub fn handle_call_hierarchy_incoming( | |||
1079 | } | 1083 | } |
1080 | 1084 | ||
1081 | pub fn handle_call_hierarchy_outgoing( | 1085 | pub fn handle_call_hierarchy_outgoing( |
1082 | world: WorldSnapshot, | 1086 | snap: GlobalStateSnapshot, |
1083 | params: CallHierarchyOutgoingCallsParams, | 1087 | params: CallHierarchyOutgoingCallsParams, |
1084 | ) -> Result<Option<Vec<CallHierarchyOutgoingCall>>> { | 1088 | ) -> Result<Option<Vec<CallHierarchyOutgoingCall>>> { |
1085 | let _p = profile("handle_call_hierarchy_outgoing"); | 1089 | let _p = profile("handle_call_hierarchy_outgoing"); |
1086 | let item = params.item; | 1090 | let item = params.item; |
1087 | 1091 | ||
1088 | let doc = TextDocumentIdentifier::new(item.uri); | 1092 | let doc = TextDocumentIdentifier::new(item.uri); |
1089 | let frange = from_proto::file_range(&world, doc, item.range)?; | 1093 | let frange = from_proto::file_range(&snap, doc, item.range)?; |
1090 | let fpos = FilePosition { file_id: frange.file_id, offset: frange.range.start() }; | 1094 | let fpos = FilePosition { file_id: frange.file_id, offset: frange.range.start() }; |
1091 | 1095 | ||
1092 | let call_items = match world.analysis().outgoing_calls(fpos)? { | 1096 | let call_items = match snap.analysis().outgoing_calls(fpos)? { |
1093 | None => return Ok(None), | 1097 | None => return Ok(None), |
1094 | Some(it) => it, | 1098 | Some(it) => it, |
1095 | }; | 1099 | }; |
@@ -1098,8 +1102,8 @@ pub fn handle_call_hierarchy_outgoing( | |||
1098 | 1102 | ||
1099 | for call_item in call_items.into_iter() { | 1103 | for call_item in call_items.into_iter() { |
1100 | let file_id = call_item.target.file_id(); | 1104 | let file_id = call_item.target.file_id(); |
1101 | let line_index = world.analysis().file_line_index(file_id)?; | 1105 | let line_index = snap.analysis().file_line_index(file_id)?; |
1102 | let item = to_proto::call_hierarchy_item(&world, call_item.target)?; | 1106 | let item = to_proto::call_hierarchy_item(&snap, call_item.target)?; |
1103 | res.push(CallHierarchyOutgoingCall { | 1107 | res.push(CallHierarchyOutgoingCall { |
1104 | to: item, | 1108 | to: item, |
1105 | from_ranges: call_item | 1109 | from_ranges: call_item |
@@ -1114,31 +1118,31 @@ pub fn handle_call_hierarchy_outgoing( | |||
1114 | } | 1118 | } |
1115 | 1119 | ||
1116 | pub fn handle_semantic_tokens( | 1120 | pub fn handle_semantic_tokens( |
1117 | world: WorldSnapshot, | 1121 | snap: GlobalStateSnapshot, |
1118 | params: SemanticTokensParams, | 1122 | params: SemanticTokensParams, |
1119 | ) -> Result<Option<SemanticTokensResult>> { | 1123 | ) -> Result<Option<SemanticTokensResult>> { |
1120 | let _p = profile("handle_semantic_tokens"); | 1124 | let _p = profile("handle_semantic_tokens"); |
1121 | 1125 | ||
1122 | let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; | 1126 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; |
1123 | let text = world.analysis().file_text(file_id)?; | 1127 | let text = snap.analysis().file_text(file_id)?; |
1124 | let line_index = world.analysis().file_line_index(file_id)?; | 1128 | let line_index = snap.analysis().file_line_index(file_id)?; |
1125 | 1129 | ||
1126 | let highlights = world.analysis().highlight(file_id)?; | 1130 | let highlights = snap.analysis().highlight(file_id)?; |
1127 | let semantic_tokens = to_proto::semantic_tokens(&text, &line_index, highlights); | 1131 | let semantic_tokens = to_proto::semantic_tokens(&text, &line_index, highlights); |
1128 | Ok(Some(semantic_tokens.into())) | 1132 | Ok(Some(semantic_tokens.into())) |
1129 | } | 1133 | } |
1130 | 1134 | ||
1131 | pub fn handle_semantic_tokens_range( | 1135 | pub fn handle_semantic_tokens_range( |
1132 | world: WorldSnapshot, | 1136 | snap: GlobalStateSnapshot, |
1133 | params: SemanticTokensRangeParams, | 1137 | params: SemanticTokensRangeParams, |
1134 | ) -> Result<Option<SemanticTokensRangeResult>> { | 1138 | ) -> Result<Option<SemanticTokensRangeResult>> { |
1135 | let _p = profile("handle_semantic_tokens_range"); | 1139 | let _p = profile("handle_semantic_tokens_range"); |
1136 | 1140 | ||
1137 | let frange = from_proto::file_range(&world, params.text_document, params.range)?; | 1141 | let frange = from_proto::file_range(&snap, params.text_document, params.range)?; |
1138 | let text = world.analysis().file_text(frange.file_id)?; | 1142 | let text = snap.analysis().file_text(frange.file_id)?; |
1139 | let line_index = world.analysis().file_line_index(frange.file_id)?; | 1143 | let line_index = snap.analysis().file_line_index(frange.file_id)?; |
1140 | 1144 | ||
1141 | let highlights = world.analysis().highlight_range(frange)?; | 1145 | let highlights = snap.analysis().highlight_range(frange)?; |
1142 | let semantic_tokens = to_proto::semantic_tokens(&text, &line_index, highlights); | 1146 | let semantic_tokens = to_proto::semantic_tokens(&text, &line_index, highlights); |
1143 | Ok(Some(semantic_tokens.into())) | 1147 | Ok(Some(semantic_tokens.into())) |
1144 | } | 1148 | } |