Skip to content

Commit e07fbab

Browse files
Resolve inlay hint data
Skip every propery set in inlay hint client resolve capabilities, reducing overall json footprint.
1 parent 0e002fe commit e07fbab

File tree

9 files changed

+200
-51
lines changed

9 files changed

+200
-51
lines changed

crates/ide/src/inlay_hints.rs

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,42 @@ pub struct InlayHintsConfig {
5252
pub closure_style: ClosureStyle,
5353
pub max_length: Option<usize>,
5454
pub closing_brace_hints_min_lines: Option<usize>,
55+
pub fields_to_resolve: InlayFieldsToResolve,
56+
}
57+
58+
#[derive(Clone, Debug, PartialEq, Eq)]
59+
pub struct InlayFieldsToResolve {
60+
pub client_capability_fields: Vec<String>,
61+
}
62+
63+
impl InlayFieldsToResolve {
64+
pub const fn empty() -> Self {
65+
Self { client_capability_fields: Vec::new() }
66+
}
67+
68+
pub fn is_empty(&self) -> bool {
69+
self.client_capability_fields.is_empty()
70+
}
71+
72+
pub fn resolve_text_edits(&self) -> bool {
73+
self.client_capability_fields.iter().find(|s| s.as_str() == "textEdits").is_some()
74+
}
75+
76+
pub fn resolve_hint_tooltip(&self) -> bool {
77+
self.client_capability_fields.iter().find(|s| s.as_str() == "tooltip").is_some()
78+
}
79+
80+
pub fn resolve_label_tooltip(&self) -> bool {
81+
self.client_capability_fields.iter().find(|s| s.as_str() == "label.tooltip").is_some()
82+
}
83+
84+
pub fn resolve_label_location(&self) -> bool {
85+
self.client_capability_fields.iter().find(|s| s.as_str() == "label.location").is_some()
86+
}
87+
88+
pub fn resolve_label_command(&self) -> bool {
89+
self.client_capability_fields.iter().find(|s| s.as_str() == "label.command").is_some()
90+
}
5591
}
5692

5793
#[derive(Clone, Debug, PartialEq, Eq)]
@@ -529,6 +565,7 @@ fn closure_has_block_body(closure: &ast::ClosureExpr) -> bool {
529565

530566
#[cfg(test)]
531567
mod tests {
568+
532569
use expect_test::Expect;
533570
use hir::ClosureStyle;
534571
use itertools::Itertools;
@@ -538,7 +575,7 @@ mod tests {
538575
use crate::DiscriminantHints;
539576
use crate::{fixture, inlay_hints::InlayHintsConfig, LifetimeElisionHints};
540577

541-
use super::ClosureReturnTypeHints;
578+
use super::{ClosureReturnTypeHints, InlayFieldsToResolve};
542579

543580
pub(super) const DISABLED_CONFIG: InlayHintsConfig = InlayHintsConfig {
544581
discriminant_hints: DiscriminantHints::Never,
@@ -559,6 +596,7 @@ mod tests {
559596
param_names_for_lifetime_elision_hints: false,
560597
max_length: None,
561598
closing_brace_hints_min_lines: None,
599+
fields_to_resolve: InlayFieldsToResolve::empty(),
562600
};
563601
pub(super) const TEST_CONFIG: InlayHintsConfig = InlayHintsConfig {
564602
type_hints: true,
@@ -567,7 +605,19 @@ mod tests {
567605
closure_return_type_hints: ClosureReturnTypeHints::WithBlock,
568606
binding_mode_hints: true,
569607
lifetime_elision_hints: LifetimeElisionHints::Always,
570-
..DISABLED_CONFIG
608+
discriminant_hints: DiscriminantHints::Never,
609+
render_colons: false,
610+
closure_capture_hints: false,
611+
adjustment_hints: AdjustmentHints::Never,
612+
adjustment_hints_mode: AdjustmentHintsMode::Prefix,
613+
adjustment_hints_hide_outside_unsafe: false,
614+
hide_named_constructor_hints: false,
615+
hide_closure_initialization_hints: false,
616+
closure_style: ClosureStyle::ImplFn,
617+
param_names_for_lifetime_elision_hints: false,
618+
max_length: None,
619+
closing_brace_hints_min_lines: None,
620+
fields_to_resolve: InlayFieldsToResolve::empty(),
571621
};
572622

573623
#[track_caller]

crates/ide/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,9 @@ pub use crate::{
9191
MemoryLayoutHoverConfig, MemoryLayoutHoverRenderKind,
9292
},
9393
inlay_hints::{
94-
AdjustmentHints, AdjustmentHintsMode, ClosureReturnTypeHints, DiscriminantHints, InlayHint,
95-
InlayHintLabel, InlayHintLabelPart, InlayHintPosition, InlayHintsConfig, InlayKind,
96-
InlayTooltip, LifetimeElisionHints,
94+
AdjustmentHints, AdjustmentHintsMode, ClosureReturnTypeHints, DiscriminantHints,
95+
InlayFieldsToResolve, InlayHint, InlayHintLabel, InlayHintLabelPart, InlayHintPosition,
96+
InlayHintsConfig, InlayKind, InlayTooltip, LifetimeElisionHints,
9797
},
9898
join_lines::JoinLinesConfig,
9999
markup::Markup,

crates/ide/src/static_index.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use ide_db::{
1212
};
1313
use syntax::{AstNode, SyntaxKind::*, TextRange, T};
1414

15+
use crate::inlay_hints::InlayFieldsToResolve;
1516
use crate::{
1617
hover::hover_for_definition,
1718
inlay_hints::AdjustmentHintsMode,
@@ -125,6 +126,7 @@ impl StaticIndex<'_> {
125126
max_length: Some(25),
126127
closure_capture_hints: false,
127128
closing_brace_hints_min_lines: Some(25),
129+
fields_to_resolve: InlayFieldsToResolve::empty(),
128130
},
129131
file_id,
130132
None,

crates/rust-analyzer/src/cli/analysis_stats.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ use hir_def::{
1515
hir::{ExprId, PatId},
1616
};
1717
use hir_ty::{Interner, Substitution, TyExt, TypeFlags};
18-
use ide::{Analysis, AnnotationConfig, DiagnosticsConfig, InlayHintsConfig, LineCol, RootDatabase};
18+
use ide::{
19+
Analysis, AnnotationConfig, DiagnosticsConfig, InlayFieldsToResolve, InlayHintsConfig, LineCol,
20+
RootDatabase,
21+
};
1922
use ide_db::{
2023
base_db::{
2124
salsa::{self, debug::DebugQueryTable, ParallelDatabase},
@@ -782,6 +785,7 @@ impl flags::AnalysisStats {
782785
closure_style: hir::ClosureStyle::ImplFn,
783786
max_length: Some(25),
784787
closing_brace_hints_min_lines: Some(20),
788+
fields_to_resolve: InlayFieldsToResolve::empty(),
785789
},
786790
file_id,
787791
None,

crates/rust-analyzer/src/config.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ use cfg::{CfgAtom, CfgDiff};
1313
use flycheck::FlycheckConfig;
1414
use ide::{
1515
AssistConfig, CallableSnippets, CompletionConfig, DiagnosticsConfig, ExprFillDefaultMode,
16-
HighlightConfig, HighlightRelatedConfig, HoverConfig, HoverDocFormat, InlayHintsConfig,
17-
JoinLinesConfig, MemoryLayoutHoverConfig, MemoryLayoutHoverRenderKind, Snippet, SnippetScope,
16+
HighlightConfig, HighlightRelatedConfig, HoverConfig, HoverDocFormat, InlayFieldsToResolve,
17+
InlayHintsConfig, JoinLinesConfig, MemoryLayoutHoverConfig, MemoryLayoutHoverRenderKind,
18+
Snippet, SnippetScope,
1819
};
1920
use ide_db::{
2021
imports::insert_use::{ImportGranularity, InsertUseConfig, PrefixKind},
@@ -1335,6 +1336,18 @@ impl Config {
13351336
}
13361337

13371338
pub fn inlay_hints(&self) -> InlayHintsConfig {
1339+
let client_capability_fields = self
1340+
.caps
1341+
.text_document
1342+
.as_ref()
1343+
.and_then(|text| text.inlay_hint.as_ref())
1344+
.and_then(|inlay_hint_caps| inlay_hint_caps.resolve_support.as_ref())
1345+
.map(|inlay_resolve| inlay_resolve.properties.iter())
1346+
.into_iter()
1347+
.flatten()
1348+
.cloned()
1349+
.collect::<Vec<_>>();
1350+
13381351
InlayHintsConfig {
13391352
render_colons: self.data.inlayHints_renderColons,
13401353
type_hints: self.data.inlayHints_typeHints_enable,
@@ -1395,6 +1408,7 @@ impl Config {
13951408
} else {
13961409
None
13971410
},
1411+
fields_to_resolve: InlayFieldsToResolve { client_capability_fields },
13981412
}
13991413
}
14001414

crates/rust-analyzer/src/handlers/request.rs

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ use anyhow::Context;
1111

1212
use ide::{
1313
AnnotationConfig, AssistKind, AssistResolveStrategy, Cancellable, FilePosition, FileRange,
14-
HoverAction, HoverGotoTypeData, Query, RangeInfo, ReferenceCategory, Runnable, RunnableKind,
15-
SingleResolve, SourceChange, TextEdit,
14+
HoverAction, HoverGotoTypeData, InlayFieldsToResolve, Query, RangeInfo, ReferenceCategory,
15+
Runnable, RunnableKind, SingleResolve, SourceChange, TextEdit,
1616
};
1717
use ide_db::SymbolKind;
1818
use lsp_server::ErrorCode;
@@ -30,7 +30,7 @@ use serde_json::json;
3030
use stdx::{format_to, never};
3131
use syntax::{algo, ast, AstNode, TextRange, TextSize};
3232
use triomphe::Arc;
33-
use vfs::{AbsPath, AbsPathBuf, VfsPath};
33+
use vfs::{AbsPath, AbsPathBuf, FileId, VfsPath};
3434

3535
use crate::{
3636
cargo_target_spec::CargoTargetSpec,
@@ -1412,17 +1412,71 @@ pub(crate) fn handle_inlay_hints(
14121412
snap.analysis
14131413
.inlay_hints(&inlay_hints_config, file_id, Some(range))?
14141414
.into_iter()
1415-
.map(|it| to_proto::inlay_hint(&snap, &line_index, it))
1415+
.map(|it| {
1416+
to_proto::inlay_hint(
1417+
&snap,
1418+
&inlay_hints_config.fields_to_resolve,
1419+
&line_index,
1420+
file_id,
1421+
it,
1422+
)
1423+
})
14161424
.collect::<Cancellable<Vec<_>>>()?,
14171425
))
14181426
}
14191427

14201428
pub(crate) fn handle_inlay_hints_resolve(
1421-
_snap: GlobalStateSnapshot,
1422-
hint: InlayHint,
1429+
snap: GlobalStateSnapshot,
1430+
mut original_hint: InlayHint,
14231431
) -> anyhow::Result<InlayHint> {
14241432
let _p = profile::span("handle_inlay_hints_resolve");
1425-
Ok(hint)
1433+
1434+
let data = match original_hint.data.take() {
1435+
Some(it) => it,
1436+
None => return Ok(original_hint),
1437+
};
1438+
1439+
let resolve_data: lsp_ext::InlayHintResolveData = serde_json::from_value(data)?;
1440+
let file_id = FileId(resolve_data.file_id);
1441+
let line_index = snap.file_line_index(file_id)?;
1442+
let range = from_proto::text_range(
1443+
&line_index,
1444+
lsp_types::Range { start: original_hint.position, end: original_hint.position },
1445+
)?;
1446+
let range_start = range.start();
1447+
let range_end = range.end();
1448+
let large_range = TextRange::new(
1449+
range_start.checked_sub(1.into()).unwrap_or(range_start),
1450+
range_end.checked_add(1.into()).unwrap_or(range_end),
1451+
);
1452+
let mut forced_resolve_inlay_hints_config = snap.config.inlay_hints();
1453+
forced_resolve_inlay_hints_config.fields_to_resolve = InlayFieldsToResolve::empty();
1454+
let resolve_hints = snap.analysis.inlay_hints(
1455+
&forced_resolve_inlay_hints_config,
1456+
file_id,
1457+
Some(large_range),
1458+
)?;
1459+
1460+
let mut resolved_hints = resolve_hints
1461+
.into_iter()
1462+
.filter_map(|it| {
1463+
to_proto::inlay_hint(
1464+
&snap,
1465+
&forced_resolve_inlay_hints_config.fields_to_resolve,
1466+
&line_index,
1467+
file_id,
1468+
it,
1469+
)
1470+
.ok()
1471+
})
1472+
.filter(|hint| hint.position == original_hint.position)
1473+
.filter(|hint| hint.kind == original_hint.kind);
1474+
if let Some(resolved_hint) = resolved_hints.next() {
1475+
if resolved_hints.next().is_none() {
1476+
return Ok(resolved_hint);
1477+
}
1478+
}
1479+
Ok(original_hint)
14261480
}
14271481

14281482
pub(crate) fn handle_call_hierarchy_prepare(

crates/rust-analyzer/src/lsp/ext.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -682,7 +682,9 @@ pub struct CompletionResolveData {
682682
}
683683

684684
#[derive(Debug, Serialize, Deserialize)]
685-
pub struct InlayHintResolveData {}
685+
pub struct InlayHintResolveData {
686+
pub file_id: u32,
687+
}
686688

687689
#[derive(Debug, Serialize, Deserialize)]
688690
pub struct CompletionImport {

0 commit comments

Comments
 (0)