jvikstrom created this revision. jvikstrom added reviewers: hokein, ilya-biryukov. Herald added subscribers: cfe-commits, kadircet, arphaman, jkorous, MaskRay. Herald added a project: clang. jvikstrom updated this revision to Diff 214334. jvikstrom added a comment.
Added comment to decodeTokens function. 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. Repository: rG LLVM Github Monorepo 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,88 @@ 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 HighlightingInformation { + // 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 HighlightingToken that clangd sent. +interface HighlightingToken { + // Start column for this token. + character: number; + // The TextMate scope index to the clangd scopes. + scope: number; + length: number; +} +// All highlightings for line. +interface HighlightingLine { + line: number; + tokens: HighlightingToken[]; +} + +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 Feature implements vscodelc.StaticFeature { + scopes: 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.scopes = serverCapabilities.semanticHighlighting.scopes; + } + + handleNotification(params: HighlightingInformation) { + const tokenLines = params.lines.map((line): HighlightingLine => { + 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): HighlightingToken[] { + 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