[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