diff --git a/extensions/typescript-language-features/src/features/bufferSyncSupport.ts b/extensions/typescript-language-features/src/features/bufferSyncSupport.ts index d63c8c3a81c..564325f563c 100644 --- a/extensions/typescript-language-features/src/features/bufferSyncSupport.ts +++ b/extensions/typescript-language-features/src/features/bufferSyncSupport.ts @@ -117,10 +117,16 @@ class SyncedBufferMap extends ResourceMap { } class PendingDiagnostics extends ResourceMap { - public getFileList(): Set { - return new Set(Array.from(this.entries) - .sort((a, b) => a[1] - b[1]) - .map(entry => entry[0])); + public getOrderedFileSet(): ResourceMap { + const orderedResources = Array.from(this.entries) + .sort((a, b) => a.value - b.value) + .map(entry => entry.resource); + + const map = new ResourceMap(); + for (const resource of orderedResources) { + map.set(resource, void 0); + } + return map; } } @@ -128,7 +134,7 @@ class GetErrRequest { public static executeGetErrRequest( client: ITypeScriptServiceClient, - files: string[], + files: ResourceMap, onDone: () => void ) { const token = new vscode.CancellationTokenSource(); @@ -139,13 +145,15 @@ class GetErrRequest { private constructor( client: ITypeScriptServiceClient, - public readonly files: string[], + public readonly files: ResourceMap, private readonly _token: vscode.CancellationTokenSource, onDone: () => void ) { const args: Proto.GeterrRequestArgs = { delay: 0, - files + files: Array.from(files.entries) + .map(entry => client.normalizedPath(entry.resource)) + .filter(x => !!x) as string[] }; client.executeAsync('geterr', args, _token.token) @@ -345,27 +353,25 @@ export default class BufferSyncSupport extends Disposable { } private sendPendingDiagnostics(): void { - const fileList = this.pendingDiagnostics.getFileList(); + const orderedFileSet = this.pendingDiagnostics.getOrderedFileSet(); // Add all open TS buffers to the geterr request. They might be visible for (const buffer of this.syncedBuffers.values) { if (!this.pendingDiagnostics.has(buffer.resource)) { - fileList.add(buffer.filepath); + orderedFileSet.set(buffer.resource, void 0); } } - if (this.pendingGetErr) { - for (const file of this.pendingGetErr.files) { - fileList.add(file); - } - } - - if (fileList.size) { + if (orderedFileSet.size) { if (this.pendingGetErr) { this.pendingGetErr.cancel(); + + for (const file of this.pendingGetErr.files.entries) { + orderedFileSet.set(file.resource, void 0); + } } - const getErr = this.pendingGetErr = GetErrRequest.executeGetErrRequest(this.client, Array.from(fileList), () => { + const getErr = this.pendingGetErr = GetErrRequest.executeGetErrRequest(this.client, orderedFileSet, () => { if (this.pendingGetErr === getErr) { this.pendingGetErr = undefined; } diff --git a/extensions/typescript-language-features/src/utils/resourceMap.ts b/extensions/typescript-language-features/src/utils/resourceMap.ts index 73364c03207..33d6f00b4be 100644 --- a/extensions/typescript-language-features/src/utils/resourceMap.ts +++ b/extensions/typescript-language-features/src/utils/resourceMap.ts @@ -15,12 +15,16 @@ import { getTempFile } from './temp'; * file systems. */ export class ResourceMap { - private readonly _map = new Map(); + private readonly _map = new Map(); constructor( - private readonly _normalizePath?: (resource: vscode.Uri) => string | null + private readonly _normalizePath: (resource: vscode.Uri) => string | null = (resource) => resource.fsPath ) { } + public get size() { + return this._map.size; + } + public has(resource: vscode.Uri): boolean { const file = this.toKey(resource); return !!file && this._map.has(file); @@ -28,13 +32,23 @@ export class ResourceMap { public get(resource: vscode.Uri): T | undefined { const file = this.toKey(resource); - return file ? this._map.get(file) : undefined; + if (!file) { + return undefined; + } + const entry = this._map.get(file); + return entry ? entry.value : undefined; } public set(resource: vscode.Uri, value: T) { const file = this.toKey(resource); - if (file) { - this._map.set(file, value); + if (!file) { + return; + } + const entry = this._map.get(file); + if (entry) { + entry.value = value; + } else { + this._map.set(file, { resource, value }); } } @@ -45,20 +59,20 @@ export class ResourceMap { } } - public clear() { + public clear(): void { this._map.clear(); } public get values(): Iterable { + return Array.from(this._map.values()).map(x => x.value); + } + + public get entries(): Iterable<{ resource: vscode.Uri, value: T }> { return this._map.values(); } - public get entries() { - return this._map.entries(); - } - private toKey(resource: vscode.Uri): string | null { - const key = this._normalizePath ? this._normalizePath(resource) : resource.fsPath; + const key = this._normalizePath(resource); if (!key) { return key; }