aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_lsp_server/src/main_loop
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-02-17 15:38:33 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-02-17 15:38:33 +0000
commit982f72c022b45629e6adbaef22884359d3495ecf (patch)
treecc1a13dcf026a72d76496fb8ee2643619560f471 /crates/ra_lsp_server/src/main_loop
parentf937d11ad892036fa93b25a2c19d10dcebe4ab24 (diff)
parentfd5307e60d268423f7026db28b15bd2b31575396 (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.rs38
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
511pub fn handle_formatting( 526pub 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}