11445: Upstream inlay hints r=lnicola a=lnicola

Closes https://github.com/rust-analyzer/rust-analyzer/issues/2797
Closes https://github.com/rust-analyzer/rust-analyzer/issues/3394 (since now resolve the hints for the range given only, not for the whole document. We don't actually resolve anything due to [hard requirement](https://github.com/rust-analyzer/rust-analyzer/pull/11445#issuecomment-1035227434) on label being immutable. Any further heavy actions could go to the `resolve` method that's now available via the official Code API for hints)

Based on `@SomeoneToIgnore's` branch, with a couple of updates:

 - I squashed, more or less successfully, the commits on that branch
 - downloading the `.d.ts` no longer works, but you can get it manually from https://raw.githubusercontent.com/microsoft/vscode/release/1.64/src/vscode-dts/vscode.proposed.inlayHints.d.ts
 - you might need to pass `--enable-proposed-api matklad.rust-analyzer`
 - if I'm reading the definition right, `InlayHintKind` needs to be serialized as a number, not string
 - this doesn't work anyway -- the client-side gets the hints, but they don't display

Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
Co-authored-by: Laurențiu Nicola <lnicola@dend.ro>
This commit is contained in:
bors[bot]
2022-03-07 16:49:12 +00:00
committed by GitHub
13 changed files with 552 additions and 640 deletions

View File

@@ -115,6 +115,7 @@ pub fn server_capabilities(config: &Config) -> ServerCapabilities {
experimental: Some(json!({
"externalDocs": true,
"hoverRange": true,
"inlayHints": true,
"joinLines": true,
"matchingBrace": true,
"moveItem": true,

View File

@@ -1318,11 +1318,22 @@ pub(crate) fn handle_inlay_hints(
params: InlayHintsParams,
) -> Result<Vec<InlayHint>> {
let _p = profile::span("handle_inlay_hints");
let file_id = from_proto::file_id(&snap, &params.text_document.uri)?;
let document_uri = &params.text_document.uri;
let file_id = from_proto::file_id(&snap, document_uri)?;
let line_index = snap.file_line_index(file_id)?;
let range = params
.range
.map(|range| {
from_proto::file_range(
&snap,
TextDocumentIdentifier::new(document_uri.to_owned()),
range,
)
})
.transpose()?;
Ok(snap
.analysis
.inlay_hints(&snap.config.inlay_hints(), file_id)?
.inlay_hints(&snap.config.inlay_hints(), file_id, range)?
.into_iter()
.map(|it| to_proto::inlay_hint(&line_index, it))
.collect())

View File

@@ -233,27 +233,34 @@ pub enum InlayHints {}
impl Request for InlayHints {
type Params = InlayHintsParams;
type Result = Vec<InlayHint>;
const METHOD: &'static str = "rust-analyzer/inlayHints";
const METHOD: &'static str = "experimental/inlayHints";
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct InlayHintsParams {
pub text_document: TextDocumentIdentifier,
pub range: Option<lsp_types::Range>,
}
#[derive(Debug, PartialEq, Eq, Deserialize, Serialize)]
pub enum InlayKind {
TypeHint,
ParameterHint,
ChainingHint,
#[derive(Eq, PartialEq, Debug, Copy, Clone, Serialize, Deserialize)]
#[serde(transparent)]
pub struct InlayHintKind(u8);
impl InlayHintKind {
pub const TYPE: InlayHintKind = InlayHintKind(1);
pub const PARAMETER: InlayHintKind = InlayHintKind(2);
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct InlayHint {
pub range: Range,
pub kind: InlayKind,
pub label: String,
pub position: Position,
pub kind: Option<InlayHintKind>,
pub tooltip: Option<String>,
pub padding_left: Option<bool>,
pub padding_right: Option<bool>,
}
pub enum Ssr {}

View File

@@ -416,12 +416,18 @@ pub(crate) fn signature_help(
pub(crate) fn inlay_hint(line_index: &LineIndex, inlay_hint: InlayHint) -> lsp_ext::InlayHint {
lsp_ext::InlayHint {
label: inlay_hint.label.to_string(),
range: range(line_index, inlay_hint.range),
kind: match inlay_hint.kind {
InlayKind::ParameterHint => lsp_ext::InlayKind::ParameterHint,
InlayKind::TypeHint => lsp_ext::InlayKind::TypeHint,
InlayKind::ChainingHint => lsp_ext::InlayKind::ChainingHint,
position: match inlay_hint.kind {
InlayKind::ParameterHint => position(line_index, inlay_hint.range.start()),
_ => position(line_index, inlay_hint.range.end()),
},
kind: match inlay_hint.kind {
InlayKind::ParameterHint => Some(lsp_ext::InlayHintKind::PARAMETER),
InlayKind::TypeHint => Some(lsp_ext::InlayHintKind::TYPE),
InlayKind::ChainingHint => None,
},
tooltip: None,
padding_left: Some(true),
padding_right: Some(true),
}
}