diff --git a/src/vs/editor/contrib/codeAction/test/browser/codeAction.test.ts b/src/vs/editor/contrib/codeAction/test/browser/codeAction.test.ts index 09699fd6d12..ac919bb6192 100644 --- a/src/vs/editor/contrib/codeAction/test/browser/codeAction.test.ts +++ b/src/vs/editor/contrib/codeAction/test/browser/codeAction.test.ts @@ -6,6 +6,7 @@ import * as assert from 'assert'; import { CancellationToken } from 'vs/base/common/cancellation'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; import { Range } from 'vs/editor/common/core/range'; import { LanguageFeatureRegistry } from 'vs/editor/common/languageFeatureRegistry'; import * as languages from 'vs/editor/common/languages'; @@ -105,6 +106,8 @@ suite('CodeAction', () => { disposables.clear(); }); + ensureNoDisposablesAreLeakedInTestSuite(); + test('CodeActions are sorted by type, #38623', async () => { const provider = staticCodeActionProvider( @@ -130,7 +133,7 @@ suite('CodeAction', () => { new CodeActionItem(testData.tsLint.abc, provider) ]; - const { validActions: actions } = await getCodeActions(registry, model, new Range(1, 1, 2, 1), { type: languages.CodeActionTriggerType.Invoke, triggerAction: CodeActionTriggerSource.Default }, Progress.None, CancellationToken.None); + const { validActions: actions } = disposables.add(await getCodeActions(registry, model, new Range(1, 1, 2, 1), { type: languages.CodeActionTriggerType.Invoke, triggerAction: CodeActionTriggerSource.Default }, Progress.None, CancellationToken.None)); assert.strictEqual(actions.length, 6); assert.deepStrictEqual(actions, expected); }); @@ -145,20 +148,20 @@ suite('CodeAction', () => { disposables.add(registry.register('fooLang', provider)); { - const { validActions: actions } = await getCodeActions(registry, model, new Range(1, 1, 2, 1), { type: languages.CodeActionTriggerType.Auto, triggerAction: CodeActionTriggerSource.Default, filter: { include: new CodeActionKind('a') } }, Progress.None, CancellationToken.None); + const { validActions: actions } = disposables.add(await getCodeActions(registry, model, new Range(1, 1, 2, 1), { type: languages.CodeActionTriggerType.Auto, triggerAction: CodeActionTriggerSource.Default, filter: { include: new CodeActionKind('a') } }, Progress.None, CancellationToken.None)); assert.strictEqual(actions.length, 2); assert.strictEqual(actions[0].action.title, 'a'); assert.strictEqual(actions[1].action.title, 'a.b'); } { - const { validActions: actions } = await getCodeActions(registry, model, new Range(1, 1, 2, 1), { type: languages.CodeActionTriggerType.Auto, triggerAction: CodeActionTriggerSource.Default, filter: { include: new CodeActionKind('a.b') } }, Progress.None, CancellationToken.None); + const { validActions: actions } = disposables.add(await getCodeActions(registry, model, new Range(1, 1, 2, 1), { type: languages.CodeActionTriggerType.Auto, triggerAction: CodeActionTriggerSource.Default, filter: { include: new CodeActionKind('a.b') } }, Progress.None, CancellationToken.None)); assert.strictEqual(actions.length, 1); assert.strictEqual(actions[0].action.title, 'a.b'); } { - const { validActions: actions } = await getCodeActions(registry, model, new Range(1, 1, 2, 1), { type: languages.CodeActionTriggerType.Auto, triggerAction: CodeActionTriggerSource.Default, filter: { include: new CodeActionKind('a.b.c') } }, Progress.None, CancellationToken.None); + const { validActions: actions } = disposables.add(await getCodeActions(registry, model, new Range(1, 1, 2, 1), { type: languages.CodeActionTriggerType.Auto, triggerAction: CodeActionTriggerSource.Default, filter: { include: new CodeActionKind('a.b.c') } }, Progress.None, CancellationToken.None)); assert.strictEqual(actions.length, 0); } }); @@ -177,7 +180,7 @@ suite('CodeAction', () => { disposables.add(registry.register('fooLang', provider)); - const { validActions: actions } = await getCodeActions(registry, model, new Range(1, 1, 2, 1), { type: languages.CodeActionTriggerType.Auto, triggerAction: CodeActionTriggerSource.Default, filter: { include: new CodeActionKind('a') } }, Progress.None, CancellationToken.None); + const { validActions: actions } = disposables.add(await getCodeActions(registry, model, new Range(1, 1, 2, 1), { type: languages.CodeActionTriggerType.Auto, triggerAction: CodeActionTriggerSource.Default, filter: { include: new CodeActionKind('a') } }, Progress.None, CancellationToken.None)); assert.strictEqual(actions.length, 1); assert.strictEqual(actions[0].action.title, 'a'); }); @@ -191,13 +194,13 @@ suite('CodeAction', () => { disposables.add(registry.register('fooLang', provider)); { - const { validActions: actions } = await getCodeActions(registry, model, new Range(1, 1, 2, 1), { type: languages.CodeActionTriggerType.Auto, triggerAction: CodeActionTriggerSource.SourceAction }, Progress.None, CancellationToken.None); + const { validActions: actions } = disposables.add(await getCodeActions(registry, model, new Range(1, 1, 2, 1), { type: languages.CodeActionTriggerType.Auto, triggerAction: CodeActionTriggerSource.SourceAction }, Progress.None, CancellationToken.None)); assert.strictEqual(actions.length, 1); assert.strictEqual(actions[0].action.title, 'b'); } { - const { validActions: actions } = await getCodeActions(registry, model, new Range(1, 1, 2, 1), { type: languages.CodeActionTriggerType.Auto, triggerAction: CodeActionTriggerSource.Default, filter: { include: CodeActionKind.Source, includeSourceActions: true } }, Progress.None, CancellationToken.None); + const { validActions: actions } = disposables.add(await getCodeActions(registry, model, new Range(1, 1, 2, 1), { type: languages.CodeActionTriggerType.Auto, triggerAction: CodeActionTriggerSource.Default, filter: { include: CodeActionKind.Source, includeSourceActions: true } }, Progress.None, CancellationToken.None)); assert.strictEqual(actions.length, 1); assert.strictEqual(actions[0].action.title, 'a'); } @@ -213,13 +216,13 @@ suite('CodeAction', () => { disposables.add(registry.register('fooLang', provider)); { - const { validActions: actions } = await getCodeActions(registry, model, new Range(1, 1, 2, 1), { + const { validActions: actions } = disposables.add(await getCodeActions(registry, model, new Range(1, 1, 2, 1), { type: languages.CodeActionTriggerType.Auto, triggerAction: CodeActionTriggerSource.SourceAction, filter: { include: CodeActionKind.Source.append('test'), excludes: [CodeActionKind.Source], includeSourceActions: true, } - }, Progress.None, CancellationToken.None); + }, Progress.None, CancellationToken.None)); assert.strictEqual(actions.length, 1); assert.strictEqual(actions[0].action.title, 'b'); } @@ -250,12 +253,12 @@ suite('CodeAction', () => { })); { - const { validActions: actions } = await getCodeActions(registry, model, new Range(1, 1, 2, 1), { + const { validActions: actions } = disposables.add(await getCodeActions(registry, model, new Range(1, 1, 2, 1), { type: languages.CodeActionTriggerType.Auto, triggerAction: CodeActionTriggerSource.Refactor, filter: { include: baseType, excludes: [subType], } - }, Progress.None, CancellationToken.None); + }, Progress.None, CancellationToken.None)); assert.strictEqual(didInvoke, false); assert.strictEqual(actions.length, 1); assert.strictEqual(actions[0].action.title, 'a'); @@ -275,12 +278,12 @@ suite('CodeAction', () => { disposables.add(registry.register('fooLang', provider)); - const { validActions: actions } = await getCodeActions(registry, model, new Range(1, 1, 2, 1), { + const { validActions: actions } = disposables.add(await getCodeActions(registry, model, new Range(1, 1, 2, 1), { type: languages.CodeActionTriggerType.Auto, triggerAction: CodeActionTriggerSource.Refactor, filter: { include: CodeActionKind.QuickFix } - }, Progress.None, CancellationToken.None); + }, Progress.None, CancellationToken.None)); assert.strictEqual(actions.length, 0); assert.strictEqual(wasInvoked, false); }); diff --git a/src/vs/workbench/api/test/browser/extHostApiCommands.test.ts b/src/vs/workbench/api/test/browser/extHostApiCommands.test.ts index ab55eb49740..35e7543d864 100644 --- a/src/vs/workbench/api/test/browser/extHostApiCommands.test.ts +++ b/src/vs/workbench/api/test/browser/extHostApiCommands.test.ts @@ -62,6 +62,7 @@ import { IExtHostTelemetry } from 'vs/workbench/api/common/extHostTelemetry'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { ensureFileSystemProviderError } from 'vs/platform/files/common/files'; function assertRejects(fn: () => Promise, message: string = 'Expected rejection') { return fn().then(() => assert.ok(false, message), _err => assert.ok(true)); @@ -203,6 +204,8 @@ suite('ExtHostLanguageFeatureCommands', function () { return rpcProtocol.sync(); }); + ensureFileSystemProviderError(); + // --- workspace symbols test('WorkspaceSymbols, invalid arguments', function () { diff --git a/src/vs/workbench/api/test/browser/extHostDecorations.test.ts b/src/vs/workbench/api/test/browser/extHostDecorations.test.ts index 9666ee3e640..26b419f6e06 100644 --- a/src/vs/workbench/api/test/browser/extHostDecorations.test.ts +++ b/src/vs/workbench/api/test/browser/extHostDecorations.test.ts @@ -8,6 +8,7 @@ import { timeout } from 'vs/base/common/async'; import { CancellationToken } from 'vs/base/common/cancellation'; import { URI } from 'vs/base/common/uri'; import { mock } from 'vs/base/test/common/mock'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; import { NullLogService } from 'vs/platform/log/common/log'; import { MainThreadDecorationsShape } from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostDecorations } from 'vs/workbench/api/common/extHostDecorations'; @@ -20,6 +21,8 @@ suite('ExtHostDecorations', function () { let extHostDecorations: ExtHostDecorations; const providers = new Set(); + ensureNoDisposablesAreLeakedInTestSuite(); + setup(function () { providers.clear(); @@ -79,6 +82,9 @@ suite('ExtHostDecorations', function () { const secondResult = await Promise.race([second, timeout(30).then(() => false)]); assert.strictEqual(typeof secondResult, 'object'); + + + await timeout(30); }); }); diff --git a/src/vs/workbench/api/test/browser/extHostDocumentData.test.ts b/src/vs/workbench/api/test/browser/extHostDocumentData.test.ts index 638cce74296..b8912834f80 100644 --- a/src/vs/workbench/api/test/browser/extHostDocumentData.test.ts +++ b/src/vs/workbench/api/test/browser/extHostDocumentData.test.ts @@ -13,6 +13,7 @@ import { IModelChangedEvent } from 'vs/editor/common/model/mirrorTextModel'; import { mock } from 'vs/base/test/common/mock'; import * as perfData from './extHostDocumentData.test.perf-data'; import { setDefaultGetWordAtTextConfig } from 'vs/editor/common/core/wordHelper'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; suite('ExtHostDocumentData', () => { @@ -39,6 +40,8 @@ suite('ExtHostDocumentData', () => { ], '\n', 1, 'text', false); }); + ensureNoDisposablesAreLeakedInTestSuite(); + test('readonly-ness', () => { assert.throws(() => (data as any).document.uri = null); assert.throws(() => (data as any).document.fileName = 'foofile'); diff --git a/src/vs/workbench/api/test/browser/extHostDocumentsAndEditors.test.ts b/src/vs/workbench/api/test/browser/extHostDocumentsAndEditors.test.ts index 22e8c4a4a11..3f4255c49c8 100644 --- a/src/vs/workbench/api/test/browser/extHostDocumentsAndEditors.test.ts +++ b/src/vs/workbench/api/test/browser/extHostDocumentsAndEditors.test.ts @@ -8,6 +8,7 @@ import { URI } from 'vs/base/common/uri'; import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; import { TestRPCProtocol } from 'vs/workbench/api/test/common/testRPCProtocol'; import { NullLogService } from 'vs/platform/log/common/log'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; suite('ExtHostDocumentsAndEditors', () => { @@ -17,6 +18,8 @@ suite('ExtHostDocumentsAndEditors', () => { editors = new ExtHostDocumentsAndEditors(new TestRPCProtocol(), new NullLogService()); }); + ensureNoDisposablesAreLeakedInTestSuite(); + test('The value of TextDocument.isClosed is incorrect when a text document is closed, #27949', () => { editors.$acceptDocumentsAndEditorsDelta({ @@ -35,7 +38,7 @@ suite('ExtHostDocumentsAndEditors', () => { return new Promise((resolve, reject) => { - editors.onDidRemoveDocuments(e => { + const d = editors.onDidRemoveDocuments(e => { try { for (const data of e) { @@ -44,6 +47,8 @@ suite('ExtHostDocumentsAndEditors', () => { resolve(undefined); } catch (e) { reject(e); + } finally { + d.dispose(); } }); diff --git a/src/vs/workbench/api/test/browser/extHostFileSystemEventService.test.ts b/src/vs/workbench/api/test/browser/extHostFileSystemEventService.test.ts index 64d35e85b79..5063354ee59 100644 --- a/src/vs/workbench/api/test/browser/extHostFileSystemEventService.test.ts +++ b/src/vs/workbench/api/test/browser/extHostFileSystemEventService.test.ts @@ -6,9 +6,12 @@ import * as assert from 'assert'; import { ExtHostFileSystemEventService } from 'vs/workbench/api/common/extHostFileSystemEventService'; import { IMainContext } from 'vs/workbench/api/common/extHost.protocol'; import { NullLogService } from 'vs/platform/log/common/log'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; suite('ExtHostFileSystemEventService', () => { + ensureNoDisposablesAreLeakedInTestSuite(); + test('FileSystemWatcher ignore events properties are reversed #26851', function () { const protocol: IMainContext = { @@ -23,11 +26,13 @@ suite('ExtHostFileSystemEventService', () => { assert.strictEqual(watcher1.ignoreChangeEvents, false); assert.strictEqual(watcher1.ignoreCreateEvents, false); assert.strictEqual(watcher1.ignoreDeleteEvents, false); + watcher1.dispose(); const watcher2 = new ExtHostFileSystemEventService(protocol, new NullLogService(), undefined!).createFileSystemWatcher(undefined!, undefined!, '**/somethingBoring', true, true, true); assert.strictEqual(watcher2.ignoreChangeEvents, true); assert.strictEqual(watcher2.ignoreCreateEvents, true); assert.strictEqual(watcher2.ignoreDeleteEvents, true); + watcher2.dispose(); }); }); diff --git a/src/vs/workbench/api/test/browser/extHostLanguageFeatures.test.ts b/src/vs/workbench/api/test/browser/extHostLanguageFeatures.test.ts index dc5f1061385..0a04c931776 100644 --- a/src/vs/workbench/api/test/browser/extHostLanguageFeatures.test.ts +++ b/src/vs/workbench/api/test/browser/extHostLanguageFeatures.test.ts @@ -44,7 +44,7 @@ import { nullExtensionDescription as defaultExtension } from 'vs/workbench/servi import { provideSelectionRanges } from 'vs/editor/contrib/smartSelect/browser/smartSelect'; import { mock } from 'vs/base/test/common/mock'; import { IEditorWorkerService } from 'vs/editor/common/services/editorWorker'; -import { dispose } from 'vs/base/common/lifecycle'; +import { DisposableStore } from 'vs/base/common/lifecycle'; import { NullApiDeprecationService } from 'vs/workbench/api/common/extHostApiDeprecationService'; import { Progress } from 'vs/platform/progress/common/progress'; import { IExtHostFileSystemInfo } from 'vs/workbench/api/common/extHostFileSystemInfo'; @@ -55,6 +55,7 @@ import { LanguageFeaturesService } from 'vs/editor/common/services/languageFeatu import { CodeActionTriggerSource } from 'vs/editor/contrib/codeAction/common/types'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; import { IExtHostTelemetry } from 'vs/workbench/api/common/extHostTelemetry'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; suite('ExtHostLanguageFeatures', function () { @@ -62,7 +63,7 @@ suite('ExtHostLanguageFeatures', function () { let model: ITextModel; let extHost: ExtHostLanguageFeatures; let mainThread: MainThreadLanguageFeatures; - let disposables: vscode.Disposable[] = []; + const disposables = new DisposableStore(); let rpcProtocol: TestRPCProtocol; let languageFeaturesService: ILanguageFeaturesService; let originalErrorHandler: (e: any) => any; @@ -121,7 +122,7 @@ suite('ExtHostLanguageFeatures', function () { } }); rpcProtocol.set(ExtHostContext.ExtHostCommands, commands); - rpcProtocol.set(MainContext.MainThreadCommands, inst.createInstance(MainThreadCommands, rpcProtocol)); + rpcProtocol.set(MainContext.MainThreadCommands, disposables.add(inst.createInstance(MainThreadCommands, rpcProtocol))); const diagnostics = new ExtHostDiagnostics(rpcProtocol, new NullLogService(), new class extends mock() { }, extHostDocumentsAndEditors); rpcProtocol.set(ExtHostContext.ExtHostDiagnostics, diagnostics); @@ -133,7 +134,7 @@ suite('ExtHostLanguageFeatures', function () { }); rpcProtocol.set(ExtHostContext.ExtHostLanguageFeatures, extHost); - mainThread = rpcProtocol.set(MainContext.MainThreadLanguageFeatures, inst.createInstance(MainThreadLanguageFeatures, rpcProtocol)); + mainThread = rpcProtocol.set(MainContext.MainThreadLanguageFeatures, disposables.add(inst.createInstance(MainThreadLanguageFeatures, rpcProtocol))); }); suiteTeardown(() => { @@ -144,10 +145,12 @@ suite('ExtHostLanguageFeatures', function () { }); teardown(() => { - disposables = dispose(disposables); + disposables.clear(); return rpcProtocol.sync(); }); + ensureNoDisposablesAreLeakedInTestSuite(); + // --- outline test('DocumentSymbols, register/deregister', async () => { @@ -166,12 +169,12 @@ suite('ExtHostLanguageFeatures', function () { }); test('DocumentSymbols, evil provider', async () => { - disposables.push(extHost.registerDocumentSymbolProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentSymbolProvider { + disposables.add(extHost.registerDocumentSymbolProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentSymbolProvider { provideDocumentSymbols(): any { throw new Error('evil document symbol provider'); } })); - disposables.push(extHost.registerDocumentSymbolProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentSymbolProvider { + disposables.add(extHost.registerDocumentSymbolProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentSymbolProvider { provideDocumentSymbols(): any { return [new types.SymbolInformation('test', types.SymbolKind.Field, new types.Range(0, 0, 0, 0))]; } @@ -183,7 +186,7 @@ suite('ExtHostLanguageFeatures', function () { }); test('DocumentSymbols, data conversion', async () => { - disposables.push(extHost.registerDocumentSymbolProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentSymbolProvider { + disposables.add(extHost.registerDocumentSymbolProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentSymbolProvider { provideDocumentSymbols(): any { return [new types.SymbolInformation('test', types.SymbolKind.Field, new types.Range(0, 0, 0, 0))]; } @@ -207,7 +210,7 @@ suite('ExtHostLanguageFeatures', function () { { name: 'containerPort', range: { startLineNumber: 4, startColumn: 9, endLineNumber: 4, endColumn: 26 } } ]; - extHost.registerDocumentSymbolProvider(defaultExtension, defaultSelector, { + disposables.add(extHost.registerDocumentSymbolProvider(defaultExtension, defaultSelector, { provideDocumentSymbols: (doc, token): any => { return symbols.map(s => { return new types.SymbolInformation( @@ -217,7 +220,7 @@ suite('ExtHostLanguageFeatures', function () { ); }); } - }); + })); await rpcProtocol.sync(); @@ -231,12 +234,12 @@ suite('ExtHostLanguageFeatures', function () { test('CodeLens, evil provider', async () => { - disposables.push(extHost.registerCodeLensProvider(defaultExtension, defaultSelector, new class implements vscode.CodeLensProvider { + disposables.add(extHost.registerCodeLensProvider(defaultExtension, defaultSelector, new class implements vscode.CodeLensProvider { provideCodeLenses(): any { throw new Error('evil'); } })); - disposables.push(extHost.registerCodeLensProvider(defaultExtension, defaultSelector, new class implements vscode.CodeLensProvider { + disposables.add(extHost.registerCodeLensProvider(defaultExtension, defaultSelector, new class implements vscode.CodeLensProvider { provideCodeLenses() { return [new types.CodeLens(new types.Range(0, 0, 0, 0))]; } @@ -245,11 +248,12 @@ suite('ExtHostLanguageFeatures', function () { await rpcProtocol.sync(); const value = await getCodeLensModel(languageFeaturesService.codeLensProvider, model, CancellationToken.None); assert.strictEqual(value.lenses.length, 1); + value.dispose(); }); test('CodeLens, do not resolve a resolved lens', async () => { - disposables.push(extHost.registerCodeLensProvider(defaultExtension, defaultSelector, new class implements vscode.CodeLensProvider { + disposables.add(extHost.registerCodeLensProvider(defaultExtension, defaultSelector, new class implements vscode.CodeLensProvider { provideCodeLenses(): any { return [new types.CodeLens( new types.Range(0, 0, 0, 0), @@ -267,11 +271,12 @@ suite('ExtHostLanguageFeatures', function () { const symbol = await Promise.resolve(data.provider.resolveCodeLens!(model, data.symbol, CancellationToken.None)); assert.strictEqual(symbol!.command!.id, 'id'); assert.strictEqual(symbol!.command!.title, 'Title'); + value.dispose(); }); test('CodeLens, missing command', async () => { - disposables.push(extHost.registerCodeLensProvider(defaultExtension, defaultSelector, new class implements vscode.CodeLensProvider { + disposables.add(extHost.registerCodeLensProvider(defaultExtension, defaultSelector, new class implements vscode.CodeLensProvider { provideCodeLenses() { return [new types.CodeLens(new types.Range(0, 0, 0, 0))]; } @@ -284,13 +289,14 @@ suite('ExtHostLanguageFeatures', function () { const symbol = await Promise.resolve(data.provider.resolveCodeLens!(model, data.symbol, CancellationToken.None)); assert.strictEqual(symbol!.command!.id, 'missing'); assert.strictEqual(symbol!.command!.title, '!!MISSING: command!!'); + value.dispose(); }); // --- definition test('Definition, data conversion', async () => { - disposables.push(extHost.registerDefinitionProvider(defaultExtension, defaultSelector, new class implements vscode.DefinitionProvider { + disposables.add(extHost.registerDefinitionProvider(defaultExtension, defaultSelector, new class implements vscode.DefinitionProvider { provideDefinition(): any { return [new types.Location(model.uri, new types.Range(1, 2, 3, 4))]; } @@ -306,12 +312,12 @@ suite('ExtHostLanguageFeatures', function () { test('Definition, one or many', async () => { - disposables.push(extHost.registerDefinitionProvider(defaultExtension, defaultSelector, new class implements vscode.DefinitionProvider { + disposables.add(extHost.registerDefinitionProvider(defaultExtension, defaultSelector, new class implements vscode.DefinitionProvider { provideDefinition(): any { return [new types.Location(model.uri, new types.Range(1, 1, 1, 1))]; } })); - disposables.push(extHost.registerDefinitionProvider(defaultExtension, defaultSelector, new class implements vscode.DefinitionProvider { + disposables.add(extHost.registerDefinitionProvider(defaultExtension, defaultSelector, new class implements vscode.DefinitionProvider { provideDefinition(): any { return new types.Location(model.uri, new types.Range(2, 1, 1, 1)); } @@ -324,13 +330,13 @@ suite('ExtHostLanguageFeatures', function () { test('Definition, registration order', async () => { - disposables.push(extHost.registerDefinitionProvider(defaultExtension, defaultSelector, new class implements vscode.DefinitionProvider { + disposables.add(extHost.registerDefinitionProvider(defaultExtension, defaultSelector, new class implements vscode.DefinitionProvider { provideDefinition(): any { return [new types.Location(URI.parse('far://first'), new types.Range(2, 3, 4, 5))]; } })); - disposables.push(extHost.registerDefinitionProvider(defaultExtension, defaultSelector, new class implements vscode.DefinitionProvider { + disposables.add(extHost.registerDefinitionProvider(defaultExtension, defaultSelector, new class implements vscode.DefinitionProvider { provideDefinition(): any { return new types.Location(URI.parse('far://second'), new types.Range(1, 2, 3, 4)); } @@ -346,12 +352,12 @@ suite('ExtHostLanguageFeatures', function () { test('Definition, evil provider', async () => { - disposables.push(extHost.registerDefinitionProvider(defaultExtension, defaultSelector, new class implements vscode.DefinitionProvider { + disposables.add(extHost.registerDefinitionProvider(defaultExtension, defaultSelector, new class implements vscode.DefinitionProvider { provideDefinition(): any { throw new Error('evil provider'); } })); - disposables.push(extHost.registerDefinitionProvider(defaultExtension, defaultSelector, new class implements vscode.DefinitionProvider { + disposables.add(extHost.registerDefinitionProvider(defaultExtension, defaultSelector, new class implements vscode.DefinitionProvider { provideDefinition(): any { return new types.Location(model.uri, new types.Range(1, 1, 1, 1)); } @@ -366,7 +372,7 @@ suite('ExtHostLanguageFeatures', function () { test('Declaration, data conversion', async () => { - disposables.push(extHost.registerDeclarationProvider(defaultExtension, defaultSelector, new class implements vscode.DeclarationProvider { + disposables.add(extHost.registerDeclarationProvider(defaultExtension, defaultSelector, new class implements vscode.DeclarationProvider { provideDeclaration(): any { return [new types.Location(model.uri, new types.Range(1, 2, 3, 4))]; } @@ -384,7 +390,7 @@ suite('ExtHostLanguageFeatures', function () { test('Implementation, data conversion', async () => { - disposables.push(extHost.registerImplementationProvider(defaultExtension, defaultSelector, new class implements vscode.ImplementationProvider { + disposables.add(extHost.registerImplementationProvider(defaultExtension, defaultSelector, new class implements vscode.ImplementationProvider { provideImplementation(): any { return [new types.Location(model.uri, new types.Range(1, 2, 3, 4))]; } @@ -402,7 +408,7 @@ suite('ExtHostLanguageFeatures', function () { test('Type Definition, data conversion', async () => { - disposables.push(extHost.registerTypeDefinitionProvider(defaultExtension, defaultSelector, new class implements vscode.TypeDefinitionProvider { + disposables.add(extHost.registerTypeDefinitionProvider(defaultExtension, defaultSelector, new class implements vscode.TypeDefinitionProvider { provideTypeDefinition(): any { return [new types.Location(model.uri, new types.Range(1, 2, 3, 4))]; } @@ -420,7 +426,7 @@ suite('ExtHostLanguageFeatures', function () { test('HoverProvider, word range at pos', async () => { - disposables.push(extHost.registerHoverProvider(defaultExtension, defaultSelector, new class implements vscode.HoverProvider { + disposables.add(extHost.registerHoverProvider(defaultExtension, defaultSelector, new class implements vscode.HoverProvider { provideHover(): any { return new types.Hover('Hello'); } @@ -436,7 +442,7 @@ suite('ExtHostLanguageFeatures', function () { test('HoverProvider, given range', async () => { - disposables.push(extHost.registerHoverProvider(defaultExtension, defaultSelector, new class implements vscode.HoverProvider { + disposables.add(extHost.registerHoverProvider(defaultExtension, defaultSelector, new class implements vscode.HoverProvider { provideHover(): any { return new types.Hover('Hello', new types.Range(3, 0, 8, 7)); } @@ -451,14 +457,14 @@ suite('ExtHostLanguageFeatures', function () { test('HoverProvider, registration order', async () => { - disposables.push(extHost.registerHoverProvider(defaultExtension, defaultSelector, new class implements vscode.HoverProvider { + disposables.add(extHost.registerHoverProvider(defaultExtension, defaultSelector, new class implements vscode.HoverProvider { provideHover(): any { return new types.Hover('registered first'); } })); - disposables.push(extHost.registerHoverProvider(defaultExtension, defaultSelector, new class implements vscode.HoverProvider { + disposables.add(extHost.registerHoverProvider(defaultExtension, defaultSelector, new class implements vscode.HoverProvider { provideHover(): any { return new types.Hover('registered second'); } @@ -475,12 +481,12 @@ suite('ExtHostLanguageFeatures', function () { test('HoverProvider, evil provider', async () => { - disposables.push(extHost.registerHoverProvider(defaultExtension, defaultSelector, new class implements vscode.HoverProvider { + disposables.add(extHost.registerHoverProvider(defaultExtension, defaultSelector, new class implements vscode.HoverProvider { provideHover(): any { throw new Error('evil'); } })); - disposables.push(extHost.registerHoverProvider(defaultExtension, defaultSelector, new class implements vscode.HoverProvider { + disposables.add(extHost.registerHoverProvider(defaultExtension, defaultSelector, new class implements vscode.HoverProvider { provideHover(): any { return new types.Hover('Hello'); } @@ -495,7 +501,7 @@ suite('ExtHostLanguageFeatures', function () { test('Occurrences, data conversion', async () => { - disposables.push(extHost.registerDocumentHighlightProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentHighlightProvider { + disposables.add(extHost.registerDocumentHighlightProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentHighlightProvider { provideDocumentHighlights(): any { return [new types.DocumentHighlight(new types.Range(0, 0, 0, 4))]; } @@ -511,12 +517,12 @@ suite('ExtHostLanguageFeatures', function () { test('Occurrences, order 1/2', async () => { - disposables.push(extHost.registerDocumentHighlightProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentHighlightProvider { + disposables.add(extHost.registerDocumentHighlightProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentHighlightProvider { provideDocumentHighlights(): any { return []; } })); - disposables.push(extHost.registerDocumentHighlightProvider(defaultExtension, '*', new class implements vscode.DocumentHighlightProvider { + disposables.add(extHost.registerDocumentHighlightProvider(defaultExtension, '*', new class implements vscode.DocumentHighlightProvider { provideDocumentHighlights(): any { return [new types.DocumentHighlight(new types.Range(0, 0, 0, 4))]; } @@ -532,12 +538,12 @@ suite('ExtHostLanguageFeatures', function () { test('Occurrences, order 2/2', async () => { - disposables.push(extHost.registerDocumentHighlightProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentHighlightProvider { + disposables.add(extHost.registerDocumentHighlightProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentHighlightProvider { provideDocumentHighlights(): any { return [new types.DocumentHighlight(new types.Range(0, 0, 0, 2))]; } })); - disposables.push(extHost.registerDocumentHighlightProvider(defaultExtension, '*', new class implements vscode.DocumentHighlightProvider { + disposables.add(extHost.registerDocumentHighlightProvider(defaultExtension, '*', new class implements vscode.DocumentHighlightProvider { provideDocumentHighlights(): any { return [new types.DocumentHighlight(new types.Range(0, 0, 0, 4))]; } @@ -553,13 +559,13 @@ suite('ExtHostLanguageFeatures', function () { test('Occurrences, evil provider', async () => { - disposables.push(extHost.registerDocumentHighlightProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentHighlightProvider { + disposables.add(extHost.registerDocumentHighlightProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentHighlightProvider { provideDocumentHighlights(): any { throw new Error('evil'); } })); - disposables.push(extHost.registerDocumentHighlightProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentHighlightProvider { + disposables.add(extHost.registerDocumentHighlightProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentHighlightProvider { provideDocumentHighlights(): any { return [new types.DocumentHighlight(new types.Range(0, 0, 0, 4))]; } @@ -574,13 +580,13 @@ suite('ExtHostLanguageFeatures', function () { test('References, registration order', async () => { - disposables.push(extHost.registerReferenceProvider(defaultExtension, defaultSelector, new class implements vscode.ReferenceProvider { + disposables.add(extHost.registerReferenceProvider(defaultExtension, defaultSelector, new class implements vscode.ReferenceProvider { provideReferences(): any { return [new types.Location(URI.parse('far://register/first'), new types.Range(0, 0, 0, 0))]; } })); - disposables.push(extHost.registerReferenceProvider(defaultExtension, defaultSelector, new class implements vscode.ReferenceProvider { + disposables.add(extHost.registerReferenceProvider(defaultExtension, defaultSelector, new class implements vscode.ReferenceProvider { provideReferences(): any { return [new types.Location(URI.parse('far://register/second'), new types.Range(0, 0, 0, 0))]; } @@ -596,7 +602,7 @@ suite('ExtHostLanguageFeatures', function () { test('References, data conversion', async () => { - disposables.push(extHost.registerReferenceProvider(defaultExtension, defaultSelector, new class implements vscode.ReferenceProvider { + disposables.add(extHost.registerReferenceProvider(defaultExtension, defaultSelector, new class implements vscode.ReferenceProvider { provideReferences(): any { return [new types.Location(model.uri, new types.Position(0, 0))]; } @@ -612,12 +618,12 @@ suite('ExtHostLanguageFeatures', function () { test('References, evil provider', async () => { - disposables.push(extHost.registerReferenceProvider(defaultExtension, defaultSelector, new class implements vscode.ReferenceProvider { + disposables.add(extHost.registerReferenceProvider(defaultExtension, defaultSelector, new class implements vscode.ReferenceProvider { provideReferences(): any { throw new Error('evil'); } })); - disposables.push(extHost.registerReferenceProvider(defaultExtension, defaultSelector, new class implements vscode.ReferenceProvider { + disposables.add(extHost.registerReferenceProvider(defaultExtension, defaultSelector, new class implements vscode.ReferenceProvider { provideReferences(): any { return [new types.Location(model.uri, new types.Range(0, 0, 0, 0))]; } @@ -632,7 +638,7 @@ suite('ExtHostLanguageFeatures', function () { test('Quick Fix, command data conversion', async () => { - disposables.push(extHost.registerCodeActionProvider(defaultExtension, defaultSelector, { + disposables.add(extHost.registerCodeActionProvider(defaultExtension, defaultSelector, { provideCodeActions(): vscode.Command[] { return [ { command: 'test1', title: 'Testing1' }, @@ -642,18 +648,20 @@ suite('ExtHostLanguageFeatures', function () { })); await rpcProtocol.sync(); - const { validActions: actions } = await getCodeActions(languageFeaturesService.codeActionProvider, model, model.getFullModelRange(), { type: languages.CodeActionTriggerType.Invoke, triggerAction: CodeActionTriggerSource.QuickFix }, Progress.None, CancellationToken.None); + const value = await getCodeActions(languageFeaturesService.codeActionProvider, model, model.getFullModelRange(), { type: languages.CodeActionTriggerType.Invoke, triggerAction: CodeActionTriggerSource.QuickFix }, Progress.None, CancellationToken.None); + const { validActions: actions } = value; assert.strictEqual(actions.length, 2); const [first, second] = actions; assert.strictEqual(first.action.title, 'Testing1'); assert.strictEqual(first.action.command!.id, 'test1'); assert.strictEqual(second.action.title, 'Testing2'); assert.strictEqual(second.action.command!.id, 'test2'); + value.dispose(); }); test('Quick Fix, code action data conversion', async () => { - disposables.push(extHost.registerCodeActionProvider(defaultExtension, defaultSelector, { + disposables.add(extHost.registerCodeActionProvider(defaultExtension, defaultSelector, { provideCodeActions(): vscode.CodeAction[] { return [ { @@ -666,19 +674,21 @@ suite('ExtHostLanguageFeatures', function () { })); await rpcProtocol.sync(); - const { validActions: actions } = await getCodeActions(languageFeaturesService.codeActionProvider, model, model.getFullModelRange(), { type: languages.CodeActionTriggerType.Invoke, triggerAction: CodeActionTriggerSource.Default }, Progress.None, CancellationToken.None); + const value = await getCodeActions(languageFeaturesService.codeActionProvider, model, model.getFullModelRange(), { type: languages.CodeActionTriggerType.Invoke, triggerAction: CodeActionTriggerSource.Default }, Progress.None, CancellationToken.None); + const { validActions: actions } = value; assert.strictEqual(actions.length, 1); const [first] = actions; assert.strictEqual(first.action.title, 'Testing1'); assert.strictEqual(first.action.command!.title, 'Testing1Command'); assert.strictEqual(first.action.command!.id, 'test1'); assert.strictEqual(first.action.kind, 'test.scope'); + value.dispose(); }); test('Cannot read property \'id\' of undefined, #29469', async () => { - disposables.push(extHost.registerCodeActionProvider(defaultExtension, defaultSelector, new class implements vscode.CodeActionProvider { + disposables.add(extHost.registerCodeActionProvider(defaultExtension, defaultSelector, new class implements vscode.CodeActionProvider { provideCodeActions(): any { return [ undefined, @@ -689,39 +699,43 @@ suite('ExtHostLanguageFeatures', function () { })); await rpcProtocol.sync(); - const { validActions: actions } = await getCodeActions(languageFeaturesService.codeActionProvider, model, model.getFullModelRange(), { type: languages.CodeActionTriggerType.Invoke, triggerAction: CodeActionTriggerSource.Default }, Progress.None, CancellationToken.None); + const value = await getCodeActions(languageFeaturesService.codeActionProvider, model, model.getFullModelRange(), { type: languages.CodeActionTriggerType.Invoke, triggerAction: CodeActionTriggerSource.Default }, Progress.None, CancellationToken.None); + const { validActions: actions } = value; assert.strictEqual(actions.length, 1); + value.dispose(); }); test('Quick Fix, evil provider', async () => { - disposables.push(extHost.registerCodeActionProvider(defaultExtension, defaultSelector, new class implements vscode.CodeActionProvider { + disposables.add(extHost.registerCodeActionProvider(defaultExtension, defaultSelector, new class implements vscode.CodeActionProvider { provideCodeActions(): any { throw new Error('evil'); } })); - disposables.push(extHost.registerCodeActionProvider(defaultExtension, defaultSelector, new class implements vscode.CodeActionProvider { + disposables.add(extHost.registerCodeActionProvider(defaultExtension, defaultSelector, new class implements vscode.CodeActionProvider { provideCodeActions(): any { return [{ command: 'test', title: 'Testing' }]; } })); await rpcProtocol.sync(); - const { validActions: actions } = await getCodeActions(languageFeaturesService.codeActionProvider, model, model.getFullModelRange(), { type: languages.CodeActionTriggerType.Invoke, triggerAction: CodeActionTriggerSource.QuickFix }, Progress.None, CancellationToken.None); + const value = await getCodeActions(languageFeaturesService.codeActionProvider, model, model.getFullModelRange(), { type: languages.CodeActionTriggerType.Invoke, triggerAction: CodeActionTriggerSource.QuickFix }, Progress.None, CancellationToken.None); + const { validActions: actions } = value; assert.strictEqual(actions.length, 1); + value.dispose(); }); // --- navigate types test('Navigate types, evil provider', async () => { - disposables.push(extHost.registerWorkspaceSymbolProvider(defaultExtension, new class implements vscode.WorkspaceSymbolProvider { + disposables.add(extHost.registerWorkspaceSymbolProvider(defaultExtension, new class implements vscode.WorkspaceSymbolProvider { provideWorkspaceSymbols(): any { throw new Error('evil'); } })); - disposables.push(extHost.registerWorkspaceSymbolProvider(defaultExtension, new class implements vscode.WorkspaceSymbolProvider { + disposables.add(extHost.registerWorkspaceSymbolProvider(defaultExtension, new class implements vscode.WorkspaceSymbolProvider { provideWorkspaceSymbols(): any { return [new types.SymbolInformation('testing', types.SymbolKind.Array, new types.Range(0, 0, 1, 1))]; } @@ -736,19 +750,19 @@ suite('ExtHostLanguageFeatures', function () { test('Navigate types, de-duplicate results', async () => { const uri = URI.from({ scheme: 'foo', path: '/some/path' }); - disposables.push(extHost.registerWorkspaceSymbolProvider(defaultExtension, new class implements vscode.WorkspaceSymbolProvider { + disposables.add(extHost.registerWorkspaceSymbolProvider(defaultExtension, new class implements vscode.WorkspaceSymbolProvider { provideWorkspaceSymbols(): any { return [new types.SymbolInformation('ONE', types.SymbolKind.Array, undefined, new types.Location(uri, new types.Range(0, 0, 1, 1)))]; } })); - disposables.push(extHost.registerWorkspaceSymbolProvider(defaultExtension, new class implements vscode.WorkspaceSymbolProvider { + disposables.add(extHost.registerWorkspaceSymbolProvider(defaultExtension, new class implements vscode.WorkspaceSymbolProvider { provideWorkspaceSymbols(): any { return [new types.SymbolInformation('ONE', types.SymbolKind.Array, undefined, new types.Location(uri, new types.Range(0, 0, 1, 1)))]; // get de-duped } })); - disposables.push(extHost.registerWorkspaceSymbolProvider(defaultExtension, new class implements vscode.WorkspaceSymbolProvider { + disposables.add(extHost.registerWorkspaceSymbolProvider(defaultExtension, new class implements vscode.WorkspaceSymbolProvider { provideWorkspaceSymbols(): any { return [new types.SymbolInformation('ONE', types.SymbolKind.Array, undefined, new types.Location(uri, undefined!))]; // NO dedupe because of resolve } @@ -757,7 +771,7 @@ suite('ExtHostLanguageFeatures', function () { } })); - disposables.push(extHost.registerWorkspaceSymbolProvider(defaultExtension, new class implements vscode.WorkspaceSymbolProvider { + disposables.add(extHost.registerWorkspaceSymbolProvider(defaultExtension, new class implements vscode.WorkspaceSymbolProvider { provideWorkspaceSymbols(): any { return [new types.SymbolInformation('ONE', types.SymbolKind.Struct, undefined, new types.Location(uri, new types.Range(0, 0, 1, 1)))]; // NO dedupe because of kind } @@ -772,7 +786,7 @@ suite('ExtHostLanguageFeatures', function () { test('Rename, evil provider 0/2', async () => { - disposables.push(extHost.registerRenameProvider(defaultExtension, defaultSelector, new class implements vscode.RenameProvider { + disposables.add(extHost.registerRenameProvider(defaultExtension, defaultSelector, new class implements vscode.RenameProvider { provideRenameEdits(): any { throw new class Foo { }; } @@ -790,7 +804,7 @@ suite('ExtHostLanguageFeatures', function () { test('Rename, evil provider 1/2', async () => { - disposables.push(extHost.registerRenameProvider(defaultExtension, defaultSelector, new class implements vscode.RenameProvider { + disposables.add(extHost.registerRenameProvider(defaultExtension, defaultSelector, new class implements vscode.RenameProvider { provideRenameEdits(): any { throw Error('evil'); } @@ -803,13 +817,13 @@ suite('ExtHostLanguageFeatures', function () { test('Rename, evil provider 2/2', async () => { - disposables.push(extHost.registerRenameProvider(defaultExtension, '*', new class implements vscode.RenameProvider { + disposables.add(extHost.registerRenameProvider(defaultExtension, '*', new class implements vscode.RenameProvider { provideRenameEdits(): any { throw Error('evil'); } })); - disposables.push(extHost.registerRenameProvider(defaultExtension, defaultSelector, new class implements vscode.RenameProvider { + disposables.add(extHost.registerRenameProvider(defaultExtension, defaultSelector, new class implements vscode.RenameProvider { provideRenameEdits(): any { const edit = new types.WorkspaceEdit(); edit.replace(model.uri, new types.Range(0, 0, 0, 0), 'testing'); @@ -824,7 +838,7 @@ suite('ExtHostLanguageFeatures', function () { test('Rename, ordering', async () => { - disposables.push(extHost.registerRenameProvider(defaultExtension, '*', new class implements vscode.RenameProvider { + disposables.add(extHost.registerRenameProvider(defaultExtension, '*', new class implements vscode.RenameProvider { provideRenameEdits(): any { const edit = new types.WorkspaceEdit(); edit.replace(model.uri, new types.Range(0, 0, 0, 0), 'testing'); @@ -833,7 +847,7 @@ suite('ExtHostLanguageFeatures', function () { } })); - disposables.push(extHost.registerRenameProvider(defaultExtension, defaultSelector, new class implements vscode.RenameProvider { + disposables.add(extHost.registerRenameProvider(defaultExtension, defaultSelector, new class implements vscode.RenameProvider { provideRenameEdits(): any { return; } @@ -849,7 +863,7 @@ suite('ExtHostLanguageFeatures', function () { const called = [false, false, false, false]; - disposables.push(extHost.registerRenameProvider(defaultExtension, defaultSelector, new class implements vscode.RenameProvider { + disposables.add(extHost.registerRenameProvider(defaultExtension, defaultSelector, new class implements vscode.RenameProvider { prepareRename(document: vscode.TextDocument, position: vscode.Position,): vscode.ProviderResult { called[0] = true; const range = document.getWordRangeAtPosition(position); @@ -862,7 +876,7 @@ suite('ExtHostLanguageFeatures', function () { } })); - disposables.push(extHost.registerRenameProvider(defaultExtension, defaultSelector, new class implements vscode.RenameProvider { + disposables.add(extHost.registerRenameProvider(defaultExtension, defaultSelector, new class implements vscode.RenameProvider { prepareRename(document: vscode.TextDocument, position: vscode.Position,): vscode.ProviderResult { called[2] = true; return Promise.reject('Cannot rename this symbol2.'); @@ -883,7 +897,7 @@ suite('ExtHostLanguageFeatures', function () { const called = [false, false, false]; - disposables.push(extHost.registerRenameProvider(defaultExtension, defaultSelector, new class implements vscode.RenameProvider { + disposables.add(extHost.registerRenameProvider(defaultExtension, defaultSelector, new class implements vscode.RenameProvider { prepareRename(document: vscode.TextDocument, position: vscode.Position,): vscode.ProviderResult { called[0] = true; const range = document.getWordRangeAtPosition(position); @@ -896,7 +910,7 @@ suite('ExtHostLanguageFeatures', function () { } })); - disposables.push(extHost.registerRenameProvider(defaultExtension, defaultSelector, new class implements vscode.RenameProvider { + disposables.add(extHost.registerRenameProvider(defaultExtension, defaultSelector, new class implements vscode.RenameProvider { provideRenameEdits(document: vscode.TextDocument, position: vscode.Position, newName: string,): vscode.ProviderResult { called[2] = true; @@ -915,13 +929,13 @@ suite('ExtHostLanguageFeatures', function () { test('Parameter Hints, order', async () => { - disposables.push(extHost.registerSignatureHelpProvider(defaultExtension, defaultSelector, new class implements vscode.SignatureHelpProvider { + disposables.add(extHost.registerSignatureHelpProvider(defaultExtension, defaultSelector, new class implements vscode.SignatureHelpProvider { provideSignatureHelp(): any { return undefined; } }, [])); - disposables.push(extHost.registerSignatureHelpProvider(defaultExtension, defaultSelector, new class implements vscode.SignatureHelpProvider { + disposables.add(extHost.registerSignatureHelpProvider(defaultExtension, defaultSelector, new class implements vscode.SignatureHelpProvider { provideSignatureHelp(): vscode.SignatureHelp { return { signatures: [], @@ -938,7 +952,7 @@ suite('ExtHostLanguageFeatures', function () { test('Parameter Hints, evil provider', async () => { - disposables.push(extHost.registerSignatureHelpProvider(defaultExtension, defaultSelector, new class implements vscode.SignatureHelpProvider { + disposables.add(extHost.registerSignatureHelpProvider(defaultExtension, defaultSelector, new class implements vscode.SignatureHelpProvider { provideSignatureHelp(): any { throw new Error('evil'); } @@ -953,74 +967,77 @@ suite('ExtHostLanguageFeatures', function () { test('Suggest, order 1/3', async () => { - disposables.push(extHost.registerCompletionItemProvider(defaultExtension, '*', new class implements vscode.CompletionItemProvider { + disposables.add(extHost.registerCompletionItemProvider(defaultExtension, '*', new class implements vscode.CompletionItemProvider { provideCompletionItems(): any { return [new types.CompletionItem('testing1')]; } }, [])); - disposables.push(extHost.registerCompletionItemProvider(defaultExtension, defaultSelector, new class implements vscode.CompletionItemProvider { + disposables.add(extHost.registerCompletionItemProvider(defaultExtension, defaultSelector, new class implements vscode.CompletionItemProvider { provideCompletionItems(): any { return [new types.CompletionItem('testing2')]; } }, [])); await rpcProtocol.sync(); - const { items } = await provideSuggestionItems(languageFeaturesService.completionProvider, model, new EditorPosition(1, 1), new CompletionOptions(undefined, new Set().add(languages.CompletionItemKind.Snippet))); - assert.strictEqual(items.length, 1); - assert.strictEqual(items[0].completion.insertText, 'testing2'); + const value = await provideSuggestionItems(languageFeaturesService.completionProvider, model, new EditorPosition(1, 1), new CompletionOptions(undefined, new Set().add(languages.CompletionItemKind.Snippet))); + assert.strictEqual(value.items.length, 1); + assert.strictEqual(value.items[0].completion.insertText, 'testing2'); + value.disposable.dispose(); }); test('Suggest, order 2/3', async () => { - disposables.push(extHost.registerCompletionItemProvider(defaultExtension, '*', new class implements vscode.CompletionItemProvider { + disposables.add(extHost.registerCompletionItemProvider(defaultExtension, '*', new class implements vscode.CompletionItemProvider { provideCompletionItems(): any { return [new types.CompletionItem('weak-selector')]; // weaker selector but result } }, [])); - disposables.push(extHost.registerCompletionItemProvider(defaultExtension, defaultSelector, new class implements vscode.CompletionItemProvider { + disposables.add(extHost.registerCompletionItemProvider(defaultExtension, defaultSelector, new class implements vscode.CompletionItemProvider { provideCompletionItems(): any { return []; // stronger selector but not a good result; } }, [])); await rpcProtocol.sync(); - const { items } = await provideSuggestionItems(languageFeaturesService.completionProvider, model, new EditorPosition(1, 1), new CompletionOptions(undefined, new Set().add(languages.CompletionItemKind.Snippet))); - assert.strictEqual(items.length, 1); - assert.strictEqual(items[0].completion.insertText, 'weak-selector'); + const value = await provideSuggestionItems(languageFeaturesService.completionProvider, model, new EditorPosition(1, 1), new CompletionOptions(undefined, new Set().add(languages.CompletionItemKind.Snippet))); + assert.strictEqual(value.items.length, 1); + assert.strictEqual(value.items[0].completion.insertText, 'weak-selector'); + value.disposable.dispose(); }); test('Suggest, order 3/3', async () => { - disposables.push(extHost.registerCompletionItemProvider(defaultExtension, defaultSelector, new class implements vscode.CompletionItemProvider { + disposables.add(extHost.registerCompletionItemProvider(defaultExtension, defaultSelector, new class implements vscode.CompletionItemProvider { provideCompletionItems(): any { return [new types.CompletionItem('strong-1')]; } }, [])); - disposables.push(extHost.registerCompletionItemProvider(defaultExtension, defaultSelector, new class implements vscode.CompletionItemProvider { + disposables.add(extHost.registerCompletionItemProvider(defaultExtension, defaultSelector, new class implements vscode.CompletionItemProvider { provideCompletionItems(): any { return [new types.CompletionItem('strong-2')]; } }, [])); await rpcProtocol.sync(); - const { items } = await provideSuggestionItems(languageFeaturesService.completionProvider, model, new EditorPosition(1, 1), new CompletionOptions(undefined, new Set().add(languages.CompletionItemKind.Snippet))); - assert.strictEqual(items.length, 2); - assert.strictEqual(items[0].completion.insertText, 'strong-1'); // sort by label - assert.strictEqual(items[1].completion.insertText, 'strong-2'); + const value = await provideSuggestionItems(languageFeaturesService.completionProvider, model, new EditorPosition(1, 1), new CompletionOptions(undefined, new Set().add(languages.CompletionItemKind.Snippet))); + assert.strictEqual(value.items.length, 2); + assert.strictEqual(value.items[0].completion.insertText, 'strong-1'); // sort by label + assert.strictEqual(value.items[1].completion.insertText, 'strong-2'); + value.disposable.dispose(); }); test('Suggest, evil provider', async () => { - disposables.push(extHost.registerCompletionItemProvider(defaultExtension, defaultSelector, new class implements vscode.CompletionItemProvider { + disposables.add(extHost.registerCompletionItemProvider(defaultExtension, defaultSelector, new class implements vscode.CompletionItemProvider { provideCompletionItems(): any { throw new Error('evil'); } }, [])); - disposables.push(extHost.registerCompletionItemProvider(defaultExtension, defaultSelector, new class implements vscode.CompletionItemProvider { + disposables.add(extHost.registerCompletionItemProvider(defaultExtension, defaultSelector, new class implements vscode.CompletionItemProvider { provideCompletionItems(): any { return [new types.CompletionItem('testing')]; } @@ -1028,13 +1045,15 @@ suite('ExtHostLanguageFeatures', function () { await rpcProtocol.sync(); - const { items } = await provideSuggestionItems(languageFeaturesService.completionProvider, model, new EditorPosition(1, 1), new CompletionOptions(undefined, new Set().add(languages.CompletionItemKind.Snippet))); - assert.strictEqual(items[0].container.incomplete, false); + const value = await provideSuggestionItems(languageFeaturesService.completionProvider, model, new EditorPosition(1, 1), new CompletionOptions(undefined, new Set().add(languages.CompletionItemKind.Snippet))); + assert.strictEqual(value.items[0].container.incomplete, false); + value.disposable.dispose(); + }); test('Suggest, CompletionList', async () => { - disposables.push(extHost.registerCompletionItemProvider(defaultExtension, defaultSelector, new class implements vscode.CompletionItemProvider { + disposables.add(extHost.registerCompletionItemProvider(defaultExtension, defaultSelector, new class implements vscode.CompletionItemProvider { provideCompletionItems(): any { return new types.CompletionList([new types.CompletionItem('hello')], true); } @@ -1043,6 +1062,7 @@ suite('ExtHostLanguageFeatures', function () { await rpcProtocol.sync(); await provideSuggestionItems(languageFeaturesService.completionProvider, model, new EditorPosition(1, 1), new CompletionOptions(undefined, new Set().add(languages.CompletionItemKind.Snippet))).then(model => { assert.strictEqual(model.items[0].container.incomplete, true); + model.disposable.dispose(); }); }); @@ -1055,7 +1075,7 @@ suite('ExtHostLanguageFeatures', function () { }; test('Format Doc, data conversion', async () => { - disposables.push(extHost.registerDocumentFormattingEditProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentFormattingEditProvider { + disposables.add(extHost.registerDocumentFormattingEditProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentFormattingEditProvider { provideDocumentFormattingEdits(): any { return [new types.TextEdit(new types.Range(0, 0, 0, 0), 'testing'), types.TextEdit.setEndOfLine(types.EndOfLine.LF)]; } @@ -1073,7 +1093,7 @@ suite('ExtHostLanguageFeatures', function () { }); test('Format Doc, evil provider', async () => { - disposables.push(extHost.registerDocumentFormattingEditProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentFormattingEditProvider { + disposables.add(extHost.registerDocumentFormattingEditProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentFormattingEditProvider { provideDocumentFormattingEdits(): any { throw new Error('evil'); } @@ -1085,19 +1105,19 @@ suite('ExtHostLanguageFeatures', function () { test('Format Doc, order', async () => { - disposables.push(extHost.registerDocumentFormattingEditProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentFormattingEditProvider { + disposables.add(extHost.registerDocumentFormattingEditProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentFormattingEditProvider { provideDocumentFormattingEdits(): any { return undefined; } })); - disposables.push(extHost.registerDocumentFormattingEditProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentFormattingEditProvider { + disposables.add(extHost.registerDocumentFormattingEditProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentFormattingEditProvider { provideDocumentFormattingEdits(): any { return [new types.TextEdit(new types.Range(0, 0, 0, 0), 'testing')]; } })); - disposables.push(extHost.registerDocumentFormattingEditProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentFormattingEditProvider { + disposables.add(extHost.registerDocumentFormattingEditProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentFormattingEditProvider { provideDocumentFormattingEdits(): any { return undefined; } @@ -1112,7 +1132,7 @@ suite('ExtHostLanguageFeatures', function () { }); test('Format Range, data conversion', async () => { - disposables.push(extHost.registerDocumentRangeFormattingEditProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentRangeFormattingEditProvider { + disposables.add(extHost.registerDocumentRangeFormattingEditProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentRangeFormattingEditProvider { provideDocumentRangeFormattingEdits(): any { return [new types.TextEdit(new types.Range(0, 0, 0, 0), 'testing')]; } @@ -1127,17 +1147,17 @@ suite('ExtHostLanguageFeatures', function () { }); test('Format Range, + format_doc', async () => { - disposables.push(extHost.registerDocumentRangeFormattingEditProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentRangeFormattingEditProvider { + disposables.add(extHost.registerDocumentRangeFormattingEditProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentRangeFormattingEditProvider { provideDocumentRangeFormattingEdits(): any { return [new types.TextEdit(new types.Range(0, 0, 0, 0), 'range')]; } })); - disposables.push(extHost.registerDocumentRangeFormattingEditProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentRangeFormattingEditProvider { + disposables.add(extHost.registerDocumentRangeFormattingEditProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentRangeFormattingEditProvider { provideDocumentRangeFormattingEdits(): any { return [new types.TextEdit(new types.Range(2, 3, 4, 5), 'range2')]; } })); - disposables.push(extHost.registerDocumentFormattingEditProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentFormattingEditProvider { + disposables.add(extHost.registerDocumentFormattingEditProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentFormattingEditProvider { provideDocumentFormattingEdits(): any { return [new types.TextEdit(new types.Range(0, 0, 1, 1), 'doc')]; } @@ -1154,7 +1174,7 @@ suite('ExtHostLanguageFeatures', function () { }); test('Format Range, evil provider', async () => { - disposables.push(extHost.registerDocumentRangeFormattingEditProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentRangeFormattingEditProvider { + disposables.add(extHost.registerDocumentRangeFormattingEditProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentRangeFormattingEditProvider { provideDocumentRangeFormattingEdits(): any { throw new Error('evil'); } @@ -1166,7 +1186,7 @@ suite('ExtHostLanguageFeatures', function () { test('Format on Type, data conversion', async () => { - disposables.push(extHost.registerOnTypeFormattingEditProvider(defaultExtension, defaultSelector, new class implements vscode.OnTypeFormattingEditProvider { + disposables.add(extHost.registerOnTypeFormattingEditProvider(defaultExtension, defaultSelector, new class implements vscode.OnTypeFormattingEditProvider { provideOnTypeFormattingEdits(): any { return [new types.TextEdit(new types.Range(0, 0, 0, 0), arguments[2])]; } @@ -1182,7 +1202,7 @@ suite('ExtHostLanguageFeatures', function () { test('Links, data conversion', async () => { - disposables.push(extHost.registerDocumentLinkProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentLinkProvider { + disposables.add(extHost.registerDocumentLinkProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentLinkProvider { provideDocumentLinks() { const link = new types.DocumentLink(new types.Range(0, 0, 1, 1), URI.parse('foo:bar#3')); link.tooltip = 'tooltip'; @@ -1191,7 +1211,7 @@ suite('ExtHostLanguageFeatures', function () { })); await rpcProtocol.sync(); - const { links } = await getLinks(languageFeaturesService.linkProvider, model, CancellationToken.None); + const { links } = disposables.add(await getLinks(languageFeaturesService.linkProvider, model, CancellationToken.None)); assert.strictEqual(links.length, 1); const [first] = links; assert.strictEqual(first.url?.toString(), 'foo:bar#3'); @@ -1201,20 +1221,20 @@ suite('ExtHostLanguageFeatures', function () { test('Links, evil provider', async () => { - disposables.push(extHost.registerDocumentLinkProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentLinkProvider { + disposables.add(extHost.registerDocumentLinkProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentLinkProvider { provideDocumentLinks() { return [new types.DocumentLink(new types.Range(0, 0, 1, 1), URI.parse('foo:bar#3'))]; } })); - disposables.push(extHost.registerDocumentLinkProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentLinkProvider { + disposables.add(extHost.registerDocumentLinkProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentLinkProvider { provideDocumentLinks(): any { throw new Error(); } })); await rpcProtocol.sync(); - const { links } = await getLinks(languageFeaturesService.linkProvider, model, CancellationToken.None); + const { links } = disposables.add(await getLinks(languageFeaturesService.linkProvider, model, CancellationToken.None)); assert.strictEqual(links.length, 1); const [first] = links; assert.strictEqual(first.url?.toString(), 'foo:bar#3'); @@ -1223,7 +1243,7 @@ suite('ExtHostLanguageFeatures', function () { test('Document colors, data conversion', async () => { - disposables.push(extHost.registerColorProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentColorProvider { + disposables.add(extHost.registerColorProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentColorProvider { provideDocumentColors(): vscode.ColorInformation[] { return [new types.ColorInformation(new types.Range(0, 0, 0, 20), new types.Color(0.1, 0.2, 0.3, 0.4))]; } @@ -1243,7 +1263,7 @@ suite('ExtHostLanguageFeatures', function () { // -- selection ranges test('Selection Ranges, data conversion', async () => { - disposables.push(extHost.registerSelectionRangeProvider(defaultExtension, defaultSelector, new class implements vscode.SelectionRangeProvider { + disposables.add(extHost.registerSelectionRangeProvider(defaultExtension, defaultSelector, new class implements vscode.SelectionRangeProvider { provideSelectionRanges() { return [ new types.SelectionRange(new types.Range(0, 10, 0, 18), new types.SelectionRange(new types.Range(0, 2, 0, 20))), diff --git a/src/vs/workbench/api/test/browser/mainThreadDocumentsAndEditors.test.ts b/src/vs/workbench/api/test/browser/mainThreadDocumentsAndEditors.test.ts index 14ef427ac59..3d66d2dffa6 100644 --- a/src/vs/workbench/api/test/browser/mainThreadDocumentsAndEditors.test.ts +++ b/src/vs/workbench/api/test/browser/mainThreadDocumentsAndEditors.test.ts @@ -31,6 +31,7 @@ import { TestLanguageConfigurationService } from 'vs/editor/test/common/modes/te import { TextModel } from 'vs/editor/common/model/textModel'; import { LanguageService } from 'vs/editor/common/services/languageService'; import { DisposableStore } from 'vs/base/common/lifecycle'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; suite('MainThreadDocumentsAndEditors', () => { @@ -120,10 +121,12 @@ suite('MainThreadDocumentsAndEditors', () => { disposables.dispose(); }); + ensureNoDisposablesAreLeakedInTestSuite(); + test('Model#add', () => { deltas.length = 0; - modelService.createModel('farboo', null); + disposables.add(modelService.createModel('farboo', null)); assert.strictEqual(deltas.length, 1); const [delta] = deltas; @@ -143,6 +146,7 @@ suite('MainThreadDocumentsAndEditors', () => { TextModel._MODEL_SYNC_LIMIT = largeModelString.length / 2; const model = modelService.createModel(largeModelString, null); + disposables.add(model); assert.ok(model.isTooLargeForSyncing()); assert.strictEqual(deltas.length, 1); @@ -172,6 +176,7 @@ suite('MainThreadDocumentsAndEditors', () => { deltas.length = 0; assert.strictEqual(deltas.length, 0); editor.dispose(); + model.dispose(); } finally { TextModel._MODEL_SYNC_LIMIT = oldLimit; @@ -182,6 +187,7 @@ suite('MainThreadDocumentsAndEditors', () => { this.timeout(1000 * 60); // increase timeout for this one test const model = modelService.createModel('test', null, undefined, true); + disposables.add(model); assert.ok(model.isForSimpleWidget); assert.strictEqual(deltas.length, 1); @@ -227,10 +233,10 @@ suite('MainThreadDocumentsAndEditors', () => { assert.strictEqual(second.newActiveEditor, undefined); editor.dispose(); + model.dispose(); }); test('editor with dispos-ed/-ing model', () => { - modelService.createModel('foobar', null); const model = modelService.createModel('farboo', null); const editor = myCreateTestCodeEditor(model); @@ -248,5 +254,6 @@ suite('MainThreadDocumentsAndEditors', () => { assert.strictEqual(first.addedEditors, undefined); editor.dispose(); + model.dispose(); }); }); diff --git a/src/vs/workbench/contrib/snippets/test/browser/snippetsService.test.ts b/src/vs/workbench/contrib/snippets/test/browser/snippetsService.test.ts index 406ff2a20b1..e74a499f9c0 100644 --- a/src/vs/workbench/contrib/snippets/test/browser/snippetsService.test.ts +++ b/src/vs/workbench/contrib/snippets/test/browser/snippetsService.test.ts @@ -16,6 +16,7 @@ import { EditOperation } from 'vs/editor/common/core/editOperation'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { ILanguageService } from 'vs/editor/common/languages/language'; import { generateUuid } from 'vs/base/common/uuid'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; class SimpleSnippetService implements ISnippetsService { declare readonly _serviceBrand: undefined; @@ -83,9 +84,11 @@ suite('SnippetsService', function () { disposables.dispose(); }); + ensureNoDisposablesAreLeakedInTestSuite(); + test('snippet completions - simple', function () { - const provider = new SnippetCompletionProvider(languageService, snippetService, new TestLanguageConfigurationService()); + const provider = new SnippetCompletionProvider(languageService, snippetService, disposables.add(new TestLanguageConfigurationService())); const model = disposables.add(instantiateTextModel(instantiationService, '', 'fooLang')); return provider.provideCompletionItems(model, new Position(1, 1), context)!.then(result => { @@ -96,7 +99,7 @@ suite('SnippetsService', function () { test('snippet completions - simple 2', async function () { - const provider = new SnippetCompletionProvider(languageService, snippetService, new TestLanguageConfigurationService()); + const provider = new SnippetCompletionProvider(languageService, snippetService, disposables.add(new TestLanguageConfigurationService())); const model = disposables.add(instantiateTextModel(instantiationService, 'hello ', 'fooLang')); await provider.provideCompletionItems(model, new Position(1, 6) /* hello| */, context)!.then(result => { @@ -112,7 +115,7 @@ suite('SnippetsService', function () { test('snippet completions - with prefix', function () { - const provider = new SnippetCompletionProvider(languageService, snippetService, new TestLanguageConfigurationService()); + const provider = new SnippetCompletionProvider(languageService, snippetService, disposables.add(new TestLanguageConfigurationService())); const model = disposables.add(instantiateTextModel(instantiationService, 'bar', 'fooLang')); return provider.provideCompletionItems(model, new Position(1, 4), context)!.then(result => { @@ -150,7 +153,7 @@ suite('SnippetsService', function () { generateUuid() )]); - const provider = new SnippetCompletionProvider(languageService, snippetService, new TestLanguageConfigurationService()); + const provider = new SnippetCompletionProvider(languageService, snippetService, disposables.add(new TestLanguageConfigurationService())); const model = disposables.add(instantiateTextModel(instantiationService, 'bar-bar', 'fooLang')); await provider.provideCompletionItems(model, new Position(1, 3), context)!.then(result => { @@ -222,7 +225,7 @@ suite('SnippetsService', function () { generateUuid() )]); - const provider = new SnippetCompletionProvider(languageService, snippetService, new TestLanguageConfigurationService()); + const provider = new SnippetCompletionProvider(languageService, snippetService, disposables.add(new TestLanguageConfigurationService())); let model = instantiateTextModel(instantiationService, '\t { @@ -259,7 +262,7 @@ suite('SnippetsService', function () { generateUuid() )]); - const provider = new SnippetCompletionProvider(languageService, snippetService, new TestLanguageConfigurationService()); + const provider = new SnippetCompletionProvider(languageService, snippetService, disposables.add(new TestLanguageConfigurationService())); const model = disposables.add(instantiateTextModel(instantiationService, '\n\t\n>/head>', 'fooLang')); return provider.provideCompletionItems(model, new Position(1, 1), context)!.then(result => { @@ -293,7 +296,7 @@ suite('SnippetsService', function () { generateUuid() )]); - const provider = new SnippetCompletionProvider(languageService, snippetService, new TestLanguageConfigurationService()); + const provider = new SnippetCompletionProvider(languageService, snippetService, disposables.add(new TestLanguageConfigurationService())); const model = disposables.add(instantiateTextModel(instantiationService, '', 'fooLang')); return provider.provideCompletionItems(model, new Position(1, 1), context)!.then(result => { @@ -322,7 +325,7 @@ suite('SnippetsService', function () { SnippetSource.User, generateUuid() )]); - const provider = new SnippetCompletionProvider(languageService, snippetService, new TestLanguageConfigurationService()); + const provider = new SnippetCompletionProvider(languageService, snippetService, disposables.add(new TestLanguageConfigurationService())); const model = disposables.add(instantiateTextModel(instantiationService, 'p-', 'fooLang')); @@ -349,7 +352,7 @@ suite('SnippetsService', function () { generateUuid() )]); - const provider = new SnippetCompletionProvider(languageService, snippetService, new TestLanguageConfigurationService()); + const provider = new SnippetCompletionProvider(languageService, snippetService, disposables.add(new TestLanguageConfigurationService())); const model = disposables.add(instantiateTextModel(instantiationService, 'Thisisaverylonglinegoingwithmore100bcharactersandthismakesintellisensebecomea Thisisaverylonglinegoingwithmore100bcharactersandthismakesintellisensebecomea b', 'fooLang')); const result = await provider.provideCompletionItems(model, new Position(1, 158), context)!; @@ -370,7 +373,7 @@ suite('SnippetsService', function () { generateUuid() )]); - const provider = new SnippetCompletionProvider(languageService, snippetService, new TestLanguageConfigurationService()); + const provider = new SnippetCompletionProvider(languageService, snippetService, disposables.add(new TestLanguageConfigurationService())); const model = disposables.add(instantiateTextModel(instantiationService, ':', 'fooLang')); const result = await provider.provideCompletionItems(model, new Position(1, 2), context)!; @@ -391,7 +394,7 @@ suite('SnippetsService', function () { generateUuid() )]); - const provider = new SnippetCompletionProvider(languageService, snippetService, new TestLanguageConfigurationService()); + const provider = new SnippetCompletionProvider(languageService, snippetService, disposables.add(new TestLanguageConfigurationService())); const model = disposables.add(instantiateTextModel(instantiationService, 'template', 'fooLang')); const result = await provider.provideCompletionItems(model, new Position(1, 9), context)!; @@ -416,7 +419,7 @@ suite('SnippetsService', function () { generateUuid() )]); - const provider = new SnippetCompletionProvider(languageService, snippetService, new TestLanguageConfigurationService()); + const provider = new SnippetCompletionProvider(languageService, snippetService, disposables.add(new TestLanguageConfigurationService())); const model = disposables.add(instantiateTextModel(instantiationService, 'Thisisaverylonglinegoingwithmore100bcharactersandthismakesintellisensebecomea Thisisaverylonglinegoingwithmore100bcharactersandthismakesintellisensebecomea b text_after_b', 'fooLang')); const result = await provider.provideCompletionItems(model, new Position(1, 158), context)!; @@ -425,7 +428,7 @@ suite('SnippetsService', function () { }); test('issue #61296: VS code freezes when editing CSS file with emoji', async function () { - const languageConfigurationService = new TestLanguageConfigurationService(); + const languageConfigurationService = disposables.add(new TestLanguageConfigurationService()); disposables.add(languageConfigurationService.register('fooLang', { wordPattern: /(#?-?\d*\.\d\w*%?)|(::?[\w-]*(?=[^,{;]*[,{]))|(([@#.!])?[\w-?]+%?|[@#!.])/g })); @@ -463,7 +466,7 @@ suite('SnippetsService', function () { generateUuid() )]); - const provider = new SnippetCompletionProvider(languageService, snippetService, new TestLanguageConfigurationService()); + const provider = new SnippetCompletionProvider(languageService, snippetService, disposables.add(new TestLanguageConfigurationService())); const model = disposables.add(instantiateTextModel(instantiationService, 'a ', 'fooLang')); const result = await provider.provideCompletionItems(model, new Position(1, 3), context)!; @@ -494,7 +497,7 @@ suite('SnippetsService', function () { generateUuid() )]); - const provider = new SnippetCompletionProvider(languageService, snippetService, new TestLanguageConfigurationService()); + const provider = new SnippetCompletionProvider(languageService, snippetService, disposables.add(new TestLanguageConfigurationService())); let model = instantiateTextModel(instantiationService, ' <', 'fooLang'); let result = await provider.provideCompletionItems(model, new Position(1, 3), context)!; @@ -526,7 +529,7 @@ suite('SnippetsService', function () { generateUuid() )]); - const provider = new SnippetCompletionProvider(languageService, snippetService, new TestLanguageConfigurationService()); + const provider = new SnippetCompletionProvider(languageService, snippetService, disposables.add(new TestLanguageConfigurationService())); let model = instantiateTextModel(instantiationService, 'not wordFoo bar', 'fooLang'); let result = await provider.provideCompletionItems(model, new Position(1, 3), context)!; @@ -570,7 +573,7 @@ suite('SnippetsService', function () { generateUuid() )]); - const provider = new SnippetCompletionProvider(languageService, snippetService, new TestLanguageConfigurationService()); + const provider = new SnippetCompletionProvider(languageService, snippetService, disposables.add(new TestLanguageConfigurationService())); const model = instantiateTextModel(instantiationService, 'filler e KEEP ng filler', 'fooLang'); const result = await provider.provideCompletionItems(model, new Position(1, 9), context)!; @@ -583,7 +586,7 @@ suite('SnippetsService', function () { }); test('Snippet will replace auto-closing pair if specified in prefix', async function () { - const languageConfigurationService = new TestLanguageConfigurationService(); + const languageConfigurationService = disposables.add(new TestLanguageConfigurationService()); disposables.add(languageConfigurationService.register('fooLang', { brackets: [ ['{', '}'], @@ -631,7 +634,7 @@ suite('SnippetsService', function () { generateUuid() )]); - const provider = new SnippetCompletionProvider(languageService, snippetService, new TestLanguageConfigurationService()); + const provider = new SnippetCompletionProvider(languageService, snippetService, disposables.add(new TestLanguageConfigurationService())); const model = instantiateTextModel(instantiationService, ' ci', 'fooLang'); const result = await provider.provideCompletionItems(model, new Position(1, 4), context)!; @@ -652,7 +655,7 @@ suite('SnippetsService', function () { // new Snippet(['fooLang'], '\'ccc', '\'ccc', '', 'value', '', SnippetSource.User, generateUuid()) ]); - const provider = new SnippetCompletionProvider(languageService, snippetService, new TestLanguageConfigurationService()); + const provider = new SnippetCompletionProvider(languageService, snippetService, disposables.add(new TestLanguageConfigurationService())); const model = instantiateTextModel(instantiationService, '\'\'', 'fooLang'); const result = await provider.provideCompletionItems( @@ -674,7 +677,7 @@ suite('SnippetsService', function () { new Snippet(false, ['fooLang'], '\'ccc', '\'ccc', '', 'value', '', SnippetSource.User, generateUuid()) ]); - const provider = new SnippetCompletionProvider(languageService, snippetService, new TestLanguageConfigurationService()); + const provider = new SnippetCompletionProvider(languageService, snippetService, disposables.add(new TestLanguageConfigurationService())); const model = instantiateTextModel(instantiationService, '\'\'', 'fooLang'); @@ -695,7 +698,7 @@ suite('SnippetsService', function () { new Snippet(false, ['fooLang'], '^y', '^y', '', 'value', '', SnippetSource.User, generateUuid()), ]); - const provider = new SnippetCompletionProvider(languageService, snippetService, new TestLanguageConfigurationService()); + const provider = new SnippetCompletionProvider(languageService, snippetService, disposables.add(new TestLanguageConfigurationService())); const model = instantiateTextModel(instantiationService, '\'hellot\'', 'fooLang'); const result = await provider.provideCompletionItems( @@ -716,7 +719,7 @@ suite('SnippetsService', function () { new Snippet(false, ['fooLang'], '^y', '^y', '', 'value', '', SnippetSource.User, generateUuid()), ]); - const provider = new SnippetCompletionProvider(languageService, snippetService, new TestLanguageConfigurationService()); + const provider = new SnippetCompletionProvider(languageService, snippetService, disposables.add(new TestLanguageConfigurationService())); const model = instantiateTextModel(instantiationService, ')*&^', 'fooLang'); const result = await provider.provideCompletionItems( @@ -736,7 +739,7 @@ suite('SnippetsService', function () { new Snippet(false, ['fooLang'], 'foobarrrrrr', 'foobarrrrrr', '', 'value', '', SnippetSource.User, generateUuid()), ]); - const provider = new SnippetCompletionProvider(languageService, snippetService, new TestLanguageConfigurationService()); + const provider = new SnippetCompletionProvider(languageService, snippetService, disposables.add(new TestLanguageConfigurationService())); const model = instantiateTextModel(instantiationService, 'foobar', 'fooLang'); const result = await provider.provideCompletionItems( @@ -756,7 +759,7 @@ suite('SnippetsService', function () { ]); - const provider = new SnippetCompletionProvider(languageService, snippetService, new TestLanguageConfigurationService()); + const provider = new SnippetCompletionProvider(languageService, snippetService, disposables.add(new TestLanguageConfigurationService())); const model = instantiateTextModel(instantiationService, 'function abc(w)', 'fooLang'); const result = await provider.provideCompletionItems( model, @@ -775,7 +778,7 @@ suite('SnippetsService', function () { new Snippet(false, ['fooLang'], 'div#', 'div#', '', 'div#', '', SnippetSource.User, generateUuid()), ]); - const provider = new SnippetCompletionProvider(languageService, snippetService, new TestLanguageConfigurationService()); + const provider = new SnippetCompletionProvider(languageService, snippetService, disposables.add(new TestLanguageConfigurationService())); const model = instantiateTextModel(instantiationService, 'di', 'fooLang'); const result = await provider.provideCompletionItems( model, @@ -804,8 +807,8 @@ suite('SnippetsService', function () { snippetService = new SimpleSnippetService([ new Snippet(false, ['fooLang'], 'foo', 'Foo- Bar', '', 'Foo', '', SnippetSource.User, generateUuid()), ]); - const model = instantiateTextModel(instantiationService, ' bar', 'fooLang'); - const provider = new SnippetCompletionProvider(languageService, snippetService, new TestLanguageConfigurationService()); + const model = disposables.add(instantiateTextModel(instantiationService, ' bar', 'fooLang')); + const provider = new SnippetCompletionProvider(languageService, snippetService, disposables.add(new TestLanguageConfigurationService())); const result = await provider.provideCompletionItems( model, new Position(1, 8),