128 lines
6.8 KiB
Plaintext
128 lines
6.8 KiB
Plaintext
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.register = void 0;
|
|
const shared_1 = require("../shared");
|
|
function register(ctx) {
|
|
const { ts } = ctx;
|
|
return (uri, range, legend) => {
|
|
const document = ctx.getTextDocument(uri);
|
|
if (!document)
|
|
return;
|
|
const file = ctx.uriToFileName(uri);
|
|
const start = range ? document.offsetAt(range.start) : 0;
|
|
const length = range ? (document.offsetAt(range.end) - start) : document.getText().length;
|
|
if (ctx.language.typescript?.languageServiceHost.getCancellationToken?.().isCancellationRequested())
|
|
return;
|
|
const response2 = (0, shared_1.safeCall)(() => ctx.languageService.getEncodedSyntacticClassifications(file, { start, length }));
|
|
if (!response2)
|
|
return;
|
|
if (ctx.language.typescript?.languageServiceHost.getCancellationToken?.().isCancellationRequested())
|
|
return;
|
|
const response1 = (0, shared_1.safeCall)(() => ctx.languageService.getEncodedSemanticClassifications(file, { start, length }, ts.SemanticClassificationFormat.TwentyTwenty));
|
|
if (!response1)
|
|
return;
|
|
let tokenModifiersTable = [];
|
|
tokenModifiersTable[2 /* TokenModifier.async */] = 1 << legend.tokenModifiers.indexOf('async');
|
|
tokenModifiersTable[0 /* TokenModifier.declaration */] = 1 << legend.tokenModifiers.indexOf('declaration');
|
|
tokenModifiersTable[3 /* TokenModifier.readonly */] = 1 << legend.tokenModifiers.indexOf('readonly');
|
|
tokenModifiersTable[1 /* TokenModifier.static */] = 1 << legend.tokenModifiers.indexOf('static');
|
|
tokenModifiersTable[5 /* TokenModifier.local */] = 1 << legend.tokenModifiers.indexOf('local'); // missing in server tokenModifiers
|
|
tokenModifiersTable[4 /* TokenModifier.defaultLibrary */] = 1 << legend.tokenModifiers.indexOf('defaultLibrary');
|
|
tokenModifiersTable = tokenModifiersTable.map(mod => Math.max(mod, 0));
|
|
const tokenSpan = [...response1.spans, ...response2.spans];
|
|
const tokens = [];
|
|
let i = 0;
|
|
while (i < tokenSpan.length) {
|
|
const offset = tokenSpan[i++];
|
|
const length = tokenSpan[i++];
|
|
const tsClassification = tokenSpan[i++];
|
|
let tokenModifiers = 0;
|
|
let tokenType = getTokenTypeFromClassification(tsClassification);
|
|
if (tokenType !== undefined) {
|
|
// it's a classification as returned by the typescript-vscode-sh-plugin
|
|
tokenModifiers = getTokenModifierFromClassification(tsClassification);
|
|
}
|
|
else {
|
|
// typescript-vscode-sh-plugin is not present
|
|
tokenType = tokenTypeMap[tsClassification];
|
|
if (tokenType === undefined) {
|
|
continue;
|
|
}
|
|
}
|
|
const serverToken = tsTokenTypeToServerTokenType(tokenType);
|
|
if (serverToken === undefined) {
|
|
continue;
|
|
}
|
|
const serverTokenModifiers = tsTokenModifierToServerTokenModifier(tokenModifiers);
|
|
// 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);
|
|
for (let line = startPos.line; line <= endPos.line; line++) {
|
|
const startCharacter = (line === startPos.line ? startPos.character : 0);
|
|
const endCharacter = (line === endPos.line ? endPos.character : docLineLength(document, line));
|
|
tokens.push([line, startCharacter, endCharacter - startCharacter, serverToken, serverTokenModifiers]);
|
|
}
|
|
}
|
|
return tokens;
|
|
function tsTokenTypeToServerTokenType(tokenType) {
|
|
return legend.tokenTypes.indexOf(tokenTypes[tokenType]);
|
|
}
|
|
function tsTokenModifierToServerTokenModifier(input) {
|
|
let m = 0;
|
|
let i = 0;
|
|
while (input) {
|
|
if (input & 1) {
|
|
m |= tokenModifiersTable[i];
|
|
}
|
|
input = input >> 1;
|
|
i++;
|
|
}
|
|
return m;
|
|
}
|
|
};
|
|
}
|
|
exports.register = register;
|
|
function docLineLength(document, line) {
|
|
const currentLineOffset = document.offsetAt({ line, character: 0 });
|
|
const nextLineOffset = document.offsetAt({ line: line + 1, character: 0 });
|
|
return nextLineOffset - currentLineOffset;
|
|
}
|
|
function getTokenTypeFromClassification(tsClassification) {
|
|
if (tsClassification > 255 /* TokenEncodingConsts.modifierMask */) {
|
|
return (tsClassification >> 8 /* TokenEncodingConsts.typeOffset */) - 1;
|
|
}
|
|
return undefined;
|
|
}
|
|
function getTokenModifierFromClassification(tsClassification) {
|
|
return tsClassification & 255 /* TokenEncodingConsts.modifierMask */;
|
|
}
|
|
const tokenTypes = [];
|
|
tokenTypes[0 /* TokenType.class */] = 'class';
|
|
tokenTypes[1 /* TokenType.enum */] = 'enum';
|
|
tokenTypes[2 /* TokenType.interface */] = 'interface';
|
|
tokenTypes[3 /* TokenType.namespace */] = 'namespace';
|
|
tokenTypes[4 /* TokenType.typeParameter */] = 'typeParameter';
|
|
tokenTypes[5 /* TokenType.type */] = 'type';
|
|
tokenTypes[6 /* TokenType.parameter */] = 'parameter';
|
|
tokenTypes[7 /* TokenType.variable */] = 'variable';
|
|
tokenTypes[8 /* TokenType.enumMember */] = 'enumMember';
|
|
tokenTypes[9 /* TokenType.property */] = 'property';
|
|
tokenTypes[10 /* TokenType.function */] = 'function';
|
|
tokenTypes[11 /* TokenType.method */] = 'method';
|
|
const tokenModifiers = [];
|
|
tokenModifiers[2 /* TokenModifier.async */] = 'async';
|
|
tokenModifiers[0 /* TokenModifier.declaration */] = 'declaration';
|
|
tokenModifiers[3 /* TokenModifier.readonly */] = 'readonly';
|
|
tokenModifiers[1 /* TokenModifier.static */] = 'static';
|
|
tokenModifiers[5 /* TokenModifier.local */] = 'local'; // missing in server tokenModifiers
|
|
tokenModifiers[4 /* TokenModifier.defaultLibrary */] = 'defaultLibrary';
|
|
// mapping for the original ExperimentalProtocol.ClassificationType from TypeScript (only used when plugin is not available)
|
|
const tokenTypeMap = [];
|
|
tokenTypeMap[11 /* ExperimentalProtocol.ClassificationType.className */] = 0 /* TokenType.class */;
|
|
tokenTypeMap[12 /* ExperimentalProtocol.ClassificationType.enumName */] = 1 /* TokenType.enum */;
|
|
tokenTypeMap[13 /* ExperimentalProtocol.ClassificationType.interfaceName */] = 2 /* TokenType.interface */;
|
|
tokenTypeMap[14 /* ExperimentalProtocol.ClassificationType.moduleName */] = 3 /* TokenType.namespace */;
|
|
tokenTypeMap[15 /* ExperimentalProtocol.ClassificationType.typeParameterName */] = 4 /* TokenType.typeParameter */;
|
|
tokenTypeMap[16 /* ExperimentalProtocol.ClassificationType.typeAliasName */] = 5 /* TokenType.type */;
|
|
tokenTypeMap[17 /* ExperimentalProtocol.ClassificationType.parameterName */] = 6 /* TokenType.parameter */;
|
|
//# sourceMappingURL=semanticTokens.js.map |