Deduplicate lsp locations
This commit is contained in:
parent
30b992e95a
commit
91a8f34aee
@ -2,7 +2,6 @@
|
|||||||
//! Protocol. This module specifically handles requests.
|
//! Protocol. This module specifically handles requests.
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashSet,
|
|
||||||
fs,
|
fs,
|
||||||
io::Write as _,
|
io::Write as _,
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
@ -14,10 +13,10 @@ use anyhow::Context;
|
|||||||
use ide::{
|
use ide::{
|
||||||
AnnotationConfig, AssistKind, AssistResolveStrategy, Cancellable, FilePosition, FileRange,
|
AnnotationConfig, AssistKind, AssistResolveStrategy, Cancellable, FilePosition, FileRange,
|
||||||
HoverAction, HoverGotoTypeData, InlayFieldsToResolve, Query, RangeInfo, RangeLimit,
|
HoverAction, HoverGotoTypeData, InlayFieldsToResolve, Query, RangeInfo, RangeLimit,
|
||||||
ReferenceCategory, ReferenceSearchResult, Runnable, RunnableKind, SingleResolve, SourceChange,
|
ReferenceCategory, Runnable, RunnableKind, SingleResolve, SourceChange, TextEdit,
|
||||||
TextEdit,
|
|
||||||
};
|
};
|
||||||
use ide_db::SymbolKind;
|
use ide_db::SymbolKind;
|
||||||
|
use itertools::Itertools;
|
||||||
use lsp_server::ErrorCode;
|
use lsp_server::ErrorCode;
|
||||||
use lsp_types::{
|
use lsp_types::{
|
||||||
CallHierarchyIncomingCall, CallHierarchyIncomingCallsParams, CallHierarchyItem,
|
CallHierarchyIncomingCall, CallHierarchyIncomingCallsParams, CallHierarchyItem,
|
||||||
@ -30,8 +29,6 @@ use lsp_types::{
|
|||||||
};
|
};
|
||||||
use project_model::{ManifestPath, ProjectWorkspace, TargetKind};
|
use project_model::{ManifestPath, ProjectWorkspace, TargetKind};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
#[allow(unused_imports)]
|
|
||||||
use stdx::IsNoneOr;
|
|
||||||
use stdx::{format_to, never};
|
use stdx::{format_to, never};
|
||||||
use syntax::{algo, ast, AstNode, TextRange, TextSize};
|
use syntax::{algo, ast, AstNode, TextRange, TextSize};
|
||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
@ -1059,10 +1056,9 @@ pub(crate) fn handle_references(
|
|||||||
let exclude_imports = snap.config.find_all_refs_exclude_imports();
|
let exclude_imports = snap.config.find_all_refs_exclude_imports();
|
||||||
let exclude_tests = snap.config.find_all_refs_exclude_tests();
|
let exclude_tests = snap.config.find_all_refs_exclude_tests();
|
||||||
|
|
||||||
let Some(mut refs) = snap.analysis.find_all_refs(position, None)? else {
|
let Some(refs) = snap.analysis.find_all_refs(position, None)? else {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
};
|
};
|
||||||
deduplicate_declarations(&mut refs);
|
|
||||||
|
|
||||||
let include_declaration = params.context.include_declaration;
|
let include_declaration = params.context.include_declaration;
|
||||||
let locations = refs
|
let locations = refs
|
||||||
@ -1088,23 +1084,13 @@ pub(crate) fn handle_references(
|
|||||||
})
|
})
|
||||||
.chain(decl)
|
.chain(decl)
|
||||||
})
|
})
|
||||||
|
.unique()
|
||||||
.filter_map(|frange| to_proto::location(&snap, frange).ok())
|
.filter_map(|frange| to_proto::location(&snap, frange).ok())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
Ok(Some(locations))
|
Ok(Some(locations))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deduplicate_declarations(refs: &mut Vec<ReferenceSearchResult>) {
|
|
||||||
if refs.iter().filter(|decl| decl.declaration.is_some()).take(2).count() > 1 {
|
|
||||||
let mut seen_navigation_targets = HashSet::new();
|
|
||||||
refs.retain(|res| {
|
|
||||||
res.declaration
|
|
||||||
.as_ref()
|
|
||||||
.is_none_or(|decl| seen_navigation_targets.insert(decl.nav.clone()))
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn handle_formatting(
|
pub(crate) fn handle_formatting(
|
||||||
snap: GlobalStateSnapshot,
|
snap: GlobalStateSnapshot,
|
||||||
params: lsp_types::DocumentFormattingParams,
|
params: lsp_types::DocumentFormattingParams,
|
||||||
@ -1809,10 +1795,7 @@ fn show_ref_command_link(
|
|||||||
position: &FilePosition,
|
position: &FilePosition,
|
||||||
) -> Option<lsp_ext::CommandLinkGroup> {
|
) -> Option<lsp_ext::CommandLinkGroup> {
|
||||||
if snap.config.hover_actions().references && snap.config.client_commands().show_reference {
|
if snap.config.hover_actions().references && snap.config.client_commands().show_reference {
|
||||||
if let Some(mut ref_search_res) =
|
if let Some(ref_search_res) = snap.analysis.find_all_refs(*position, None).unwrap_or(None) {
|
||||||
snap.analysis.find_all_refs(*position, None).unwrap_or(None)
|
|
||||||
{
|
|
||||||
deduplicate_declarations(&mut ref_search_res);
|
|
||||||
let uri = to_proto::url(snap, position.file_id);
|
let uri = to_proto::url(snap, position.file_id);
|
||||||
let line_index = snap.file_line_index(position.file_id).ok()?;
|
let line_index = snap.file_line_index(position.file_id).ok()?;
|
||||||
let position = to_proto::position(&line_index, position.offset);
|
let position = to_proto::position(&line_index, position.offset);
|
||||||
@ -1820,10 +1803,10 @@ fn show_ref_command_link(
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.flat_map(|res| res.references)
|
.flat_map(|res| res.references)
|
||||||
.flat_map(|(file_id, ranges)| {
|
.flat_map(|(file_id, ranges)| {
|
||||||
ranges.into_iter().filter_map(move |(range, _)| {
|
ranges.into_iter().map(move |(range, _)| FileRange { file_id, range })
|
||||||
to_proto::location(snap, FileRange { file_id, range }).ok()
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
.unique()
|
||||||
|
.filter_map(|range| to_proto::location(snap, range).ok())
|
||||||
.collect();
|
.collect();
|
||||||
let title = to_proto::reference_title(locations.len());
|
let title = to_proto::reference_title(locations.len());
|
||||||
let command = to_proto::command::show_references(title, &uri, position, locations);
|
let command = to_proto::command::show_references(title, &uri, position, locations);
|
||||||
|
@ -904,15 +904,16 @@ pub(crate) fn goto_definition_response(
|
|||||||
if snap.config.location_link() {
|
if snap.config.location_link() {
|
||||||
let links = targets
|
let links = targets
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
.unique_by(|nav| (nav.file_id, nav.full_range, nav.focus_range))
|
||||||
.map(|nav| location_link(snap, src, nav))
|
.map(|nav| location_link(snap, src, nav))
|
||||||
.collect::<Cancellable<Vec<_>>>()?;
|
.collect::<Cancellable<Vec<_>>>()?;
|
||||||
Ok(links.into())
|
Ok(links.into())
|
||||||
} else {
|
} else {
|
||||||
let locations = targets
|
let locations = targets
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|nav| {
|
.map(|nav| FileRange { file_id: nav.file_id, range: nav.focus_or_full_range() })
|
||||||
location(snap, FileRange { file_id: nav.file_id, range: nav.focus_or_full_range() })
|
.unique()
|
||||||
})
|
.map(|range| location(snap, range))
|
||||||
.collect::<Cancellable<Vec<_>>>()?;
|
.collect::<Cancellable<Vec<_>>>()?;
|
||||||
Ok(locations.into())
|
Ok(locations.into())
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user