From 5ee9f6646e5d813989d886326c9c5b6f381814bb Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Tue, 14 Jan 2020 10:07:40 +0100 Subject: [PATCH] add constants --- .../typescript-language-features/package.json | 2 +- .../src/features/semanticTokens.ts | 108 ++++++++++-------- .../typescript-language-features/yarn.lock | 8 +- 3 files changed, 68 insertions(+), 50 deletions(-) diff --git a/extensions/typescript-language-features/package.json b/extensions/typescript-language-features/package.json index 3ff2f98b8e4..681c5c4b2d1 100644 --- a/extensions/typescript-language-features/package.json +++ b/extensions/typescript-language-features/package.json @@ -19,7 +19,7 @@ "jsonc-parser": "^2.1.1", "rimraf": "^2.6.3", "semver": "5.5.1", - "typescript-vscode-sh-plugin": "^0.4.1", + "typescript-vscode-sh-plugin": "^0.3.2", "vscode-extension-telemetry": "0.1.1", "vscode-nls": "^4.0.0" }, diff --git a/extensions/typescript-language-features/src/features/semanticTokens.ts b/extensions/typescript-language-features/src/features/semanticTokens.ts index de3f11e81d7..78f7dfb36a8 100644 --- a/extensions/typescript-language-features/src/features/semanticTokens.ts +++ b/extensions/typescript-language-features/src/features/semanticTokens.ts @@ -16,8 +16,6 @@ export function register(selector: vscode.DocumentSelector, client: ITypeScriptS const provider = new SemanticTokensProvider(client); return vscode.languages.registerSemanticTokensProvider(selector, provider, provider.getLegend()); }); - const provider = new SemanticTokensProvider(client); - return vscode.languages.registerSemanticTokensProvider(selector, provider, provider.getLegend()); } /** @@ -32,12 +30,12 @@ class SemanticTokensProvider implements vscode.SemanticTokensProvider { getLegend(): vscode.SemanticTokensLegend { const tokenTypes = []; - for (let i = 0; i < TokenType._sentinel; i++) { - tokenTypes.push(TokenType[i]); + for (let i = 0; i < VSCodeShPlugin.TokenType._sentinel; i++) { + tokenTypes.push(VSCodeShPlugin.TokenType[i]); } const tokenModifiers = []; - for (let i = 0; i < TokenModifier._sentinel; i++) { - tokenModifiers.push(TokenModifier[i]); + for (let i = 0; i < VSCodeShPlugin.TokenModifier._sentinel; i++) { + tokenModifiers.push(VSCodeShPlugin.TokenModifier[i]); } return new vscode.SemanticTokensLegend(tokenTypes, tokenModifiers); } @@ -76,25 +74,25 @@ class SemanticTokensProvider implements vscode.SemanticTokensProvider { const builder = new vscode.SemanticTokensBuilder(); for (const tokenSpan of allTokenSpans) { - for (let i = 0, len = Math.floor(tokenSpan.length / 3); i < len; i++) { + let i = 0; + while (i < tokenSpan.length) { + const offset = tokenSpan[i++]; + const length = tokenSpan[i++]; + const tsClassification = tokenSpan[i++]; - const tsClassification = tokenSpan[3 * i + 2]; - let tokenType = 0; let tokenModifiers = 0; - if (tsClassification >= 0x100) { - // exendend classifications as returned by the typescript-vscode-sh-plugin - tokenType = (tsClassification >> 8) - 1; - tokenModifiers = tsClassification & 0xFF; + let tokenType = VSCodeShPlugin.getTokenTypeFromClassification(tsClassification); + if (tokenType !== undefined) { + // it's a classification as returned by the typescript-vscode-sh-plugin + tokenModifiers = VSCodeShPlugin.getTokenModifierFromClassification(tsClassification); } else { + // typescript-vscode-sh-plugin is not present tokenType = tokenTypeMap[tsClassification]; if (tokenType === undefined) { continue; } } - const offset = tokenSpan[3 * i]; - const length = tokenSpan[3 * i + 1]; - // we can use the document's range conversion methods because the result is at the same version as the document const startPos = document.positionAt(offset); const endPos = document.positionAt(offset + length); @@ -110,41 +108,61 @@ class SemanticTokensProvider implements vscode.SemanticTokensProvider { } } -// Don't change TokenType and TokenModifier enums without adopting typescript-vscode-sh-plugin -enum TokenType { - 'class', - 'enum', - 'interface', - 'namespace', - 'typeParameter', - 'type', - 'parameter', - 'variable', - 'property', - 'constant', - 'function', - 'member', - _sentinel -} +namespace VSCodeShPlugin { -enum TokenModifier { - 'declaration', - 'static', - 'async', - 'readonly', - _sentinel + // typescript-vscode-sh-plugin encodes type and modifiers in the classification: + // TSClassification = (TokenType + 1) << 8 + TokenModifier + + const TokenTypeOffset = 8; + const TokenModifierMask = (1 << TokenTypeOffset) - 1; // 0xFF + + export function getTokenTypeFromClassification(tsClassification: number): number | undefined { + if (tsClassification > TokenModifierMask) { + return (tsClassification >> TokenTypeOffset) - 1; + } + return undefined; + } + + export function getTokenModifierFromClassification(tsClassification: number) { + return tsClassification & TokenModifierMask; + } + + // Don't change TokenType and TokenModifier enums without adopting typescript-vscode-sh-plugin + export enum TokenType { + 'class', + 'enum', + 'interface', + 'namespace', + 'typeParameter', + 'type', + 'parameter', + 'variable', + 'property', + 'constant', + 'function', + 'member', + _sentinel + } + + export enum TokenModifier { + 'declaration', + 'static', + 'async', + 'readonly', + _sentinel + } } // mapping for the original ExperimentalProtocol.ClassificationType from TypeScript (only used when plugin is not available) const tokenTypeMap: number[] = []; -tokenTypeMap[ExperimentalProtocol.ClassificationType.className] = TokenType.class; -tokenTypeMap[ExperimentalProtocol.ClassificationType.enumName] = TokenType.enum; -tokenTypeMap[ExperimentalProtocol.ClassificationType.interfaceName] = TokenType.interface; -tokenTypeMap[ExperimentalProtocol.ClassificationType.moduleName] = TokenType.namespace; -tokenTypeMap[ExperimentalProtocol.ClassificationType.typeParameterName] = TokenType.typeParameter; -tokenTypeMap[ExperimentalProtocol.ClassificationType.typeAliasName] = TokenType.type; -tokenTypeMap[ExperimentalProtocol.ClassificationType.parameterName] = TokenType.parameter; +tokenTypeMap[ExperimentalProtocol.ClassificationType.className] = VSCodeShPlugin.TokenType.class; +tokenTypeMap[ExperimentalProtocol.ClassificationType.enumName] = VSCodeShPlugin.TokenType.enum; +tokenTypeMap[ExperimentalProtocol.ClassificationType.interfaceName] = VSCodeShPlugin.TokenType.interface; +tokenTypeMap[ExperimentalProtocol.ClassificationType.moduleName] = VSCodeShPlugin.TokenType.namespace; +tokenTypeMap[ExperimentalProtocol.ClassificationType.typeParameterName] = VSCodeShPlugin.TokenType.typeParameter; +tokenTypeMap[ExperimentalProtocol.ClassificationType.typeAliasName] = VSCodeShPlugin.TokenType.type; +tokenTypeMap[ExperimentalProtocol.ClassificationType.parameterName] = VSCodeShPlugin.TokenType.parameter; namespace ExperimentalProtocol { diff --git a/extensions/typescript-language-features/yarn.lock b/extensions/typescript-language-features/yarn.lock index 98feebef484..cc6e217941d 100644 --- a/extensions/typescript-language-features/yarn.lock +++ b/extensions/typescript-language-features/yarn.lock @@ -626,10 +626,10 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0: resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= -typescript-vscode-sh-plugin@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/typescript-vscode-sh-plugin/-/typescript-vscode-sh-plugin-0.4.1.tgz#6982958419ca760c0add761dd1d5f398815bee8c" - integrity sha512-IPsz/FNuk9HsjaEOsJJxGkiKGK5E4muZtjntp/BDWYZVYOj3R8JtX6++pQ0ftMOcZwxjKxeBmnS1FSUdVMifSw== +typescript-vscode-sh-plugin@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/typescript-vscode-sh-plugin/-/typescript-vscode-sh-plugin-0.3.2.tgz#bde9d0eba24ca5856024811fa354a9f5a7aeebe5" + integrity sha512-XsalETsSf3y7VWxk36plqHpsbl+TUDl278HEuhPHVBcNnwuTjcIq52J/CJw84xYmxmBcTIPUgIgLLS4OE5nX2A== uri-js@^4.2.2: version "4.2.2"