aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvsrs <[email protected]>2020-09-02 14:03:05 +0100
committervsrs <[email protected]>2020-09-29 13:29:20 +0100
commit06fbd6905014b90aa2efc1f67b92f31845011d76 (patch)
tree6d1471eeb05f7275850690b037be23e82f01263f
parentb7fda5f936737aa1111599f93cb3133fa7f65ee4 (diff)
Make method references CodeLens lazy.
-rw-r--r--crates/ide/src/lib.rs17
-rw-r--r--crates/rust-analyzer/src/handlers.rs82
2 files changed, 56 insertions, 43 deletions
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs
index 4763c0aac..286a6a110 100644
--- a/crates/ide/src/lib.rs
+++ b/crates/ide/src/lib.rs
@@ -56,7 +56,7 @@ use ide_db::{
56 symbol_index::{self, FileSymbol}, 56 symbol_index::{self, FileSymbol},
57 LineIndexDatabase, 57 LineIndexDatabase,
58}; 58};
59use syntax::{SourceFile, TextRange, TextSize}; 59use syntax::{SourceFile, SyntaxKind, TextRange, TextSize};
60 60
61use crate::display::ToNav; 61use crate::display::ToNav;
62 62
@@ -369,6 +369,21 @@ impl Analysis {
369 }) 369 })
370 } 370 }
371 371
372 /// Finds all methods and free functions for the file.
373 pub fn find_all_methods(&self, file_id: FileId) -> Cancelable<Vec<FileRange>> {
374 let res = self
375 .file_structure(file_id)?
376 .into_iter()
377 .filter(|it| match it.kind {
378 SyntaxKind::FN => true,
379 _ => false,
380 })
381 .filter_map(|it| Some(FileRange { file_id, range: it.navigation_range }))
382 .collect();
383
384 Ok(res)
385 }
386
372 /// Returns a short text describing element at position. 387 /// Returns a short text describing element at position.
373 pub fn hover( 388 pub fn hover(
374 &self, 389 &self,
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs
index 06afb8148..1a0bee5e4 100644
--- a/crates/rust-analyzer/src/handlers.rs
+++ b/crates/rust-analyzer/src/handlers.rs
@@ -955,48 +955,18 @@ pub(crate) fn handle_code_lens(
955 } 955 }
956 956
957 if snap.config.lens.references() { 957 if snap.config.lens.references() {
958 let ref_lenses = snap 958 lenses.extend(snap.analysis.find_all_methods(file_id)?.into_iter().map(|it| {
959 .analysis 959 let range = to_proto::range(&line_index, it.range);
960 .file_structure(file_id)? 960 let position = to_proto::position(&line_index, it.range.start());
961 .into_iter() 961 let lens_params =
962 .filter(|it| match it.kind { 962 lsp_types::TextDocumentPositionParams::new(params.text_document.clone(), position);
963 SyntaxKind::FN => true, 963
964 _ => false, 964 CodeLens {
965 }) 965 range,
966 .filter_map(|it| { 966 command: None,
967 let position = FilePosition { file_id, offset: it.navigation_range.start() }; 967 data: Some(to_value(CodeLensResolveData::References(lens_params)).unwrap()),
968 let scope = None; // all references 968 }
969 969 }));
970 snap.analysis.find_all_refs(position, scope).unwrap_or(None).map(|r| {
971 let mut lenses = Vec::new();
972 if r.len() == 1 {
973 // Only a declaration
974 return lenses;
975 }
976
977 let uri = to_proto::url(&snap, file_id);
978 let range = to_proto::range(&line_index, it.node_range);
979 let position = to_proto::position(&line_index, position.offset);
980
981 if snap.config.lens.method_refs {
982 let all_locations: Vec<_> = r
983 .references()
984 .iter()
985 .filter_map(|it| to_proto::location(&snap, it.file_range).ok())
986 .collect();
987 let title = reference_title(all_locations.len());
988 let all_refs =
989 show_references_command(title, &uri, position, all_locations);
990 lenses.push(CodeLens { range, command: Some(all_refs), data: None });
991 }
992
993 lenses
994 })
995 })
996 .flatten()
997 .collect_vec();
998
999 lenses.extend(ref_lenses);
1000 } 970 }
1001 971
1002 Ok(Some(lenses)) 972 Ok(Some(lenses))
@@ -1006,6 +976,7 @@ pub(crate) fn handle_code_lens(
1006#[serde(rename_all = "camelCase")] 976#[serde(rename_all = "camelCase")]
1007enum CodeLensResolveData { 977enum CodeLensResolveData {
1008 Impls(lsp_types::request::GotoImplementationParams), 978 Impls(lsp_types::request::GotoImplementationParams),
979 References(lsp_types::TextDocumentPositionParams),
1009} 980}
1010 981
1011pub(crate) fn handle_code_lens_resolve( 982pub(crate) fn handle_code_lens_resolve(
@@ -1037,6 +1008,33 @@ pub(crate) fn handle_code_lens_resolve(
1037 ); 1008 );
1038 Ok(CodeLens { range: code_lens.range, command: Some(cmd), data: None }) 1009 Ok(CodeLens { range: code_lens.range, command: Some(cmd), data: None })
1039 } 1010 }
1011 Some(CodeLensResolveData::References(doc_position)) => {
1012 let position = from_proto::file_position(&snap, doc_position.clone())?;
1013 let locations = snap
1014 .analysis
1015 .find_all_refs(position, None)
1016 .unwrap_or(None)
1017 .map(|r| {
1018 r.references()
1019 .iter()
1020 .filter_map(|it| to_proto::location(&snap, it.file_range).ok())
1021 .collect_vec()
1022 })
1023 .unwrap_or_default();
1024
1025 let cmd = if locations.is_empty() {
1026 Command { title: "No references".into(), command: "".into(), arguments: None }
1027 } else {
1028 show_references_command(
1029 reference_title(locations.len()),
1030 &doc_position.text_document.uri,
1031 code_lens.range.start,
1032 locations,
1033 )
1034 };
1035
1036 Ok(CodeLens { range: code_lens.range, command: Some(cmd), data: None })
1037 }
1040 None => Ok(CodeLens { 1038 None => Ok(CodeLens {
1041 range: code_lens.range, 1039 range: code_lens.range,
1042 command: Some(Command { title: "Error".into(), ..Default::default() }), 1040 command: Some(Command { title: "Error".into(), ..Default::default() }),