From 4169926b3fcb6f4f222f47a2ad082730a286e9ba Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Tue, 10 Dec 2024 13:01:23 +0200 Subject: [PATCH] Address the feedback from pascalkuthe * Use Base64 to minify the hash representation in the JSON data * Do hash checks only for items with similar labels --- Cargo.lock | 7 +++++++ crates/rust-analyzer/Cargo.toml | 1 + crates/rust-analyzer/src/handlers/request.rs | 10 ++++++++-- crates/rust-analyzer/src/lsp/ext.rs | 2 +- crates/rust-analyzer/src/lsp/to_proto.rs | 5 +++-- docs/dev/lsp-extensions.md | 2 +- 6 files changed, 21 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b6f2c6faf8..8b156a5401 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -84,6 +84,12 @@ dependencies = [ "vfs", ] +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "bitflags" version = "1.3.2" @@ -1649,6 +1655,7 @@ version = "0.0.0" dependencies = [ "always-assert", "anyhow", + "base64", "cargo_metadata", "cfg", "crossbeam-channel", diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml index 58d871270d..7c8610280b 100644 --- a/crates/rust-analyzer/Cargo.toml +++ b/crates/rust-analyzer/Cargo.toml @@ -21,6 +21,7 @@ path = "src/bin/main.rs" [dependencies] anyhow.workspace = true +base64 = "0.22" crossbeam-channel.workspace = true dirs = "5.0.1" dissimilar.workspace = true diff --git a/crates/rust-analyzer/src/handlers/request.rs b/crates/rust-analyzer/src/handlers/request.rs index 3f2ef7616b..e51b14f611 100644 --- a/crates/rust-analyzer/src/handlers/request.rs +++ b/crates/rust-analyzer/src/handlers/request.rs @@ -10,6 +10,7 @@ use std::{ use anyhow::Context; +use base64::{prelude::BASE64_STANDARD, Engine}; use ide::{ AnnotationConfig, AssistKind, AssistResolveStrategy, Cancellable, CompletionFieldsToResolve, FilePosition, FileRange, HoverAction, HoverGotoTypeData, InlayFieldsToResolve, Query, @@ -1136,10 +1137,15 @@ pub(crate) fn handle_completion_resolve( else { return Ok(original_completion); }; + let Ok(resolve_data_hash) = BASE64_STANDARD.decode(resolve_data.hash) else { + return Ok(original_completion); + }; let Some(corresponding_completion) = completions.into_iter().find(|completion_item| { - let hash = completion_item_hash(completion_item, resolve_data.for_ref); - hash == resolve_data.hash + // Avoid computing hashes for items that obviously do not match + // r-a might append a detail-based suffix to the label, so we cannot check for equality + original_completion.label.starts_with(completion_item.label.as_str()) + && resolve_data_hash == completion_item_hash(completion_item, resolve_data.for_ref) }) else { return Ok(original_completion); }; diff --git a/crates/rust-analyzer/src/lsp/ext.rs b/crates/rust-analyzer/src/lsp/ext.rs index afb9c909c6..df06270a8b 100644 --- a/crates/rust-analyzer/src/lsp/ext.rs +++ b/crates/rust-analyzer/src/lsp/ext.rs @@ -827,7 +827,7 @@ pub struct CompletionResolveData { pub version: Option, pub trigger_character: Option, pub for_ref: bool, - pub hash: [u8; 20], + pub hash: String, } #[derive(Debug, Serialize, Deserialize)] diff --git a/crates/rust-analyzer/src/lsp/to_proto.rs b/crates/rust-analyzer/src/lsp/to_proto.rs index a64e1a8621..612cb547b4 100644 --- a/crates/rust-analyzer/src/lsp/to_proto.rs +++ b/crates/rust-analyzer/src/lsp/to_proto.rs @@ -5,6 +5,7 @@ use std::{ sync::atomic::{AtomicU32, Ordering}, }; +use base64::{prelude::BASE64_STANDARD, Engine}; use ide::{ Annotation, AnnotationKind, Assist, AssistKind, Cancellable, CompletionFieldsToResolve, CompletionItem, CompletionItemKind, CompletionRelevance, Documentation, FileId, FileRange, @@ -402,7 +403,7 @@ fn completion_item( version, trigger_character: completion_trigger_character, for_ref: true, - hash: completion_item_hash(&item, true), + hash: BASE64_STANDARD.encode(completion_item_hash(&item, true)), }; Some(to_value(ref_resolve_data).unwrap()) } else { @@ -414,7 +415,7 @@ fn completion_item( version, trigger_character: completion_trigger_character, for_ref: false, - hash: completion_item_hash(&item, false), + hash: BASE64_STANDARD.encode(completion_item_hash(&item, false)), }; (ref_resolve_data, Some(to_value(resolve_data).unwrap())) } else { diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md index 80b35d453a..2aad2cfa36 100644 --- a/docs/dev/lsp-extensions.md +++ b/docs/dev/lsp-extensions.md @@ -1,5 +1,5 @@