jvikstrom updated this revision to Diff 214364.
jvikstrom marked 4 inline comments as done.
jvikstrom added a comment.

Address comments.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D65998/new/

https://reviews.llvm.org/D65998

Files:
  clang-tools-extra/clangd/clients/clangd-vscode/src/semantic-highlighting.ts
  
clang-tools-extra/clangd/clients/clangd-vscode/test/semantic-highlighting.test.ts

Index: clang-tools-extra/clangd/clients/clangd-vscode/test/semantic-highlighting.test.ts
===================================================================
--- clang-tools-extra/clangd/clients/clangd-vscode/test/semantic-highlighting.test.ts
+++ clang-tools-extra/clangd/clients/clangd-vscode/test/semantic-highlighting.test.ts
@@ -3,7 +3,7 @@
 
 import * as TM from '../src/semantic-highlighting';
 
-suite('TextMate Tests', () => {
+suite('SemanticHighlighting Tests', () => {
   test('Parses arrays of textmate themes.', async () => {
     const themePath =
         path.join(__dirname, '../../test/assets/includeTheme.jsonc');
@@ -15,4 +15,24 @@
     assert.deepEqual(getScopeRule('b'), {scope : 'b', textColor : '#000'});
     assert.deepEqual(getScopeRule('c'), {scope : 'c', textColor : '#bcd'});
   });
+  test('Decodes tokens correctly', () => {
+    const testCases: string[] = [
+      'AAAAAAABAAA=', 'AAAAAAADAAkAAAAEAAEAAA==',
+      'AAAAAAADAAkAAAAEAAEAAAAAAAoAAQAA'
+    ];
+    const expected = [
+      [ {character : 0, scope : 0, length : 1} ],
+      [
+        {character : 0, scope : 9, length : 3},
+        {character : 4, scope : 0, length : 1}
+      ],
+      [
+        {character : 0, scope : 9, length : 3},
+        {character : 4, scope : 0, length : 1},
+        {character : 10, scope : 0, length : 1}
+      ]
+    ];
+    testCases.forEach((testCase, i) => assert.deepEqual(
+                          TM.decodeTokens(testCase), expected[i]));
+  });
 });
Index: clang-tools-extra/clangd/clients/clangd-vscode/src/semantic-highlighting.ts
===================================================================
--- clang-tools-extra/clangd/clients/clangd-vscode/src/semantic-highlighting.ts
+++ clang-tools-extra/clangd/clients/clangd-vscode/src/semantic-highlighting.ts
@@ -2,6 +2,89 @@
 import * as jsonc from "jsonc-parser";
 import * as path from 'path';
 import * as vscode from 'vscode';
+import * as vscodelc from 'vscode-languageclient';
+
+// The information clangd sends when highlightings should be updated.
+interface SemanticHighlightingParams {
+  // The information about the text document where these highlightings should be
+  // applied.
+  textDocument: {uri: string;};
+  // All the lines of highlightings that should be applied.
+  lines: [ {
+    line: number;
+    tokens: string;
+  } ];
+}
+// A single SemanticHighlightingToken that clangd sent.
+interface SemanticHighlightingToken {
+  // Start column for this token.
+  character: number;
+  // The TextMate scope index to the clangd scopes.
+  scope: number;
+  length: number;
+}
+// All highlightings for line.
+interface SemanticHighlightingInformation {
+  line: number;
+  tokens: SemanticHighlightingToken[];
+}
+
+export const NotificationType = new vscodelc.NotificationType<{}, void>(
+    'textDocument/semanticHighlighting');
+
+// The feature that should be registered in the vscode lsp for enabling
+// experimental semantic highlighting.
+export class SemanticHighlightingFeature implements vscodelc.StaticFeature {
+  scopeLookupTable: string[][];
+  fillClientCapabilities(capabilities: vscodelc.ClientCapabilities) {
+    // Extend the ClientCapabilities type and add semantic highlighting
+    // capability to the object.
+    const textDocumentCapabilities: vscodelc.TextDocumentClientCapabilities&
+        {semanticHighlightingCapabilities?: {semanticHighlighting : boolean}} =
+        capabilities.textDocument;
+    textDocumentCapabilities.semanticHighlightingCapabilities = {
+      semanticHighlighting : true,
+    };
+  }
+
+  initialize(capabilities: vscodelc.ServerCapabilities,
+             documentSelector: vscodelc.DocumentSelector|undefined) {
+    // The semantic highlighting capability information is in the capabilities
+    // object but to access the data we must first extend the ServerCapabilities
+    // type.
+    const serverCapabilities: vscodelc.ServerCapabilities&
+        {semanticHighlighting?: {scopes : string[][]}} = capabilities;
+    if (!serverCapabilities.semanticHighlighting)
+      return;
+    this.scopeLookupTable = serverCapabilities.semanticHighlighting.scopes;
+  }
+
+  handleNotification(params: SemanticHighlightingParams) {
+    const tokenLines =
+        params.lines.map((line): SemanticHighlightingInformation => {
+          return { line: line.line, tokens: decodeTokens(line.tokens), }
+        });
+  }
+}
+
+// Converts a string of base64 encoded tokens into the corresponding array of
+// HighlightingTokens.
+export function decodeTokens(tokens: string): SemanticHighlightingToken[] {
+  const scopeMask = 0xFFFF;
+  const lenShift = 0x10;
+  const uint32Size = 4;
+  const buf = Buffer.from(tokens, 'base64');
+  const retTokens = [];
+  for (let i = 0, end = buf.length / uint32Size; i < end; i += 2) {
+    const start = buf.readUInt32BE(i * uint32Size);
+    const lenKind = buf.readUInt32BE((i + 1) * uint32Size);
+    const scope = lenKind & scopeMask;
+    const len = lenKind >>> lenShift;
+    retTokens.push({character : start, scope : scope, length : len});
+  }
+
+  return retTokens;
+}
 
 // A rule for how to color TextMate scopes.
 interface TokenColorRule {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to