(
&self,
params: GotoImplementationParams,
)
| 576 | } |
| 577 | |
| 578 | async fn goto_implementation( |
| 579 | &self, |
| 580 | params: GotoImplementationParams, |
| 581 | ) -> Result<Option<GotoImplementationResponse>> { |
| 582 | let uri = params |
| 583 | .text_document_position_params |
| 584 | .text_document |
| 585 | .uri |
| 586 | .to_string(); |
| 587 | let position = params.text_document_position_params.position; |
| 588 | let token = match params.work_done_progress_params.work_done_token { |
| 589 | Some(t) => Some(t), |
| 590 | None => self.progress_create("goto_implementation").await, |
| 591 | }; |
| 592 | |
| 593 | if let Some(ref tok) = token { |
| 594 | self.progress_begin(tok, "Go to Implementation", Some("Scanning…".to_string())) |
| 595 | .await; |
| 596 | } |
| 597 | |
| 598 | // Run on a blocking thread so the async runtime stays free to |
| 599 | // flush progress notifications to the client. |
| 600 | // |
| 601 | // Wrapped in tokio::spawn for cancellation safety (see references handler). |
| 602 | let backend = self.clone_for_blocking(); |
| 603 | let uri_clone = uri.clone(); |
| 604 | let result = tokio::spawn(async move { |
| 605 | tokio::task::spawn_blocking(move || { |
| 606 | backend.handle_with_position( |
| 607 | "goto_implementation", |
| 608 | &uri_clone, |
| 609 | position, |
| 610 | |content, pos| { |
| 611 | backend |
| 612 | .resolve_implementation(&uri_clone, content, pos) |
| 613 | .map(|locs| { |
| 614 | locs.into_iter() |
| 615 | .map(|l| backend.translate_location(l)) |
| 616 | .collect() |
| 617 | }) |
| 618 | .and_then(wrap_locations) |
| 619 | }, |
| 620 | ) |
| 621 | }) |
| 622 | .await |
| 623 | .unwrap_or(Ok(None)) |
| 624 | }) |
| 625 | .await |
| 626 | .unwrap_or(Ok(None)); |
| 627 | |
| 628 | if let Some(ref tok) = token { |
| 629 | self.progress_end(tok, Some("Done".to_string())).await; |
| 630 | } |
| 631 | |
| 632 | result |
| 633 | } |
| 634 | |
| 635 | async fn goto_type_definition( |
no test coverage detected