Skip to content

Commit 2ca09d9

Browse files
committed
visit ast
1 parent e53c956 commit 2ca09d9

2 files changed

Lines changed: 73 additions & 13 deletions

File tree

extensions/html-language-features/server/src/modes/javascriptSemanticTokens.ts

Lines changed: 70 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,41 @@ export function getSemanticTokens(jsLanguageService: ts.LanguageService, current
1414
let resultTokens: SemanticTokenData[] = [];
1515
const tokens = jsLanguageService.getSemanticClassifications(fileName, { start: 0, length: currentTextDocument.getText().length });
1616
for (let token of tokens) {
17-
const typeIdx = tokenMapping[token.classificationType];
17+
const typeIdx = tokenFromClassificationMapping[token.classificationType];
1818
if (typeIdx !== undefined) {
1919
resultTokens.push({ offset: token.textSpan.start, length: token.textSpan.length, typeIdx, modifierSet: 0 });
2020
}
2121
}
2222

23+
const program = jsLanguageService.getProgram();
24+
if (program) {
25+
const typeChecker = program.getTypeChecker();
26+
27+
28+
function visit(node: ts.Node) {
29+
if (node.kind === ts.SyntaxKind.Identifier) {
30+
const symbol = typeChecker.getSymbolAtLocation(node);
31+
if (symbol) {
32+
let typeIdx = tokenFromDeclarationMapping[symbol.valueDeclaration.kind];
33+
let modifierSet = 0;
34+
if (symbol.valueDeclaration === node.parent) {
35+
modifierSet = TokenModifier.declaration;
36+
}
37+
if (typeIdx !== undefined) {
38+
resultTokens.push({ offset: node.pos, length: node.end - node.pos, typeIdx, modifierSet });
39+
}
40+
}
41+
}
42+
43+
ts.forEachChild(node, visit);
44+
}
45+
const sourceFile = program.getSourceFile(fileName);
46+
if (sourceFile) {
47+
visit(sourceFile);
48+
}
49+
}
50+
51+
2352
resultTokens = resultTokens.sort((d1, d2) => d1.offset - d2.offset);
2453
const offsetRanges = ranges.map(r => ({ startOffset: currentTextDocument.offsetAt(r.start), endOffset: currentTextDocument.offsetAt(r.end) })).sort((d1, d2) => d1.startOffset - d2.startOffset);
2554

@@ -62,15 +91,45 @@ export function getSemanticTokenLegend() {
6291
}
6392

6493

65-
const tokenTypes: string[] = ['class', 'enum', 'interface', 'namespace', 'parameterType', 'type', 'parameter'];
66-
const tokenModifiers: string[] = [];
94+
const tokenTypes: string[] = ['class', 'enum', 'interface', 'namespace', 'parameterType', 'type', 'parameter', 'variable', 'property', 'constant', 'function'];
95+
const tokenModifiers: string[] = ['declaration',];
96+
97+
enum TokenType {
98+
'class' = 0,
99+
'enum' = 1,
100+
'interface' = 2,
101+
'namespace' = 3,
102+
'parameterType' = 4,
103+
'type' = 5,
104+
'parameter' = 6,
105+
'variable' = 7,
106+
'property' = 8,
107+
'constant' = 9,
108+
'function' = 10,
109+
}
110+
111+
enum TokenModifier {
112+
'declaration' = 0x01,
113+
114+
}
115+
116+
const tokenFromClassificationMapping: { [name: string]: TokenType } = {
117+
[ts.ClassificationTypeNames.className]: TokenType.class,
118+
[ts.ClassificationTypeNames.enumName]: TokenType.enum,
119+
[ts.ClassificationTypeNames.interfaceName]: TokenType.interface,
120+
[ts.ClassificationTypeNames.moduleName]: TokenType.namespace,
121+
[ts.ClassificationTypeNames.typeParameterName]: TokenType.parameterType,
122+
[ts.ClassificationTypeNames.typeAliasName]: TokenType.type,
123+
[ts.ClassificationTypeNames.parameterName]: TokenType.parameter
124+
};
67125

68-
const tokenMapping: { [name: string]: number } = {
69-
[ts.ClassificationTypeNames.className]: tokenTypes.indexOf('class'),
70-
[ts.ClassificationTypeNames.enumName]: tokenTypes.indexOf('enum'),
71-
[ts.ClassificationTypeNames.interfaceName]: tokenTypes.indexOf('interface'),
72-
[ts.ClassificationTypeNames.moduleName]: tokenTypes.indexOf('namespace'),
73-
[ts.ClassificationTypeNames.typeParameterName]: tokenTypes.indexOf('parameterType'),
74-
[ts.ClassificationTypeNames.typeAliasName]: tokenTypes.indexOf('type'),
75-
[ts.ClassificationTypeNames.parameterName]: tokenTypes.indexOf('parameter')
126+
const tokenFromDeclarationMapping: { [name: string]: TokenType } = {
127+
[ts.SyntaxKind.VariableDeclaration]: TokenType.variable,
128+
[ts.SyntaxKind.Parameter]: TokenType.parameter,
129+
[ts.SyntaxKind.PropertyDeclaration]: TokenType.property,
130+
[ts.SyntaxKind.ModuleDeclaration]: TokenType.namespace,
131+
[ts.SyntaxKind.EnumDeclaration]: TokenType.enum,
132+
[ts.SyntaxKind.EnumMember]: TokenType.property,
133+
[ts.SyntaxKind.ClassDeclaration]: TokenType.property,
134+
[ts.SyntaxKind.MethodDeclaration]: TokenType.function
76135
};

src/vs/platform/theme/common/tokenClassificationRegistry.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -381,20 +381,21 @@ function registerDefaultClassifications(): void {
381381
registerTokenType('parameterType', nls.localize('parameterType', "Style for parameter types."), undefined, 'type');
382382

383383
registerTokenType('function', nls.localize('function', "Style for functions"), [['entity.name.function'], ['support.function']]);
384+
registerTokenType('member', nls.localize('member', "Style for member"), [['entity.name.function'], ['support.function']]);
384385
registerTokenType('macro', nls.localize('macro', "Style for macros."), undefined, 'function');
385386

386387
registerTokenType('variable', nls.localize('variable', "Style for variables."), [['variable'], ['entity.name.variable']]);
387388
registerTokenType('constant', nls.localize('constant', "Style for constants."), undefined, 'variable');
388389
registerTokenType('parameter', nls.localize('parameter', "Style for parameters."), undefined, 'variable');
389-
registerTokenType('property', nls.localize('propertie', "Style for properties."), undefined, 'variable');
390+
registerTokenType('property', nls.localize('property', "Style for properties."), undefined, 'variable');
390391

391392
registerTokenType('label', nls.localize('labels', "Style for labels. "), undefined);
392393

393394
// default token modifiers
394395

395396
tokenClassificationRegistry.registerTokenModifier('declaration', nls.localize('declaration', "Style for all symbol declarations."), undefined);
396397
tokenClassificationRegistry.registerTokenModifier('documentation', nls.localize('documentation', "Style to use for references in documentation."), undefined);
397-
tokenClassificationRegistry.registerTokenModifier('member', nls.localize('member', "Style to use for member functions, variables (fields) and types."), undefined);
398+
//tokenClassificationRegistry.registerTokenModifier('member', nls.localize('member', "Style to use for member functions, variables (fields) and types."), undefined);
398399
tokenClassificationRegistry.registerTokenModifier('static', nls.localize('static', "Style to use for symbols that are static."), undefined);
399400
tokenClassificationRegistry.registerTokenModifier('abstract', nls.localize('abstract', "Style to use for symbols that are abstract."), undefined);
400401
tokenClassificationRegistry.registerTokenModifier('deprecated', nls.localize('deprecated', "Style to use for symbols that are deprecated."), undefined);

0 commit comments

Comments
 (0)