summaryrefslogtreecommitdiff
path: root/cli/lsp/tsc.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/lsp/tsc.rs')
-rw-r--r--cli/lsp/tsc.rs62
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",