From 8cdf377b6679db12cd7b37141925ab05a3e68253 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 8 Apr 2016 17:30:56 +0200 Subject: [PATCH] add DiagnosticsCollection#has and #get --- .../vscode-api-tests/src/languages.test.ts | 30 +++++++++++- src/vs/vscode.d.ts | 18 ++++++++ .../workbench/api/node/extHostDiagnostics.ts | 46 +++++++++++++++++-- 3 files changed, 89 insertions(+), 5 deletions(-) diff --git a/extensions/vscode-api-tests/src/languages.test.ts b/extensions/vscode-api-tests/src/languages.test.ts index f4199b0ff50..b93e4189f69 100644 --- a/extensions/vscode-api-tests/src/languages.test.ts +++ b/extensions/vscode-api-tests/src/languages.test.ts @@ -10,7 +10,7 @@ import {languages, Uri, Diagnostic, Range} from 'vscode'; suite('languages namespace tests', () => { - test('diagnostic collection', function () { + test('diagnostic collection, forEach, clear, has', function () { let collection = languages.createDiagnosticCollection('test'); assert.equal(collection.name, 'test'); collection.dispose(); @@ -43,5 +43,33 @@ suite('languages namespace tests', () => { ]); collection.forEach(() => c++); assert.equal(c, 2); + + assert.ok(collection.has(Uri.parse('foo:bar1'))); + assert.ok(collection.has(Uri.parse('foo:bar2'))); + assert.ok(!collection.has(Uri.parse('foo:bar3'))); + collection.delete(Uri.parse('foo:bar1')); + assert.ok(!collection.has(Uri.parse('foo:bar1'))); + }); + + test('diagnostic collection, immutable read', function () { + let collection = languages.createDiagnosticCollection('test'); + collection.set(Uri.parse('foo:bar'), [ + new Diagnostic(new Range(0, 0, 1, 1), 'message-1'), + new Diagnostic(new Range(0, 0, 1, 1), 'message-2') + ]); + + let array = collection.get(Uri.parse('foo:bar')); + assert.throws(() => array.length = 0); + assert.throws(() => array.pop()); + assert.throws(() => array[0] = new Diagnostic(new Range(0, 0, 0, 0), 'evil')); + + collection.forEach((uri, array) => { + assert.throws(() => array.length = 0); + assert.throws(() => array.pop()); + assert.throws(() => array[0] = new Diagnostic(new Range(0, 0, 0, 0), 'evil')); + }); + + array = collection.get(Uri.parse('foo:bar')); + assert.equal(array.length, 2); }); }); \ No newline at end of file diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index c5d074b8fcc..ec8aa7ffa99 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -2509,6 +2509,24 @@ declare namespace vscode { */ forEach(callback: (uri: Uri, diagnostics: Diagnostic[], collection: DiagnosticCollection) => any, thisArg?: any): void; + /** + * Get the diagnostics for a given resource. *Note* that you cannot + * modify the diagnostics-array returned from this call. + * + * @param uri A resource identifier. + * @returns An immutable array of [diagnostics](#Diagnostic) or `undefined`. + */ + get(uri: Uri): Diagnostic[]; + + /** + * Check if this collection contains diagnostics for a + * given resource. + * + * @param uri A resource identifier. + * @returns `true` if this collection has diagnostic for the given resource. + */ + has(uri: Uri): boolean; + /** * Dispose and free associated resources. Calls * [clear](#DiagnosticCollection.clear). diff --git a/src/vs/workbench/api/node/extHostDiagnostics.ts b/src/vs/workbench/api/node/extHostDiagnostics.ts index 1c6dea5eb6c..e38853a228c 100644 --- a/src/vs/workbench/api/node/extHostDiagnostics.ts +++ b/src/vs/workbench/api/node/extHostDiagnostics.ts @@ -11,7 +11,7 @@ import {TPromise} from 'vs/base/common/winjs.base'; import Severity from 'vs/base/common/severity'; import * as vscode from 'vscode'; -class DiagnosticCollection implements vscode.DiagnosticCollection { +export class DiagnosticCollection implements vscode.DiagnosticCollection { private static _maxDiagnosticsPerFile: number = 250; @@ -113,10 +113,24 @@ class DiagnosticCollection implements vscode.DiagnosticCollection { forEach(callback: (uri: URI, diagnostics: vscode.Diagnostic[], collection: DiagnosticCollection) => any, thisArg?: any): void { this._checkDisposed(); for (let key in this._data) { - callback.apply(thisArg, [URI.parse(key), this._data[key], this]); + let uri = URI.parse(key); + callback.apply(thisArg, [uri, this.get(uri), this]); } } + get(uri: URI): vscode.Diagnostic[] { + this._checkDisposed(); + let result = this._data[uri.toString()]; + if (Array.isArray(result)) { + return Object.freeze(result.slice(0)); + } + } + + has(uri: URI): boolean { + this._checkDisposed(); + return Array.isArray(this._data[uri.toString()]); + } + private _checkDisposed() { if (this._isDisposed) { throw new Error('illegal state - object is disposed'); @@ -150,20 +164,44 @@ class DiagnosticCollection implements vscode.DiagnosticCollection { } } +@Remotable.ExtHostContext('ExtHostDiagnostics') export class ExtHostDiagnostics { private static _idPool: number = 0; + private _proxy: MainThreadDiagnostics; + private _collections: DiagnosticCollection[]; - constructor(threadService: IThreadService) { + constructor(@IThreadService threadService: IThreadService) { this._proxy = threadService.getRemotable(MainThreadDiagnostics); + this._collections = []; } createDiagnosticCollection(name: string): vscode.DiagnosticCollection { if (!name) { name = '_generated_diagnostic_collection_name_#' + ExtHostDiagnostics._idPool++; } - return new DiagnosticCollection(name, this._proxy); + + const {_collections, _proxy} = this; + const result = new class extends DiagnosticCollection { + constructor() { + super(name, _proxy); + _collections.push(this); + } + dispose() { + super.dispose(); + let idx = _collections.indexOf(this); + if (idx !== -1) { + _collections.splice(idx, 1); + } + } + }; + + return result; + } + + forEach(callback: (collection: DiagnosticCollection) => any): void { + this._collections.forEach(callback); } } -- GitLab