mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 12:54:58 +00:00
Make method references CodeLens lazy.
This commit is contained in:
parent
b7fda5f936
commit
06fbd69050
2 changed files with 55 additions and 42 deletions
|
@ -56,7 +56,7 @@ use ide_db::{
|
||||||
symbol_index::{self, FileSymbol},
|
symbol_index::{self, FileSymbol},
|
||||||
LineIndexDatabase,
|
LineIndexDatabase,
|
||||||
};
|
};
|
||||||
use syntax::{SourceFile, TextRange, TextSize};
|
use syntax::{SourceFile, SyntaxKind, TextRange, TextSize};
|
||||||
|
|
||||||
use crate::display::ToNav;
|
use crate::display::ToNav;
|
||||||
|
|
||||||
|
@ -369,6 +369,21 @@ impl Analysis {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Finds all methods and free functions for the file.
|
||||||
|
pub fn find_all_methods(&self, file_id: FileId) -> Cancelable<Vec<FileRange>> {
|
||||||
|
let res = self
|
||||||
|
.file_structure(file_id)?
|
||||||
|
.into_iter()
|
||||||
|
.filter(|it| match it.kind {
|
||||||
|
SyntaxKind::FN => true,
|
||||||
|
_ => false,
|
||||||
|
})
|
||||||
|
.filter_map(|it| Some(FileRange { file_id, range: it.navigation_range }))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a short text describing element at position.
|
/// Returns a short text describing element at position.
|
||||||
pub fn hover(
|
pub fn hover(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -955,48 +955,18 @@ pub(crate) fn handle_code_lens(
|
||||||
}
|
}
|
||||||
|
|
||||||
if snap.config.lens.references() {
|
if snap.config.lens.references() {
|
||||||
let ref_lenses = snap
|
lenses.extend(snap.analysis.find_all_methods(file_id)?.into_iter().map(|it| {
|
||||||
.analysis
|
let range = to_proto::range(&line_index, it.range);
|
||||||
.file_structure(file_id)?
|
let position = to_proto::position(&line_index, it.range.start());
|
||||||
.into_iter()
|
let lens_params =
|
||||||
.filter(|it| match it.kind {
|
lsp_types::TextDocumentPositionParams::new(params.text_document.clone(), position);
|
||||||
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| {
|
CodeLens {
|
||||||
let mut lenses = Vec::new();
|
range,
|
||||||
if r.len() == 1 {
|
command: None,
|
||||||
// Only a declaration
|
data: Some(to_value(CodeLensResolveData::References(lens_params)).unwrap()),
|
||||||
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))
|
||||||
|
@ -1006,6 +976,7 @@ pub(crate) fn handle_code_lens(
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
enum CodeLensResolveData {
|
enum CodeLensResolveData {
|
||||||
Impls(lsp_types::request::GotoImplementationParams),
|
Impls(lsp_types::request::GotoImplementationParams),
|
||||||
|
References(lsp_types::TextDocumentPositionParams),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn handle_code_lens_resolve(
|
pub(crate) fn handle_code_lens_resolve(
|
||||||
|
@ -1037,6 +1008,33 @@ pub(crate) fn handle_code_lens_resolve(
|
||||||
);
|
);
|
||||||
Ok(CodeLens { range: code_lens.range, command: Some(cmd), data: None })
|
Ok(CodeLens { range: code_lens.range, command: Some(cmd), data: None })
|
||||||
}
|
}
|
||||||
|
Some(CodeLensResolveData::References(doc_position)) => {
|
||||||
|
let position = from_proto::file_position(&snap, doc_position.clone())?;
|
||||||
|
let locations = snap
|
||||||
|
.analysis
|
||||||
|
.find_all_refs(position, None)
|
||||||
|
.unwrap_or(None)
|
||||||
|
.map(|r| {
|
||||||
|
r.references()
|
||||||
|
.iter()
|
||||||
|
.filter_map(|it| to_proto::location(&snap, it.file_range).ok())
|
||||||
|
.collect_vec()
|
||||||
|
})
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
let cmd = if locations.is_empty() {
|
||||||
|
Command { title: "No references".into(), command: "".into(), arguments: None }
|
||||||
|
} else {
|
||||||
|
show_references_command(
|
||||||
|
reference_title(locations.len()),
|
||||||
|
&doc_position.text_document.uri,
|
||||||
|
code_lens.range.start,
|
||||||
|
locations,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(CodeLens { range: code_lens.range, command: Some(cmd), data: None })
|
||||||
|
}
|
||||||
None => Ok(CodeLens {
|
None => Ok(CodeLens {
|
||||||
range: code_lens.range,
|
range: code_lens.range,
|
||||||
command: Some(Command { title: "Error".into(), ..Default::default() }),
|
command: Some(Command { title: "Error".into(), ..Default::default() }),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue