Skip to content

Commit 06fbd69

Browse files
committed
Make method references CodeLens lazy.
1 parent b7fda5f commit 06fbd69

File tree

2 files changed

+56
-43
lines changed

2 files changed

+56
-43
lines changed

crates/ide/src/lib.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ use ide_db::{
5656
symbol_index::{self, FileSymbol},
5757
LineIndexDatabase,
5858
};
59-
use syntax::{SourceFile, TextRange, TextSize};
59+
use syntax::{SourceFile, SyntaxKind, TextRange, TextSize};
6060

6161
use crate::display::ToNav;
6262

@@ -369,6 +369,21 @@ impl Analysis {
369369
})
370370
}
371371

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+
372387
/// Returns a short text describing element at position.
373388
pub fn hover(
374389
&self,

crates/rust-analyzer/src/handlers.rs

Lines changed: 40 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -955,48 +955,18 @@ pub(crate) fn handle_code_lens(
955955
}
956956

957957
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);
958+
lenses.extend(snap.analysis.find_all_methods(file_id)?.into_iter().map(|it| {
959+
let range = to_proto::range(&line_index, it.range);
960+
let position = to_proto::position(&line_index, it.range.start());
961+
let lens_params =
962+
lsp_types::TextDocumentPositionParams::new(params.text_document.clone(), position);
963+
964+
CodeLens {
965+
range,
966+
command: None,
967+
data: Some(to_value(CodeLensResolveData::References(lens_params)).unwrap()),
968+
}
969+
}));
1000970
}
1001971

1002972
Ok(Some(lenses))
@@ -1006,6 +976,7 @@ pub(crate) fn handle_code_lens(
1006976
#[serde(rename_all = "camelCase")]
1007977
enum CodeLensResolveData {
1008978
Impls(lsp_types::request::GotoImplementationParams),
979+
References(lsp_types::TextDocumentPositionParams),
1009980
}
1010981

1011982
pub(crate) fn handle_code_lens_resolve(
@@ -1037,6 +1008,33 @@ pub(crate) fn handle_code_lens_resolve(
10371008
);
10381009
Ok(CodeLens { range: code_lens.range, command: Some(cmd), data: None })
10391010
}
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+
}
10401038
None => Ok(CodeLens {
10411039
range: code_lens.range,
10421040
command: Some(Command { title: "Error".into(), ..Default::default() }),

0 commit comments

Comments
 (0)