aboutsummaryrefslogtreecommitdiff
path: root/crates/rust-analyzer/src/main_loop/handlers.rs
diff options
context:
space:
mode:
authorMikhail Rakhmanov <[email protected]>2020-06-03 18:26:01 +0100
committerMikhail Rakhmanov <[email protected]>2020-06-03 18:26:01 +0100
commit6a0083a519680e8d16bde5d7c1940c8dd6d4e9d4 (patch)
tree2b377141d722257cfea18e74b955aea1a8f6cc1a /crates/rust-analyzer/src/main_loop/handlers.rs
parent1f7de306f547ecb394a34445fd6ac1d6bc8ab439 (diff)
parent794f6da821c5d6e2490b996baffe162e4753262d (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.rs390
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
41pub fn handle_analyzer_status(world: WorldSnapshot, _: ()) -> Result<String> { 40pub 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
53pub fn handle_syntax_tree( 52pub 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, &params.text_document.uri)?; 57 let id = from_proto::file_id(&snap, &params.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
65pub fn handle_expand_macro( 64pub 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, &params.text_document.uri)?; 69 let file_id = from_proto::file_id(&snap, &params.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
78pub fn handle_selection_range( 77pub 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, &params.text_document.uri)?; 82 let file_id = from_proto::file_id(&snap, &params.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
121pub fn handle_matching_brace( 120pub 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, &params.text_document.uri)?; 125 let file_id = from_proto::file_id(&snap, &params.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
143pub fn handle_join_lines( 142pub 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, &params.text_document.uri)?; 147 let file_id = from_proto::file_id(&snap, &params.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
166pub fn handle_on_enter( 165pub 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`.
183pub fn handle_on_type_formatting( 182pub 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
222pub fn handle_document_symbol( 221pub 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, &params.text_document.uri)?; 226 let file_id = from_proto::file_id(&snap, &params.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
290pub fn handle_workspace_symbol( 289pub 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
334pub fn handle_goto_definition( 333pub 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
349pub fn handle_goto_implementation( 348pub 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
364pub fn handle_goto_type_definition( 363pub 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
379pub fn handle_parent_module( 378pub 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
390pub fn handle_runnables( 389pub 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, &params.text_document.uri)?; 394 let file_id = from_proto::file_id(&snap, &params.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
455pub fn handle_completion( 454pub 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
497pub fn handle_folding_range( 496pub 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, &params.text_document.uri)?; 501 let file_id = from_proto::file_id(&snap, &params.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
514pub fn handle_signature_help( 513pub 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
538pub fn handle_hover(world: WorldSnapshot, params: lsp_types::HoverParams) -> Result<Option<Hover>> { 537pub 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
557pub fn handle_prepare_rename( 559pub 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
575pub fn handle_rename(world: WorldSnapshot, params: RenameParams) -> Result<Option<WorkspaceEdit>> { 577pub 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
596pub fn handle_references( 601pub 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
623pub fn handle_formatting( 628pub 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, &params.text_document.uri)?; 633 let file_id = from_proto::file_id(&snap, &params.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
699fn handle_fixes( 704fn 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, &params.text_document.uri)?; 709 let file_id = from_proto::file_id(&snap, &params.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
738pub fn handle_code_action( 743pub 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, &params.text_document.uri)?; 755 let file_id = from_proto::file_id(&snap, &params.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, &params, &mut res)?; 761 handle_fixes(&snap, &params, &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
776pub fn handle_resolve_code_action( 778pub 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, &params.code_action_params.text_document.uri)?; 783 let file_id = from_proto::file_id(&snap, &params.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
795pub fn handle_code_lens( 797pub 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, &params.text_document.uri)?; 809 let file_id = from_proto::file_id(&snap, &params.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
907pub fn handle_code_lens_resolve(world: WorldSnapshot, code_lens: CodeLens) -> Result<CodeLens> { 908pub 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
952pub fn handle_document_highlight( 956pub 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
979pub fn handle_ssr( 983pub 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(&params.query, params.parse_only)??; 989 snap.analysis().structural_search_replace(&params.query, params.parse_only)??;
986 to_proto::workspace_edit(&world, source_change) 990 to_proto::workspace_edit(&snap, source_change)
987} 991}
988 992
989pub fn publish_diagnostics(world: &WorldSnapshot, file_id: FileId) -> Result<DiagnosticTask> { 993pub 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
1009pub fn handle_inlay_hints( 1013pub 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, &params.text_document.uri)?; 1018 let file_id = from_proto::file_id(&snap, &params.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
1024pub fn handle_call_hierarchy_prepare( 1028pub 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
1046pub fn handle_call_hierarchy_incoming( 1050pub 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
1081pub fn handle_call_hierarchy_outgoing( 1085pub 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
1116pub fn handle_semantic_tokens( 1120pub 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, &params.text_document.uri)?; 1126 let file_id = from_proto::file_id(&snap, &params.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
1131pub fn handle_semantic_tokens_range( 1135pub 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}