5
5
*--------------------------------------------------------------------------------------------*/
6
6
7
7
import { TokenType , TokenModifier , TokenEncodingConsts , VersionRequirement } from './constants' ;
8
+ import * as semanticTokensVisitor from './semanticTokensVisitor' ;
9
+
10
+ const computeOracleTokens = false ;
8
11
9
12
export = function init ( modules : { typescript : typeof import ( "typescript/lib/tsserverlibrary" ) } ) {
10
13
const ts = modules . typescript ;
11
14
15
+ const newImplementation = semanticTokensVisitor . init ( ts ) ;
16
+
12
17
function hasVersion ( requiredMajor : number , requiredMinor : number ) {
13
18
const parts = ts . version . split ( '.' ) ;
14
19
const majorVersion = Number ( parts [ 0 ] ) ;
@@ -20,14 +25,36 @@ export = function init(modules: { typescript: typeof import("typescript/lib/tsse
20
25
const intercept : Partial < ts . LanguageService > = Object . create ( null ) ;
21
26
22
27
if ( ! hasVersion ( VersionRequirement . major , VersionRequirement . minor ) ) {
23
- logger ?. msg ( `typescript-vscode-sh-plugin not active, version ${ VersionRequirement . major } .${ VersionRequirement . minor } required, is ${ ts . version } ` , ts . server . Msg . Info ) ;
28
+ // logger?.msg(`typescript-vscode-sh-plugin not active, version ${VersionRequirement.major}.${VersionRequirement.minor} required, is ${ts.version}`, ts.server.Msg.Info);
24
29
return languageService ;
25
30
}
26
31
logger ?. msg ( `typescript-vscode-sh-plugin initialized. Intercepting getEncodedSemanticClassifications and getEncodedSyntacticClassifications.` , ts . server . Msg . Info ) ;
27
32
28
33
intercept . getEncodedSemanticClassifications = ( filename : string , span : ts . TextSpan ) => {
34
+ const start = Date . now ( ) ;
35
+ const actualTokens = newImplementation . getEncodedSemanticClassifications ( languageService , filename , logger ) ;
36
+ const duration = Date . now ( ) - start ;
37
+
38
+ logger ?. msg ( `COMPUTING ${ actualTokens . length / 3 } TOOK ${ duration } ms !` , ts . server . Msg . Info ) ;
39
+
40
+ if ( computeOracleTokens ) {
41
+ const oracleTokens = getSemanticTokens ( languageService , filename , span ) ;
42
+ const program = languageService . getProgram ( ) ;
43
+ if ( program ) {
44
+ const sourceFile = program . getSourceFile ( filename ) ;
45
+ if ( sourceFile ) {
46
+ const diffs = newImplementation . compareTokens ( sourceFile , actualTokens , oracleTokens ) ;
47
+ if ( diffs . length > 0 ) {
48
+ logger ?. msg ( `REQUEST YIELDED DIFFERENT RESULTS:` , ts . server . Msg . Info ) ;
49
+ logger ?. msg ( diffs . join ( '\n' ) , ts . server . Msg . Info ) ;
50
+ } else {
51
+ logger ?. msg ( `REQUEST WAS EQUAL IN BOTH TOKENIZERS` ) ;
52
+ }
53
+ }
54
+ }
55
+ }
29
56
return {
30
- spans : getSemanticTokens ( languageService , filename , span ) ,
57
+ spans : actualTokens ,
31
58
endOfLineState : ts . EndOfLineState . None
32
59
}
33
60
} ;
@@ -89,8 +116,8 @@ export = function init(modules: { typescript: typeof import("typescript/lib/tsse
89
116
if ( typeIdx !== undefined ) {
90
117
let modifierSet = 0 ;
91
118
if ( node . parent ) {
92
- const parentTypeIdx = tokenFromDeclarationMapping [ node . parent . kind ] ;
93
- if ( parentTypeIdx === typeIdx && ( < ts . NamedDeclaration > node . parent ) . name === node ) {
119
+ const parentIsDeclaration = ( ts . isBindingElement ( node . parent ) || tokenFromDeclarationMapping [ node . parent . kind ] === typeIdx ) ;
120
+ if ( parentIsDeclaration && ( < ts . NamedDeclaration > node . parent ) . name === node ) {
94
121
modifierSet = 1 << TokenModifier . declaration ;
95
122
}
96
123
}
@@ -112,15 +139,21 @@ export = function init(modules: { typescript: typeof import("typescript/lib/tsse
112
139
if ( modifiers & ts . ModifierFlags . Async ) {
113
140
modifierSet |= 1 << TokenModifier . async ;
114
141
}
115
- if ( ( modifiers & ts . ModifierFlags . Readonly ) || ( nodeFlags & ts . NodeFlags . Const ) || ( symbol . getFlags ( ) & ts . SymbolFlags . EnumMember ) ) {
116
- modifierSet |= 1 << TokenModifier . readonly ;
142
+ if ( typeIdx !== TokenType . interface ) {
143
+ if ( ( modifiers & ts . ModifierFlags . Readonly ) || ( nodeFlags & ts . NodeFlags . Const ) || ( symbol . getFlags ( ) & ts . SymbolFlags . EnumMember ) ) {
144
+ modifierSet |= 1 << TokenModifier . readonly ;
145
+ }
117
146
}
118
147
if ( ( typeIdx === TokenType . variable || typeIdx === TokenType . function ) && isLocalDeclaration ( decl , sourceFile ) ) {
119
148
modifierSet |= 1 << TokenModifier . local ;
120
149
}
121
150
if ( program . isSourceFileDefaultLibrary ( decl . getSourceFile ( ) ) ) {
122
151
modifierSet |= 1 << TokenModifier . defaultLibrary ;
123
152
}
153
+ } else if ( symbol . declarations . length > 0 ) {
154
+ if ( program . isSourceFileDefaultLibrary ( symbol . declarations [ 0 ] . getSourceFile ( ) ) ) {
155
+ modifierSet |= 1 << TokenModifier . defaultLibrary ;
156
+ }
124
157
}
125
158
126
159
collector ( node , typeIdx , modifierSet ) ;
@@ -150,7 +183,10 @@ export = function init(modules: { typescript: typeof import("typescript/lib/tsse
150
183
} else if ( flags & ts . SymbolFlags . TypeParameter ) {
151
184
return TokenType . typeParameter ;
152
185
}
153
- const decl = symbol . valueDeclaration || symbol . declarations && symbol . declarations [ 0 ] ;
186
+ let decl = symbol . valueDeclaration || symbol . declarations && symbol . declarations [ 0 ] ;
187
+ if ( decl && decl . kind === ts . SyntaxKind . BindingElement ) {
188
+ decl = findBindingElementParentDeclaration ( < ts . BindingElement > decl ) ;
189
+ }
154
190
return decl && tokenFromDeclarationMapping [ decl . kind ] ;
155
191
}
156
192
@@ -173,8 +209,21 @@ export = function init(modules: { typescript: typeof import("typescript/lib/tsse
173
209
return typeIdx ;
174
210
}
175
211
212
+ function findBindingElementParentDeclaration ( element : ts . BindingElement ) : ts . VariableDeclaration | ts . ParameterDeclaration {
213
+ while ( true ) {
214
+ if ( element . parent . parent . kind === ts . SyntaxKind . BindingElement ) {
215
+ element = element . parent . parent ;
216
+ } else {
217
+ return element . parent . parent ;
218
+ }
219
+ }
220
+ }
221
+
176
222
function isLocalDeclaration ( decl : ts . Declaration , sourceFile : ts . SourceFile ) : boolean {
177
- if ( ts . isVariableDeclaration ( decl ) ) {
223
+ if ( ts . isBindingElement ( decl ) ) {
224
+ decl = findBindingElementParentDeclaration ( decl ) ;
225
+ }
226
+ if ( ts . isVariableDeclaration ( decl ) || ts . isBindingElement ( decl ) ) {
178
227
return ( ! ts . isSourceFile ( decl . parent . parent . parent ) || ts . isCatchClause ( decl . parent ) ) && decl . getSourceFile ( ) === sourceFile ;
179
228
} else if ( ts . isFunctionDeclaration ( decl ) ) {
180
229
return ! ts . isSourceFile ( decl . parent ) && decl . getSourceFile ( ) === sourceFile ;
@@ -224,8 +273,10 @@ export = function init(modules: { typescript: typeof import("typescript/lib/tsse
224
273
[ ts . SyntaxKind . ClassDeclaration ] : TokenType . class ,
225
274
[ ts . SyntaxKind . MethodDeclaration ] : TokenType . member ,
226
275
[ ts . SyntaxKind . FunctionDeclaration ] : TokenType . function ,
276
+ [ ts . SyntaxKind . FunctionExpression ] : TokenType . function ,
227
277
[ ts . SyntaxKind . MethodSignature ] : TokenType . member ,
228
278
[ ts . SyntaxKind . GetAccessor ] : TokenType . property ,
279
+ [ ts . SyntaxKind . SetAccessor ] : TokenType . property ,
229
280
[ ts . SyntaxKind . PropertySignature ] : TokenType . property ,
230
281
[ ts . SyntaxKind . InterfaceDeclaration ] : TokenType . interface ,
231
282
[ ts . SyntaxKind . TypeAliasDeclaration ] : TokenType . type ,
0 commit comments