diff options
Diffstat (limited to 'cli/lsp/tsc.rs')
-rw-r--r-- | cli/lsp/tsc.rs | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/cli/lsp/tsc.rs b/cli/lsp/tsc.rs index 128a2ba00..38f291d03 100644 --- a/cli/lsp/tsc.rs +++ b/cli/lsp/tsc.rs @@ -6,6 +6,8 @@ use super::analysis::ResolvedDependencyErr; use super::config; use super::language_server; use super::language_server::StateSnapshot; +use super::semantic_tokens::SemanticTokensBuilder; +use super::semantic_tokens::TsTokenEncodingConsts; use super::text; use super::text::LineIndex; @@ -888,6 +890,56 @@ impl FileTextChanges { #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase")] +pub struct Classifications { + spans: Vec<u32>, +} + +impl Classifications { + pub fn to_semantic_tokens( + &self, + line_index: &LineIndex, + ) -> lsp::SemanticTokens { + let token_count = self.spans.len() / 3; + let mut builder = SemanticTokensBuilder::new(); + for i in 0..token_count { + let src_offset = 3 * i; + let offset = self.spans[src_offset]; + let length = self.spans[src_offset + 1]; + let ts_classification = self.spans[src_offset + 2]; + + let token_type = + Classifications::get_token_type_from_classification(ts_classification); + let token_modifiers = + Classifications::get_token_modifier_from_classification( + ts_classification, + ); + + let start_pos = line_index.position_tsc(offset.into()); + let end_pos = line_index.position_tsc(TextSize::from(offset + length)); + + // start_pos.line == end_pos.line is always true as there are no multiline tokens + builder.push( + start_pos.line, + start_pos.character, + end_pos.character - start_pos.character, + token_type, + token_modifiers, + ); + } + builder.build(None) + } + + fn get_token_type_from_classification(ts_classification: u32) -> u32 { + (ts_classification >> (TsTokenEncodingConsts::TypeOffset as u32)) - 1 + } + + fn get_token_modifier_from_classification(ts_classification: u32) -> u32 { + ts_classification & (TsTokenEncodingConsts::ModifierMask as u32) + } +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] pub struct CodeAction { description: String, changes: Vec<FileTextChanges>, @@ -2150,6 +2202,8 @@ pub enum RequestMethod { GetDiagnostics(Vec<ModuleSpecifier>), /// Return document highlights at position. GetDocumentHighlights((ModuleSpecifier, u32, Vec<ModuleSpecifier>)), + /// Get semantic highlights information for a particular file. + GetEncodedSemanticClassifications((ModuleSpecifier, TextSpan)), /// Get implementation information for a specific position. GetImplementation((ModuleSpecifier, u32)), /// Get a "navigation tree" for a specifier. @@ -2259,6 +2313,14 @@ impl RequestMethod { "position": position, "filesToSearch": files_to_search, }), + RequestMethod::GetEncodedSemanticClassifications((specifier, span)) => { + json!({ + "id": id, + "method": "getEncodedSemanticClassifications", + "specifier": specifier, + "span": span, + }) + } RequestMethod::GetImplementation((specifier, position)) => json!({ "id": id, "method": "getImplementation", |