diff options
author | vsrs <[email protected]> | 2020-09-01 14:33:02 +0100 |
---|---|---|
committer | vsrs <[email protected]> | 2020-09-29 13:29:20 +0100 |
commit | eeb40dbece3421d685c75bf2860610e6fd3b7b73 (patch) | |
tree | da6e1ad2b01dd550be8f6d7499a9fc5f432e9732 | |
parent | e813de6cdd53e542bce8d4a554288dc2f17bbf5e (diff) |
Add method references CodeLens
-rw-r--r-- | crates/rust-analyzer/src/config.rs | 21 | ||||
-rw-r--r-- | crates/rust-analyzer/src/handlers.rs | 55 | ||||
-rw-r--r-- | editors/code/package.json | 5 | ||||
-rw-r--r-- | editors/code/src/config.ts | 1 |
4 files changed, 74 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 | ||
79 | impl Default for LensConfig { | 80 | impl 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 | ||
85 | impl LensConfig { | 86 | impl 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 | }; |
14 | use itertools::Itertools; | ||
14 | use lsp_server::ErrorCode; | 15 | use lsp_server::ErrorCode; |
15 | use lsp_types::{ | 16 | use 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 | ||
1298 | fn reference_title(count: usize) -> String { | ||
1299 | if count == 1 { | ||
1300 | "1 reference".into() | ||
1301 | } else { | ||
1302 | format!("{} references", count) | ||
1303 | } | ||
1304 | } | ||
1305 | |||
1251 | fn show_references_command( | 1306 | fn show_references_command( |
1252 | title: String, | 1307 | title: String, |
1253 | uri: &lsp_types::Url, | 1308 | uri: &lsp_types::Url, |
diff --git a/editors/code/package.json b/editors/code/package.json index 132664926..4414b3e66 100644 --- a/editors/code/package.json +++ b/editors/code/package.json | |||
@@ -554,6 +554,11 @@ | |||
554 | "type": "boolean", | 554 | "type": "boolean", |
555 | "default": true | 555 | "default": true |
556 | }, | 556 | }, |
557 | "rust-analyzer.lens.methodReferences": { | ||
558 | "markdownDescription": "Whether to show `Method References` lens. Only applies when `#rust-analyzer.lens.enable#` is set.", | ||
559 | "type": "boolean", | ||
560 | "default": true | ||
561 | }, | ||
557 | "rust-analyzer.hoverActions.enable": { | 562 | "rust-analyzer.hoverActions.enable": { |
558 | "description": "Whether to show HoverActions in Rust files.", | 563 | "description": "Whether to show HoverActions in Rust files.", |
559 | "type": "boolean", | 564 | "type": "boolean", |
diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index 033b04b60..848e92af9 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts | |||
@@ -138,6 +138,7 @@ export class Config { | |||
138 | run: this.get<boolean>("lens.run"), | 138 | run: this.get<boolean>("lens.run"), |
139 | debug: this.get<boolean>("lens.debug"), | 139 | debug: this.get<boolean>("lens.debug"), |
140 | implementations: this.get<boolean>("lens.implementations"), | 140 | implementations: this.get<boolean>("lens.implementations"), |
141 | methodReferences: this.get<boolean>("lens.methodReferences"), | ||
141 | }; | 142 | }; |
142 | } | 143 | } |
143 | 144 | ||