@@ -248,6 +248,53 @@ export class TMScopeDecodeData {
248248 }
249249}
250250
251+ /**
252+ * Data associated with a stack of text mate scopes as part of decoding.
253+ */
254+ export class TMScopesDecodeData {
255+ _tmScopesDecodeDataBrand : void ;
256+
257+ /**
258+ * The last scope in the stack.
259+ */
260+ public readonly scope : string ;
261+ /**
262+ * The resolved tokens mask.
263+ * tokens[i] === true ===> token with id i is present.
264+ */
265+ public readonly tokensMask : boolean [ ] ;
266+ /**
267+ * The resolved language.
268+ */
269+ private readonly language : string ;
270+
271+ constructor ( parent : TMScopesDecodeData , scope : TMScopeDecodeData ) {
272+ // 1) Inherit data from `parent`.
273+ let tokensMask : boolean [ ] ;
274+ let language : string ;
275+ if ( parent ) {
276+ tokensMask = parent . tokensMask . slice ( 0 ) ;
277+ language = parent . language ;
278+ } else {
279+ tokensMask = [ ] ;
280+ language = null ;
281+ }
282+
283+ // 2) Overwrite with data from `scope`.
284+ let scopeTokenIds = scope . tokenIds ;
285+ for ( let i = 0 , len = scopeTokenIds . length ; i < len ; i ++ ) {
286+ tokensMask [ scopeTokenIds [ i ] ] = true ;
287+ }
288+ if ( scope . language ) {
289+ language = scope . language ;
290+ }
291+
292+ this . scope = scope . scope ;
293+ this . tokensMask = tokensMask ;
294+ this . language = language ;
295+ }
296+ }
297+
251298export class DecodeMap {
252299 _decodeMapBrand : void ;
253300
@@ -256,15 +303,15 @@ export class DecodeMap {
256303 private readonly scopeToTokenIds : { [ scope : string ] : TMScopeDecodeData ; } ;
257304 private readonly tokenToTokenId : { [ token : string ] : number ; } ;
258305 private readonly tokenIdToToken : string [ ] ;
259- prevToken : TMTokenDecodeData ;
306+ prevTokenScopes : TMScopesDecodeData [ ] ;
260307
261308 constructor ( scopeRegistry : TMScopeRegistry ) {
262309 this . lastAssignedTokenId = 0 ;
263310 this . scopeRegistry = scopeRegistry ;
264311 this . scopeToTokenIds = Object . create ( null ) ;
265312 this . tokenToTokenId = Object . create ( null ) ;
266313 this . tokenIdToToken = [ null ] ;
267- this . prevToken = new TMTokenDecodeData ( [ ] , [ ] ) ;
314+ this . prevTokenScopes = [ ] ;
268315 }
269316
270317 private _getTokenId ( token : string ) : number {
@@ -313,18 +360,6 @@ export class DecodeMap {
313360 }
314361}
315362
316- export class TMTokenDecodeData {
317- _tmTokenDecodeDataBrand : void ;
318-
319- public readonly scopes : string [ ] ;
320- public readonly scopeTokensMaps : boolean [ ] [ ] ;
321-
322- constructor ( scopes : string [ ] , scopeTokensMaps : boolean [ ] [ ] ) {
323- this . scopes = scopes ;
324- this . scopeTokensMaps = scopeTokensMaps ;
325- }
326- }
327-
328363function depth ( stackElement : StackElement ) : number {
329364 let result = 0 ;
330365 while ( stackElement ) {
@@ -390,34 +425,36 @@ export function decodeTextMateTokens(line: string, offsetDelta: number, decodeMa
390425}
391426
392427export function decodeTextMateToken ( decodeMap : DecodeMap , scopes : string [ ] ) : string {
393- const prevTokenScopes = decodeMap . prevToken . scopes ;
428+ if ( scopes . length <= 1 ) {
429+ // fast case
430+ return '' ;
431+ }
432+
433+ const prevTokenScopes = decodeMap . prevTokenScopes ;
394434 const prevTokenScopesLength = prevTokenScopes . length ;
395- const prevTokenScopeTokensMaps = decodeMap . prevToken . scopeTokensMaps ;
396435
397- let scopeTokensMaps : boolean [ ] [ ] = [ ] ;
398- let prevScopeTokensMaps : boolean [ ] = [ ] ;
436+ let resultScopes : TMScopesDecodeData [ ] = [ null ] ;
437+ let lastResultScope : TMScopesDecodeData = null ;
438+
399439 let sameAsPrev = true ;
400440 for ( let level = 1 /* deliberately skip scope 0*/ , scopesLength = scopes . length ; level < scopesLength ; level ++ ) {
401441 let scope = scopes [ level ] ;
402442
403- if ( sameAsPrev ) {
404- if ( level < prevTokenScopesLength && prevTokenScopes [ level ] === scope ) {
405- prevScopeTokensMaps = prevTokenScopeTokensMaps [ level ] ;
406- scopeTokensMaps [ level ] = prevScopeTokensMaps ;
443+ if ( sameAsPrev && level < prevTokenScopesLength ) {
444+ let prevTokenScope = prevTokenScopes [ level ] ;
445+ if ( prevTokenScope . scope === scope ) {
446+ // continue reusing the results of the previous token's computation
447+ lastResultScope = prevTokenScope ;
448+ resultScopes [ level ] = lastResultScope ;
407449 continue ;
408450 }
409- sameAsPrev = false ;
410451 }
452+ sameAsPrev = false ;
411453
412- let decodedScope = decodeMap . decodeTMScope ( scope ) ;
413- let decodedScopeTokens = decodedScope . tokenIds ;
414- prevScopeTokensMaps = prevScopeTokensMaps . slice ( 0 ) ;
415- for ( let i = 0 , len = decodedScopeTokens . length ; i < len ; i ++ ) {
416- prevScopeTokensMaps [ decodedScopeTokens [ i ] ] = true ;
417- }
418- scopeTokensMaps [ level ] = prevScopeTokensMaps ;
454+ lastResultScope = new TMScopesDecodeData ( lastResultScope , decodeMap . decodeTMScope ( scope ) ) ;
455+ resultScopes [ level ] = lastResultScope ;
419456 }
420457
421- decodeMap . prevToken = new TMTokenDecodeData ( scopes , scopeTokensMaps ) ;
422- return decodeMap . getToken ( prevScopeTokensMaps ) ;
458+ decodeMap . prevTokenScopes = resultScopes ;
459+ return decodeMap . getToken ( lastResultScope . tokensMask ) ;
423460}
0 commit comments