aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorvsrs <[email protected]>2020-09-01 14:33:02 +0100
committervsrs <[email protected]>2020-09-29 13:29:20 +0100
commiteeb40dbece3421d685c75bf2860610e6fd3b7b73 (patch)
treeda6e1ad2b01dd550be8f6d7499a9fc5f432e9732 /crates
parente813de6cdd53e542bce8d4a554288dc2f17bbf5e (diff)
Add method references CodeLens
Diffstat (limited to 'crates')
-rw-r--r--crates/rust-analyzer/src/config.rs21
-rw-r--r--crates/rust-analyzer/src/handlers.rs55
2 files changed, 68 insertions, 8 deletions
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index fab15f860..fa8472e62 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -74,19 +74,18 @@ pub struct LensConfig {
74 pub run: bool, 74 pub run: bool,
75 pub debug: bool, 75 pub debug: bool,
76 pub implementations: bool, 76 pub implementations: bool,
77 pub method_refs: bool,
77} 78}
78 79
79impl Default for LensConfig { 80impl Default for LensConfig {
80 fn default() -> Self { 81 fn default() -> Self {
81 Self { run: true, debug: true, implementations: true } 82 Self { run: true, debug: true, implementations: true, method_refs: true }
82 } 83 }
83} 84}
84 85
85impl LensConfig { 86impl LensConfig {
86 pub const NO_LENS: LensConfig = Self { run: false, debug: false, implementations: false };
87
88 pub fn any(&self) -> bool { 87 pub fn any(&self) -> bool {
89 self.implementations || self.runnable() 88 self.implementations || self.runnable() || self.references()
90 } 89 }
91 90
92 pub fn none(&self) -> bool { 91 pub fn none(&self) -> bool {
@@ -96,6 +95,10 @@ impl LensConfig {
96 pub fn runnable(&self) -> bool { 95 pub fn runnable(&self) -> bool {
97 self.run || self.debug 96 self.run || self.debug
98 } 97 }
98
99 pub fn references(&self) -> bool {
100 self.method_refs
101 }
99} 102}
100 103
101#[derive(Debug, Clone)] 104#[derive(Debug, Clone)]
@@ -278,6 +281,7 @@ impl Config {
278 run: data.lens_enable && data.lens_run, 281 run: data.lens_enable && data.lens_run,
279 debug: data.lens_enable && data.lens_debug, 282 debug: data.lens_enable && data.lens_debug,
280 implementations: data.lens_enable && data.lens_implementations, 283 implementations: data.lens_enable && data.lens_implementations,
284 method_refs: data.lens_enable && data.lens_methodReferences,
281 }; 285 };
282 286
283 if !data.linkedProjects.is_empty() { 287 if !data.linkedProjects.is_empty() {
@@ -459,10 +463,11 @@ config_data! {
459 inlayHints_parameterHints: bool = true, 463 inlayHints_parameterHints: bool = true,
460 inlayHints_typeHints: bool = true, 464 inlayHints_typeHints: bool = true,
461 465
462 lens_debug: bool = true, 466 lens_debug: bool = true,
463 lens_enable: bool = true, 467 lens_enable: bool = true,
464 lens_implementations: bool = true, 468 lens_implementations: bool = true,
465 lens_run: bool = true, 469 lens_run: bool = true,
470 lens_methodReferences: bool = true,
466 471
467 linkedProjects: Vec<ManifestOrProjectJson> = Vec::new(), 472 linkedProjects: Vec<ManifestOrProjectJson> = Vec::new(),
468 lruCapacity: Option<usize> = None, 473 lruCapacity: Option<usize> = None,
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs
index f7c7a378a..06afb8148 100644
--- a/crates/rust-analyzer/src/handlers.rs
+++ b/crates/rust-analyzer/src/handlers.rs
@@ -11,6 +11,7 @@ use ide::{
11 FileId, FilePosition, FileRange, HoverAction, HoverGotoTypeData, NavigationTarget, Query, 11 FileId, FilePosition, FileRange, HoverAction, HoverGotoTypeData, NavigationTarget, Query,
12 RangeInfo, Runnable, RunnableKind, SearchScope, TextEdit, 12 RangeInfo, Runnable, RunnableKind, SearchScope, TextEdit,
13}; 13};
14use itertools::Itertools;
14use lsp_server::ErrorCode; 15use lsp_server::ErrorCode;
15use lsp_types::{ 16use lsp_types::{
16 CallHierarchyIncomingCall, CallHierarchyIncomingCallsParams, CallHierarchyItem, 17 CallHierarchyIncomingCall, CallHierarchyIncomingCallsParams, CallHierarchyItem,
@@ -952,6 +953,52 @@ pub(crate) fn handle_code_lens(
952 }), 953 }),
953 ); 954 );
954 } 955 }
956
957 if snap.config.lens.references() {
958 let ref_lenses = snap
959 .analysis
960 .file_structure(file_id)?
961 .into_iter()
962 .filter(|it| match it.kind {
963 SyntaxKind::FN => true,
964 _ => false,
965 })
966 .filter_map(|it| {
967 let position = FilePosition { file_id, offset: it.navigation_range.start() };
968 let scope = None; // all references
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 }
1001
955 Ok(Some(lenses)) 1002 Ok(Some(lenses))
956} 1003}
957 1004
@@ -1248,6 +1295,14 @@ fn implementation_title(count: usize) -> String {
1248 } 1295 }
1249} 1296}
1250 1297
1298fn reference_title(count: usize) -> String {
1299 if count == 1 {
1300 "1 reference".into()
1301 } else {
1302 format!("{} references", count)
1303 }
1304}
1305
1251fn show_references_command( 1306fn show_references_command(
1252 title: String, 1307 title: String,
1253 uri: &lsp_types::Url, 1308 uri: &lsp_types::Url,