From c34e736195f22e4f857098e28c2093c5590ba055 Mon Sep 17 00:00:00 2001 From: Alexandru Dima Date: Thu, 7 Nov 2019 16:06:46 +0100 Subject: [PATCH] Forward SemanticColoring disposals to the ext host --- .../src/features/semanticColoring.ts | 8 ++++++++ .../editor/common/services/modelServiceImpl.ts | 16 ++++++++++------ .../api/browser/mainThreadLanguageFeatures.ts | 13 +++++++------ src/vs/workbench/api/common/extHost.protocol.ts | 1 + .../api/common/extHostLanguageFeatures.ts | 9 +++++++++ 5 files changed, 35 insertions(+), 12 deletions(-) diff --git a/extensions/typescript-language-features/src/features/semanticColoring.ts b/extensions/typescript-language-features/src/features/semanticColoring.ts index be83ef883c3..d8c050d7d41 100644 --- a/extensions/typescript-language-features/src/features/semanticColoring.ts +++ b/extensions/typescript-language-features/src/features/semanticColoring.ts @@ -6,6 +6,12 @@ import * as vscode from 'vscode'; import { ITypeScriptServiceClient, ExperimentalProtocol } from '../typescriptService'; +function timeout(time: number): Promise { + return new Promise((resolve, _reject) => { + setTimeout(resolve, time); + }); +} + class SemanticColoringProvider implements vscode.SemanticColoringProvider { constructor( @@ -46,6 +52,8 @@ class SemanticColoringProvider implements vscode.SemanticColoringProvider { } async provideSemanticColoring(document: vscode.TextDocument, token: vscode.CancellationToken): Promise { + await timeout(0); + const file = this.client.toOpenedFilePath(document); if (!file) { return null; diff --git a/src/vs/editor/common/services/modelServiceImpl.ts b/src/vs/editor/common/services/modelServiceImpl.ts index b771a1bd85e..f2e2f54f14e 100644 --- a/src/vs/editor/common/services/modelServiceImpl.ts +++ b/src/vs/editor/common/services/modelServiceImpl.ts @@ -459,7 +459,6 @@ class ModelSemanticColoring extends Disposable { private readonly _fetchSemanticTokens: RunOnceScheduler; private _currentResponse: SemanticColoring | null; private _currentRequestCancellationTokenSource: CancellationTokenSource | null; - private _currentRequestVersion: number; constructor(model: ITextModel) { super(); @@ -468,7 +467,6 @@ class ModelSemanticColoring extends Disposable { this._fetchSemanticTokens = this._register(new RunOnceScheduler(() => this._fetchSemanticTokensNow(), 500)); this._currentResponse = null; this._currentRequestCancellationTokenSource = null; - this._currentRequestVersion = -1; this._register(this._model.onDidChangeContent(e => this._fetchSemanticTokens.schedule())); this._register(SemanticColoringProviderRegistry.onDidChange(e => this._fetchSemanticTokens.schedule())); @@ -497,16 +495,16 @@ class ModelSemanticColoring extends Disposable { return; } this._currentRequestCancellationTokenSource = new CancellationTokenSource(); - this._currentRequestVersion = this._model.getVersionId(); + const currentRequestVersion = this._model.getVersionId(); const request = Promise.resolve(provider.provideSemanticColoring(this._model, this._currentRequestCancellationTokenSource.token)); request.then((res) => { this._currentRequestCancellationTokenSource = null; - this._setSemanticTokens(this._currentRequestVersion, res || null); + this._setSemanticTokens(currentRequestVersion, res || null); }, (err) => { - this._currentRequestCancellationTokenSource = null; errors.onUnexpectedError(err); - this._setSemanticTokens(this._currentRequestVersion, null); + this._currentRequestCancellationTokenSource = null; + this._setSemanticTokens(currentRequestVersion, null); }); } @@ -520,6 +518,12 @@ class ModelSemanticColoring extends Disposable { this._model.setSemanticTokens(null); return; } + + if (versionId !== this._model.getVersionId()) { + console.log(`TODO@semantic: model changed in the meantime!!!`); + } + // TODO@semantic + // TODO@semantic: diff here and reduce to only really needed tokens... // TODO@semantic: might also be a good idea to split areas... ? const result: MultilineTokens2[] = []; diff --git a/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts b/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts index 3bf1c91f082..cb88646ecf9 100644 --- a/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts +++ b/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts @@ -606,7 +606,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha } -class SemanticColoringCacheEntry implements modes.SemanticColoring { +class MainThreadSemanticColoringCacheEntry implements modes.SemanticColoring { constructor( private readonly _parent: MainThreadSemanticColoringProvider, @@ -623,7 +623,7 @@ class SemanticColoringCacheEntry implements modes.SemanticColoring { class MainThreadSemanticColoringProvider implements modes.SemanticColoringProvider { - private readonly _cache = new Map(); + private readonly _cache = new Map(); constructor( private readonly _proxy: ExtHostLanguageFeaturesShape, @@ -632,8 +632,9 @@ class MainThreadSemanticColoringProvider implements modes.SemanticColoringProvid ) { } - release(entry: SemanticColoringCacheEntry): void { + release(entry: MainThreadSemanticColoringCacheEntry): void { this._cache.delete(entry.uri.toString()); + this._proxy.$releaseSemanticColoring(this._handle, entry.id); } getLegend(): modes.SemanticColoringLegend { @@ -650,12 +651,12 @@ class MainThreadSemanticColoringProvider implements modes.SemanticColoringProvid return null; } const dto = decodeSemanticTokensDto(encodedDto); - const res = this._createSemanticColoring(model, lastResult, dto); + const res = this._resolveDeltas(model, lastResult, dto); this._cache.set(model.uri.toString(), res); return res; } - private _createSemanticColoring(model: ITextModel, lastResult: SemanticColoringCacheEntry | null, dto: ISemanticTokensDto): SemanticColoringCacheEntry { + private _resolveDeltas(model: ITextModel, lastResult: MainThreadSemanticColoringCacheEntry | null, dto: ISemanticTokensDto): MainThreadSemanticColoringCacheEntry { let areas: modes.SemanticColoringArea[] = []; for (let i = 0, len = dto.areas.length; i < len; i++) { const areaDto = dto.areas[i]; @@ -671,6 +672,6 @@ class MainThreadSemanticColoringProvider implements modes.SemanticColoringProvid }; } } - return new SemanticColoringCacheEntry(this, model.uri, dto.id, areas); + return new MainThreadSemanticColoringCacheEntry(this, model.uri, dto.id, areas); } } diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 26719ecde27..d0f68d94f3b 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -1145,6 +1145,7 @@ export interface ExtHostLanguageFeaturesShape { $provideRenameEdits(handle: number, resource: UriComponents, position: IPosition, newName: string, token: CancellationToken): Promise; $resolveRenameLocation(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise; $provideSemanticColoring(handle: number, resource: UriComponents, previousSemanticColoringResultId: number, token: CancellationToken): Promise; + $releaseSemanticColoring(handle: number, semanticColoringResultId: number): void; $provideCompletionItems(handle: number, resource: UriComponents, position: IPosition, context: modes.CompletionContext, token: CancellationToken): Promise; $resolveCompletionItem(handle: number, resource: UriComponents, position: IPosition, id: ChainedCacheId, token: CancellationToken): Promise; $releaseCompletionItems(handle: number, id: number): void; diff --git a/src/vs/workbench/api/common/extHostLanguageFeatures.ts b/src/vs/workbench/api/common/extHostLanguageFeatures.ts index 4e34ccc6104..4d25880b146 100644 --- a/src/vs/workbench/api/common/extHostLanguageFeatures.ts +++ b/src/vs/workbench/api/common/extHostLanguageFeatures.ts @@ -633,6 +633,7 @@ class SemanticColoringAdapter { const previousResult = (previousSemanticColoringResultId !== 0 ? this._previousResults.get(previousSemanticColoringResultId) : null); if (previousResult) { + this._previousResults.delete(previousSemanticColoringResultId); return this._deltaEncode(previousResult, value); } @@ -640,6 +641,10 @@ class SemanticColoringAdapter { }); } + async releaseSemanticColoring(semanticColoringResultId: number): Promise { + this._previousResults.delete(semanticColoringResultId); + } + private _deltaEncode(previousResult: vscode.SemanticColoring, currentResult: vscode.SemanticColoring): VSBuffer { console.log(previousResult); console.log(currentResult); @@ -1542,6 +1547,10 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF return this._withAdapter(handle, SemanticColoringAdapter, adapter => adapter.provideSemanticColoring(URI.revive(resource), previousSemanticColoringResultId, token), null); } + $releaseSemanticColoring(handle: number, semanticColoringResultId: number): void { + this._withAdapter(handle, SemanticColoringAdapter, adapter => adapter.releaseSemanticColoring(semanticColoringResultId), undefined); + } + //#endregion // --- suggestion