diff --git a/src/vs/editor/common/languages/modesRegistry.ts b/src/vs/editor/common/languages/modesRegistry.ts index 28fdbf80051..a61af971493 100644 --- a/src/vs/editor/common/languages/modesRegistry.ts +++ b/src/vs/editor/common/languages/modesRegistry.ts @@ -7,7 +7,7 @@ import * as nls from '../../../nls.js'; import { Emitter, Event } from '../../../base/common/event.js'; import { ILanguageExtensionPoint } from './language.js'; import { Registry } from '../../../platform/registry/common/platform.js'; -import { IDisposable } from '../../../base/common/lifecycle.js'; +import { Disposable, IDisposable } from '../../../base/common/lifecycle.js'; import { Mimes } from '../../../base/common/mime.js'; import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from '../../../platform/configuration/common/configurationRegistry.js'; @@ -16,14 +16,15 @@ export const Extensions = { ModesRegistry: 'editor.modesRegistry' }; -export class EditorModesRegistry { +export class EditorModesRegistry extends Disposable { private readonly _languages: ILanguageExtensionPoint[]; - private readonly _onDidChangeLanguages = new Emitter(); + private readonly _onDidChangeLanguages = this._register(new Emitter()); public readonly onDidChangeLanguages: Event = this._onDidChangeLanguages.event; constructor() { + super(); this._languages = []; } diff --git a/src/vs/editor/contrib/colorPicker/browser/colorDetector.ts b/src/vs/editor/contrib/colorPicker/browser/colorDetector.ts index e6043ebbd33..b5a12f416cd 100644 --- a/src/vs/editor/contrib/colorPicker/browser/colorDetector.ts +++ b/src/vs/editor/contrib/colorPicker/browser/colorDetector.ts @@ -47,7 +47,7 @@ export class ColorDetector extends Disposable implements IEditorContribution { private readonly _ruleFactory: DynamicCssRules; - private readonly _decoratorLimitReporter = new DecoratorLimitReporter(); + private readonly _decoratorLimitReporter = this._register(new DecoratorLimitReporter()); constructor( private readonly _editor: ICodeEditor, @@ -269,8 +269,8 @@ export class ColorDetector extends Disposable implements IEditorContribution { } } -export class DecoratorLimitReporter { - private _onDidChange = new Emitter(); +export class DecoratorLimitReporter extends Disposable { + private _onDidChange = this._register(new Emitter()); public readonly onDidChange: Event = this._onDidChange.event; private _computed: number = 0; diff --git a/src/vs/editor/contrib/folding/browser/folding.ts b/src/vs/editor/contrib/folding/browser/folding.ts index dedd1ce7964..edbc626e7b0 100644 --- a/src/vs/editor/contrib/folding/browser/folding.ts +++ b/src/vs/editor/contrib/folding/browser/folding.ts @@ -124,7 +124,7 @@ export class FoldingController extends Disposable implements IEditorContribution super(); this.editor = editor; - this._foldingLimitReporter = new RangesLimitReporter(editor); + this._foldingLimitReporter = this._register(new RangesLimitReporter(editor)); const options = this.editor.getOptions(); this._isEnabled = options.get(EditorOption.folding); @@ -513,15 +513,16 @@ export class FoldingController extends Disposable implements IEditorContribution } } -export class RangesLimitReporter implements FoldingLimitReporter { +export class RangesLimitReporter extends Disposable implements FoldingLimitReporter { constructor(private readonly editor: ICodeEditor) { + super(); } public get limit() { return this.editor.getOptions().get(EditorOption.foldingMaximumRegions); } - private _onDidChange = new Emitter(); + private _onDidChange = this._register(new Emitter()); public readonly onDidChange: Event = this._onDidChange.event; private _computed: number = 0; diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollModelProvider.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollModelProvider.ts index b313d5490df..7b0800a58c4 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollModelProvider.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollModelProvider.ts @@ -316,7 +316,7 @@ abstract class StickyModelFromCandidateFoldingProvider extends StickyModelCandid constructor(editor: IActiveCodeEditor) { super(editor); - this._foldingLimitReporter = new RangesLimitReporter(editor); + this._foldingLimitReporter = this._register(new RangesLimitReporter(editor)); } protected createStickyModel(token: CancellationToken, model: FoldingRegions): StickyModel { diff --git a/src/vs/platform/configuration/common/configurationRegistry.ts b/src/vs/platform/configuration/common/configurationRegistry.ts index bd8a8f2065f..4bfc7cbf6b8 100644 --- a/src/vs/platform/configuration/common/configurationRegistry.ts +++ b/src/vs/platform/configuration/common/configurationRegistry.ts @@ -13,6 +13,7 @@ import { getLanguageTagSettingPlainKey } from './configuration.js'; import { Extensions as JSONExtensions, IJSONContributionRegistry } from '../../jsonschemas/common/jsonContributionRegistry.js'; import { Registry } from '../../registry/common/platform.js'; import { IPolicy, PolicyName } from '../../../base/common/policy.js'; +import { Disposable } from '../../../base/common/lifecycle.js'; export enum EditPresentationTypes { Multiline = 'multilineText', @@ -272,7 +273,7 @@ export const configurationDefaultsSchemaId = 'vscode://schemas/settings/configur const contributionRegistry = Registry.as(JSONExtensions.JSONContribution); -class ConfigurationRegistry implements IConfigurationRegistry { +class ConfigurationRegistry extends Disposable implements IConfigurationRegistry { private readonly registeredConfigurationDefaults: IConfigurationDefaults[] = []; private readonly configurationDefaultsOverrides: Map; @@ -284,13 +285,14 @@ class ConfigurationRegistry implements IConfigurationRegistry { private readonly resourceLanguageSettingsSchema: IJSONSchema; private readonly overrideIdentifiers = new Set(); - private readonly _onDidSchemaChange = new Emitter(); + private readonly _onDidSchemaChange = this._register(new Emitter()); readonly onDidSchemaChange: Event = this._onDidSchemaChange.event; - private readonly _onDidUpdateConfiguration = new Emitter<{ properties: ReadonlySet; defaultsOverrides?: boolean }>(); + private readonly _onDidUpdateConfiguration = this._register(new Emitter<{ properties: ReadonlySet; defaultsOverrides?: boolean }>()); readonly onDidUpdateConfiguration = this._onDidUpdateConfiguration.event; constructor() { + super(); this.configurationDefaultsOverrides = new Map(); this.defaultLanguageConfigurationOverridesNode = { id: 'defaultOverrides', diff --git a/src/vs/platform/jsonschemas/common/jsonContributionRegistry.ts b/src/vs/platform/jsonschemas/common/jsonContributionRegistry.ts index f32f480f0b8..5f37ab3c587 100644 --- a/src/vs/platform/jsonschemas/common/jsonContributionRegistry.ts +++ b/src/vs/platform/jsonschemas/common/jsonContributionRegistry.ts @@ -5,7 +5,7 @@ import { Emitter, Event } from '../../../base/common/event.js'; import { getCompressedContent, IJSONSchema } from '../../../base/common/jsonSchema.js'; -import { DisposableStore, IDisposable, toDisposable } from '../../../base/common/lifecycle.js'; +import { Disposable, DisposableStore, IDisposable, toDisposable } from '../../../base/common/lifecycle.js'; import * as platform from '../../registry/common/platform.js'; export const Extensions = { @@ -65,15 +65,15 @@ function normalizeId(id: string) { -class JSONContributionRegistry implements IJSONContributionRegistry { +class JSONContributionRegistry extends Disposable implements IJSONContributionRegistry { private readonly schemasById: { [id: string]: IJSONSchema } = {}; private readonly schemaAssociations: { [uri: string]: string[] } = {}; - private readonly _onDidChangeSchema = new Emitter(); + private readonly _onDidChangeSchema = this._register(new Emitter()); readonly onDidChangeSchema: Event = this._onDidChangeSchema.event; - private readonly _onDidChangeSchemaAssociations = new Emitter(); + private readonly _onDidChangeSchemaAssociations = this._register(new Emitter()); readonly onDidChangeSchemaAssociations: Event = this._onDidChangeSchemaAssociations.event; public registerSchema(uri: string, unresolvedSchemaContent: IJSONSchema, store?: DisposableStore): void { diff --git a/src/vs/platform/registry/common/platform.ts b/src/vs/platform/registry/common/platform.ts index b4a9bdd775e..9beaaf7c25c 100644 --- a/src/vs/platform/registry/common/platform.ts +++ b/src/vs/platform/registry/common/platform.ts @@ -48,6 +48,16 @@ class RegistryImpl implements IRegistry { public as(id: string): any { return this.data.get(id) || null; } + + public dispose() { + this.data.forEach((value) => { + if (Types.isFunction(value.dispose)) { + value.dispose(); + } + }); + this.data.clear(); + } + } export const Registry: IRegistry = new RegistryImpl(); diff --git a/src/vs/platform/theme/common/colorUtils.ts b/src/vs/platform/theme/common/colorUtils.ts index b1f28d96686..74a83383b05 100644 --- a/src/vs/platform/theme/common/colorUtils.ts +++ b/src/vs/platform/theme/common/colorUtils.ts @@ -12,6 +12,7 @@ import { IJSONContributionRegistry, Extensions as JSONExtensions } from '../../j import * as platform from '../../registry/common/platform.js'; import { IColorTheme } from './themeService.js'; import * as nls from '../../../nls.js'; +import { Disposable } from '../../../base/common/lifecycle.js'; // ------ API types @@ -133,9 +134,9 @@ export interface IColorRegistry { type IJSONSchemaForColors = IJSONSchema & { properties: { [name: string]: { oneOf: [IJSONSchemaWithSnippets, IJSONSchema] } } }; type IJSONSchemaWithSnippets = IJSONSchema & { defaultSnippets: IJSONSchemaSnippet[] }; -class ColorRegistry implements IColorRegistry { +class ColorRegistry extends Disposable implements IColorRegistry { - private readonly _onDidChangeSchema = new Emitter(); + private readonly _onDidChangeSchema = this._register(new Emitter()); readonly onDidChangeSchema: Event = this._onDidChangeSchema.event; private colorsById: { [key: string]: ColorContribution }; @@ -143,6 +144,7 @@ class ColorRegistry implements IColorRegistry { private colorReferenceSchema: IJSONSchema & { enum: string[]; enumDescriptions: string[] } = { type: 'string', enum: [], enumDescriptions: [] }; constructor() { + super(); this.colorsById = {}; } @@ -214,7 +216,7 @@ class ColorRegistry implements IColorRegistry { return this.colorReferenceSchema; } - public toString() { + public override toString() { const sorter = (a: string, b: string) => { const cat1 = a.indexOf('.') === -1 ? 0 : 1; const cat2 = b.indexOf('.') === -1 ? 0 : 1; diff --git a/src/vs/platform/theme/common/iconRegistry.ts b/src/vs/platform/theme/common/iconRegistry.ts index 88cee9c3ddb..9feac0c4ca4 100644 --- a/src/vs/platform/theme/common/iconRegistry.ts +++ b/src/vs/platform/theme/common/iconRegistry.ts @@ -14,6 +14,7 @@ import { URI } from '../../../base/common/uri.js'; import { localize } from '../../../nls.js'; import { Extensions as JSONExtensions, IJSONContributionRegistry } from '../../jsonschemas/common/jsonContributionRegistry.js'; import * as platform from '../../registry/common/platform.js'; +import { Disposable } from '../../../base/common/lifecycle.js'; // ------ API types @@ -156,9 +157,9 @@ export const fontColorRegex = /^#[0-9a-fA-F]{0,6}$/; export const fontIdErrorMessage = localize('schema.fontId.formatError', 'The font ID must only contain letters, numbers, underscores and dashes.'); -class IconRegistry implements IIconRegistry { +class IconRegistry extends Disposable implements IIconRegistry { - private readonly _onDidChange = new Emitter(); + private readonly _onDidChange = this._register(new Emitter()); readonly onDidChange: Event = this._onDidChange.event; private iconsById: { [key: string]: IconContribution }; @@ -182,6 +183,7 @@ class IconRegistry implements IIconRegistry { private iconFontsById: { [key: string]: IconFontDefinition }; constructor() { + super(); this.iconsById = {}; this.iconFontsById = {}; } @@ -263,7 +265,7 @@ class IconRegistry implements IIconRegistry { return this.iconFontsById[id]; } - public toString() { + public override toString() { const sorter = (i1: IconContribution, i2: IconContribution) => { return i1.id.localeCompare(i2.id); }; diff --git a/src/vs/platform/theme/common/themeService.ts b/src/vs/platform/theme/common/themeService.ts index 649b9a44a91..fae8bf7f085 100644 --- a/src/vs/platform/theme/common/themeService.ts +++ b/src/vs/platform/theme/common/themeService.ts @@ -134,13 +134,14 @@ export interface IThemingRegistry { readonly onThemingParticipantAdded: Event; } -class ThemingRegistry implements IThemingRegistry { +class ThemingRegistry extends Disposable implements IThemingRegistry { private themingParticipants: IThemingParticipant[] = []; private readonly onThemingParticipantAddedEmitter: Emitter; constructor() { + super(); this.themingParticipants = []; - this.onThemingParticipantAddedEmitter = new Emitter(); + this.onThemingParticipantAddedEmitter = this._register(new Emitter()); } public onColorThemeChange(participant: IThemingParticipant): IDisposable { diff --git a/src/vs/platform/theme/common/tokenClassificationRegistry.ts b/src/vs/platform/theme/common/tokenClassificationRegistry.ts index 6b7e07ce8f3..f3503dea201 100644 --- a/src/vs/platform/theme/common/tokenClassificationRegistry.ts +++ b/src/vs/platform/theme/common/tokenClassificationRegistry.ts @@ -7,6 +7,7 @@ import { RunOnceScheduler } from '../../../base/common/async.js'; import { Color } from '../../../base/common/color.js'; import { Emitter, Event } from '../../../base/common/event.js'; import { IJSONSchema, IJSONSchemaMap } from '../../../base/common/jsonSchema.js'; +import { Disposable } from '../../../base/common/lifecycle.js'; import * as nls from '../../../nls.js'; import { Extensions as JSONExtensions, IJSONContributionRegistry } from '../../jsonschemas/common/jsonContributionRegistry.js'; import * as platform from '../../registry/common/platform.js'; @@ -261,9 +262,9 @@ export interface ITokenClassificationRegistry { getTokenStylingSchema(): IJSONSchema; } -class TokenClassificationRegistry implements ITokenClassificationRegistry { +class TokenClassificationRegistry extends Disposable implements ITokenClassificationRegistry { - private readonly _onDidChangeSchema = new Emitter(); + private readonly _onDidChangeSchema = this._register(new Emitter()); readonly onDidChangeSchema: Event = this._onDidChangeSchema.event; private currentTypeNumber = 0; @@ -347,6 +348,7 @@ class TokenClassificationRegistry implements ITokenClassificationRegistry { }; constructor() { + super(); this.tokenTypeById = Object.create(null); this.tokenModifierById = Object.create(null); this.typeHierarchy = Object.create(null); @@ -471,7 +473,7 @@ class TokenClassificationRegistry implements ITokenClassificationRegistry { } - public toString() { + public override toString() { const sorter = (a: string, b: string) => { const cat1 = a.indexOf('.') === -1 ? 0 : 1; const cat2 = b.indexOf('.') === -1 ? 0 : 1; diff --git a/src/vs/workbench/api/test/common/extHostExtensionActivator.test.ts b/src/vs/workbench/api/test/common/extHostExtensionActivator.test.ts index c13ac061a76..d7a3c6f68e8 100644 --- a/src/vs/workbench/api/test/common/extHostExtensionActivator.test.ts +++ b/src/vs/workbench/api/test/common/extHostExtensionActivator.test.ts @@ -13,6 +13,7 @@ import { NullLogService } from '../../../../platform/log/common/log.js'; import { ActivatedExtension, EmptyExtension, ExtensionActivationTimes, ExtensionsActivator, IExtensionsActivatorHost } from '../../common/extHostExtensionActivator.js'; import { ExtensionDescriptionRegistry, IActivationEventsReader } from '../../../services/extensions/common/extensionDescriptionRegistry.js'; import { ExtensionActivationReason, MissingExtensionDependency } from '../../../services/extensions/common/extensions.js'; +import { DisposableStore } from '../../../../base/common/lifecycle.js'; suite('ExtensionsActivator', () => { @@ -23,26 +24,30 @@ suite('ExtensionsActivator', () => { const idC = new ExtensionIdentifier(`c`); test('calls activate only once with sequential activations', async () => { + const disposables = new DisposableStore(); const host = new SimpleExtensionsActivatorHost(); const activator = createActivator(host, [ desc(idA) - ]); + ], [], disposables); await activator.activateByEvent('*', false); assert.deepStrictEqual(host.activateCalls, [idA]); await activator.activateByEvent('*', false); assert.deepStrictEqual(host.activateCalls, [idA]); + + disposables.dispose(); }); test('calls activate only once with parallel activations', async () => { + const disposables = new DisposableStore(); const extActivation = new ExtensionActivationPromiseSource(); const host = new PromiseExtensionsActivatorHost([ [idA, extActivation] ]); const activator = createActivator(host, [ desc(idA, [], ['evt1', 'evt2']) - ]); + ], [], disposables); const activate1 = activator.activateByEvent('evt1', false); const activate2 = activator.activateByEvent('evt2', false); @@ -53,9 +58,12 @@ suite('ExtensionsActivator', () => { await activate2; assert.deepStrictEqual(host.activateCalls, [idA]); + + disposables.dispose(); }); test('activates dependencies first', async () => { + const disposables = new DisposableStore(); const extActivationA = new ExtensionActivationPromiseSource(); const extActivationB = new ExtensionActivationPromiseSource(); const host = new PromiseExtensionsActivatorHost([ @@ -65,7 +73,7 @@ suite('ExtensionsActivator', () => { const activator = createActivator(host, [ desc(idA, [idB], ['evt1']), desc(idB, [], ['evt1']), - ]); + ], [], disposables); const activate = activator.activateByEvent('evt1', false); @@ -81,22 +89,28 @@ suite('ExtensionsActivator', () => { await activate; assert.deepStrictEqual(host.activateCalls, [idB, idA]); + + disposables.dispose(); }); test('Supports having resolved extensions', async () => { + const disposables = new DisposableStore(); const host = new SimpleExtensionsActivatorHost(); const bExt = desc(idB); delete (>bExt).main; delete (>bExt).browser; const activator = createActivator(host, [ desc(idA, [idB]) - ], [bExt]); + ], [bExt], disposables); await activator.activateByEvent('*', false); assert.deepStrictEqual(host.activateCalls, [idA]); + + disposables.dispose(); }); test('Supports having external extensions', async () => { + const disposables = new DisposableStore(); const extActivationA = new ExtensionActivationPromiseSource(); const extActivationB = new ExtensionActivationPromiseSource(); const host = new PromiseExtensionsActivatorHost([ @@ -107,7 +121,7 @@ suite('ExtensionsActivator', () => { (>bExt).api = 'none'; const activator = createActivator(host, [ desc(idA, [idB]) - ], [bExt]); + ], [bExt], disposables); const activate = activator.activateByEvent('*', false); @@ -121,14 +135,17 @@ suite('ExtensionsActivator', () => { await activate; assert.deepStrictEqual(host.activateCalls, [idB, idA]); + + disposables.dispose(); }); test('Error: activateById with missing extension', async () => { + const disposables = new DisposableStore(); const host = new SimpleExtensionsActivatorHost(); const activator = createActivator(host, [ desc(idA), desc(idB), - ]); + ], [], disposables); let error: Error | undefined = undefined; try { @@ -138,21 +155,27 @@ suite('ExtensionsActivator', () => { } assert.strictEqual(typeof error === 'undefined', false); + + disposables.dispose(); }); test('Error: dependency missing', async () => { + const disposables = new DisposableStore(); const host = new SimpleExtensionsActivatorHost(); const activator = createActivator(host, [ desc(idA, [idB]), - ]); + ], [], disposables); await activator.activateByEvent('*', false); assert.deepStrictEqual(host.errors.length, 1); assert.deepStrictEqual(host.errors[0][0], idA); + + disposables.dispose(); }); test('Error: dependency activation failed', async () => { + const disposables = new DisposableStore(); const extActivationA = new ExtensionActivationPromiseSource(); const extActivationB = new ExtensionActivationPromiseSource(); const host = new PromiseExtensionsActivatorHost([ @@ -162,7 +185,7 @@ suite('ExtensionsActivator', () => { const activator = createActivator(host, [ desc(idA, [idB]), desc(idB) - ]); + ], [], disposables); const activate = activator.activateByEvent('*', false); extActivationB.reject(new Error(`b fails!`)); @@ -171,9 +194,12 @@ suite('ExtensionsActivator', () => { assert.deepStrictEqual(host.errors.length, 2); assert.deepStrictEqual(host.errors[0][0], idB); assert.deepStrictEqual(host.errors[1][0], idA); + + disposables.dispose(); }); test('issue #144518: Problem with git extension and vscode-icons', async () => { + const disposables = new DisposableStore(); const extActivationA = new ExtensionActivationPromiseSource(); const extActivationB = new ExtensionActivationPromiseSource(); const extActivationC = new ExtensionActivationPromiseSource(); @@ -186,7 +212,7 @@ suite('ExtensionsActivator', () => { desc(idA, [idB]), desc(idB), desc(idC), - ]); + ], [], disposables); activator.activateByEvent('*', false); assert.deepStrictEqual(host.activateCalls, [idB, idC]); @@ -196,6 +222,8 @@ suite('ExtensionsActivator', () => { assert.deepStrictEqual(host.activateCalls, [idB, idC, idA]); extActivationA.resolve(); + + disposables.dispose(); }); class SimpleExtensionsActivatorHost implements IExtensionsActivatorHost { @@ -255,10 +283,10 @@ suite('ExtensionsActivator', () => { } }; - function createActivator(host: IExtensionsActivatorHost, extensionDescriptions: IExtensionDescription[], otherHostExtensionDescriptions: IExtensionDescription[] = []): ExtensionsActivator { - const registry = new ExtensionDescriptionRegistry(basicActivationEventsReader, extensionDescriptions); - const globalRegistry = new ExtensionDescriptionRegistry(basicActivationEventsReader, extensionDescriptions.concat(otherHostExtensionDescriptions)); - return new ExtensionsActivator(registry, globalRegistry, host, new NullLogService()); + function createActivator(host: IExtensionsActivatorHost, extensionDescriptions: IExtensionDescription[], otherHostExtensionDescriptions: IExtensionDescription[] = [], disposables: DisposableStore): ExtensionsActivator { + const registry = disposables.add(new ExtensionDescriptionRegistry(basicActivationEventsReader, extensionDescriptions)); + const globalRegistry = disposables.add(new ExtensionDescriptionRegistry(basicActivationEventsReader, extensionDescriptions.concat(otherHostExtensionDescriptions))); + return disposables.add(new ExtensionsActivator(registry, globalRegistry, host, new NullLogService())); } function desc(id: ExtensionIdentifier, deps: ExtensionIdentifier[] = [], activationEvents: string[] = ['*']): IExtensionDescription { diff --git a/src/vs/workbench/contrib/chat/browser/viewsWelcome/chatViewsWelcome.ts b/src/vs/workbench/contrib/chat/browser/viewsWelcome/chatViewsWelcome.ts index e0e7383bf40..f1b94e924b6 100644 --- a/src/vs/workbench/contrib/chat/browser/viewsWelcome/chatViewsWelcome.ts +++ b/src/vs/workbench/contrib/chat/browser/viewsWelcome/chatViewsWelcome.ts @@ -5,7 +5,7 @@ import { Emitter, Event } from '../../../../../base/common/event.js'; import { IMarkdownString } from '../../../../../base/common/htmlContent.js'; -import { DisposableStore } from '../../../../../base/common/lifecycle.js'; +import { Disposable, DisposableStore } from '../../../../../base/common/lifecycle.js'; import { ThemeIcon } from '../../../../../base/common/themables.js'; import { ContextKeyExpression } from '../../../../../platform/contextkey/common/contextkey.js'; import { Registry } from '../../../../../platform/registry/common/platform.js'; @@ -27,9 +27,9 @@ export interface IChatViewsWelcomeContributionRegistry { register(descriptor: IChatViewsWelcomeDescriptor): void; } -class ChatViewsWelcomeContributionRegistry implements IChatViewsWelcomeContributionRegistry { +class ChatViewsWelcomeContributionRegistry extends Disposable implements IChatViewsWelcomeContributionRegistry { private readonly descriptors: IChatViewsWelcomeDescriptor[] = []; - private readonly _onDidChange = new Emitter(); + private readonly _onDidChange = this._register(new Emitter()); public readonly onDidChange: Event = this._onDidChange.event; public register(descriptor: IChatViewsWelcomeDescriptor): void { diff --git a/src/vs/workbench/contrib/files/browser/explorerFileContrib.ts b/src/vs/workbench/contrib/files/browser/explorerFileContrib.ts index 116ec0994a9..4eb1ae4b3d3 100644 --- a/src/vs/workbench/contrib/files/browser/explorerFileContrib.ts +++ b/src/vs/workbench/contrib/files/browser/explorerFileContrib.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { Emitter } from '../../../../base/common/event.js'; -import { DisposableStore, IDisposable } from '../../../../base/common/lifecycle.js'; +import { Disposable, DisposableStore, IDisposable } from '../../../../base/common/lifecycle.js'; import { URI } from '../../../../base/common/uri.js'; import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js'; import { Registry } from '../../../../platform/registry/common/platform.js'; @@ -36,8 +36,8 @@ export interface IExplorerFileContributionRegistry { register(descriptor: IExplorerFileContributionDescriptor): void; } -class ExplorerFileContributionRegistry implements IExplorerFileContributionRegistry { - private readonly _onDidRegisterDescriptor = new Emitter(); +class ExplorerFileContributionRegistry extends Disposable implements IExplorerFileContributionRegistry { + private readonly _onDidRegisterDescriptor = this._register(new Emitter()); public readonly onDidRegisterDescriptor = this._onDidRegisterDescriptor.event; private readonly descriptors: IExplorerFileContributionDescriptor[] = []; diff --git a/src/vs/workbench/contrib/themes/browser/themes.contribution.ts b/src/vs/workbench/contrib/themes/browser/themes.contribution.ts index 64b0d0de73e..e64fcc3e374 100644 --- a/src/vs/workbench/contrib/themes/browser/themes.contribution.ts +++ b/src/vs/workbench/contrib/themes/browser/themes.contribution.ts @@ -41,7 +41,7 @@ import { mainWindow } from '../../../../base/browser/window.js'; import { IPreferencesService } from '../../../services/preferences/common/preferences.js'; import { Toggle } from '../../../../base/browser/ui/toggle/toggle.js'; import { defaultToggleStyles } from '../../../../platform/theme/browser/defaultStyles.js'; -import { DisposableStore } from '../../../../base/common/lifecycle.js'; +import { DisposableStore, IDisposable } from '../../../../base/common/lifecycle.js'; export const manageExtensionIcon = registerIcon('theme-selection-manage-extension', Codicon.gear, localize('manageExtensionIcon', 'Icon for the \'Manage\' action in the theme selection quick pick.')); @@ -53,7 +53,7 @@ enum ConfigureItem { CUSTOM_TOP_ENTRY = 'customTopEntry' } -class MarketplaceThemesPicker { +class MarketplaceThemesPicker implements IDisposable { private readonly _installedExtensions: Promise>; private readonly _marketplaceExtensions: Set = new Set(); private readonly _marketplaceThemes: ThemeItem[] = []; @@ -275,6 +275,7 @@ class MarketplaceThemesPicker { this._queryDelayer.dispose(); this._marketplaceExtensions.clear(); this._marketplaceThemes.length = 0; + this._onDidChange.dispose(); } } diff --git a/src/vs/workbench/services/extensions/common/extensionDescriptionRegistry.ts b/src/vs/workbench/services/extensions/common/extensionDescriptionRegistry.ts index 10486e47ffd..ed188f581ec 100644 --- a/src/vs/workbench/services/extensions/common/extensionDescriptionRegistry.ts +++ b/src/vs/workbench/services/extensions/common/extensionDescriptionRegistry.ts @@ -26,7 +26,7 @@ export interface IReadOnlyExtensionDescriptionRegistry { getExtensionDescriptionByIdOrUUID(extensionId: ExtensionIdentifier | string, uuid: string | undefined): IExtensionDescription | undefined; } -export class ExtensionDescriptionRegistry implements IReadOnlyExtensionDescriptionRegistry { +export class ExtensionDescriptionRegistry extends Disposable implements IReadOnlyExtensionDescriptionRegistry { public static isHostExtension(extensionId: ExtensionIdentifier | string, myRegistry: ExtensionDescriptionRegistry, globalRegistry: ExtensionDescriptionRegistry): boolean { if (myRegistry.getExtensionDescription(extensionId)) { @@ -44,7 +44,7 @@ export class ExtensionDescriptionRegistry implements IReadOnlyExtensionDescripti return false; } - private readonly _onDidChange = new Emitter(); + private readonly _onDidChange = this._register(new Emitter()); public readonly onDidChange = this._onDidChange.event; private _versionId: number = 0; @@ -57,6 +57,7 @@ export class ExtensionDescriptionRegistry implements IReadOnlyExtensionDescripti private readonly _activationEventsReader: IActivationEventsReader, extensionDescriptions: IExtensionDescription[] ) { + super(); this._extensionDescriptions = extensionDescriptions; this._initialize(); } diff --git a/src/vs/workbench/services/extensions/test/common/extensionDescriptionRegistry.test.ts b/src/vs/workbench/services/extensions/test/common/extensionDescriptionRegistry.test.ts index aa9cc6c629d..24348eb2260 100644 --- a/src/vs/workbench/services/extensions/test/common/extensionDescriptionRegistry.test.ts +++ b/src/vs/workbench/services/extensions/test/common/extensionDescriptionRegistry.test.ts @@ -28,6 +28,8 @@ suite('ExtensionDescriptionRegistry', () => { registry.deltaExtensions([extensionA2], [idA]); assert.deepStrictEqual(registry.getAllExtensionDescriptions(), [extensionA2]); + + registry.dispose(); }); function desc(id: ExtensionIdentifier, version: string, activationEvents: string[] = ['*']): IExtensionDescription { diff --git a/src/vs/workbench/services/output/common/output.ts b/src/vs/workbench/services/output/common/output.ts index 0617017a0bc..f5f30494024 100644 --- a/src/vs/workbench/services/output/common/output.ts +++ b/src/vs/workbench/services/output/common/output.ts @@ -10,6 +10,7 @@ import { RawContextKey } from '../../../../platform/contextkey/common/contextkey import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js'; import { LogLevel } from '../../../../platform/log/common/log.js'; import { Range } from '../../../../editor/common/core/range.js'; +import { Disposable } from '../../../../base/common/lifecycle.js'; /** * Mime type used by the output editor. @@ -271,16 +272,16 @@ export interface IOutputChannelRegistry { removeChannel(id: string): void; } -class OutputChannelRegistry implements IOutputChannelRegistry { +class OutputChannelRegistry extends Disposable implements IOutputChannelRegistry { private channels = new Map(); - private readonly _onDidRegisterChannel = new Emitter(); + private readonly _onDidRegisterChannel = this._register(new Emitter()); readonly onDidRegisterChannel = this._onDidRegisterChannel.event; - private readonly _onDidRemoveChannel = new Emitter(); + private readonly _onDidRemoveChannel = this._register(new Emitter()); readonly onDidRemoveChannel = this._onDidRemoveChannel.event; - private readonly _onDidUpdateChannelFiles = new Emitter(); + private readonly _onDidUpdateChannelFiles = this._register(new Emitter()); readonly onDidUpdateChannelSources = this._onDidUpdateChannelFiles.event; public registerChannel(descriptor: IOutputChannelDescriptor): void {