fix: Fix inlay hint resolution being broken

This commit is contained in:
Lukas Wirth 2024-04-14 08:20:01 +02:00
parent ff9ebc747d
commit 2c5c12acfe
8 changed files with 89 additions and 37 deletions

View file

@ -1508,11 +1508,18 @@ pub(crate) fn handle_inlay_hints_resolve(
file_id,
hint_position,
resolve_data.hash,
|hint| {
std::hash::BuildHasher::hash_one(
&std::hash::BuildHasherDefault::<ide_db::FxHasher>::default(),
hint,
)
// json only supports numbers up to 2^53 - 1 as integers, so mask the rest
& ((1 << 53) - 1)
},
)?;
let mut resolved_hints = resolve_hints
.into_iter()
.filter_map(|it| {
Ok(resolve_hints
.and_then(|it| {
to_proto::inlay_hint(
&snap,
&forced_resolve_inlay_hints_config.fields_to_resolve,
@ -1523,13 +1530,8 @@ pub(crate) fn handle_inlay_hints_resolve(
.ok()
})
.filter(|hint| hint.position == original_hint.position)
.filter(|hint| hint.kind == original_hint.kind);
if let Some(resolved_hint) = resolved_hints.next() {
if resolved_hints.next().is_none() {
return Ok(resolved_hint);
}
}
Ok(original_hint)
.filter(|hint| hint.kind == original_hint.kind)
.unwrap_or(original_hint))
}
pub(crate) fn handle_call_hierarchy_prepare(

View file

@ -463,13 +463,6 @@ pub struct TestInfo {
pub runnable: Runnable,
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct InlayHintsParams {
pub text_document: TextDocumentIdentifier,
pub range: Option<lsp_types::Range>,
}
pub enum Ssr {}
impl Request for Ssr {

View file

@ -453,6 +453,8 @@ pub(crate) fn inlay_hint(
&std::hash::BuildHasherDefault::<FxHasher>::default(),
&inlay_hint,
)
// json only supports numbers up to 2^53 - 1 as integers, so mask the rest
& ((1 << 53) - 1)
});
let mut something_to_resolve = false;

View file

@ -23,12 +23,12 @@ use lsp_types::{
notification::DidOpenTextDocument,
request::{
CodeActionRequest, Completion, Formatting, GotoTypeDefinition, HoverRequest,
WillRenameFiles, WorkspaceSymbolRequest,
InlayHintRequest, InlayHintResolveRequest, WillRenameFiles, WorkspaceSymbolRequest,
},
CodeActionContext, CodeActionParams, CompletionParams, DidOpenTextDocumentParams,
DocumentFormattingParams, FileRename, FormattingOptions, GotoDefinitionParams, HoverParams,
PartialResultParams, Position, Range, RenameFilesParams, TextDocumentItem,
TextDocumentPositionParams, WorkDoneProgressParams,
InlayHint, InlayHintLabel, InlayHintParams, PartialResultParams, Position, Range,
RenameFilesParams, TextDocumentItem, TextDocumentPositionParams, WorkDoneProgressParams,
};
use rust_analyzer::lsp::ext::{OnEnter, Runnables, RunnablesParams, UnindexedProject};
use serde_json::json;
@ -75,6 +75,48 @@ use std::collections::Spam;
assert!(res.to_string().contains("HashMap"));
}
#[test]
fn resolves_inlay_hints() {
if skip_slow_tests() {
return;
}
let server = Project::with_fixture(
r#"
//- /Cargo.toml
[package]
name = "foo"
version = "0.0.0"
//- /src/lib.rs
struct Foo;
fn f() {
let x = Foo;
}
"#,
)
.server()
.wait_until_workspace_is_loaded();
let res = server.send_request::<InlayHintRequest>(InlayHintParams {
range: Range::new(Position::new(0, 0), Position::new(3, 1)),
text_document: server.doc_id("src/lib.rs"),
work_done_progress_params: WorkDoneProgressParams::default(),
});
let mut hints = serde_json::from_value::<Option<Vec<InlayHint>>>(res).unwrap().unwrap();
let hint = hints.pop().unwrap();
assert!(hint.data.is_some());
assert!(
matches!(&hint.label, InlayHintLabel::LabelParts(parts) if parts[1].location.is_none())
);
let res = server.send_request::<InlayHintResolveRequest>(hint);
let hint = serde_json::from_value::<InlayHint>(res).unwrap();
assert!(hint.data.is_none());
assert!(
matches!(&hint.label, InlayHintLabel::LabelParts(parts) if parts[1].location.is_some())
);
}
#[test]
fn test_runnables_project() {
if skip_slow_tests() {

View file

@ -159,6 +159,18 @@ impl Project<'_> {
content_format: Some(vec![lsp_types::MarkupKind::Markdown]),
..Default::default()
}),
inlay_hint: Some(lsp_types::InlayHintClientCapabilities {
resolve_support: Some(lsp_types::InlayHintResolveClientCapabilities {
properties: vec![
"textEdits".to_owned(),
"tooltip".to_owned(),
"label.tooltip".to_owned(),
"label.location".to_owned(),
"label.command".to_owned(),
],
}),
..Default::default()
}),
..Default::default()
}),
window: Some(lsp_types::WindowClientCapabilities {