diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-02-17 15:38:33 +0000 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-02-17 15:38:33 +0000 |
commit | 982f72c022b45629e6adbaef22884359d3495ecf (patch) | |
tree | cc1a13dcf026a72d76496fb8ee2643619560f471 /crates/ra_lsp_server/src/main_loop | |
parent | f937d11ad892036fa93b25a2c19d10dcebe4ab24 (diff) | |
parent | fd5307e60d268423f7026db28b15bd2b31575396 (diff) |
Merge #844
844: Refactor find_all_refs to return ReferenceSearchResult r=vipentti a=vipentti
This refactors `find_all_refs` to return a new `ReferenceSearchResult` based on feedback in #839.
There are few questions/notes regarding the refactor:
1. Introducing `NavigationTarget::from_bind_pat` this simply forwards the call to `NavigationTarget::from_named`, could we just expose `from_named` directly as `pub(crate)` ?
2. Added an utility method `NavigationTarget::range` since there were few places where you would use `self.focus_range.unwrap_or(self.full_range)`
3. Implementing `IntoIterator` for `ReferenceSearchResult`. This turns `ReferenceSearchResult` into an iterator over `FileRanges` and allows previous code to mostly stay as it was based on the order that `find_all_refs` previously had (declaration first and then the references). I'm not sure if there is a way of doing the conversion to `IntoIter` without the allocation of a new vector
4. Is it possible to have a binding without a name? I'm not sure if the `NavigationTarget::from_bind_pat` can cause some edge-cases that previously were ok
This fixes #835.
Co-authored-by: Ville Penttinen <[email protected]>
Diffstat (limited to 'crates/ra_lsp_server/src/main_loop')
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/handlers.rs | 38 |
1 files changed, 28 insertions, 10 deletions
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index 09d896c40..9208ee473 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs | |||
@@ -456,14 +456,16 @@ pub fn handle_prepare_rename( | |||
456 | 456 | ||
457 | // We support renaming references like handle_rename does. | 457 | // We support renaming references like handle_rename does. |
458 | // In the future we may want to reject the renaming of things like keywords here too. | 458 | // In the future we may want to reject the renaming of things like keywords here too. |
459 | let refs = world.analysis().find_all_refs(position)?; | 459 | let refs = match world.analysis().find_all_refs(position)? { |
460 | let r = match refs.first() { | ||
461 | Some(r) => r, | ||
462 | None => return Ok(None), | 460 | None => return Ok(None), |
461 | Some(refs) => refs, | ||
463 | }; | 462 | }; |
463 | |||
464 | // Refs should always have a declaration | ||
465 | let r = refs.declaration(); | ||
464 | let file_id = params.text_document.try_conv_with(&world)?; | 466 | let file_id = params.text_document.try_conv_with(&world)?; |
465 | let line_index = world.analysis().file_line_index(file_id); | 467 | let line_index = world.analysis().file_line_index(file_id); |
466 | let loc = to_location(r.0, r.1, &world, &line_index)?; | 468 | let loc = to_location(r.file_id(), r.range(), &world, &line_index)?; |
467 | 469 | ||
468 | Ok(Some(PrepareRenameResponse::Range(loc.range))) | 470 | Ok(Some(PrepareRenameResponse::Range(loc.range))) |
469 | } | 471 | } |
@@ -501,11 +503,24 @@ pub fn handle_references( | |||
501 | let line_index = world.analysis().file_line_index(file_id); | 503 | let line_index = world.analysis().file_line_index(file_id); |
502 | let offset = params.position.conv_with(&line_index); | 504 | let offset = params.position.conv_with(&line_index); |
503 | 505 | ||
504 | let refs = world.analysis().find_all_refs(FilePosition { file_id, offset })?; | 506 | let refs = match world.analysis().find_all_refs(FilePosition { file_id, offset })? { |
507 | None => return Ok(None), | ||
508 | Some(refs) => refs, | ||
509 | }; | ||
505 | 510 | ||
506 | Ok(Some( | 511 | let locations = if params.context.include_declaration { |
507 | refs.into_iter().filter_map(|r| to_location(r.0, r.1, &world, &line_index).ok()).collect(), | 512 | refs.into_iter() |
508 | )) | 513 | .filter_map(|r| to_location(r.file_id, r.range, &world, &line_index).ok()) |
514 | .collect() | ||
515 | } else { | ||
516 | // Only iterate over the references if include_declaration was false | ||
517 | refs.references() | ||
518 | .iter() | ||
519 | .filter_map(|r| to_location(r.file_id, r.range, &world, &line_index).ok()) | ||
520 | .collect() | ||
521 | }; | ||
522 | |||
523 | Ok(Some(locations)) | ||
509 | } | 524 | } |
510 | 525 | ||
511 | pub fn handle_formatting( | 526 | pub fn handle_formatting( |
@@ -712,11 +727,14 @@ pub fn handle_document_highlight( | |||
712 | let file_id = params.text_document.try_conv_with(&world)?; | 727 | let file_id = params.text_document.try_conv_with(&world)?; |
713 | let line_index = world.analysis().file_line_index(file_id); | 728 | let line_index = world.analysis().file_line_index(file_id); |
714 | 729 | ||
715 | let refs = world.analysis().find_all_refs(params.try_conv_with(&world)?)?; | 730 | let refs = match world.analysis().find_all_refs(params.try_conv_with(&world)?)? { |
731 | None => return Ok(None), | ||
732 | Some(refs) => refs, | ||
733 | }; | ||
716 | 734 | ||
717 | Ok(Some( | 735 | Ok(Some( |
718 | refs.into_iter() | 736 | refs.into_iter() |
719 | .map(|r| DocumentHighlight { range: r.1.conv_with(&line_index), kind: None }) | 737 | .map(|r| DocumentHighlight { range: r.range.conv_with(&line_index), kind: None }) |
720 | .collect(), | 738 | .collect(), |
721 | )) | 739 | )) |
722 | } | 740 | } |