[clang-tools-extra] r368568 - [clangd] Added the vscode SemanticHighlighting feature code but did not enable it in the client.

Johan Vikstrom via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 12 06:33:43 PDT 2019


Author: jvikstrom
Date: Mon Aug 12 06:33:43 2019
New Revision: 368568

URL: http://llvm.org/viewvc/llvm-project?rev=368568&view=rev
Log:
[clangd] Added the vscode SemanticHighlighting feature code but did not enable it in the client.

Summary: Added the code for the StaticFeature that must be registered to the client. Also decoding the notification data into objects. Did not register it to the client yet.

Reviewers: hokein, ilya-biryukov

Subscribers: MaskRay, jkorous, arphaman, kadircet, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D65998

Modified:
    clang-tools-extra/trunk/clangd/clients/clangd-vscode/package.json
    clang-tools-extra/trunk/clangd/clients/clangd-vscode/src/semantic-highlighting.ts
    clang-tools-extra/trunk/clangd/clients/clangd-vscode/test/semantic-highlighting.test.ts

Modified: clang-tools-extra/trunk/clangd/clients/clangd-vscode/package.json
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/clients/clangd-vscode/package.json?rev=368568&r1=368567&r2=368568&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/clients/clangd-vscode/package.json (original)
+++ clang-tools-extra/trunk/clangd/clients/clangd-vscode/package.json Mon Aug 12 06:33:43 2019
@@ -38,7 +38,8 @@
     "dependencies": {
         "jsonc-parser": "^2.1.0",
         "vscode-languageclient": "^5.3.0-next.6",
-        "vscode-languageserver": "^5.3.0-next.6"
+        "vscode-languageserver": "^5.3.0-next.6",
+        "vscode-languageserver-types": "^3.14.0"
     },
     "devDependencies": {
         "@types/mocha": "^2.2.32",

Modified: clang-tools-extra/trunk/clangd/clients/clangd-vscode/src/semantic-highlighting.ts
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/clients/clangd-vscode/src/semantic-highlighting.ts?rev=368568&r1=368567&r2=368568&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/clients/clangd-vscode/src/semantic-highlighting.ts (original)
+++ clang-tools-extra/trunk/clangd/clients/clangd-vscode/src/semantic-highlighting.ts Mon Aug 12 06:33:43 2019
@@ -2,6 +2,95 @@ import * as fs from 'fs';
 import * as jsonc from "jsonc-parser";
 import * as path from 'path';
 import * as vscode from 'vscode';
+import * as vscodelc from 'vscode-languageclient';
+import * as vscodelct from 'vscode-languageserver-types';
+
+// Parameters for the semantic highlighting (server-side) push notification.
+// Mirrors the structure in the semantic highlighting proposal for LSP.
+interface SemanticHighlightingParams {
+  // The text document that has to be decorated with the semantic highlighting
+  // information.
+  textDocument: vscodelct.VersionedTextDocumentIdentifier;
+  // An array of semantic highlighting information.
+  lines: SemanticHighlightingInformation[];
+}
+// Contains the highlighting information for a specified line. Mirrors the
+// structure in the semantic highlighting proposal for LSP.
+interface SemanticHighlightingInformation {
+  // The zero-based line position in the text document.
+  line: number;
+  // A base64 encoded string representing every single highlighted characters
+  // with its start position, length and the "lookup table" index of of the
+  // semantic highlighting Text Mate scopes.
+  tokens?: string;
+}
+
+// A SemanticHighlightingToken decoded from the base64 data sent by clangd.
+interface SemanticHighlightingToken {
+  // Start column for this token.
+  character: number;
+  // Length of the token.
+  length: number;
+  // The TextMate scope index to the clangd scope lookup table.
+  scopeIndex: number;
+}
+
+// Language server push notification providing the semantic highlighting
+// information for a text document.
+export const NotificationType =
+    new vscodelc.NotificationType<SemanticHighlightingParams, void>(
+        'textDocument/semanticHighlighting');
+
+// The feature that should be registered in the vscode lsp for enabling
+// experimental semantic highlighting.
+export class SemanticHighlightingFeature implements vscodelc.StaticFeature {
+  // The TextMate scope lookup table. A token with scope index i has the scopes
+  // on index i in the lookup table.
+  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) {}
+}
+
+// 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 scopeIndex = lenKind & scopeMask;
+    const len = lenKind >>> lenShift;
+    retTokens.push({character : start, scopeIndex : scopeIndex, length : len});
+  }
+
+  return retTokens;
+}
 
 // A rule for how to color TextMate scopes.
 interface TokenColorRule {

Modified: clang-tools-extra/trunk/clangd/clients/clangd-vscode/test/semantic-highlighting.test.ts
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/clients/clangd-vscode/test/semantic-highlighting.test.ts?rev=368568&r1=368567&r2=368568&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/clients/clangd-vscode/test/semantic-highlighting.test.ts (original)
+++ clang-tools-extra/trunk/clangd/clients/clangd-vscode/test/semantic-highlighting.test.ts Mon Aug 12 06:33:43 2019
@@ -3,7 +3,7 @@ import * as path from 'path';
 
 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');
@@ -11,8 +11,28 @@ suite('TextMate Tests', () => {
     const getScopeRule = (scope: string) =>
         scopeColorRules.find((v) => v.scope === scope);
     assert.equal(scopeColorRules.length, 3);
-    assert.deepEqual(getScopeRule('a'), {scope : 'a', textColor : '#fff'});
-    assert.deepEqual(getScopeRule('b'), {scope : 'b', textColor : '#000'});
-    assert.deepEqual(getScopeRule('c'), {scope : 'c', textColor : '#bcd'});
+    assert.deepEqual(getScopeRule('a'), {scope : 'a', foreground : '#fff'});
+    assert.deepEqual(getScopeRule('b'), {scope : 'b', foreground : '#000'});
+    assert.deepEqual(getScopeRule('c'), {scope : 'c', foreground : '#bcd'});
+  });
+  test('Decodes tokens correctly', () => {
+    const testCases: string[] = [
+      'AAAAAAABAAA=', 'AAAAAAADAAkAAAAEAAEAAA==',
+      'AAAAAAADAAkAAAAEAAEAAAAAAAoAAQAA'
+    ];
+    const expected = [
+      [ {character : 0, scopeIndex : 0, length : 1} ],
+      [
+        {character : 0, scopeIndex : 9, length : 3},
+        {character : 4, scopeIndex : 0, length : 1}
+      ],
+      [
+        {character : 0, scopeIndex : 9, length : 3},
+        {character : 4, scopeIndex : 0, length : 1},
+        {character : 10, scopeIndex : 0, length : 1}
+      ]
+    ];
+    testCases.forEach((testCase, i) => assert.deepEqual(
+                          TM.decodeTokens(testCase), expected[i]));
   });
 });




More information about the cfe-commits mailing list