import * as vscode from 'vscode' ; import { DefaultClient , GetSemanticTokensParams , GetSemanticTokensRequest , openFileVersions , GetSemanticTokensResult } from '../client' ; export class SemanticTokensProvider implements vscode . DocumentSemanticTokensProvider { private client : DefaultClient ; public onDidChangeSemanticTokensEvent = new vscode . EventEmitter < void > ( ) ; public onDidChangeSemanticTokens ? : vscode . Event < void > ; private tokenCaches : Map < string , [ number , vscode . SemanticTokens ] > = new Map < string , [ number , vscode . SemanticTokens ] > ( ) ; constructor ( client ) { this . client = client ; this . onDidChangeSemanticTokens = this . onDidChangeSemanticTokensEvent . event ; } public async provideDocumentSemanticTokens ( document , token ) { await this . client . awaitUntilLanguageClientReady ( ) ; const uriString = document . uri . toString ( ) ; const cache = this . tokenCaches . get ( uriString ) ; if ( cache && cache [ 0 ] === document . version ) { return cache [ 1 ] ; } else { token . onCancellationRequested ( _e => this . client . abortRequest ( id ) ) ; const id = ++ DefaultClient . abortRequestId ; const params = { id : id , uri : uriString } ; const tokensResult = await this . client . languageClient . sendRequest ( GetSemanticTokensRequest , params ) ; if ( tokensResult . canceled ) { throw new vscode . CancellationError ( ) ; } else { if ( tokensResult . fileVersion !== openFileVersions . get ( uriString ) ) { throw new vscode . CancellationError ( ) ; } else { const builder = new vscode . SemanticTokensBuilder ( this . client . semanticTokensLegend ) ; tokensResult . tokens . forEach ( ( token ) => { builder . push ( token . line , token . character , token . length , token . type , token . modifiers ) ; } ) ; const tokens = builder . build ( ) ; this . tokenCaches . set ( uriString , [ tokensResult . fileVersion , tokens ] ) ; return tokens ; } } } } public invalidateFile ( uri ) { this . tokenCaches . delete ( uri ) ; this . onDidChangeSemanticTokensEvent . fire ( ) ; } }