diff options
Diffstat (limited to 'cli/lsp/tsc.rs')
-rw-r--r-- | cli/lsp/tsc.rs | 151 |
1 files changed, 139 insertions, 12 deletions
diff --git a/cli/lsp/tsc.rs b/cli/lsp/tsc.rs index ef57682f1..5dc7200b7 100644 --- a/cli/lsp/tsc.rs +++ b/cli/lsp/tsc.rs @@ -166,16 +166,12 @@ pub async fn get_asset( } } -fn display_parts_to_string( - maybe_parts: Option<Vec<SymbolDisplayPart>>, -) -> Option<String> { - maybe_parts.map(|parts| { - parts - .into_iter() - .map(|p| p.text) - .collect::<Vec<String>>() - .join("") - }) +fn display_parts_to_string(parts: Vec<SymbolDisplayPart>) -> String { + parts + .into_iter() + .map(|p| p.text) + .collect::<Vec<String>>() + .join("") } fn get_tag_body_text(tag: &JSDocTagInfo) -> Option<String> { @@ -433,7 +429,7 @@ impl QuickInfo { pub fn to_hover(&self, line_index: &LineIndex) -> lsp::Hover { let mut contents = Vec::<lsp::MarkedString>::new(); if let Some(display_string) = - display_parts_to_string(self.display_parts.clone()) + self.display_parts.clone().map(display_parts_to_string) { contents.push(lsp::MarkedString::from_language_code( "typescript".to_string(), @@ -441,7 +437,7 @@ impl QuickInfo { )); } if let Some(documentation) = - display_parts_to_string(self.documentation.clone()) + self.documentation.clone().map(display_parts_to_string) { contents.push(lsp::MarkedString::from_markdown(documentation)); } @@ -946,6 +942,91 @@ impl CompletionEntry { } } +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct SignatureHelpItems { + items: Vec<SignatureHelpItem>, + applicable_span: TextSpan, + selected_item_index: u32, + argument_index: u32, + argument_count: u32, +} + +impl SignatureHelpItems { + pub fn into_signature_help(self) -> lsp::SignatureHelp { + lsp::SignatureHelp { + signatures: self + .items + .into_iter() + .map(|item| item.into_signature_information()) + .collect(), + active_parameter: Some(self.argument_index), + active_signature: Some(self.selected_item_index), + } + } +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct SignatureHelpItem { + is_variadic: bool, + prefix_display_parts: Vec<SymbolDisplayPart>, + suffix_display_parts: Vec<SymbolDisplayPart>, + separator_display_parts: Vec<SymbolDisplayPart>, + parameters: Vec<SignatureHelpParameter>, + documentation: Vec<SymbolDisplayPart>, + tags: Vec<JSDocTagInfo>, +} + +impl SignatureHelpItem { + pub fn into_signature_information(self) -> lsp::SignatureInformation { + let prefix_text = display_parts_to_string(self.prefix_display_parts); + let params_text = self + .parameters + .iter() + .map(|param| display_parts_to_string(param.display_parts.clone())) + .collect::<Vec<String>>() + .join(", "); + let suffix_text = display_parts_to_string(self.suffix_display_parts); + lsp::SignatureInformation { + label: format!("{}{}{}", prefix_text, params_text, suffix_text), + documentation: Some(lsp::Documentation::String(display_parts_to_string( + self.documentation, + ))), + parameters: Some( + self + .parameters + .into_iter() + .map(|param| param.into_parameter_information()) + .collect(), + ), + active_parameter: None, + } + } +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct SignatureHelpParameter { + name: String, + documentation: Vec<SymbolDisplayPart>, + display_parts: Vec<SymbolDisplayPart>, + is_optional: bool, +} + +impl SignatureHelpParameter { + pub fn into_parameter_information(self) -> lsp::ParameterInformation { + lsp::ParameterInformation { + label: lsp::ParameterLabel::Simple(display_parts_to_string( + self.display_parts, + )), + documentation: Some(lsp::Documentation::String(display_parts_to_string( + self.documentation, + ))), + } + } +} + #[derive(Debug, Clone, Deserialize)] struct Response { id: usize, @@ -1361,6 +1442,41 @@ pub struct UserPreferences { pub provide_refactor_not_applicable_reason: Option<bool>, } +#[derive(Debug, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct SignatureHelpItemsOptions { + #[serde(skip_serializing_if = "Option::is_none")] + pub trigger_reason: Option<SignatureHelpTriggerReason>, +} + +#[derive(Debug, Serialize)] +pub enum SignatureHelpTriggerKind { + #[serde(rename = "characterTyped")] + CharacterTyped, + #[serde(rename = "invoked")] + Invoked, + #[serde(rename = "retrigger")] + Retrigger, +} + +impl From<lsp::SignatureHelpTriggerKind> for SignatureHelpTriggerKind { + fn from(kind: lsp::SignatureHelpTriggerKind) -> Self { + match kind { + lsp::SignatureHelpTriggerKind::Invoked => Self::Invoked, + lsp::SignatureHelpTriggerKind::TriggerCharacter => Self::CharacterTyped, + lsp::SignatureHelpTriggerKind::ContentChange => Self::Retrigger, + } + } +} + +#[derive(Debug, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct SignatureHelpTriggerReason { + pub kind: SignatureHelpTriggerKind, + #[serde(skip_serializing_if = "Option::is_none")] + pub trigger_character: Option<String>, +} + /// Methods that are supported by the Language Service in the compiler isolate. #[derive(Debug)] pub enum RequestMethod { @@ -1390,6 +1506,8 @@ pub enum RequestMethod { GetQuickInfo((ModuleSpecifier, u32)), /// Get document references for a specific position. GetReferences((ModuleSpecifier, u32)), + /// Get signature help items for a specific position. + GetSignatureHelpItems((ModuleSpecifier, u32, SignatureHelpItemsOptions)), /// Get the diagnostic codes that support some form of code fix. GetSupportedCodeFixes, } @@ -1497,6 +1615,15 @@ impl RequestMethod { "specifier": specifier, "position": position, }), + RequestMethod::GetSignatureHelpItems((specifier, position, options)) => { + json!({ + "id": id, + "method": "getSignatureHelpItems", + "specifier": specifier, + "position": position, + "options": options, + }) + } RequestMethod::GetSupportedCodeFixes => json!({ "id": id, "method": "getSupportedCodeFixes", |