diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:50 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:50 +0000 |
commit | 2e00214b3efbdfeefaa0fe9e8b8fd519de7adc35 (patch) | |
tree | d325add32978dbdc1db975a438b3a77d571b1ab8 /src/tools/rust-analyzer/crates/rust-analyzer/src/to_proto.rs | |
parent | Releasing progress-linux version 1.68.2+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-2e00214b3efbdfeefaa0fe9e8b8fd519de7adc35.tar.xz rustc-2e00214b3efbdfeefaa0fe9e8b8fd519de7adc35.zip |
Merging upstream version 1.69.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/tools/rust-analyzer/crates/rust-analyzer/src/to_proto.rs')
-rw-r--r-- | src/tools/rust-analyzer/crates/rust-analyzer/src/to_proto.rs | 277 |
1 files changed, 144 insertions, 133 deletions
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/to_proto.rs index e736b2ff9..92029dc1d 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/to_proto.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/to_proto.rs @@ -9,9 +9,9 @@ use ide::{ Annotation, AnnotationKind, Assist, AssistKind, Cancellable, CompletionItem, CompletionItemKind, CompletionRelevance, Documentation, FileId, FileRange, FileSystemEdit, Fold, FoldKind, Highlight, HlMod, HlOperator, HlPunct, HlRange, HlTag, Indel, InlayHint, - InlayHintLabel, InlayKind, Markup, NavigationTarget, ReferenceCategory, RenameError, Runnable, - Severity, SignatureHelp, SourceChange, StructureNodeKind, SymbolKind, TextEdit, TextRange, - TextSize, + InlayHintLabel, InlayHintLabelPart, InlayKind, Markup, NavigationTarget, ReferenceCategory, + RenameError, Runnable, Severity, SignatureHelp, SourceChange, StructureNodeKind, SymbolKind, + TextEdit, TextRange, TextSize, }; use itertools::Itertools; use serde_json::to_value; @@ -31,8 +31,8 @@ pub(crate) fn position(line_index: &LineIndex, offset: TextSize) -> lsp_types::P let line_col = line_index.index.line_col(offset); match line_index.encoding { PositionEncoding::Utf8 => lsp_types::Position::new(line_col.line, line_col.col), - PositionEncoding::Utf16 => { - let line_col = line_index.index.to_utf16(line_col); + PositionEncoding::Wide(enc) => { + let line_col = line_index.index.to_wide(enc, line_col); lsp_types::Position::new(line_col.line, line_col.col) } } @@ -212,11 +212,17 @@ pub(crate) fn completion_items( tdpp: lsp_types::TextDocumentPositionParams, items: Vec<CompletionItem>, ) -> Vec<lsp_types::CompletionItem> { - let max_relevance = items.iter().map(|it| it.relevance().score()).max().unwrap_or_default(); + let max_relevance = items.iter().map(|it| it.relevance.score()).max().unwrap_or_default(); let mut res = Vec::with_capacity(items.len()); for item in items { - completion_item(&mut res, config, line_index, &tdpp, max_relevance, item) + completion_item(&mut res, config, line_index, &tdpp, max_relevance, item); } + + if let Some(limit) = config.completion().limit { + res.sort_by(|item1, item2| item1.sort_text.cmp(&item2.sort_text)); + res.truncate(limit); + } + res } @@ -229,22 +235,26 @@ fn completion_item( item: CompletionItem, ) { let insert_replace_support = config.insert_replace_support().then_some(tdpp.position); + let ref_match = item.ref_match(); + let lookup = item.lookup().to_string(); + let mut additional_text_edits = Vec::new(); // LSP does not allow arbitrary edits in completion, so we have to do a // non-trivial mapping here. let text_edit = { let mut text_edit = None; - let source_range = item.source_range(); - for indel in item.text_edit().iter() { + let source_range = item.source_range; + for indel in item.text_edit { if indel.delete.contains_range(source_range) { + // Extract this indel as the main edit text_edit = Some(if indel.delete == source_range { self::completion_text_edit(line_index, insert_replace_support, indel.clone()) } else { assert!(source_range.end() == indel.delete.end()); let range1 = TextRange::new(indel.delete.start(), source_range.start()); let range2 = source_range; - let indel1 = Indel::replace(range1, String::new()); + let indel1 = Indel::delete(range1); let indel2 = Indel::replace(range2, indel.insert.clone()); additional_text_edits.push(self::text_edit(line_index, indel1)); self::completion_text_edit(line_index, insert_replace_support, indel2) @@ -258,23 +268,23 @@ fn completion_item( text_edit.unwrap() }; - let insert_text_format = item.is_snippet().then_some(lsp_types::InsertTextFormat::SNIPPET); - let tags = item.deprecated().then(|| vec![lsp_types::CompletionItemTag::DEPRECATED]); - let command = if item.trigger_call_info() && config.client_commands().trigger_parameter_hints { + let insert_text_format = item.is_snippet.then_some(lsp_types::InsertTextFormat::SNIPPET); + let tags = item.deprecated.then(|| vec![lsp_types::CompletionItemTag::DEPRECATED]); + let command = if item.trigger_call_info && config.client_commands().trigger_parameter_hints { Some(command::trigger_parameter_hints()) } else { None }; let mut lsp_item = lsp_types::CompletionItem { - label: item.label().to_string(), - detail: item.detail().map(|it| it.to_string()), - filter_text: Some(item.lookup().to_string()), - kind: Some(completion_item_kind(item.kind())), + label: item.label.to_string(), + detail: item.detail.map(|it| it.to_string()), + filter_text: Some(lookup), + kind: Some(completion_item_kind(item.kind)), text_edit: Some(text_edit), additional_text_edits: Some(additional_text_edits), - documentation: item.documentation().map(documentation), - deprecated: Some(item.deprecated()), + documentation: item.documentation.map(documentation), + deprecated: Some(item.deprecated), tags, command, insert_text_format, @@ -288,12 +298,13 @@ fn completion_item( }); } - set_score(&mut lsp_item, max_relevance, item.relevance()); + set_score(&mut lsp_item, max_relevance, item.relevance); if config.completion().enable_imports_on_the_fly { - if let imports @ [_, ..] = item.imports_to_add() { - let imports: Vec<_> = imports - .iter() + if !item.import_to_add.is_empty() { + let imports: Vec<_> = item + .import_to_add + .into_iter() .filter_map(|import_edit| { let import_path = &import_edit.import_path; let import_name = import_path.segments().last()?; @@ -310,18 +321,13 @@ fn completion_item( } } - if let Some((mutability, offset, relevance)) = item.ref_match() { - let mut lsp_item_with_ref = lsp_item.clone(); + if let Some((label, indel, relevance)) = ref_match { + let mut lsp_item_with_ref = lsp_types::CompletionItem { label, ..lsp_item.clone() }; + lsp_item_with_ref + .additional_text_edits + .get_or_insert_with(Default::default) + .push(self::text_edit(line_index, indel)); set_score(&mut lsp_item_with_ref, max_relevance, relevance); - lsp_item_with_ref.label = - format!("&{}{}", mutability.as_keyword_for_ref(), lsp_item_with_ref.label); - lsp_item_with_ref.additional_text_edits.get_or_insert_with(Default::default).push( - self::text_edit( - line_index, - Indel::insert(offset, format!("&{}", mutability.as_keyword_for_ref())), - ), - ); - acc.push(lsp_item_with_ref); }; @@ -431,137 +437,140 @@ pub(crate) fn inlay_hint( mut inlay_hint: InlayHint, ) -> Cancellable<lsp_types::InlayHint> { match inlay_hint.kind { - InlayKind::ParameterHint if render_colons => inlay_hint.label.append_str(":"), - InlayKind::TypeHint if render_colons => inlay_hint.label.prepend_str(": "), - InlayKind::ClosureReturnTypeHint => inlay_hint.label.prepend_str(" -> "), - InlayKind::DiscriminantHint => inlay_hint.label.prepend_str(" = "), + InlayKind::Parameter if render_colons => inlay_hint.label.append_str(":"), + InlayKind::Type if render_colons => inlay_hint.label.prepend_str(": "), + InlayKind::ClosureReturnType => inlay_hint.label.prepend_str(" -> "), + InlayKind::Discriminant => inlay_hint.label.prepend_str(" = "), _ => {} } + let (label, tooltip) = inlay_hint_label(snap, inlay_hint.label)?; + Ok(lsp_types::InlayHint { position: match inlay_hint.kind { // before annotated thing InlayKind::OpeningParenthesis - | InlayKind::ParameterHint - | InlayKind::AdjustmentHint - | InlayKind::BindingModeHint => position(line_index, inlay_hint.range.start()), + | InlayKind::Parameter + | InlayKind::Adjustment + | InlayKind::BindingMode => position(line_index, inlay_hint.range.start()), // after annotated thing - InlayKind::ClosureReturnTypeHint - | InlayKind::TypeHint - | InlayKind::DiscriminantHint - | InlayKind::ChainingHint - | InlayKind::GenericParamListHint + InlayKind::ClosureReturnType + | InlayKind::Type + | InlayKind::Discriminant + | InlayKind::Chaining + | InlayKind::GenericParamList | InlayKind::ClosingParenthesis - | InlayKind::AdjustmentHintPostfix - | InlayKind::LifetimeHint - | InlayKind::ClosingBraceHint => position(line_index, inlay_hint.range.end()), + | InlayKind::AdjustmentPostfix + | InlayKind::Lifetime + | InlayKind::ClosingBrace => position(line_index, inlay_hint.range.end()), }, padding_left: Some(match inlay_hint.kind { - InlayKind::TypeHint => !render_colons, - InlayKind::ChainingHint | InlayKind::ClosingBraceHint => true, + InlayKind::Type => !render_colons, + InlayKind::Chaining | InlayKind::ClosingBrace => true, InlayKind::ClosingParenthesis - | InlayKind::DiscriminantHint + | InlayKind::Discriminant | InlayKind::OpeningParenthesis - | InlayKind::BindingModeHint - | InlayKind::ClosureReturnTypeHint - | InlayKind::GenericParamListHint - | InlayKind::AdjustmentHint - | InlayKind::AdjustmentHintPostfix - | InlayKind::LifetimeHint - | InlayKind::ParameterHint => false, + | InlayKind::BindingMode + | InlayKind::ClosureReturnType + | InlayKind::GenericParamList + | InlayKind::Adjustment + | InlayKind::AdjustmentPostfix + | InlayKind::Lifetime + | InlayKind::Parameter => false, }), padding_right: Some(match inlay_hint.kind { InlayKind::ClosingParenthesis | InlayKind::OpeningParenthesis - | InlayKind::ChainingHint - | InlayKind::ClosureReturnTypeHint - | InlayKind::GenericParamListHint - | InlayKind::AdjustmentHint - | InlayKind::AdjustmentHintPostfix - | InlayKind::TypeHint - | InlayKind::DiscriminantHint - | InlayKind::ClosingBraceHint => false, - InlayKind::BindingModeHint => inlay_hint.label.as_simple_str() != Some("&"), - InlayKind::ParameterHint | InlayKind::LifetimeHint => true, + | InlayKind::Chaining + | InlayKind::ClosureReturnType + | InlayKind::GenericParamList + | InlayKind::Adjustment + | InlayKind::AdjustmentPostfix + | InlayKind::Type + | InlayKind::Discriminant + | InlayKind::ClosingBrace => false, + InlayKind::BindingMode => { + matches!(&label, lsp_types::InlayHintLabel::String(s) if s != "&") + } + InlayKind::Parameter | InlayKind::Lifetime => true, }), kind: match inlay_hint.kind { - InlayKind::ParameterHint => Some(lsp_types::InlayHintKind::PARAMETER), - InlayKind::ClosureReturnTypeHint | InlayKind::TypeHint | InlayKind::ChainingHint => { + InlayKind::Parameter => Some(lsp_types::InlayHintKind::PARAMETER), + InlayKind::ClosureReturnType | InlayKind::Type | InlayKind::Chaining => { Some(lsp_types::InlayHintKind::TYPE) } InlayKind::ClosingParenthesis - | InlayKind::DiscriminantHint + | InlayKind::Discriminant | InlayKind::OpeningParenthesis - | InlayKind::BindingModeHint - | InlayKind::GenericParamListHint - | InlayKind::LifetimeHint - | InlayKind::AdjustmentHint - | InlayKind::AdjustmentHintPostfix - | InlayKind::ClosingBraceHint => None, + | InlayKind::BindingMode + | InlayKind::GenericParamList + | InlayKind::Lifetime + | InlayKind::Adjustment + | InlayKind::AdjustmentPostfix + | InlayKind::ClosingBrace => None, }, text_edits: None, - data: (|| match inlay_hint.tooltip { - Some(ide::InlayTooltip::HoverOffset(file_id, offset)) => { - let uri = url(snap, file_id); - let line_index = snap.file_line_index(file_id).ok()?; - - let text_document = lsp_types::VersionedTextDocumentIdentifier { - version: snap.url_file_version(&uri)?, - uri, - }; - to_value(lsp_ext::InlayHintResolveData { - text_document, - position: lsp_ext::PositionOrRange::Position(position(&line_index, offset)), - }) - .ok() - } - Some(ide::InlayTooltip::HoverRanged(file_id, text_range)) => { - let uri = url(snap, file_id); - let text_document = lsp_types::VersionedTextDocumentIdentifier { - version: snap.url_file_version(&uri)?, - uri, - }; - let line_index = snap.file_line_index(file_id).ok()?; - to_value(lsp_ext::InlayHintResolveData { - text_document, - position: lsp_ext::PositionOrRange::Range(range(&line_index, text_range)), - }) - .ok() - } - _ => None, - })(), - tooltip: Some(match inlay_hint.tooltip { - Some(ide::InlayTooltip::String(s)) => lsp_types::InlayHintTooltip::String(s), - _ => lsp_types::InlayHintTooltip::String(inlay_hint.label.to_string()), - }), - label: inlay_hint_label(snap, inlay_hint.label)?, + data: None, + tooltip, + label, }) } fn inlay_hint_label( snap: &GlobalStateSnapshot, - label: InlayHintLabel, -) -> Cancellable<lsp_types::InlayHintLabel> { - Ok(match label.as_simple_str() { - Some(s) => lsp_types::InlayHintLabel::String(s.into()), - None => lsp_types::InlayHintLabel::LabelParts( - label + mut label: InlayHintLabel, +) -> Cancellable<(lsp_types::InlayHintLabel, Option<lsp_types::InlayHintTooltip>)> { + let res = match &*label.parts { + [InlayHintLabelPart { linked_location: None, .. }] => { + let InlayHintLabelPart { text, tooltip, .. } = label.parts.pop().unwrap(); + ( + lsp_types::InlayHintLabel::String(text), + match tooltip { + Some(ide::InlayTooltip::String(s)) => { + Some(lsp_types::InlayHintTooltip::String(s)) + } + Some(ide::InlayTooltip::Markdown(s)) => { + Some(lsp_types::InlayHintTooltip::MarkupContent(lsp_types::MarkupContent { + kind: lsp_types::MarkupKind::Markdown, + value: s, + })) + } + None => None, + }, + ) + } + _ => { + let parts = label .parts .into_iter() .map(|part| { - Ok(lsp_types::InlayHintLabelPart { - value: part.text, - tooltip: None, - location: part - .linked_location - .map(|range| location(snap, range)) - .transpose()?, - command: None, - }) + part.linked_location.map(|range| location(snap, range)).transpose().map( + |location| lsp_types::InlayHintLabelPart { + value: part.text, + tooltip: match part.tooltip { + Some(ide::InlayTooltip::String(s)) => { + Some(lsp_types::InlayHintLabelPartTooltip::String(s)) + } + Some(ide::InlayTooltip::Markdown(s)) => { + Some(lsp_types::InlayHintLabelPartTooltip::MarkupContent( + lsp_types::MarkupContent { + kind: lsp_types::MarkupKind::Markdown, + value: s, + }, + )) + } + None => None, + }, + location, + command: None, + }, + ) }) - .collect::<Cancellable<Vec<_>>>()?, - ), - }) + .collect::<Cancellable<_>>()?; + (lsp_types::InlayHintLabel::LabelParts(parts), None) + } + }; + Ok(res) } static TOKEN_RESULT_COUNTER: AtomicU32 = AtomicU32::new(1); @@ -757,6 +766,7 @@ pub(crate) fn folding_range( end_line, end_character: None, kind, + collapsed_text: None, } } else { lsp_types::FoldingRange { @@ -765,6 +775,7 @@ pub(crate) fn folding_range( end_line: range.end.line, end_character: Some(range.end.character), kind, + collapsed_text: None, } } } @@ -1351,7 +1362,7 @@ pub(crate) mod command { pub(crate) fn trigger_parameter_hints() -> lsp_types::Command { lsp_types::Command { title: "triggerParameterHints".into(), - command: "editor.action.triggerParameterHints".into(), + command: "rust-analyzer.triggerParameterHints".into(), arguments: None, } } @@ -1420,7 +1431,7 @@ fn main() { let line_index = LineIndex { index: Arc::new(ide::LineIndex::new(text)), endings: LineEndings::Unix, - encoding: PositionEncoding::Utf16, + encoding: PositionEncoding::Utf8, }; let converted: Vec<lsp_types::FoldingRange> = folds.into_iter().map(|it| folding_range(text, &line_index, true, it)).collect(); |