mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 04:53:34 +00:00
Add method references CodeLens
This commit is contained in:
parent
e813de6cdd
commit
eeb40dbece
4 changed files with 74 additions and 8 deletions
|
@ -74,19 +74,18 @@ pub struct LensConfig {
|
||||||
pub run: bool,
|
pub run: bool,
|
||||||
pub debug: bool,
|
pub debug: bool,
|
||||||
pub implementations: bool,
|
pub implementations: bool,
|
||||||
|
pub method_refs: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for LensConfig {
|
impl Default for LensConfig {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self { run: true, debug: true, implementations: true }
|
Self { run: true, debug: true, implementations: true, method_refs: true }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LensConfig {
|
impl LensConfig {
|
||||||
pub const NO_LENS: LensConfig = Self { run: false, debug: false, implementations: false };
|
|
||||||
|
|
||||||
pub fn any(&self) -> bool {
|
pub fn any(&self) -> bool {
|
||||||
self.implementations || self.runnable()
|
self.implementations || self.runnable() || self.references()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn none(&self) -> bool {
|
pub fn none(&self) -> bool {
|
||||||
|
@ -96,6 +95,10 @@ impl LensConfig {
|
||||||
pub fn runnable(&self) -> bool {
|
pub fn runnable(&self) -> bool {
|
||||||
self.run || self.debug
|
self.run || self.debug
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn references(&self) -> bool {
|
||||||
|
self.method_refs
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -278,6 +281,7 @@ impl Config {
|
||||||
run: data.lens_enable && data.lens_run,
|
run: data.lens_enable && data.lens_run,
|
||||||
debug: data.lens_enable && data.lens_debug,
|
debug: data.lens_enable && data.lens_debug,
|
||||||
implementations: data.lens_enable && data.lens_implementations,
|
implementations: data.lens_enable && data.lens_implementations,
|
||||||
|
method_refs: data.lens_enable && data.lens_methodReferences,
|
||||||
};
|
};
|
||||||
|
|
||||||
if !data.linkedProjects.is_empty() {
|
if !data.linkedProjects.is_empty() {
|
||||||
|
@ -463,6 +467,7 @@ config_data! {
|
||||||
lens_enable: bool = true,
|
lens_enable: bool = true,
|
||||||
lens_implementations: bool = true,
|
lens_implementations: bool = true,
|
||||||
lens_run: bool = true,
|
lens_run: bool = true,
|
||||||
|
lens_methodReferences: bool = true,
|
||||||
|
|
||||||
linkedProjects: Vec<ManifestOrProjectJson> = Vec::new(),
|
linkedProjects: Vec<ManifestOrProjectJson> = Vec::new(),
|
||||||
lruCapacity: Option<usize> = None,
|
lruCapacity: Option<usize> = None,
|
||||||
|
|
|
@ -11,6 +11,7 @@ use ide::{
|
||||||
FileId, FilePosition, FileRange, HoverAction, HoverGotoTypeData, NavigationTarget, Query,
|
FileId, FilePosition, FileRange, HoverAction, HoverGotoTypeData, NavigationTarget, Query,
|
||||||
RangeInfo, Runnable, RunnableKind, SearchScope, TextEdit,
|
RangeInfo, Runnable, RunnableKind, SearchScope, TextEdit,
|
||||||
};
|
};
|
||||||
|
use itertools::Itertools;
|
||||||
use lsp_server::ErrorCode;
|
use lsp_server::ErrorCode;
|
||||||
use lsp_types::{
|
use lsp_types::{
|
||||||
CallHierarchyIncomingCall, CallHierarchyIncomingCallsParams, CallHierarchyItem,
|
CallHierarchyIncomingCall, CallHierarchyIncomingCallsParams, CallHierarchyItem,
|
||||||
|
@ -952,6 +953,52 @@ pub(crate) fn handle_code_lens(
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if snap.config.lens.references() {
|
||||||
|
let ref_lenses = snap
|
||||||
|
.analysis
|
||||||
|
.file_structure(file_id)?
|
||||||
|
.into_iter()
|
||||||
|
.filter(|it| match it.kind {
|
||||||
|
SyntaxKind::FN => true,
|
||||||
|
_ => false,
|
||||||
|
})
|
||||||
|
.filter_map(|it| {
|
||||||
|
let position = FilePosition { file_id, offset: it.navigation_range.start() };
|
||||||
|
let scope = None; // all references
|
||||||
|
|
||||||
|
snap.analysis.find_all_refs(position, scope).unwrap_or(None).map(|r| {
|
||||||
|
let mut lenses = Vec::new();
|
||||||
|
if r.len() == 1 {
|
||||||
|
// Only a declaration
|
||||||
|
return lenses;
|
||||||
|
}
|
||||||
|
|
||||||
|
let uri = to_proto::url(&snap, file_id);
|
||||||
|
let range = to_proto::range(&line_index, it.node_range);
|
||||||
|
let position = to_proto::position(&line_index, position.offset);
|
||||||
|
|
||||||
|
if snap.config.lens.method_refs {
|
||||||
|
let all_locations: Vec<_> = r
|
||||||
|
.references()
|
||||||
|
.iter()
|
||||||
|
.filter_map(|it| to_proto::location(&snap, it.file_range).ok())
|
||||||
|
.collect();
|
||||||
|
let title = reference_title(all_locations.len());
|
||||||
|
let all_refs =
|
||||||
|
show_references_command(title, &uri, position, all_locations);
|
||||||
|
lenses.push(CodeLens { range, command: Some(all_refs), data: None });
|
||||||
|
}
|
||||||
|
|
||||||
|
lenses
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.flatten()
|
||||||
|
.collect_vec();
|
||||||
|
|
||||||
|
lenses.extend(ref_lenses);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(Some(lenses))
|
Ok(Some(lenses))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1248,6 +1295,14 @@ fn implementation_title(count: usize) -> String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn reference_title(count: usize) -> String {
|
||||||
|
if count == 1 {
|
||||||
|
"1 reference".into()
|
||||||
|
} else {
|
||||||
|
format!("{} references", count)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn show_references_command(
|
fn show_references_command(
|
||||||
title: String,
|
title: String,
|
||||||
uri: &lsp_types::Url,
|
uri: &lsp_types::Url,
|
||||||
|
|
|
@ -554,6 +554,11 @@
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
|
"rust-analyzer.lens.methodReferences": {
|
||||||
|
"markdownDescription": "Whether to show `Method References` lens. Only applies when `#rust-analyzer.lens.enable#` is set.",
|
||||||
|
"type": "boolean",
|
||||||
|
"default": true
|
||||||
|
},
|
||||||
"rust-analyzer.hoverActions.enable": {
|
"rust-analyzer.hoverActions.enable": {
|
||||||
"description": "Whether to show HoverActions in Rust files.",
|
"description": "Whether to show HoverActions in Rust files.",
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
|
|
|
@ -138,6 +138,7 @@ export class Config {
|
||||||
run: this.get<boolean>("lens.run"),
|
run: this.get<boolean>("lens.run"),
|
||||||
debug: this.get<boolean>("lens.debug"),
|
debug: this.get<boolean>("lens.debug"),
|
||||||
implementations: this.get<boolean>("lens.implementations"),
|
implementations: this.get<boolean>("lens.implementations"),
|
||||||
|
methodReferences: this.get<boolean>("lens.methodReferences"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue