From 4f9fe856a25ab29345b90e7725509e9ee38a37be Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:19:41 +0200 Subject: Adding upstream version 1.69.0+dfsg1. Signed-off-by: Daniel Baumann --- vendor/lsp-types/src/semantic_tokens.rs | 1472 +++++++++++++++---------------- 1 file changed, 733 insertions(+), 739 deletions(-) (limited to 'vendor/lsp-types/src/semantic_tokens.rs') diff --git a/vendor/lsp-types/src/semantic_tokens.rs b/vendor/lsp-types/src/semantic_tokens.rs index f1b6d53d2..0b881850c 100644 --- a/vendor/lsp-types/src/semantic_tokens.rs +++ b/vendor/lsp-types/src/semantic_tokens.rs @@ -1,739 +1,733 @@ -use std::borrow::Cow; - -use serde::ser::SerializeSeq; -use serde::{Deserialize, Serialize}; - -use crate::{ - PartialResultParams, Range, StaticRegistrationOptions, TextDocumentIdentifier, - TextDocumentRegistrationOptions, WorkDoneProgressOptions, WorkDoneProgressParams, -}; -/// A set of predefined token types. This set is not fixed -/// and clients can specify additional token types via the -/// corresponding client capabilities. -/// since @3.16.0 -#[derive(Debug, Eq, PartialEq, Hash, PartialOrd, Clone, Deserialize, Serialize)] -pub struct SemanticTokenType(Cow<'static, str>); - -impl SemanticTokenType { - pub const NAMESPACE: SemanticTokenType = SemanticTokenType::new("namespace"); - pub const TYPE: SemanticTokenType = SemanticTokenType::new("type"); - pub const CLASS: SemanticTokenType = SemanticTokenType::new("class"); - pub const ENUM: SemanticTokenType = SemanticTokenType::new("enum"); - pub const INTERFACE: SemanticTokenType = SemanticTokenType::new("interface"); - pub const STRUCT: SemanticTokenType = SemanticTokenType::new("struct"); - pub const TYPE_PARAMETER: SemanticTokenType = SemanticTokenType::new("typeParameter"); - pub const PARAMETER: SemanticTokenType = SemanticTokenType::new("parameter"); - pub const VARIABLE: SemanticTokenType = SemanticTokenType::new("variable"); - pub const PROPERTY: SemanticTokenType = SemanticTokenType::new("property"); - pub const ENUM_MEMBER: SemanticTokenType = SemanticTokenType::new("enumMember"); - pub const EVENT: SemanticTokenType = SemanticTokenType::new("event"); - pub const FUNCTION: SemanticTokenType = SemanticTokenType::new("function"); - pub const METHOD: SemanticTokenType = SemanticTokenType::new("method"); - pub const MACRO: SemanticTokenType = SemanticTokenType::new("macro"); - pub const KEYWORD: SemanticTokenType = SemanticTokenType::new("keyword"); - pub const MODIFIER: SemanticTokenType = SemanticTokenType::new("modifier"); - pub const COMMENT: SemanticTokenType = SemanticTokenType::new("comment"); - pub const STRING: SemanticTokenType = SemanticTokenType::new("string"); - pub const NUMBER: SemanticTokenType = SemanticTokenType::new("number"); - pub const REGEXP: SemanticTokenType = SemanticTokenType::new("regexp"); - pub const OPERATOR: SemanticTokenType = SemanticTokenType::new("operator"); - - /// since @3.17.0 - #[cfg(feature = "proposed")] - pub const DECORATOR: SemanticTokenType = SemanticTokenType::new("decorator"); - - pub const fn new(tag: &'static str) -> Self { - SemanticTokenType(Cow::Borrowed(tag)) - } - - pub fn as_str(&self) -> &str { - &self.0 - } -} - -impl From for SemanticTokenType { - fn from(from: String) -> Self { - SemanticTokenType(Cow::from(from)) - } -} - -impl From<&'static str> for SemanticTokenType { - fn from(from: &'static str) -> Self { - SemanticTokenType::new(from) - } -} - -/// A set of predefined token modifiers. This set is not fixed -/// and clients can specify additional token types via the -/// corresponding client capabilities. -/// -/// @since 3.16.0 -#[derive(Debug, Eq, PartialEq, Hash, PartialOrd, Clone, Deserialize, Serialize)] -pub struct SemanticTokenModifier(Cow<'static, str>); - -impl SemanticTokenModifier { - pub const DECLARATION: SemanticTokenModifier = SemanticTokenModifier::new("declaration"); - pub const DEFINITION: SemanticTokenModifier = SemanticTokenModifier::new("definition"); - pub const READONLY: SemanticTokenModifier = SemanticTokenModifier::new("readonly"); - pub const STATIC: SemanticTokenModifier = SemanticTokenModifier::new("static"); - pub const DEPRECATED: SemanticTokenModifier = SemanticTokenModifier::new("deprecated"); - pub const ABSTRACT: SemanticTokenModifier = SemanticTokenModifier::new("abstract"); - pub const ASYNC: SemanticTokenModifier = SemanticTokenModifier::new("async"); - pub const MODIFICATION: SemanticTokenModifier = SemanticTokenModifier::new("modification"); - pub const DOCUMENTATION: SemanticTokenModifier = SemanticTokenModifier::new("documentation"); - pub const DEFAULT_LIBRARY: SemanticTokenModifier = SemanticTokenModifier::new("defaultLibrary"); - - pub const fn new(tag: &'static str) -> Self { - SemanticTokenModifier(Cow::Borrowed(tag)) - } - - pub fn as_str(&self) -> &str { - &self.0 - } -} - -impl From for SemanticTokenModifier { - fn from(from: String) -> Self { - SemanticTokenModifier(Cow::from(from)) - } -} - -impl From<&'static str> for SemanticTokenModifier { - fn from(from: &'static str) -> Self { - SemanticTokenModifier::new(from) - } -} - -#[derive(Debug, Eq, PartialEq, Hash, PartialOrd, Clone, Deserialize, Serialize)] -pub struct TokenFormat(Cow<'static, str>); - -impl TokenFormat { - pub const RELATIVE: TokenFormat = TokenFormat::new("relative"); - - pub const fn new(tag: &'static str) -> Self { - TokenFormat(Cow::Borrowed(tag)) - } - - pub fn as_str(&self) -> &str { - &self.0 - } -} - -impl From for TokenFormat { - fn from(from: String) -> Self { - TokenFormat(Cow::from(from)) - } -} - -impl From<&'static str> for TokenFormat { - fn from(from: &'static str) -> Self { - TokenFormat::new(from) - } -} - -/// @since 3.16.0 -#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct SemanticTokensLegend { - /// The token types a server uses. - pub token_types: Vec, - - /// The token modifiers a server uses. - pub token_modifiers: Vec, -} - -/// The actual tokens. For a detailed description about how the data is -/// structured please see -/// -#[derive(Debug, Eq, PartialEq, Copy, Clone, Default)] -pub struct SemanticToken { - pub delta_line: u32, - pub delta_start: u32, - pub length: u32, - pub token_type: u32, - pub token_modifiers_bitset: u32, -} - -impl SemanticToken { - fn deserialize_tokens<'de, D>(deserializer: D) -> Result, D::Error> - where - D: serde::Deserializer<'de>, - { - let data = Vec::::deserialize(deserializer)?; - let chunks = data.chunks_exact(5); - - if !chunks.remainder().is_empty() { - return Result::Err(serde::de::Error::custom("Length is not divisible by 5")); - } - - Result::Ok( - chunks - .map(|chunk| SemanticToken { - delta_line: chunk[0], - delta_start: chunk[1], - length: chunk[2], - token_type: chunk[3], - token_modifiers_bitset: chunk[4], - }) - .collect(), - ) - } - - fn serialize_tokens(tokens: &[SemanticToken], serializer: S) -> Result - where - S: serde::Serializer, - { - let mut seq = serializer.serialize_seq(Some(tokens.len() * 5))?; - for token in tokens.iter() { - seq.serialize_element(&token.delta_line)?; - seq.serialize_element(&token.delta_start)?; - seq.serialize_element(&token.length)?; - seq.serialize_element(&token.token_type)?; - seq.serialize_element(&token.token_modifiers_bitset)?; - } - seq.end() - } - - fn deserialize_tokens_opt<'de, D>( - deserializer: D, - ) -> Result>, D::Error> - where - D: serde::Deserializer<'de>, - { - #[derive(Deserialize)] - #[serde(transparent)] - struct Wrapper { - #[serde(deserialize_with = "SemanticToken::deserialize_tokens")] - tokens: Vec, - } - - Ok(Option::::deserialize(deserializer)?.map(|wrapper| wrapper.tokens)) - } - - fn serialize_tokens_opt( - data: &Option>, - serializer: S, - ) -> Result - where - S: serde::Serializer, - { - #[derive(Serialize)] - #[serde(transparent)] - struct Wrapper { - #[serde(serialize_with = "SemanticToken::serialize_tokens")] - tokens: Vec, - } - - let opt = data.as_ref().map(|t| Wrapper { tokens: t.to_vec() }); - - opt.serialize(serializer) - } -} - -/// @since 3.16.0 -#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct SemanticTokens { - /// An optional result id. If provided and clients support delta updating - /// the client will include the result id in the next semantic token request. - /// A server can then instead of computing all semantic tokens again simply - /// send a delta. - #[serde(skip_serializing_if = "Option::is_none")] - pub result_id: Option, - - /// The actual tokens. For a detailed description about how the data is - /// structured please see - /// - #[serde( - deserialize_with = "SemanticToken::deserialize_tokens", - serialize_with = "SemanticToken::serialize_tokens" - )] - pub data: Vec, -} - -/// @since 3.16.0 -#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct SemanticTokensPartialResult { - #[serde( - deserialize_with = "SemanticToken::deserialize_tokens", - serialize_with = "SemanticToken::serialize_tokens" - )] - pub data: Vec, -} - -#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] -#[serde(rename_all = "camelCase")] -#[serde(untagged)] -pub enum SemanticTokensResult { - Tokens(SemanticTokens), - Partial(SemanticTokensPartialResult), -} - -impl From for SemanticTokensResult { - fn from(from: SemanticTokens) -> Self { - SemanticTokensResult::Tokens(from) - } -} - -impl From for SemanticTokensResult { - fn from(from: SemanticTokensPartialResult) -> Self { - SemanticTokensResult::Partial(from) - } -} - -/// @since 3.16.0 -#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct SemanticTokensEdit { - pub start: u32, - pub delete_count: u32, - - #[serde( - default, - skip_serializing_if = "Option::is_none", - deserialize_with = "SemanticToken::deserialize_tokens_opt", - serialize_with = "SemanticToken::serialize_tokens_opt" - )] - pub data: Option>, -} - -#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] -#[serde(rename_all = "camelCase")] -#[serde(untagged)] -pub enum SemanticTokensFullDeltaResult { - Tokens(SemanticTokens), - TokensDelta(SemanticTokensDelta), - PartialTokensDelta { edits: Vec }, -} - -impl From for SemanticTokensFullDeltaResult { - fn from(from: SemanticTokens) -> Self { - SemanticTokensFullDeltaResult::Tokens(from) - } -} - -impl From for SemanticTokensFullDeltaResult { - fn from(from: SemanticTokensDelta) -> Self { - SemanticTokensFullDeltaResult::TokensDelta(from) - } -} - -/// @since 3.16.0 -#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct SemanticTokensDelta { - #[serde(skip_serializing_if = "Option::is_none")] - pub result_id: Option, - /// For a detailed description how these edits are structured please see - /// - pub edits: Vec, -} - -/// Capabilities specific to the `textDocument/semanticTokens/*` requests. -/// -/// @since 3.16.0 -#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct SemanticTokensClientCapabilities { - /// Whether implementation supports dynamic registration. If this is set to `true` - /// the client supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)` - /// return value for the corresponding server capability as well. - #[serde(skip_serializing_if = "Option::is_none")] - pub dynamic_registration: Option, - - /// Which requests the client supports and might send to the server - /// depending on the server's capability. Please note that clients might not - /// show semantic tokens or degrade some of the user experience if a range - /// or full request is advertised by the client but not provided by the - /// server. If for example the client capability `requests.full` and - /// `request.range` are both set to true but the server only provides a - /// range provider the client might not render a minimap correctly or might - /// even decide to not show any semantic tokens at all. - pub requests: SemanticTokensClientCapabilitiesRequests, - - /// The token types that the client supports. - pub token_types: Vec, - - /// The token modifiers that the client supports. - pub token_modifiers: Vec, - - /// The token formats the clients supports. - pub formats: Vec, - - /// Whether the client supports tokens that can overlap each other. - #[serde(skip_serializing_if = "Option::is_none")] - pub overlapping_token_support: Option, - - /// Whether the client supports tokens that can span multiple lines. - #[serde(skip_serializing_if = "Option::is_none")] - pub multiline_token_support: Option, - - /// Whether the client allows the server to actively cancel a - /// semantic token request, e.g. supports returning - /// ErrorCodes.ServerCancelled. If a server does the client - /// needs to retrigger the request. - /// - /// since @3.17.0 - #[cfg(feature = "proposed")] - #[serde(skip_serializing_if = "Option::is_none")] - pub server_cancel_support: Option, - - - /// Whether the client uses semantic tokens to augment existing - /// syntax tokens. If set to `true` client side created syntax - /// tokens and semantic tokens are both used for colorization. If - /// set to `false` the client only uses the returned semantic tokens - /// for colorization. - /// - /// If the value is `undefined` then the client behavior is not - /// specified. - /// - /// @since 3.17.0 - #[cfg(feature = "proposed")] - #[serde(skip_serializing_if = "Option::is_none")] - pub augments_syntax_tokens: Option, -} - -#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct SemanticTokensClientCapabilitiesRequests { - /// The client will send the `textDocument/semanticTokens/range` request if the server provides a corresponding handler. - #[serde(skip_serializing_if = "Option::is_none")] - pub range: Option, - - /// The client will send the `textDocument/semanticTokens/full` request if the server provides a corresponding handler. - #[serde(skip_serializing_if = "Option::is_none")] - pub full: Option, -} - -#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] -#[serde(rename_all = "camelCase")] -#[serde(untagged)] -pub enum SemanticTokensFullOptions { - Bool(bool), - Delta { - /// The client will send the `textDocument/semanticTokens/full/delta` request if the server provides a corresponding handler. - /// The server supports deltas for full documents. - #[serde(skip_serializing_if = "Option::is_none")] - delta: Option, - }, -} - -/// @since 3.16.0 -#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct SemanticTokensOptions { - #[serde(flatten)] - pub work_done_progress_options: WorkDoneProgressOptions, - - /// The legend used by the server - pub legend: SemanticTokensLegend, - - /// Server supports providing semantic tokens for a sepcific range - /// of a document. - #[serde(skip_serializing_if = "Option::is_none")] - pub range: Option, - - /// Server supports providing semantic tokens for a full document. - #[serde(skip_serializing_if = "Option::is_none")] - pub full: Option, -} - -#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct SemanticTokensRegistrationOptions { - #[serde(flatten)] - pub text_document_registration_options: TextDocumentRegistrationOptions, - - #[serde(flatten)] - pub semantic_tokens_options: SemanticTokensOptions, - - #[serde(flatten)] - pub static_registration_options: StaticRegistrationOptions, -} - -#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] -#[serde(rename_all = "camelCase")] -#[serde(untagged)] -pub enum SemanticTokensServerCapabilities { - SemanticTokensOptions(SemanticTokensOptions), - SemanticTokensRegistrationOptions(SemanticTokensRegistrationOptions), -} - -impl From for SemanticTokensServerCapabilities { - fn from(from: SemanticTokensOptions) -> Self { - SemanticTokensServerCapabilities::SemanticTokensOptions(from) - } -} - -impl From for SemanticTokensServerCapabilities { - fn from(from: SemanticTokensRegistrationOptions) -> Self { - SemanticTokensServerCapabilities::SemanticTokensRegistrationOptions(from) - } -} - -#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct SemanticTokensWorkspaceClientCapabilities { - /// Whether the client implementation supports a refresh request sent from - /// the server to the client. - /// - /// Note that this event is global and will force the client to refresh all - /// semantic tokens currently shown. It should be used with absolute care - /// and is useful for situation where a server for example detect a project - /// wide change that requires such a calculation. - pub refresh_support: Option, -} - -#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct SemanticTokensParams { - #[serde(flatten)] - pub work_done_progress_params: WorkDoneProgressParams, - - #[serde(flatten)] - pub partial_result_params: PartialResultParams, - - /// The text document. - pub text_document: TextDocumentIdentifier, -} - -#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct SemanticTokensDeltaParams { - #[serde(flatten)] - pub work_done_progress_params: WorkDoneProgressParams, - - #[serde(flatten)] - pub partial_result_params: PartialResultParams, - - /// The text document. - pub text_document: TextDocumentIdentifier, - - /// The result id of a previous response. The result Id can either point to a full response - /// or a delta response depending on what was recevied last. - pub previous_result_id: String, -} - -#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct SemanticTokensRangeParams { - #[serde(flatten)] - pub work_done_progress_params: WorkDoneProgressParams, - - #[serde(flatten)] - pub partial_result_params: PartialResultParams, - - /// The text document. - pub text_document: TextDocumentIdentifier, - - /// The range the semantic tokens are requested for. - pub range: Range, -} - -#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] -#[serde(rename_all = "camelCase")] -#[serde(untagged)] -pub enum SemanticTokensRangeResult { - Tokens(SemanticTokens), - Partial(SemanticTokensPartialResult), -} - -impl From for SemanticTokensRangeResult { - fn from(tokens: SemanticTokens) -> Self { - SemanticTokensRangeResult::Tokens(tokens) - } -} - -impl From for SemanticTokensRangeResult { - fn from(partial: SemanticTokensPartialResult) -> Self { - SemanticTokensRangeResult::Partial(partial) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::tests::{test_deserialization, test_serialization}; - - #[test] - fn test_semantic_tokens_support_serialization() { - test_serialization( - &SemanticTokens { - result_id: None, - data: vec![], - }, - r#"{"data":[]}"#, - ); - - test_serialization( - &SemanticTokens { - result_id: None, - data: vec![SemanticToken { - delta_line: 2, - delta_start: 5, - length: 3, - token_type: 0, - token_modifiers_bitset: 3, - }], - }, - r#"{"data":[2,5,3,0,3]}"#, - ); - - test_serialization( - &SemanticTokens { - result_id: None, - data: vec![ - SemanticToken { - delta_line: 2, - delta_start: 5, - length: 3, - token_type: 0, - token_modifiers_bitset: 3, - }, - SemanticToken { - delta_line: 0, - delta_start: 5, - length: 4, - token_type: 1, - token_modifiers_bitset: 0, - }, - ], - }, - r#"{"data":[2,5,3,0,3,0,5,4,1,0]}"#, - ); - } - - #[test] - fn test_semantic_tokens_support_deserialization() { - test_deserialization( - r#"{"data":[]}"#, - &SemanticTokens { - result_id: None, - data: vec![], - }, - ); - - test_deserialization( - r#"{"data":[2,5,3,0,3]}"#, - &SemanticTokens { - result_id: None, - data: vec![SemanticToken { - delta_line: 2, - delta_start: 5, - length: 3, - token_type: 0, - token_modifiers_bitset: 3, - }], - }, - ); - - test_deserialization( - r#"{"data":[2,5,3,0,3,0,5,4,1,0]}"#, - &SemanticTokens { - result_id: None, - data: vec![ - SemanticToken { - delta_line: 2, - delta_start: 5, - length: 3, - token_type: 0, - token_modifiers_bitset: 3, - }, - SemanticToken { - delta_line: 0, - delta_start: 5, - length: 4, - token_type: 1, - token_modifiers_bitset: 0, - }, - ], - }, - ); - } - - #[test] - #[should_panic] - fn test_semantic_tokens_support_deserialization_err() { - test_deserialization( - r#"{"data":[1]}"#, - &SemanticTokens { - result_id: None, - data: vec![], - }, - ); - } - - #[test] - fn test_semantic_tokens_edit_support_deserialization() { - test_deserialization( - r#"{"start":0,"deleteCount":1,"data":[2,5,3,0,3,0,5,4,1,0]}"#, - &SemanticTokensEdit { - start: 0, - delete_count: 1, - data: Some(vec![ - SemanticToken { - delta_line: 2, - delta_start: 5, - length: 3, - token_type: 0, - token_modifiers_bitset: 3, - }, - SemanticToken { - delta_line: 0, - delta_start: 5, - length: 4, - token_type: 1, - token_modifiers_bitset: 0, - }, - ]), - }, - ); - - test_deserialization( - r#"{"start":0,"deleteCount":1}"#, - &SemanticTokensEdit { - start: 0, - delete_count: 1, - data: None, - }, - ); - } - - #[test] - fn test_semantic_tokens_edit_support_serialization() { - test_serialization( - &SemanticTokensEdit { - start: 0, - delete_count: 1, - data: Some(vec![ - SemanticToken { - delta_line: 2, - delta_start: 5, - length: 3, - token_type: 0, - token_modifiers_bitset: 3, - }, - SemanticToken { - delta_line: 0, - delta_start: 5, - length: 4, - token_type: 1, - token_modifiers_bitset: 0, - }, - ]), - }, - r#"{"start":0,"deleteCount":1,"data":[2,5,3,0,3,0,5,4,1,0]}"#, - ); - - test_serialization( - &SemanticTokensEdit { - start: 0, - delete_count: 1, - data: None, - }, - r#"{"start":0,"deleteCount":1}"#, - ); - } -} +use std::borrow::Cow; + +use serde::ser::SerializeSeq; +use serde::{Deserialize, Serialize}; + +use crate::{ + PartialResultParams, Range, StaticRegistrationOptions, TextDocumentIdentifier, + TextDocumentRegistrationOptions, WorkDoneProgressOptions, WorkDoneProgressParams, +}; +/// A set of predefined token types. This set is not fixed +/// and clients can specify additional token types via the +/// corresponding client capabilities. +/// since @3.16.0 +#[derive(Debug, Eq, PartialEq, Hash, PartialOrd, Clone, Deserialize, Serialize)] +pub struct SemanticTokenType(Cow<'static, str>); + +impl SemanticTokenType { + pub const NAMESPACE: SemanticTokenType = SemanticTokenType::new("namespace"); + pub const TYPE: SemanticTokenType = SemanticTokenType::new("type"); + pub const CLASS: SemanticTokenType = SemanticTokenType::new("class"); + pub const ENUM: SemanticTokenType = SemanticTokenType::new("enum"); + pub const INTERFACE: SemanticTokenType = SemanticTokenType::new("interface"); + pub const STRUCT: SemanticTokenType = SemanticTokenType::new("struct"); + pub const TYPE_PARAMETER: SemanticTokenType = SemanticTokenType::new("typeParameter"); + pub const PARAMETER: SemanticTokenType = SemanticTokenType::new("parameter"); + pub const VARIABLE: SemanticTokenType = SemanticTokenType::new("variable"); + pub const PROPERTY: SemanticTokenType = SemanticTokenType::new("property"); + pub const ENUM_MEMBER: SemanticTokenType = SemanticTokenType::new("enumMember"); + pub const EVENT: SemanticTokenType = SemanticTokenType::new("event"); + pub const FUNCTION: SemanticTokenType = SemanticTokenType::new("function"); + pub const METHOD: SemanticTokenType = SemanticTokenType::new("method"); + pub const MACRO: SemanticTokenType = SemanticTokenType::new("macro"); + pub const KEYWORD: SemanticTokenType = SemanticTokenType::new("keyword"); + pub const MODIFIER: SemanticTokenType = SemanticTokenType::new("modifier"); + pub const COMMENT: SemanticTokenType = SemanticTokenType::new("comment"); + pub const STRING: SemanticTokenType = SemanticTokenType::new("string"); + pub const NUMBER: SemanticTokenType = SemanticTokenType::new("number"); + pub const REGEXP: SemanticTokenType = SemanticTokenType::new("regexp"); + pub const OPERATOR: SemanticTokenType = SemanticTokenType::new("operator"); + + /// since @3.17.0 + pub const DECORATOR: SemanticTokenType = SemanticTokenType::new("decorator"); + + pub const fn new(tag: &'static str) -> Self { + SemanticTokenType(Cow::Borrowed(tag)) + } + + pub fn as_str(&self) -> &str { + &self.0 + } +} + +impl From for SemanticTokenType { + fn from(from: String) -> Self { + SemanticTokenType(Cow::from(from)) + } +} + +impl From<&'static str> for SemanticTokenType { + fn from(from: &'static str) -> Self { + SemanticTokenType::new(from) + } +} + +/// A set of predefined token modifiers. This set is not fixed +/// and clients can specify additional token types via the +/// corresponding client capabilities. +/// +/// @since 3.16.0 +#[derive(Debug, Eq, PartialEq, Hash, PartialOrd, Clone, Deserialize, Serialize)] +pub struct SemanticTokenModifier(Cow<'static, str>); + +impl SemanticTokenModifier { + pub const DECLARATION: SemanticTokenModifier = SemanticTokenModifier::new("declaration"); + pub const DEFINITION: SemanticTokenModifier = SemanticTokenModifier::new("definition"); + pub const READONLY: SemanticTokenModifier = SemanticTokenModifier::new("readonly"); + pub const STATIC: SemanticTokenModifier = SemanticTokenModifier::new("static"); + pub const DEPRECATED: SemanticTokenModifier = SemanticTokenModifier::new("deprecated"); + pub const ABSTRACT: SemanticTokenModifier = SemanticTokenModifier::new("abstract"); + pub const ASYNC: SemanticTokenModifier = SemanticTokenModifier::new("async"); + pub const MODIFICATION: SemanticTokenModifier = SemanticTokenModifier::new("modification"); + pub const DOCUMENTATION: SemanticTokenModifier = SemanticTokenModifier::new("documentation"); + pub const DEFAULT_LIBRARY: SemanticTokenModifier = SemanticTokenModifier::new("defaultLibrary"); + + pub const fn new(tag: &'static str) -> Self { + SemanticTokenModifier(Cow::Borrowed(tag)) + } + + pub fn as_str(&self) -> &str { + &self.0 + } +} + +impl From for SemanticTokenModifier { + fn from(from: String) -> Self { + SemanticTokenModifier(Cow::from(from)) + } +} + +impl From<&'static str> for SemanticTokenModifier { + fn from(from: &'static str) -> Self { + SemanticTokenModifier::new(from) + } +} + +#[derive(Debug, Eq, PartialEq, Hash, PartialOrd, Clone, Deserialize, Serialize)] +pub struct TokenFormat(Cow<'static, str>); + +impl TokenFormat { + pub const RELATIVE: TokenFormat = TokenFormat::new("relative"); + + pub const fn new(tag: &'static str) -> Self { + TokenFormat(Cow::Borrowed(tag)) + } + + pub fn as_str(&self) -> &str { + &self.0 + } +} + +impl From for TokenFormat { + fn from(from: String) -> Self { + TokenFormat(Cow::from(from)) + } +} + +impl From<&'static str> for TokenFormat { + fn from(from: &'static str) -> Self { + TokenFormat::new(from) + } +} + +/// @since 3.16.0 +#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct SemanticTokensLegend { + /// The token types a server uses. + pub token_types: Vec, + + /// The token modifiers a server uses. + pub token_modifiers: Vec, +} + +/// The actual tokens. +#[derive(Debug, Eq, PartialEq, Copy, Clone, Default)] +pub struct SemanticToken { + pub delta_line: u32, + pub delta_start: u32, + pub length: u32, + pub token_type: u32, + pub token_modifiers_bitset: u32, +} + +impl SemanticToken { + fn deserialize_tokens<'de, D>(deserializer: D) -> Result, D::Error> + where + D: serde::Deserializer<'de>, + { + let data = Vec::::deserialize(deserializer)?; + let chunks = data.chunks_exact(5); + + if !chunks.remainder().is_empty() { + return Result::Err(serde::de::Error::custom("Length is not divisible by 5")); + } + + Result::Ok( + chunks + .map(|chunk| SemanticToken { + delta_line: chunk[0], + delta_start: chunk[1], + length: chunk[2], + token_type: chunk[3], + token_modifiers_bitset: chunk[4], + }) + .collect(), + ) + } + + fn serialize_tokens(tokens: &[SemanticToken], serializer: S) -> Result + where + S: serde::Serializer, + { + let mut seq = serializer.serialize_seq(Some(tokens.len() * 5))?; + for token in tokens.iter() { + seq.serialize_element(&token.delta_line)?; + seq.serialize_element(&token.delta_start)?; + seq.serialize_element(&token.length)?; + seq.serialize_element(&token.token_type)?; + seq.serialize_element(&token.token_modifiers_bitset)?; + } + seq.end() + } + + fn deserialize_tokens_opt<'de, D>( + deserializer: D, + ) -> Result>, D::Error> + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + #[serde(transparent)] + struct Wrapper { + #[serde(deserialize_with = "SemanticToken::deserialize_tokens")] + tokens: Vec, + } + + Ok(Option::::deserialize(deserializer)?.map(|wrapper| wrapper.tokens)) + } + + fn serialize_tokens_opt( + data: &Option>, + serializer: S, + ) -> Result + where + S: serde::Serializer, + { + #[derive(Serialize)] + #[serde(transparent)] + struct Wrapper { + #[serde(serialize_with = "SemanticToken::serialize_tokens")] + tokens: Vec, + } + + let opt = data.as_ref().map(|t| Wrapper { tokens: t.to_vec() }); + + opt.serialize(serializer) + } +} + +/// @since 3.16.0 +#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct SemanticTokens { + /// An optional result id. If provided and clients support delta updating + /// the client will include the result id in the next semantic token request. + /// A server can then instead of computing all semantic tokens again simply + /// send a delta. + #[serde(skip_serializing_if = "Option::is_none")] + pub result_id: Option, + + /// The actual tokens. For a detailed description about how the data is + /// structured please see + /// + #[serde( + deserialize_with = "SemanticToken::deserialize_tokens", + serialize_with = "SemanticToken::serialize_tokens" + )] + pub data: Vec, +} + +/// @since 3.16.0 +#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct SemanticTokensPartialResult { + #[serde( + deserialize_with = "SemanticToken::deserialize_tokens", + serialize_with = "SemanticToken::serialize_tokens" + )] + pub data: Vec, +} + +#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +#[serde(untagged)] +pub enum SemanticTokensResult { + Tokens(SemanticTokens), + Partial(SemanticTokensPartialResult), +} + +impl From for SemanticTokensResult { + fn from(from: SemanticTokens) -> Self { + SemanticTokensResult::Tokens(from) + } +} + +impl From for SemanticTokensResult { + fn from(from: SemanticTokensPartialResult) -> Self { + SemanticTokensResult::Partial(from) + } +} + +/// @since 3.16.0 +#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct SemanticTokensEdit { + pub start: u32, + pub delete_count: u32, + + #[serde( + default, + skip_serializing_if = "Option::is_none", + deserialize_with = "SemanticToken::deserialize_tokens_opt", + serialize_with = "SemanticToken::serialize_tokens_opt" + )] + pub data: Option>, +} + +#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +#[serde(untagged)] +pub enum SemanticTokensFullDeltaResult { + Tokens(SemanticTokens), + TokensDelta(SemanticTokensDelta), + PartialTokensDelta { edits: Vec }, +} + +impl From for SemanticTokensFullDeltaResult { + fn from(from: SemanticTokens) -> Self { + SemanticTokensFullDeltaResult::Tokens(from) + } +} + +impl From for SemanticTokensFullDeltaResult { + fn from(from: SemanticTokensDelta) -> Self { + SemanticTokensFullDeltaResult::TokensDelta(from) + } +} + +/// @since 3.16.0 +#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct SemanticTokensDelta { + #[serde(skip_serializing_if = "Option::is_none")] + pub result_id: Option, + /// For a detailed description how these edits are structured please see + /// + pub edits: Vec, +} + +/// Capabilities specific to the `textDocument/semanticTokens/*` requests. +/// +/// @since 3.16.0 +#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct SemanticTokensClientCapabilities { + /// Whether implementation supports dynamic registration. If this is set to `true` + /// the client supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)` + /// return value for the corresponding server capability as well. + #[serde(skip_serializing_if = "Option::is_none")] + pub dynamic_registration: Option, + + /// Which requests the client supports and might send to the server + /// depending on the server's capability. Please note that clients might not + /// show semantic tokens or degrade some of the user experience if a range + /// or full request is advertised by the client but not provided by the + /// server. If for example the client capability `requests.full` and + /// `request.range` are both set to true but the server only provides a + /// range provider the client might not render a minimap correctly or might + /// even decide to not show any semantic tokens at all. + pub requests: SemanticTokensClientCapabilitiesRequests, + + /// The token types that the client supports. + pub token_types: Vec, + + /// The token modifiers that the client supports. + pub token_modifiers: Vec, + + /// The token formats the clients supports. + pub formats: Vec, + + /// Whether the client supports tokens that can overlap each other. + #[serde(skip_serializing_if = "Option::is_none")] + pub overlapping_token_support: Option, + + /// Whether the client supports tokens that can span multiple lines. + #[serde(skip_serializing_if = "Option::is_none")] + pub multiline_token_support: Option, + + /// Whether the client allows the server to actively cancel a + /// semantic token request, e.g. supports returning + /// ErrorCodes.ServerCancelled. If a server does the client + /// needs to retrigger the request. + /// + /// since @3.17.0 + #[serde(skip_serializing_if = "Option::is_none")] + pub server_cancel_support: Option, + + /// Whether the client uses semantic tokens to augment existing + /// syntax tokens. If set to `true` client side created syntax + /// tokens and semantic tokens are both used for colorization. If + /// set to `false` the client only uses the returned semantic tokens + /// for colorization. + /// + /// If the value is `undefined` then the client behavior is not + /// specified. + /// + /// @since 3.17.0 + #[serde(skip_serializing_if = "Option::is_none")] + pub augments_syntax_tokens: Option, +} + +#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct SemanticTokensClientCapabilitiesRequests { + /// The client will send the `textDocument/semanticTokens/range` request if the server provides a corresponding handler. + #[serde(skip_serializing_if = "Option::is_none")] + pub range: Option, + + /// The client will send the `textDocument/semanticTokens/full` request if the server provides a corresponding handler. + #[serde(skip_serializing_if = "Option::is_none")] + pub full: Option, +} + +#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +#[serde(untagged)] +pub enum SemanticTokensFullOptions { + Bool(bool), + Delta { + /// The client will send the `textDocument/semanticTokens/full/delta` request if the server provides a corresponding handler. + /// The server supports deltas for full documents. + #[serde(skip_serializing_if = "Option::is_none")] + delta: Option, + }, +} + +/// @since 3.16.0 +#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct SemanticTokensOptions { + #[serde(flatten)] + pub work_done_progress_options: WorkDoneProgressOptions, + + /// The legend used by the server + pub legend: SemanticTokensLegend, + + /// Server supports providing semantic tokens for a sepcific range + /// of a document. + #[serde(skip_serializing_if = "Option::is_none")] + pub range: Option, + + /// Server supports providing semantic tokens for a full document. + #[serde(skip_serializing_if = "Option::is_none")] + pub full: Option, +} + +#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct SemanticTokensRegistrationOptions { + #[serde(flatten)] + pub text_document_registration_options: TextDocumentRegistrationOptions, + + #[serde(flatten)] + pub semantic_tokens_options: SemanticTokensOptions, + + #[serde(flatten)] + pub static_registration_options: StaticRegistrationOptions, +} + +#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +#[serde(untagged)] +pub enum SemanticTokensServerCapabilities { + SemanticTokensOptions(SemanticTokensOptions), + SemanticTokensRegistrationOptions(SemanticTokensRegistrationOptions), +} + +impl From for SemanticTokensServerCapabilities { + fn from(from: SemanticTokensOptions) -> Self { + SemanticTokensServerCapabilities::SemanticTokensOptions(from) + } +} + +impl From for SemanticTokensServerCapabilities { + fn from(from: SemanticTokensRegistrationOptions) -> Self { + SemanticTokensServerCapabilities::SemanticTokensRegistrationOptions(from) + } +} + +#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct SemanticTokensWorkspaceClientCapabilities { + /// Whether the client implementation supports a refresh request sent from + /// the server to the client. + /// + /// Note that this event is global and will force the client to refresh all + /// semantic tokens currently shown. It should be used with absolute care + /// and is useful for situation where a server for example detect a project + /// wide change that requires such a calculation. + pub refresh_support: Option, +} + +#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct SemanticTokensParams { + #[serde(flatten)] + pub work_done_progress_params: WorkDoneProgressParams, + + #[serde(flatten)] + pub partial_result_params: PartialResultParams, + + /// The text document. + pub text_document: TextDocumentIdentifier, +} + +#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct SemanticTokensDeltaParams { + #[serde(flatten)] + pub work_done_progress_params: WorkDoneProgressParams, + + #[serde(flatten)] + pub partial_result_params: PartialResultParams, + + /// The text document. + pub text_document: TextDocumentIdentifier, + + /// The result id of a previous response. The result Id can either point to a full response + /// or a delta response depending on what was recevied last. + pub previous_result_id: String, +} + +#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct SemanticTokensRangeParams { + #[serde(flatten)] + pub work_done_progress_params: WorkDoneProgressParams, + + #[serde(flatten)] + pub partial_result_params: PartialResultParams, + + /// The text document. + pub text_document: TextDocumentIdentifier, + + /// The range the semantic tokens are requested for. + pub range: Range, +} + +#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +#[serde(untagged)] +pub enum SemanticTokensRangeResult { + Tokens(SemanticTokens), + Partial(SemanticTokensPartialResult), +} + +impl From for SemanticTokensRangeResult { + fn from(tokens: SemanticTokens) -> Self { + SemanticTokensRangeResult::Tokens(tokens) + } +} + +impl From for SemanticTokensRangeResult { + fn from(partial: SemanticTokensPartialResult) -> Self { + SemanticTokensRangeResult::Partial(partial) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::tests::{test_deserialization, test_serialization}; + + #[test] + fn test_semantic_tokens_support_serialization() { + test_serialization( + &SemanticTokens { + result_id: None, + data: vec![], + }, + r#"{"data":[]}"#, + ); + + test_serialization( + &SemanticTokens { + result_id: None, + data: vec![SemanticToken { + delta_line: 2, + delta_start: 5, + length: 3, + token_type: 0, + token_modifiers_bitset: 3, + }], + }, + r#"{"data":[2,5,3,0,3]}"#, + ); + + test_serialization( + &SemanticTokens { + result_id: None, + data: vec![ + SemanticToken { + delta_line: 2, + delta_start: 5, + length: 3, + token_type: 0, + token_modifiers_bitset: 3, + }, + SemanticToken { + delta_line: 0, + delta_start: 5, + length: 4, + token_type: 1, + token_modifiers_bitset: 0, + }, + ], + }, + r#"{"data":[2,5,3,0,3,0,5,4,1,0]}"#, + ); + } + + #[test] + fn test_semantic_tokens_support_deserialization() { + test_deserialization( + r#"{"data":[]}"#, + &SemanticTokens { + result_id: None, + data: vec![], + }, + ); + + test_deserialization( + r#"{"data":[2,5,3,0,3]}"#, + &SemanticTokens { + result_id: None, + data: vec![SemanticToken { + delta_line: 2, + delta_start: 5, + length: 3, + token_type: 0, + token_modifiers_bitset: 3, + }], + }, + ); + + test_deserialization( + r#"{"data":[2,5,3,0,3,0,5,4,1,0]}"#, + &SemanticTokens { + result_id: None, + data: vec![ + SemanticToken { + delta_line: 2, + delta_start: 5, + length: 3, + token_type: 0, + token_modifiers_bitset: 3, + }, + SemanticToken { + delta_line: 0, + delta_start: 5, + length: 4, + token_type: 1, + token_modifiers_bitset: 0, + }, + ], + }, + ); + } + + #[test] + #[should_panic] + fn test_semantic_tokens_support_deserialization_err() { + test_deserialization( + r#"{"data":[1]}"#, + &SemanticTokens { + result_id: None, + data: vec![], + }, + ); + } + + #[test] + fn test_semantic_tokens_edit_support_deserialization() { + test_deserialization( + r#"{"start":0,"deleteCount":1,"data":[2,5,3,0,3,0,5,4,1,0]}"#, + &SemanticTokensEdit { + start: 0, + delete_count: 1, + data: Some(vec![ + SemanticToken { + delta_line: 2, + delta_start: 5, + length: 3, + token_type: 0, + token_modifiers_bitset: 3, + }, + SemanticToken { + delta_line: 0, + delta_start: 5, + length: 4, + token_type: 1, + token_modifiers_bitset: 0, + }, + ]), + }, + ); + + test_deserialization( + r#"{"start":0,"deleteCount":1}"#, + &SemanticTokensEdit { + start: 0, + delete_count: 1, + data: None, + }, + ); + } + + #[test] + fn test_semantic_tokens_edit_support_serialization() { + test_serialization( + &SemanticTokensEdit { + start: 0, + delete_count: 1, + data: Some(vec![ + SemanticToken { + delta_line: 2, + delta_start: 5, + length: 3, + token_type: 0, + token_modifiers_bitset: 3, + }, + SemanticToken { + delta_line: 0, + delta_start: 5, + length: 4, + token_type: 1, + token_modifiers_bitset: 0, + }, + ]), + }, + r#"{"start":0,"deleteCount":1,"data":[2,5,3,0,3,0,5,4,1,0]}"#, + ); + + test_serialization( + &SemanticTokensEdit { + start: 0, + delete_count: 1, + data: None, + }, + r#"{"start":0,"deleteCount":1}"#, + ); + } +} -- cgit v1.2.3