diff --git a/src/vs/base/browser/htmlContentRenderer.ts b/src/vs/base/browser/htmlContentRenderer.ts index 5d94e04008d..b937a7fc9e5 100644 --- a/src/vs/base/browser/htmlContentRenderer.ts +++ b/src/vs/base/browser/htmlContentRenderer.ts @@ -17,7 +17,7 @@ import { cloneAndChange } from 'vs/base/common/objects'; export interface IContentActionHandler { callback: (content: string, event?: IMouseEvent) => void; - disposeables: IDisposable[]; + readonly disposeables: IDisposable[]; } export interface RenderOptions { diff --git a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts index 28658f3ee60..e00a5072157 100644 --- a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts +++ b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts @@ -9,7 +9,7 @@ import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableEle import { commonPrefixLength } from 'vs/base/common/arrays'; import { Color } from 'vs/base/common/color'; import { Emitter, Event } from 'vs/base/common/event'; -import { dispose, IDisposable, combinedDisposable } from 'vs/base/common/lifecycle'; +import { dispose, IDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { ScrollbarVisibility } from 'vs/base/common/scrollable'; import 'vs/css!./breadcrumbsWidget'; @@ -134,14 +134,14 @@ export class BreadcrumbsWidget { } private _updateDimensions(dim: dom.Dimension): IDisposable { - let disposables: IDisposable[] = []; + const disposables = new DisposableStore(); disposables.push(dom.modify(() => { this._dimension = dim; this._domNode.style.width = `${dim.width}px`; this._domNode.style.height = `${dim.height}px`; disposables.push(this._updateScrollbar()); })); - return combinedDisposable(disposables); + return disposables; } private _updateScrollbar(): IDisposable { diff --git a/src/vs/base/browser/ui/checkbox/checkbox.ts b/src/vs/base/browser/ui/checkbox/checkbox.ts index a4419eda426..7058fa3f89c 100644 --- a/src/vs/base/browser/ui/checkbox/checkbox.ts +++ b/src/vs/base/browser/ui/checkbox/checkbox.ts @@ -12,7 +12,7 @@ import { Emitter, Event } from 'vs/base/common/event'; import { KeyCode } from 'vs/base/common/keyCodes'; import * as objects from 'vs/base/common/objects'; import { BaseActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { DisposableStore } from 'vs/base/common/lifecycle'; export interface ICheckboxOpts extends ICheckboxStyles { readonly actionClassName?: string; @@ -31,19 +31,20 @@ const defaultOpts = { export class CheckboxActionViewItem extends BaseActionViewItem { private checkbox: Checkbox; - private disposables: IDisposable[] = []; + private disposables = new DisposableStore(); render(container: HTMLElement): void { this.element = container; - this.disposables = dispose(this.disposables); + this.disposables.dispose(); + this.disposables = new DisposableStore(); this.checkbox = new Checkbox({ actionClassName: this._action.class, isChecked: this._action.checked, title: this._action.label }); this.disposables.push(this.checkbox); - this.checkbox.onChange(() => this._action.checked = this.checkbox.checked, this, this.disposables); + this.disposables.push(this.checkbox.onChange(() => this._action.checked = this.checkbox.checked, this)); this.element.appendChild(this.checkbox.domNode); } @@ -64,10 +65,9 @@ export class CheckboxActionViewItem extends BaseActionViewItem { } dipsose(): void { - this.disposables = dispose(this.disposables); + this.disposables.dispose(); super.dispose(); } - } export class Checkbox extends Widget { diff --git a/src/vs/base/browser/ui/contextview/contextview.ts b/src/vs/base/browser/ui/contextview/contextview.ts index af21d4d8cf6..8e27c026220 100644 --- a/src/vs/base/browser/ui/contextview/contextview.ts +++ b/src/vs/base/browser/ui/contextview/contextview.ts @@ -5,7 +5,7 @@ import 'vs/css!./contextview'; import * as DOM from 'vs/base/browser/dom'; -import { IDisposable, dispose, toDisposable, combinedDisposable, Disposable } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose, toDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle'; import { Range } from 'vs/base/common/range'; export interface IAnchor { @@ -128,7 +128,7 @@ export class ContextView extends Disposable { this.container = container; this.container.appendChild(this.view); - const toDisposeOnSetContainer: IDisposable[] = []; + const toDisposeOnSetContainer = new DisposableStore(); ContextView.BUBBLE_UP_EVENTS.forEach(event => { toDisposeOnSetContainer.push(DOM.addStandardDisposableListener(this.container!, event, (e: Event) => { @@ -142,7 +142,7 @@ export class ContextView extends Disposable { }, true)); }); - this.toDisposeOnSetContainer = combinedDisposable(toDisposeOnSetContainer); + this.toDisposeOnSetContainer = toDisposeOnSetContainer; } } diff --git a/src/vs/base/browser/ui/grid/grid.ts b/src/vs/base/browser/ui/grid/grid.ts index 44e3deacd6c..4178efc9e98 100644 --- a/src/vs/base/browser/ui/grid/grid.ts +++ b/src/vs/base/browser/ui/grid/grid.ts @@ -5,7 +5,7 @@ import 'vs/css!./gridview'; import { Orientation } from 'vs/base/browser/ui/sash/sash'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { Disposable } from 'vs/base/common/lifecycle'; import { tail2 as tail, equals } from 'vs/base/common/arrays'; import { orthogonal, IView, GridView, Sizing as GridViewSizing, Box, IGridViewStyles } from './gridview'; import { Event, Emitter } from 'vs/base/common/event'; @@ -191,12 +191,10 @@ export interface IGridOptions { proportionalLayout?: boolean; } -export class Grid implements IDisposable { +export class Grid extends Disposable { protected gridview: GridView; private views = new Map(); - private disposables: IDisposable[] = []; - get orientation(): Orientation { return this.gridview.orientation; } set orientation(orientation: Orientation) { this.gridview.orientation = orientation; } @@ -214,10 +212,11 @@ export class Grid implements IDisposable { sashResetSizing: Sizing = Sizing.Distribute; constructor(view: T, options: IGridOptions = {}) { + super(); this.gridview = new GridView(options); - this.disposables.push(this.gridview); + this._register(this.gridview); - this.gridview.onDidSashReset(this.doResetViewSize, this, this.disposables); + this._register(this.gridview.onDidSashReset(this.doResetViewSize, this)); this._addView(view, 0, [0]); } @@ -375,10 +374,6 @@ export class Grid implements IDisposable { this.gridview.distributeViewSizes(parentLocation); } } - - dispose(): void { - this.disposables = dispose(this.disposables); - } } export interface ISerializableView extends IView { diff --git a/src/vs/base/browser/ui/menu/menubar.ts b/src/vs/base/browser/ui/menu/menubar.ts index 631b81f7075..985c171f999 100644 --- a/src/vs/base/browser/ui/menu/menubar.ts +++ b/src/vs/base/browser/ui/menu/menubar.ts @@ -15,7 +15,7 @@ import { ActionRunner, IAction, IActionRunner } from 'vs/base/common/actions'; import { RunOnceScheduler } from 'vs/base/common/async'; import { Event, Emitter } from 'vs/base/common/event'; import { KeyCode, ResolvedKeybinding } from 'vs/base/common/keyCodes'; -import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle'; +import { Disposable, dispose, IDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { withNullAsUndefined } from 'vs/base/common/types'; import { asArray } from 'vs/base/common/arrays'; @@ -896,7 +896,7 @@ interface IModifierKeyStatus { class ModifierKeyEmitter extends Emitter { - private _subscriptions: IDisposable[] = []; + private readonly _subscriptions = new DisposableStore(); private _keyStatus: IModifierKeyStatus; private static instance: ModifierKeyEmitter; @@ -992,6 +992,6 @@ class ModifierKeyEmitter extends Emitter { dispose() { super.dispose(); - this._subscriptions = dispose(this._subscriptions); + this._subscriptions.dispose(); } } \ No newline at end of file diff --git a/src/vs/base/browser/ui/selectBox/selectBoxNative.ts b/src/vs/base/browser/ui/selectBox/selectBoxNative.ts index 98dee79c329..d8101444c3c 100644 --- a/src/vs/base/browser/ui/selectBox/selectBoxNative.ts +++ b/src/vs/base/browser/ui/selectBox/selectBoxNative.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { Disposable } from 'vs/base/common/lifecycle'; import { Event, Emitter } from 'vs/base/common/event'; import { KeyCode } from 'vs/base/common/keyCodes'; import * as dom from 'vs/base/browser/dom'; @@ -11,18 +11,17 @@ import * as arrays from 'vs/base/common/arrays'; import { ISelectBoxDelegate, ISelectOptionItem, ISelectBoxOptions, ISelectBoxStyles, ISelectData } from 'vs/base/browser/ui/selectBox/selectBox'; import { isMacintosh } from 'vs/base/common/platform'; -export class SelectBoxNative implements ISelectBoxDelegate { +export class SelectBoxNative extends Disposable implements ISelectBoxDelegate { private selectElement: HTMLSelectElement; private selectBoxOptions: ISelectBoxOptions; private options: ISelectOptionItem[]; private selected: number; private readonly _onDidSelect: Emitter; - private toDispose: IDisposable[]; private styles: ISelectBoxStyles; constructor(options: ISelectOptionItem[], selected: number, styles: ISelectBoxStyles, selectBoxOptions?: ISelectBoxOptions) { - this.toDispose = []; + super(); this.selectBoxOptions = selectBoxOptions || Object.create(null); this.options = []; @@ -36,7 +35,7 @@ export class SelectBoxNative implements ISelectBoxDelegate { } this._onDidSelect = new Emitter(); - this.toDispose.push(this._onDidSelect); + this._register(this._onDidSelect); this.styles = styles; @@ -46,7 +45,7 @@ export class SelectBoxNative implements ISelectBoxDelegate { private registerListeners() { - this.toDispose.push(dom.addStandardDisposableListener(this.selectElement, 'change', (e) => { + this._register(dom.addStandardDisposableListener(this.selectElement, 'change', (e) => { this.selectElement.title = e.target.value; this._onDidSelect.fire({ index: e.target.selectedIndex, @@ -54,7 +53,7 @@ export class SelectBoxNative implements ISelectBoxDelegate { }); })); - this.toDispose.push(dom.addStandardDisposableListener(this.selectElement, 'keydown', (e) => { + this._register(dom.addStandardDisposableListener(this.selectElement, 'keydown', (e) => { let showSelect = false; if (isMacintosh) { @@ -168,8 +167,4 @@ export class SelectBoxNative implements ISelectBoxDelegate { return option; } - - public dispose(): void { - this.toDispose = dispose(this.toDispose); - } } diff --git a/src/vs/base/browser/ui/splitview/panelview.ts b/src/vs/base/browser/ui/splitview/panelview.ts index 735c201e8db..d9e41a7ee46 100644 --- a/src/vs/base/browser/ui/splitview/panelview.ts +++ b/src/vs/base/browser/ui/splitview/panelview.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import 'vs/css!./panelview'; -import { IDisposable, dispose, combinedDisposable, Disposable } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose, Disposable, DisposableStore } from 'vs/base/common/lifecycle'; import { Event, Emitter } from 'vs/base/common/event'; import { domEvent } from 'vs/base/browser/event'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; @@ -397,16 +397,16 @@ export class PanelView extends Disposable { } addPanel(panel: Panel, size: number, index = this.splitview.length): void { - const disposables: IDisposable[] = []; + const disposables = new DisposableStore(); // https://github.com/Microsoft/vscode/issues/59950 let shouldAnimate = false; disposables.push(scheduleAtNextAnimationFrame(() => shouldAnimate = true)); - Event.filter(panel.onDidChange, () => shouldAnimate) - (this.setupAnimation, this, disposables); + disposables.push(Event.filter(panel.onDidChange, () => shouldAnimate) + (this.setupAnimation, this)); - const panelItem = { panel, disposable: combinedDisposable(disposables) }; + const panelItem = { panel, disposable: disposables }; this.panelItems.splice(index, 0, panelItem); panel.width = this.width; this.splitview.addView(panel, size, index); @@ -414,7 +414,7 @@ export class PanelView extends Disposable { if (this.dnd) { const draggable = new PanelDraggable(panel, this.dnd, this.dndContext); disposables.push(draggable); - draggable.onDidDrop(this._onDidDrop.fire, this._onDidDrop, disposables); + disposables.push(draggable.onDidDrop(this._onDidDrop.fire, this._onDidDrop)); } } diff --git a/src/vs/base/browser/ui/splitview/splitview.ts b/src/vs/base/browser/ui/splitview/splitview.ts index 48b0cef6866..fc104cc5543 100644 --- a/src/vs/base/browser/ui/splitview/splitview.ts +++ b/src/vs/base/browser/ui/splitview/splitview.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import 'vs/css!./splitview'; -import { IDisposable, combinedDisposable, toDisposable, Disposable } from 'vs/base/common/lifecycle'; +import { IDisposable, toDisposable, Disposable, combinedDisposable } from 'vs/base/common/lifecycle'; import { Event, Emitter } from 'vs/base/common/event'; import * as types from 'vs/base/common/types'; import * as dom from 'vs/base/browser/dom'; @@ -199,7 +199,7 @@ export class SplitView extends Disposable { const onChangeDisposable = view.onDidChange(size => this.onViewChange(item, size)); const containerDisposable = toDisposable(() => this.viewContainer.removeChild(container)); - const disposable = combinedDisposable([onChangeDisposable, containerDisposable]); + const disposable = combinedDisposable(onChangeDisposable, containerDisposable); const layoutContainer = this.orientation === Orientation.VERTICAL ? () => item.container.style.height = `${item.size}px` @@ -245,7 +245,7 @@ export class SplitView extends Disposable { const onEndDisposable = onEnd(this.onSashEnd, this); const onDidResetDisposable = sash.onDidReset(() => this._onDidSashReset.fire(firstIndex(this.sashItems, item => item.sash === sash))); - const disposable = combinedDisposable([onStartDisposable, onChangeDisposable, onEndDisposable, onDidResetDisposable, sash]); + const disposable = combinedDisposable(onStartDisposable, onChangeDisposable, onEndDisposable, onDidResetDisposable, sash); const sashItem: ISashItem = { sash, disposable }; this.sashItems.splice(index - 1, 0, sashItem); @@ -369,10 +369,10 @@ export class SplitView extends Disposable { const index = firstIndex(this.sashItems, item => item.sash === sash); // This way, we can press Alt while we resize a sash, macOS style! - const disposable = combinedDisposable([ + const disposable = combinedDisposable( domEvent(document.body, 'keydown')(e => resetSashDragState(this.sashDragState.current, e.altKey)), domEvent(document.body, 'keyup')(() => resetSashDragState(this.sashDragState.current, false)) - ]); + ); const resetSashDragState = (start: number, alt: boolean) => { const sizes = this.viewItems.map(i => i.size); diff --git a/src/vs/base/common/actions.ts b/src/vs/base/common/actions.ts index 19267ce8ff5..b0fea386d30 100644 --- a/src/vs/base/common/actions.ts +++ b/src/vs/base/common/actions.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IDisposable, combinedDisposable, Disposable } from 'vs/base/common/lifecycle'; +import { IDisposable, Disposable } from 'vs/base/common/lifecycle'; import { Event, Emitter } from 'vs/base/common/event'; export interface ITelemetryData { @@ -217,8 +217,8 @@ export class RadioGroup extends Disposable { constructor(readonly actions: Action[]) { super(); - this._register(combinedDisposable(actions.map(action => { - return action.onDidChange(e => { + for (const action of actions) { + this._register(action.onDidChange(e => { if (e.checked && action.checked) { for (const candidate of actions) { if (candidate !== action) { @@ -226,7 +226,7 @@ export class RadioGroup extends Disposable { } } } - }); - }))); + })); + } } } diff --git a/src/vs/base/common/event.ts b/src/vs/base/common/event.ts index 0ef9379e6a5..77883c9affb 100644 --- a/src/vs/base/common/event.ts +++ b/src/vs/base/common/event.ts @@ -5,7 +5,7 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import { once as onceFn } from 'vs/base/common/functional'; -import { combinedDisposable, Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { Disposable, IDisposable, toDisposable, combinedDisposable } from 'vs/base/common/lifecycle'; import { LinkedList } from 'vs/base/common/linkedList'; /** @@ -86,7 +86,7 @@ export namespace Event { * whenever any of the provided events emit. */ export function any(...events: Event[]): Event { - return (listener, thisArgs = null, disposables?) => combinedDisposable(events.map(event => event(e => listener.call(thisArgs, e), null, disposables))); + return (listener, thisArgs = null, disposables?) => combinedDisposable(...events.map(event => event(e => listener.call(thisArgs, e), null, disposables))); } /** diff --git a/src/vs/base/common/lifecycle.ts b/src/vs/base/common/lifecycle.ts index da31c69210e..72a74f2d5b5 100644 --- a/src/vs/base/common/lifecycle.ts +++ b/src/vs/base/common/lifecycle.ts @@ -34,7 +34,7 @@ export function dispose(first: T | T[], ...rest: T[]): T } } -export function combinedDisposable(disposables: IDisposable[]): IDisposable { +export function combinedDisposable(...disposables: IDisposable[]): IDisposable { return { dispose: () => dispose(disposables) }; } @@ -42,19 +42,17 @@ export function toDisposable(fn: () => void): IDisposable { return { dispose() { fn(); } }; } - export class DisposableStore implements IDisposable { private _toDispose: IDisposable[] = []; - - private _lifecycle_disposable_isDisposed = false; + private _isDisposed = false; public dispose(): void { - this._lifecycle_disposable_isDisposed = true; + this._isDisposed = true; this._toDispose = dispose(this._toDispose); } public push(t: T): T { - if (this._lifecycle_disposable_isDisposed) { + if (this._isDisposed) { console.warn('Registering disposable on object that has already been disposed.'); t.dispose(); } else { diff --git a/src/vs/base/node/config.ts b/src/vs/base/node/config.ts index bf942fb5a45..ecfb0965701 100644 --- a/src/vs/base/node/config.ts +++ b/src/vs/base/node/config.ts @@ -6,7 +6,7 @@ import * as fs from 'fs'; import { dirname } from 'vs/base/common/path'; import * as objects from 'vs/base/common/objects'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { Event, Emitter } from 'vs/base/common/event'; import * as json from 'vs/base/common/json'; import { statLink } from 'vs/base/node/pfs'; @@ -47,12 +47,10 @@ export class ConfigWatcher implements IConfigWatcher, IDisposable { private disposed: boolean; private loaded: boolean; private timeoutHandle: NodeJS.Timer | null; - private disposables: IDisposable[]; + private readonly disposables = new DisposableStore(); private readonly _onDidUpdateConfiguration: Emitter>; constructor(private _path: string, private options: IConfigOptions = { defaultConfig: Object.create(null), onError: error => console.error(error) }) { - this.disposables = []; - this._onDidUpdateConfiguration = new Emitter>(); this.disposables.push(this._onDidUpdateConfiguration); @@ -187,6 +185,6 @@ export class ConfigWatcher implements IConfigWatcher, IDisposable { dispose(): void { this.disposed = true; - this.disposables = dispose(this.disposables); + this.disposables.dispose(); } } \ No newline at end of file diff --git a/src/vs/base/parts/ipc/common/ipc.ts b/src/vs/base/parts/ipc/common/ipc.ts index 6a2ff55e2d1..135f3016b37 100644 --- a/src/vs/base/parts/ipc/common/ipc.ts +++ b/src/vs/base/parts/ipc/common/ipc.ts @@ -464,7 +464,7 @@ export class ChannelClient implements IChannelClient, IDisposable { }; const cancellationTokenListener = cancellationToken.onCancellationRequested(cancel); - disposable = combinedDisposable([toDisposable(cancel), cancellationTokenListener]); + disposable = combinedDisposable(toDisposable(cancel), cancellationTokenListener); this.activeRequests.add(disposable); }); diff --git a/src/vs/base/parts/tree/browser/treeModel.ts b/src/vs/base/parts/tree/browser/treeModel.ts index 1ddbe4cb462..54ec61756da 100644 --- a/src/vs/base/parts/tree/browser/treeModel.ts +++ b/src/vs/base/parts/tree/browser/treeModel.ts @@ -159,7 +159,7 @@ export class ItemRegistry { public register(item: Item): void { Assert.ok(!this.isRegistered(item.id), 'item already registered: ' + item.id); - const disposable = combinedDisposable([ + const disposable = combinedDisposable( this._onDidRevealItem.add(item.onDidReveal), this._onExpandItem.add(item.onExpand), this._onDidExpandItem.add(item.onDidExpand), @@ -171,7 +171,7 @@ export class ItemRegistry { this._onRefreshItemChildren.add(item.onRefreshChildren), this._onDidRefreshItemChildren.add(item.onDidRefreshChildren), this._onDidDisposeItem.add(item.onDidDispose) - ]); + ); this.items[item.id] = { item, disposable }; } diff --git a/src/vs/code/electron-browser/sharedProcess/contrib/languagePackCachedDataCleaner.ts b/src/vs/code/electron-browser/sharedProcess/contrib/languagePackCachedDataCleaner.ts index e7f1eec7742..0f791bb8c6e 100644 --- a/src/vs/code/electron-browser/sharedProcess/contrib/languagePackCachedDataCleaner.ts +++ b/src/vs/code/electron-browser/sharedProcess/contrib/languagePackCachedDataCleaner.ts @@ -8,7 +8,7 @@ import * as pfs from 'vs/base/node/pfs'; import { IStringDictionary } from 'vs/base/common/collections'; import product from 'vs/platform/product/node/product'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; import { onUnexpectedError } from 'vs/base/common/errors'; import { ILogService } from 'vs/platform/log/common/log'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; @@ -30,14 +30,13 @@ interface LanguagePackFile { [locale: string]: LanguagePackEntry; } -export class LanguagePackCachedDataCleaner { - - private _disposables: IDisposable[] = []; +export class LanguagePackCachedDataCleaner extends Disposable { constructor( @IEnvironmentService private readonly _environmentService: IEnvironmentService, @ILogService private readonly _logService: ILogService ) { + super(); // We have no Language pack support for dev version (run from source) // So only cleanup when we have a build version. if (this._environmentService.isBuilt) { @@ -45,10 +44,6 @@ export class LanguagePackCachedDataCleaner { } } - dispose(): void { - this._disposables = dispose(this._disposables); - } - private _manageCachedDataSoon(): void { let handle: any = setTimeout(async () => { handle = undefined; @@ -101,12 +96,10 @@ export class LanguagePackCachedDataCleaner { } }, 40 * 1000); - this._disposables.push({ - dispose() { - if (handle !== undefined) { - clearTimeout(handle); - } + this._register(toDisposable(() => { + if (handle !== undefined) { + clearTimeout(handle); } - }); + })); } } \ No newline at end of file diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts index 4822a564951..e0125000316 100644 --- a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts @@ -165,12 +165,12 @@ function main(server: Server, initData: ISharedProcessInitData, configuration: I // update localizations cache (localizationsService as LocalizationsService).update(); // cache clean ups - disposables.push(combinedDisposable([ + disposables.push(combinedDisposable( instantiationService2.createInstance(NodeCachedDataCleaner), instantiationService2.createInstance(LanguagePackCachedDataCleaner), instantiationService2.createInstance(StorageDataCleaner), instantiationService2.createInstance(LogsDataCleaner) - ])); + )); disposables.push(extensionManagementService as ExtensionManagementService); }); }); diff --git a/src/vs/editor/contrib/goToDefinition/goToDefinitionResultsNavigation.ts b/src/vs/editor/contrib/goToDefinition/goToDefinitionResultsNavigation.ts index 68c34213275..71d0af4e17b 100644 --- a/src/vs/editor/contrib/goToDefinition/goToDefinitionResultsNavigation.ts +++ b/src/vs/editor/contrib/goToDefinition/goToDefinitionResultsNavigation.ts @@ -13,7 +13,7 @@ import { registerEditorCommand, EditorCommand } from 'vs/editor/browser/editorEx import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { Range } from 'vs/editor/common/core/range'; -import { Disposable, dispose, combinedDisposable, IDisposable } from 'vs/base/common/lifecycle'; +import { Disposable, dispose, IDisposable, combinedDisposable } from 'vs/base/common/lifecycle'; import { Emitter, Event } from 'vs/base/common/event'; import { IStatusbarService } from 'vs/platform/statusbar/common/statusbar'; import { localize } from 'vs/nls'; @@ -199,10 +199,10 @@ class EditorStatus extends Disposable { } private _onDidAddEditor(editor: ICodeEditor): void { - this._listener.set(editor, combinedDisposable([ + this._listener.set(editor, combinedDisposable( editor.onDidChangeCursorPosition(_ => this._onDidChange.fire({ editor })), editor.onDidChangeModelContent(_ => this._onDidChange.fire({ editor })), - ])); + )); } private _onDidRemoveEditor(editor: ICodeEditor): void { diff --git a/src/vs/editor/contrib/gotoError/gotoErrorWidget.ts b/src/vs/editor/contrib/gotoError/gotoErrorWidget.ts index b630d4fc220..2ac2c54af5e 100644 --- a/src/vs/editor/contrib/gotoError/gotoErrorWidget.ts +++ b/src/vs/editor/contrib/gotoError/gotoErrorWidget.ts @@ -6,7 +6,7 @@ import 'vs/css!./media/gotoErrorWidget'; import * as nls from 'vs/nls'; import * as dom from 'vs/base/browser/dom'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose, Disposable } from 'vs/base/common/lifecycle'; import { IMarker, MarkerSeverity, IRelatedInformation } from 'vs/platform/markers/common/markers'; import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; @@ -28,7 +28,7 @@ import { IActionBarOptions, ActionsOrientation } from 'vs/base/browser/ui/action import { peekViewTitleForeground, peekViewTitleInfoForeground } from 'vs/editor/contrib/referenceSearch/referencesWidget'; import { AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility'; -class MessageWidget { +class MessageWidget extends Disposable { private _lines: number = 0; private _longestLineLength: number = 0; @@ -38,9 +38,9 @@ class MessageWidget { private readonly _relatedBlock: HTMLDivElement; private readonly _scrollable: ScrollableElement; private readonly _relatedDiagnostics = new WeakMap(); - private readonly _disposables: IDisposable[] = []; constructor(parent: HTMLElement, editor: ICodeEditor, onRelatedInformation: (related: IRelatedInformation) => void) { + super(); this._editor = editor; const domNode = document.createElement('div'); @@ -54,7 +54,7 @@ class MessageWidget { this._relatedBlock = document.createElement('div'); domNode.appendChild(this._relatedBlock); - this._disposables.push(dom.addStandardDisposableListener(this._relatedBlock, 'click', event => { + this._register(dom.addStandardDisposableListener(this._relatedBlock, 'click', event => { event.preventDefault(); const related = this._relatedDiagnostics.get(event.target); if (related) { @@ -70,15 +70,11 @@ class MessageWidget { verticalScrollbarSize: 3 }); parent.appendChild(this._scrollable.getDomNode()); - this._disposables.push(this._scrollable.onScroll(e => { + this._register(this._scrollable.onScroll(e => { domNode.style.left = `-${e.scrollLeft}px`; domNode.style.top = `-${e.scrollTop}px`; })); - this._disposables.push(this._scrollable); - } - - dispose(): void { - dispose(this._disposables); + this._register(this._scrollable); } update({ source, message, relatedInformation, code }: IMarker): void { diff --git a/src/vs/editor/contrib/hover/hover.ts b/src/vs/editor/contrib/hover/hover.ts index b977abf6cdf..320a36402da 100644 --- a/src/vs/editor/contrib/hover/hover.ts +++ b/src/vs/editor/contrib/hover/hover.ts @@ -7,7 +7,7 @@ import 'vs/css!./hover'; import * as nls from 'vs/nls'; import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { KeyChord, KeyCode, KeyMod } from 'vs/base/common/keyCodes'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { IEmptyContentData } from 'vs/editor/browser/controller/mouseTarget'; import { ICodeEditor, IEditorMouseEvent, MouseTargetType } from 'vs/editor/browser/editorBrowser'; import { EditorAction, ServicesAccessor, registerEditorAction, registerEditorContribution } from 'vs/editor/browser/editorExtensions'; @@ -34,7 +34,7 @@ export class ModesHoverController implements IEditorContribution { private static readonly ID = 'editor.contrib.hover'; - private _toUnhook: IDisposable[]; + private _toUnhook = new DisposableStore(); private readonly _didChangeConfigurationHandler: IDisposable; private _contentWidget: ModesContentHoverWidget; @@ -73,8 +73,6 @@ export class ModesHoverController implements IEditorContribution { @ICommandService private readonly _commandService: ICommandService, @IThemeService private readonly _themeService: IThemeService ) { - this._toUnhook = []; - this._isMouseDown = false; this._hoverClicked = false; @@ -111,7 +109,8 @@ export class ModesHoverController implements IEditorContribution { } private _unhookEvents(): void { - this._toUnhook = dispose(this._toUnhook); + this._toUnhook.dispose(); + this._toUnhook = new DisposableStore(); } private _onModelDecorationsChanged(): void { diff --git a/src/vs/editor/contrib/hover/hoverWidgets.ts b/src/vs/editor/contrib/hover/hoverWidgets.ts index 71452506714..6489db5a9fa 100644 --- a/src/vs/editor/contrib/hover/hoverWidgets.ts +++ b/src/vs/editor/contrib/hover/hoverWidgets.ts @@ -8,7 +8,6 @@ import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement'; import { Widget } from 'vs/base/browser/ui/widget'; import { KeyCode } from 'vs/base/common/keyCodes'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import * as editorBrowser from 'vs/editor/browser/editorBrowser'; import { IConfigurationChangedEvent } from 'vs/editor/common/config/editorOptions'; import { Position } from 'vs/editor/common/core/position'; @@ -25,7 +24,6 @@ export class ContentHoverWidget extends Widget implements editorBrowser.IContent protected _showAtRange: Range | null; private _stoleFocus: boolean; private readonly scrollbar: DomScrollableElement; - private disposables: IDisposable[] = []; // Editor.IContentWidget.allowEditorOverflow public allowEditorOverflow = true; @@ -53,7 +51,7 @@ export class ContentHoverWidget extends Widget implements editorBrowser.IContent this._domNode.className = 'monaco-editor-hover-content'; this.scrollbar = new DomScrollableElement(this._domNode, {}); - this.disposables.push(this.scrollbar); + this._register(this.scrollbar); this._containerDomNode.appendChild(this.scrollbar.getDomNode()); this.onkeydown(this._containerDomNode, (e: IKeyboardEvent) => { @@ -129,7 +127,6 @@ export class ContentHoverWidget extends Widget implements editorBrowser.IContent public dispose(): void { this._editor.removeContentWidget(this); - this.disposables = dispose(this.disposables); super.dispose(); } diff --git a/src/vs/editor/contrib/hover/modesContentHover.ts b/src/vs/editor/contrib/hover/modesContentHover.ts index 94d846e38a0..045298ca469 100644 --- a/src/vs/editor/contrib/hover/modesContentHover.ts +++ b/src/vs/editor/contrib/hover/modesContentHover.ts @@ -8,7 +8,7 @@ import * as dom from 'vs/base/browser/dom'; import { CancellationToken } from 'vs/base/common/cancellation'; import { Color, RGBA } from 'vs/base/common/color'; import { IMarkdownString, MarkdownString, isEmptyMarkdownString, markedStringsEquals } from 'vs/base/common/htmlContent'; -import { Disposable, IDisposable, combinedDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { Disposable, IDisposable, toDisposable, DisposableStore, combinedDisposable } from 'vs/base/common/lifecycle'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { Position } from 'vs/editor/common/core/position'; import { IRange, Range } from 'vs/editor/common/core/range'; @@ -436,7 +436,7 @@ export class ModesContentHoverWidget extends ContentHoverWidget { this.updateContents(fragment); this._colorPicker.layout(); - this.renderDisposable = combinedDisposable([colorListener, colorChangeListener, widget, ...markdownDisposeables]); + this.renderDisposable = combinedDisposable(colorListener, colorChangeListener, widget, ...markdownDisposeables); }); } else { if (msg instanceof MarkerHover) { @@ -526,7 +526,7 @@ export class ModesContentHoverWidget extends ContentHoverWidget { private renderMarkerStatusbar(markerHover: MarkerHover): HTMLElement { const hoverElement = $('div.hover-row.status-bar'); - const disposables: IDisposable[] = []; + const disposables = new DisposableStore(); const actionsElement = dom.append(hoverElement, $('div.actions')); disposables.push(this.renderAction(actionsElement, { label: nls.localize('quick fixes', "Quick Fix..."), @@ -553,7 +553,7 @@ export class ModesContentHoverWidget extends ContentHoverWidget { } })); } - this.renderDisposable = combinedDisposable(disposables); + this.renderDisposable = disposables; return hoverElement; } diff --git a/src/vs/editor/contrib/markdown/markdownRenderer.ts b/src/vs/editor/contrib/markdown/markdownRenderer.ts index e013de91cd4..2016c0e642d 100644 --- a/src/vs/editor/contrib/markdown/markdownRenderer.ts +++ b/src/vs/editor/contrib/markdown/markdownRenderer.ts @@ -78,7 +78,7 @@ export class MarkdownRenderer { } render(markdown: IMarkdownString | undefined): IMarkdownRenderResult { - let disposeables: IDisposable[] = []; + const disposeables: IDisposable[] = []; let element: HTMLElement; if (!markdown) { diff --git a/src/vs/editor/contrib/rename/renameInputField.ts b/src/vs/editor/contrib/rename/renameInputField.ts index b1dce91bfc7..0c3b41c2c73 100644 --- a/src/vs/editor/contrib/rename/renameInputField.ts +++ b/src/vs/editor/contrib/rename/renameInputField.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { dispose, IDisposable } from 'vs/base/common/lifecycle'; +import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; import 'vs/css!./renameInputField'; import { ContentWidgetPositionPreference, ICodeEditor, IContentWidget, IContentWidgetPosition } from 'vs/editor/browser/editorBrowser'; import { Position } from 'vs/editor/common/core/position'; @@ -16,7 +16,7 @@ import { ITheme, IThemeService } from 'vs/platform/theme/common/themeService'; export const CONTEXT_RENAME_INPUT_VISIBLE = new RawContextKey('renameInputVisible', false); -export class RenameInputField implements IContentWidget, IDisposable { +export class RenameInputField extends Disposable implements IContentWidget { private _editor: ICodeEditor; private _position: Position; @@ -24,7 +24,6 @@ export class RenameInputField implements IContentWidget, IDisposable { private _inputField: HTMLInputElement; private _visible: boolean; private readonly _visibleContextKey: IContextKey; - private _disposables: IDisposable[] = []; // Editor.IContentWidget.allowEditorOverflow public allowEditorOverflow: boolean = true; @@ -34,18 +33,19 @@ export class RenameInputField implements IContentWidget, IDisposable { private readonly themeService: IThemeService, contextKeyService: IContextKeyService, ) { + super(); this._visibleContextKey = CONTEXT_RENAME_INPUT_VISIBLE.bindTo(contextKeyService); this._editor = editor; this._editor.addContentWidget(this); - this._disposables.push(editor.onDidChangeConfiguration(e => { + this._register(editor.onDidChangeConfiguration(e => { if (e.fontInfo) { this.updateFont(); } })); - this._disposables.push(themeService.onThemeChange(theme => this.onThemeChange(theme))); + this._register(themeService.onThemeChange(theme => this.onThemeChange(theme))); } private onThemeChange(theme: ITheme): void { @@ -53,7 +53,7 @@ export class RenameInputField implements IContentWidget, IDisposable { } public dispose(): void { - this._disposables = dispose(this._disposables); + super.dispose(); this._editor.removeContentWidget(this); } @@ -138,9 +138,9 @@ export class RenameInputField implements IContentWidget, IDisposable { this._inputField.setAttribute('selectionEnd', selectionEnd.toString()); this._inputField.size = Math.max((where.endColumn - where.startColumn) * 1.1, 20); - const disposeOnDone: IDisposable[] = []; + const disposeOnDone = new DisposableStore(); const always = () => { - dispose(disposeOnDone); + disposeOnDone.dispose(); this._hide(); }; diff --git a/src/vs/editor/contrib/suggest/suggestCommitCharacters.ts b/src/vs/editor/contrib/suggest/suggestCommitCharacters.ts index ba0789bf893..7075aceb641 100644 --- a/src/vs/editor/contrib/suggest/suggestCommitCharacters.ts +++ b/src/vs/editor/contrib/suggest/suggestCommitCharacters.ts @@ -4,14 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { isNonEmptyArray } from 'vs/base/common/arrays'; -import { dispose, IDisposable } from 'vs/base/common/lifecycle'; +import { Disposable } from 'vs/base/common/lifecycle'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { ISelectedSuggestion, SuggestWidget } from './suggestWidget'; import { CharacterSet } from 'vs/editor/common/core/characterClassifier'; -export class CommitCharacterController { - - private _disposables: IDisposable[] = []; +export class CommitCharacterController extends Disposable { private _active?: { readonly acceptCharacters: CharacterSet; @@ -19,12 +17,13 @@ export class CommitCharacterController { }; constructor(editor: ICodeEditor, widget: SuggestWidget, accept: (selected: ISelectedSuggestion) => any) { + super(); - this._disposables.push(widget.onDidShow(() => this._onItem(widget.getFocusedItem()))); - this._disposables.push(widget.onDidFocus(this._onItem, this)); - this._disposables.push(widget.onDidHide(this.reset, this)); + this._register(widget.onDidShow(() => this._onItem(widget.getFocusedItem()))); + this._register(widget.onDidFocus(this._onItem, this)); + this._register(widget.onDidHide(this.reset, this)); - this._disposables.push(editor.onWillType(text => { + this._register(editor.onWillType(text => { if (this._active) { const ch = text.charCodeAt(text.length - 1); if (this._active.acceptCharacters.has(ch) && editor.getConfiguration().contribInfo.acceptSuggestionOnCommitCharacter) { @@ -52,8 +51,4 @@ export class CommitCharacterController { reset(): void { this._active = undefined; } - - dispose() { - dispose(this._disposables); - } } diff --git a/src/vs/editor/contrib/suggest/suggestController.ts b/src/vs/editor/contrib/suggest/suggestController.ts index d267a41ca4e..76b83ec0c7a 100644 --- a/src/vs/editor/contrib/suggest/suggestController.ts +++ b/src/vs/editor/contrib/suggest/suggestController.ts @@ -7,7 +7,7 @@ import { alert } from 'vs/base/browser/ui/aria/aria'; import { isNonEmptyArray } from 'vs/base/common/arrays'; import { onUnexpectedError } from 'vs/base/common/errors'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; -import { dispose, IDisposable } from 'vs/base/common/lifecycle'; +import { dispose, IDisposable, Disposable, toDisposable } from 'vs/base/common/lifecycle'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { EditorAction, EditorCommand, registerEditorAction, registerEditorCommand, registerEditorContribution, ServicesAccessor } from 'vs/editor/browser/editorExtensions'; import { EditOperation } from 'vs/editor/common/core/editOperation'; @@ -34,7 +34,7 @@ import { IdleValue } from 'vs/base/common/async'; import { isObject } from 'vs/base/common/types'; import { CommitCharacterController } from './suggestCommitCharacters'; -export class SuggestController implements IEditorContribution { +export class SuggestController extends Disposable implements IEditorContribution { private static readonly ID: string = 'editor.contrib.suggestController'; @@ -45,7 +45,6 @@ export class SuggestController implements IEditorContribution { private readonly _model: SuggestModel; private readonly _widget: IdleValue; private readonly _alternatives: IdleValue; - private _toDispose: IDisposable[] = []; private readonly _sticky = false; // for development purposes only @@ -57,29 +56,28 @@ export class SuggestController implements IEditorContribution { @IContextKeyService private readonly _contextKeyService: IContextKeyService, @IInstantiationService private readonly _instantiationService: IInstantiationService, ) { + super(); this._model = new SuggestModel(this._editor, editorWorker); this._widget = new IdleValue(() => { const widget = this._instantiationService.createInstance(SuggestWidget, this._editor); - this._toDispose.push(widget); - this._toDispose.push(widget.onDidSelect(item => this._insertSuggestion(item, false, true), this)); + this._register(widget); + this._register(widget.onDidSelect(item => this._insertSuggestion(item, false, true), this)); // Wire up logic to accept a suggestion on certain characters - const commitCharacterController = new CommitCharacterController(this._editor, widget, item => this._insertSuggestion(item, false, true)); - this._toDispose.push( - commitCharacterController, - this._model.onDidSuggest(e => { - if (e.completionModel.items.length === 0) { - commitCharacterController.reset(); - } - }) + const commitCharacterController = this._register(new CommitCharacterController(this._editor, widget, item => this._insertSuggestion(item, false, true))); + this._register(this._model.onDidSuggest(e => { + if (e.completionModel.items.length === 0) { + commitCharacterController.reset(); + } + }) ); // Wire up makes text edit context key let makesTextEdit = SuggestContext.MakesTextEdit.bindTo(this._contextKeyService); - this._toDispose.push(widget.onDidFocus(({ item }) => { + this._register(widget.onDidFocus(({ item }) => { const position = this._editor.getPosition()!; const startColumn = item.completion.range.startColumn; @@ -103,36 +101,36 @@ export class SuggestController implements IEditorContribution { } makesTextEdit.set(value); })); - this._toDispose.push({ - dispose() { makesTextEdit.reset(); } - }); + this._register(toDisposable(() => { + makesTextEdit.reset(); + })); return widget; }); this._alternatives = new IdleValue(() => { let res = new SuggestAlternatives(this._editor, this._contextKeyService); - this._toDispose.push(res); + this._register(res); return res; }); - this._toDispose.push(_instantiationService.createInstance(WordContextKey, _editor)); + this._register(_instantiationService.createInstance(WordContextKey, _editor)); - this._toDispose.push(this._model.onDidTrigger(e => { + this._register(this._model.onDidTrigger(e => { this._widget.getValue().showTriggered(e.auto, e.shy ? 250 : 50); })); - this._toDispose.push(this._model.onDidSuggest(e => { + this._register(this._model.onDidSuggest(e => { if (!e.shy) { let index = this._memoryService.select(this._editor.getModel()!, this._editor.getPosition()!, e.completionModel.items); this._widget.getValue().showSuggestions(e.completionModel, index, e.isFrozen, e.auto); } })); - this._toDispose.push(this._model.onDidCancel(e => { + this._register(this._model.onDidCancel(e => { if (this._widget && !e.retrigger) { this._widget.getValue().hideWidget(); } })); - this._toDispose.push(this._editor.onDidBlurEditorWidget(() => { + this._register(this._editor.onDidBlurEditorWidget(() => { if (!this._sticky) { this._model.cancel(); } @@ -144,7 +142,7 @@ export class SuggestController implements IEditorContribution { const { acceptSuggestionOnEnter } = this._editor.getConfiguration().contribInfo; acceptSuggestionsOnEnter.set(acceptSuggestionOnEnter === 'on' || acceptSuggestionOnEnter === 'smart'); }; - this._toDispose.push(this._editor.onDidChangeConfiguration((e) => updateFromConfig())); + this._register(this._editor.onDidChangeConfiguration((e) => updateFromConfig())); updateFromConfig(); } @@ -154,7 +152,7 @@ export class SuggestController implements IEditorContribution { } dispose(): void { - this._toDispose = dispose(this._toDispose); + super.dispose(); this._widget.dispose(); if (this._model) { this._model.dispose(); diff --git a/src/vs/editor/standalone/browser/simpleServices.ts b/src/vs/editor/standalone/browser/simpleServices.ts index 6bd70b0ac3e..541e5a14a78 100644 --- a/src/vs/editor/standalone/browser/simpleServices.ts +++ b/src/vs/editor/standalone/browser/simpleServices.ts @@ -8,7 +8,7 @@ import * as dom from 'vs/base/browser/dom'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { Emitter, Event } from 'vs/base/common/event'; import { Keybinding, ResolvedKeybinding, SimpleKeybinding, createKeybinding } from 'vs/base/common/keyCodes'; -import { IDisposable, IReference, ImmortalReference, combinedDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { IDisposable, IReference, ImmortalReference, toDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { OS, isLinux, isMacintosh } from 'vs/base/common/platform'; import Severity from 'vs/base/common/severity'; import { URI } from 'vs/base/common/uri'; @@ -291,7 +291,7 @@ export class StandaloneKeybindingService extends AbstractKeybindingService { throw new Error(`Invalid keybinding`); } - let toDispose: IDisposable[] = []; + const toDispose = new DisposableStore(); this._dynamicKeybindings.push({ keybinding: keybinding, @@ -323,7 +323,7 @@ export class StandaloneKeybindingService extends AbstractKeybindingService { } this.updateResolver({ source: KeybindingSource.Default }); - return combinedDisposable(toDispose); + return toDispose; } private updateResolver(event: IKeybindingEvent): void { diff --git a/src/vs/editor/standalone/browser/standaloneCodeEditor.ts b/src/vs/editor/standalone/browser/standaloneCodeEditor.ts index 75fae893624..b747e6aa3e9 100644 --- a/src/vs/editor/standalone/browser/standaloneCodeEditor.ts +++ b/src/vs/editor/standalone/browser/standaloneCodeEditor.ts @@ -5,7 +5,7 @@ import * as browser from 'vs/base/browser/browser'; import * as aria from 'vs/base/browser/ui/aria/aria'; -import { Disposable, IDisposable, combinedDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { Disposable, IDisposable, toDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { ICodeEditor, IDiffEditor } from 'vs/editor/browser/editorBrowser'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget'; @@ -227,7 +227,7 @@ export class StandaloneCodeEditor extends CodeEditorWidget implements IStandalon }; - let toDispose: IDisposable[] = []; + const toDispose = new DisposableStore(); // Generate a unique id to allow the same descriptor.id across multiple editor instances const uniqueId = this.getId() + ':' + id; @@ -251,11 +251,9 @@ export class StandaloneCodeEditor extends CodeEditorWidget implements IStandalon // Register the keybindings if (Array.isArray(keybindings)) { - toDispose = toDispose.concat( - keybindings.map((kb) => { - return this._standaloneKeybindingService.addDynamicKeybinding(uniqueId, kb, run, keybindingsWhen); - }) - ); + for (const kb of keybindings) { + toDispose.push(this._standaloneKeybindingService.addDynamicKeybinding(uniqueId, kb, run, keybindingsWhen)); + } } // Finally, register an internal editor action @@ -274,7 +272,7 @@ export class StandaloneCodeEditor extends CodeEditorWidget implements IStandalon delete this._actions[id]; })); - return combinedDisposable(toDispose); + return toDispose; } } diff --git a/src/vs/platform/contextview/browser/contextMenuHandler.ts b/src/vs/platform/contextview/browser/contextMenuHandler.ts index 53ba4d21e04..6b67d1cb58b 100644 --- a/src/vs/platform/contextview/browser/contextMenuHandler.ts +++ b/src/vs/platform/contextview/browser/contextMenuHandler.ts @@ -5,7 +5,7 @@ import 'vs/css!./contextMenuHandler'; -import { combinedDisposable, IDisposable } from 'vs/base/common/lifecycle'; +import { IDisposable, combinedDisposable } from 'vs/base/common/lifecycle'; import { ActionRunner, IRunEvent } from 'vs/base/common/actions'; import { Menu } from 'vs/base/browser/ui/menu/menu'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; @@ -104,7 +104,7 @@ export class ContextMenuHandler { this.contextViewService.hideContextView(true); }, null, menuDisposables); - return combinedDisposable([...menuDisposables, menu]); + return combinedDisposable(...menuDisposables, menu); }, focus: () => { diff --git a/src/vs/platform/driver/electron-main/driver.ts b/src/vs/platform/driver/electron-main/driver.ts index 8a202409c45..2b341fb2ed6 100644 --- a/src/vs/platform/driver/electron-main/driver.ts +++ b/src/vs/platform/driver/electron-main/driver.ts @@ -210,5 +210,5 @@ export async function serve( const channel = new DriverChannel(driver); server.registerChannel('driver', channel); - return combinedDisposable([server, windowServer]); + return combinedDisposable(server, windowServer); } diff --git a/src/vs/platform/list/browser/listService.ts b/src/vs/platform/list/browser/listService.ts index d9d37956a76..a13c639276a 100644 --- a/src/vs/platform/list/browser/listService.ts +++ b/src/vs/platform/list/browser/listService.ts @@ -8,7 +8,7 @@ import { IListMouseEvent, IListTouchEvent, IListRenderer, IListVirtualDelegate } import { IPagedRenderer, PagedList } from 'vs/base/browser/ui/list/listPaging'; import { DefaultStyleController, IListOptions, IMultipleSelectionController, IOpenController, isSelectionRangeChangeEvent, isSelectionSingleChangeEvent, List } from 'vs/base/browser/ui/list/listWidget'; import { Emitter, Event } from 'vs/base/common/event'; -import { combinedDisposable, Disposable, dispose, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { Disposable, dispose, IDisposable, toDisposable, DisposableStore, combinedDisposable } from 'vs/base/common/lifecycle'; import { ScrollbarVisibility } from 'vs/base/common/scrollable'; import { isUndefinedOrNull } from 'vs/base/common/types'; import { ITree, ITreeConfiguration, ITreeOptions } from 'vs/base/parts/tree/browser/tree'; @@ -78,7 +78,7 @@ export class ListService implements IListService { this._lastFocusedWidget = widget; } - const result = combinedDisposable([ + return combinedDisposable( widget.onDidFocus(() => this._lastFocusedWidget = widget), toDisposable(() => this.lists.splice(this.lists.indexOf(registeredList), 1)), widget.onDidDispose(() => { @@ -87,9 +87,7 @@ export class ListService implements IListService { this._lastFocusedWidget = undefined; } }) - ]); - - return result; + ); } } @@ -200,7 +198,7 @@ class WorkbenchOpenController extends Disposable implements IOpenController { } function toWorkbenchListOptions(options: IListOptions, configurationService: IConfigurationService, keybindingService: IKeybindingService): [IListOptions, IDisposable] { - const disposables: IDisposable[] = []; + const disposables = new DisposableStore(); const result = { ...options }; if (options.multipleSelectionSupport !== false && !options.multipleSelectionController) { @@ -222,7 +220,7 @@ function toWorkbenchListOptions(options: IListOptions, configurationServic }; } - return [result, combinedDisposable(disposables)]; + return [result, disposables]; } let sharedListStyleSheet: HTMLStyleElement; @@ -283,7 +281,7 @@ export class WorkbenchList extends List { this._useAltAsMultipleSelectionModifier = useAltAsMultipleSelectionModifier(configurationService); - this.disposables.push(combinedDisposable([ + this.disposables.push( this.contextKeyService, (listService as ListService).register(this), attachListStyler(this, themeService), @@ -301,7 +299,7 @@ export class WorkbenchList extends List { this.listHasSelectionOrFocus.set(selection.length > 0 || focus.length > 0); }) - ])); + ); this.registerListeners(); } @@ -324,7 +322,7 @@ export class WorkbenchPagedList extends PagedList { readonly contextKeyService: IContextKeyService; private readonly configurationService: IConfigurationService; - private disposables: IDisposable[]; + private readonly disposables: DisposableStore; private _useAltAsMultipleSelectionModifier: boolean; @@ -351,7 +349,8 @@ export class WorkbenchPagedList extends PagedList { } ); - this.disposables = [workbenchListOptionsDisposable]; + this.disposables = new DisposableStore(); + this.disposables.push(workbenchListOptionsDisposable); this.contextKeyService = createScopedContextKeyService(contextKeyService, this); this.configurationService = configurationService; @@ -361,11 +360,9 @@ export class WorkbenchPagedList extends PagedList { this._useAltAsMultipleSelectionModifier = useAltAsMultipleSelectionModifier(configurationService); - this.disposables.push(combinedDisposable([ - this.contextKeyService, - (listService as ListService).register(this), - attachListStyler(this, themeService) - ])); + this.disposables.push(this.contextKeyService); + this.disposables.push((listService as ListService).register(this)); + this.disposables.push(attachListStyler(this, themeService)); this.registerListeners(); } @@ -385,7 +382,7 @@ export class WorkbenchPagedList extends PagedList { dispose(): void { super.dispose(); - this.disposables = dispose(this.disposables); + this.disposables.dispose(); } } @@ -533,7 +530,7 @@ function massageControllerOptions(options: IControllerOptions): IControllerOptio */ export class WorkbenchTreeController extends DefaultController { - protected disposables: IDisposable[] = []; + protected readonly disposables = new DisposableStore(); constructor( options: IControllerOptions, @@ -561,7 +558,7 @@ export class WorkbenchTreeController extends DefaultController { } dispose(): void { - this.disposables = dispose(this.disposables); + this.disposables.dispose(); } } diff --git a/src/vs/workbench/api/browser/mainThreadDocuments.ts b/src/vs/workbench/api/browser/mainThreadDocuments.ts index af99b8a7720..62b7978fa29 100644 --- a/src/vs/workbench/api/browser/mainThreadDocuments.ts +++ b/src/vs/workbench/api/browser/mainThreadDocuments.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { toErrorMessage } from 'vs/base/common/errorMessage'; -import { IDisposable, IReference, dispose } from 'vs/base/common/lifecycle'; +import { IDisposable, IReference, dispose, Disposable } from 'vs/base/common/lifecycle'; import { Schemas } from 'vs/base/common/network'; import { URI, UriComponents } from 'vs/base/common/uri'; import { ITextModel } from 'vs/editor/common/model'; @@ -64,7 +64,7 @@ export class BoundModelReferenceCollection { } } -export class MainThreadDocuments implements MainThreadDocumentsShape { +export class MainThreadDocuments extends Disposable implements MainThreadDocumentsShape { private readonly _modelService: IModelService; private readonly _textModelResolverService: ITextModelService; @@ -73,7 +73,6 @@ export class MainThreadDocuments implements MainThreadDocumentsShape { private readonly _untitledEditorService: IUntitledEditorService; private readonly _environmentService: IWorkbenchEnvironmentService; - private _toDispose: IDisposable[]; private _modelToDisposeMap: { [modelUrl: string]: IDisposable; }; private readonly _proxy: ExtHostDocumentsShape; private readonly _modelIsSynced: { [modelId: string]: boolean; }; @@ -90,6 +89,7 @@ export class MainThreadDocuments implements MainThreadDocumentsShape { @IUntitledEditorService untitledEditorService: IUntitledEditorService, @IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService ) { + super(); this._modelService = modelService; this._textModelResolverService = textModelResolverService; this._textFileService = textFileService; @@ -100,23 +100,22 @@ export class MainThreadDocuments implements MainThreadDocumentsShape { this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostDocuments); this._modelIsSynced = {}; - this._toDispose = []; - this._toDispose.push(documentsAndEditors.onDocumentAdd(models => models.forEach(this._onModelAdded, this))); - this._toDispose.push(documentsAndEditors.onDocumentRemove(urls => urls.forEach(this._onModelRemoved, this))); - this._toDispose.push(this._modelReferenceCollection); - this._toDispose.push(modelService.onModelModeChanged(this._onModelModeChanged, this)); + this._register(documentsAndEditors.onDocumentAdd(models => models.forEach(this._onModelAdded, this))); + this._register(documentsAndEditors.onDocumentRemove(urls => urls.forEach(this._onModelRemoved, this))); + this._register(this._modelReferenceCollection); + this._register(modelService.onModelModeChanged(this._onModelModeChanged, this)); - this._toDispose.push(textFileService.models.onModelSaved(e => { + this._register(textFileService.models.onModelSaved(e => { if (this._shouldHandleFileEvent(e)) { this._proxy.$acceptModelSaved(e.resource); } })); - this._toDispose.push(textFileService.models.onModelReverted(e => { + this._register(textFileService.models.onModelReverted(e => { if (this._shouldHandleFileEvent(e)) { this._proxy.$acceptDirtyStateChanged(e.resource, false); } })); - this._toDispose.push(textFileService.models.onModelDirty(e => { + this._register(textFileService.models.onModelDirty(e => { if (this._shouldHandleFileEvent(e)) { this._proxy.$acceptDirtyStateChanged(e.resource, true); } @@ -130,7 +129,7 @@ export class MainThreadDocuments implements MainThreadDocumentsShape { this._modelToDisposeMap[modelUrl].dispose(); }); this._modelToDisposeMap = Object.create(null); - this._toDispose = dispose(this._toDispose); + super.dispose(); } private _shouldHandleFileEvent(e: TextFileModelChangeEvent): boolean { diff --git a/src/vs/workbench/api/browser/mainThreadDocumentsAndEditors.ts b/src/vs/workbench/api/browser/mainThreadDocumentsAndEditors.ts index dda2fa8a663..5c8a9b248bb 100644 --- a/src/vs/workbench/api/browser/mainThreadDocumentsAndEditors.ts +++ b/src/vs/workbench/api/browser/mainThreadDocumentsAndEditors.ts @@ -176,11 +176,11 @@ class MainThreadDocumentAndEditorStateComputer { } private _onDidAddEditor(e: ICodeEditor): void { - this._toDisposeOnEditorRemove.set(e.getId(), combinedDisposable([ + this._toDisposeOnEditorRemove.set(e.getId(), combinedDisposable( e.onDidChangeModel(() => this._updateState()), e.onDidFocusEditorText(() => this._updateState()), e.onDidFocusEditorWidget(() => this._updateState(e)) - ])); + )); this._updateState(); } diff --git a/src/vs/workbench/browser/parts/compositePart.ts b/src/vs/workbench/browser/parts/compositePart.ts index adbbceb087c..c22cf6b86f2 100644 --- a/src/vs/workbench/browser/parts/compositePart.ts +++ b/src/vs/workbench/browser/parts/compositePart.ts @@ -6,7 +6,7 @@ import 'vs/css!./media/compositepart'; import * as nls from 'vs/nls'; import { defaultGenerator } from 'vs/base/common/idGenerator'; -import { IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose, DisposableStore } from 'vs/base/common/lifecycle'; import * as strings from 'vs/base/common/strings'; import { Emitter } from 'vs/base/common/event'; import * as errors from 'vs/base/common/errors'; @@ -175,13 +175,13 @@ export abstract class CompositePart extends Part { const compositeInstantiationService = this.instantiationService.createChild(new ServiceCollection([IProgressService, progressService])); const composite = compositeDescriptor.instantiate(compositeInstantiationService); - const disposables: IDisposable[] = []; + const disposables = new DisposableStore(); // Remember as Instantiated - this.instantiatedCompositeItems.set(id, { composite, disposable: toDisposable(() => dispose(disposables)), progressService }); + this.instantiatedCompositeItems.set(id, { composite, disposable: disposables, progressService }); // Register to title area update events from the composite - composite.onTitleAreaUpdate(() => this.onTitleAreaUpdate(composite.getId()), this, disposables); + disposables.push(composite.onTitleAreaUpdate(() => this.onTitleAreaUpdate(composite.getId()), this)); return composite; } diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index 5cd799b070a..7f09ad3f84a 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -384,14 +384,14 @@ export class BreadcrumbsControl { this._breadcrumbsPickerShowing = true; this._updateCkBreadcrumbsActive(); - return combinedDisposable([ + return combinedDisposable( picker, selectListener, focusListener, zoomListener, focusTracker, blurListener - ]); + ); }, getAnchor: () => { let maxInnerWidth = window.innerWidth - 8 /*a little less the full widget*/; diff --git a/src/vs/workbench/browser/parts/editor/editorStatus.ts b/src/vs/workbench/browser/parts/editor/editorStatus.ts index 9c89adfcc22..8adaeea1850 100644 --- a/src/vs/workbench/browser/parts/editor/editorStatus.ts +++ b/src/vs/workbench/browser/parts/editor/editorStatus.ts @@ -15,7 +15,7 @@ import { Action } from 'vs/base/common/actions'; import { Language } from 'vs/base/common/platform'; import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput'; import { IFileEditorInput, EncodingMode, IEncodingSupport, toResource, SideBySideEditorInput, IEditor as IBaseEditor, IEditorInput, SideBySideEditor, IModeSupport } from 'vs/workbench/common/editor'; -import { IDisposable, combinedDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose, toDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService'; import { IEditorAction } from 'vs/editor/common/editorCommon'; import { EndOfLineSequence } from 'vs/editor/common/model'; @@ -316,7 +316,7 @@ export class EditorStatus implements IStatusbarItem { private eolElement: StatusBarItem; private modeElement: StatusBarItem; private metadataElement: StatusBarItem; - private toDispose: IDisposable[]; + private readonly toDispose = new DisposableStore(); private activeEditorListeners: IDisposable[]; private delayedRender: IDisposable | null; private toRender: StateChange | null; @@ -333,7 +333,6 @@ export class EditorStatus implements IStatusbarItem { @INotificationService private readonly notificationService: INotificationService, @IAccessibilityService private readonly accessibilityService: IAccessibilityService ) { - this.toDispose = []; this.activeEditorListeners = []; this.state = new State(); } @@ -385,20 +384,18 @@ export class EditorStatus implements IStatusbarItem { this.delayedRender = null; this.toRender = null; - this.toDispose.push( - toDisposable(() => { - if (this.delayedRender) { - this.delayedRender.dispose(); - this.delayedRender = null; - } - }), - this.editorService.onDidActiveEditorChange(() => this.updateStatusBar()), - this.untitledEditorService.onDidChangeEncoding(r => this.onResourceEncodingChange(r)), - this.textFileService.models.onModelEncodingChanged(e => this.onResourceEncodingChange(e.resource)), - TabFocus.onDidChangeTabFocus(e => this.onTabFocusModeChange()), - ); + this.toDispose.push(toDisposable(() => { + if (this.delayedRender) { + this.delayedRender.dispose(); + this.delayedRender = null; + } + })); + this.toDispose.push(this.editorService.onDidActiveEditorChange(() => this.updateStatusBar())); + this.toDispose.push(this.untitledEditorService.onDidChangeEncoding(r => this.onResourceEncodingChange(r))); + this.toDispose.push(this.textFileService.models.onModelEncodingChanged(e => this.onResourceEncodingChange((e.resource)))); + this.toDispose.push(TabFocus.onDidChangeTabFocus(e => this.onTabFocusModeChange())); - return combinedDisposable(this.toDispose); + return this.toDispose; } private updateState(update: StateDelta): void { diff --git a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts index 919151455e1..7b516cd7077 100644 --- a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts +++ b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts @@ -20,7 +20,7 @@ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IMenuService } from 'vs/platform/actions/common/actions'; import { TitleControl } from 'vs/workbench/browser/parts/editor/titleControl'; import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen'; -import { IDisposable, dispose, combinedDisposable } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose, DisposableStore, combinedDisposable } from 'vs/base/common/lifecycle'; import { ScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement'; import { ScrollbarVisibility } from 'vs/base/common/scrollable'; import { getOrSet } from 'vs/base/common/map'; @@ -454,13 +454,13 @@ export class TabsTitleControl extends TitleControl { // Eventing const eventsDisposable = this.registerTabListeners(tabContainer, index); - this.tabDisposeables.push(combinedDisposable([eventsDisposable, tabActionBar, tabActionRunner, editorLabel])); + this.tabDisposeables.push(combinedDisposable(eventsDisposable, tabActionBar, tabActionRunner, editorLabel)); return tabContainer; } private registerTabListeners(tab: HTMLElement, index: number): IDisposable { - const disposables: IDisposable[] = []; + const disposables = new DisposableStore(); const handleClickOrTouch = (e: MouseEvent | GestureEvent): void => { tab.blur(); @@ -669,7 +669,7 @@ export class TabsTitleControl extends TitleControl { } })); - return combinedDisposable(disposables); + return disposables; } private isSupportedDropTransfer(e: DragEvent): boolean { diff --git a/src/vs/workbench/browser/parts/views/panelViewlet.ts b/src/vs/workbench/browser/parts/views/panelViewlet.ts index 10e2fd42d31..ec1b456a8a1 100644 --- a/src/vs/workbench/browser/parts/views/panelViewlet.ts +++ b/src/vs/workbench/browser/parts/views/panelViewlet.ts @@ -355,7 +355,7 @@ export class PanelViewlet extends Viewlet { headerBorder: SIDE_BAR_SECTION_HEADER_BORDER, dropBackground: SIDE_BAR_DRAG_AND_DROP_BACKGROUND }, panel); - const disposable = combinedDisposable([onDidFocus, onDidChangeTitleArea, panelStyler, onDidChange]); + const disposable = combinedDisposable(onDidFocus, onDidChangeTitleArea, panelStyler, onDidChange); const panelItem: IViewletPanelItem = { panel, disposable }; this.panelItems.splice(index, 0, panelItem); diff --git a/src/vs/workbench/browser/parts/views/viewsViewlet.ts b/src/vs/workbench/browser/parts/views/viewsViewlet.ts index 679a4c15742..8dfe43f5871 100644 --- a/src/vs/workbench/browser/parts/views/viewsViewlet.ts +++ b/src/vs/workbench/browser/parts/views/viewsViewlet.ts @@ -207,7 +207,7 @@ export abstract class ViewContainerViewlet extends PanelViewlet implements IView this.viewsModel.setCollapsed(viewDescriptor.id, collapsed); }); - this.viewDisposables.splice(index, 0, combinedDisposable([contextMenuDisposable, collapseDisposable])); + this.viewDisposables.splice(index, 0, combinedDisposable(contextMenuDisposable, collapseDisposable)); panelsToAdd.push({ panel, size: size || panel.minimumSize, index }); } diff --git a/src/vs/workbench/common/actions.ts b/src/vs/workbench/common/actions.ts index af3e7f2e497..aafca62c310 100644 --- a/src/vs/workbench/common/actions.ts +++ b/src/vs/workbench/common/actions.ts @@ -8,7 +8,7 @@ import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/co import { ICommandHandler, CommandsRegistry } from 'vs/platform/commands/common/commands'; import { SyncActionDescriptor, MenuRegistry, MenuId, ICommandAction } from 'vs/platform/actions/common/actions'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IDisposable, combinedDisposable } from 'vs/base/common/lifecycle'; +import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; @@ -33,7 +33,7 @@ Registry.add(Extensions.WorkbenchActions, new class implements IWorkbenchActionR } private registerWorkbenchCommandFromAction(descriptor: SyncActionDescriptor, alias: string, category?: string, when?: ContextKeyExpr): IDisposable { - let registrations: IDisposable[] = []; + const registrations = new DisposableStore(); // command registrations.push(CommandsRegistry.registerCommand(descriptor.id, this.createCommandHandler(descriptor))); @@ -78,7 +78,7 @@ Registry.add(Extensions.WorkbenchActions, new class implements IWorkbenchActionR // TODO@alex,joh // support removal of keybinding rule // support removal of command-ui - return combinedDisposable(registrations); + return registrations; } private createCommandHandler(descriptor: SyncActionDescriptor): ICommandHandler { diff --git a/src/vs/workbench/contrib/debug/browser/baseDebugView.ts b/src/vs/workbench/contrib/debug/browser/baseDebugView.ts index 5a250925b81..b9c11d7fe1b 100644 --- a/src/vs/workbench/contrib/debug/browser/baseDebugView.ts +++ b/src/vs/workbench/contrib/debug/browser/baseDebugView.ts @@ -9,7 +9,7 @@ import { Expression, Variable, ExpressionContainer } from 'vs/workbench/contrib/ import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { IInputValidationOptions, InputBox } from 'vs/base/browser/ui/inputbox/inputBox'; import { ITreeRenderer, ITreeNode } from 'vs/base/browser/ui/tree/tree'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose, DisposableStore } from 'vs/base/common/lifecycle'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { attachInputBoxStyler } from 'vs/platform/theme/common/styler'; import { KeyCode } from 'vs/base/common/keyCodes'; @@ -127,7 +127,7 @@ export interface IExpressionTemplateData { value: HTMLSpanElement; inputBoxContainer: HTMLElement; enableInputBox(expression: IExpression, options: IInputBoxOptions): void; - toDispose: IDisposable[]; + readonly toDispose: IDisposable; label: HighlightedLabel; } @@ -148,7 +148,7 @@ export abstract class AbstractExpressionsRenderer implements ITreeRenderer { name.style.display = 'none'; @@ -180,7 +180,7 @@ export abstract class AbstractExpressionsRenderer implements ITreeRenderer this.updateLabel(), this, this.disposables); + this.disposables.push(this.labelService.onDidChangeFormatters(() => this.updateLabel(), this)); } update(): void { @@ -270,7 +270,7 @@ export class InstallAction extends ExtensionAction { } dispose(): void { - this.disposables = dispose(this.disposables); + this.disposables.dispose(); super.dispose(); } } @@ -284,7 +284,7 @@ export class RemoteInstallAction extends ExtensionAction { private static readonly InstallingClass = 'extension-action install installing'; updateWhenCounterExtensionChanges: boolean = true; - private disposables: IDisposable[] = []; + private readonly disposables = new DisposableStore(); private installing: boolean = false; constructor( @@ -295,7 +295,7 @@ export class RemoteInstallAction extends ExtensionAction { @IConfigurationService private readonly configurationService: IConfigurationService, ) { super(`extensions.remoteinstall`, RemoteInstallAction.INSTALL_LABEL, RemoteInstallAction.Class, false); - this.labelService.onDidChangeFormatters(() => this.updateLabel(), this, this.disposables); + this.disposables.push(this.labelService.onDidChangeFormatters(() => this.updateLabel(), this)); this.updateLabel(); this.update(); } @@ -354,7 +354,7 @@ export class RemoteInstallAction extends ExtensionAction { } dispose(): void { - this.disposables = dispose(this.disposables); + this.disposables.dispose(); super.dispose(); } } @@ -368,7 +368,7 @@ export class LocalInstallAction extends ExtensionAction { private static readonly InstallingClass = 'extension-action install installing'; updateWhenCounterExtensionChanges: boolean = true; - private disposables: IDisposable[] = []; + private readonly disposables = new DisposableStore(); private installing: boolean = false; constructor( @@ -379,7 +379,7 @@ export class LocalInstallAction extends ExtensionAction { @IConfigurationService private readonly configurationService: IConfigurationService, ) { super(`extensions.localinstall`, LocalInstallAction.INSTALL_LABEL, LocalInstallAction.Class, false); - this.labelService.onDidChangeFormatters(() => this.updateLabel(), this, this.disposables); + this.disposables.push(this.labelService.onDidChangeFormatters(() => this.updateLabel(), this)); this.updateLabel(); this.update(); } @@ -433,7 +433,7 @@ export class LocalInstallAction extends ExtensionAction { } dispose(): void { - this.disposables = dispose(this.disposables); + this.disposables.dispose(); super.dispose(); } } @@ -498,16 +498,15 @@ export class CombinedInstallAction extends ExtensionAction { private static readonly NoExtensionClass = 'extension-action prominent install no-extension'; private installAction: InstallAction; private uninstallAction: UninstallAction; - private disposables: IDisposable[] = []; + private readonly disposables = new DisposableStore(); constructor( @IInstantiationService instantiationService: IInstantiationService ) { super('extensions.combinedInstall', '', '', false); - this.installAction = instantiationService.createInstance(InstallAction); - this.uninstallAction = instantiationService.createInstance(UninstallAction); - this.disposables.push(this.installAction, this.uninstallAction); + this.installAction = this.disposables.push(instantiationService.createInstance(InstallAction)); + this.uninstallAction = this.disposables.push(instantiationService.createInstance(UninstallAction)); this.update(); } @@ -563,7 +562,7 @@ export class CombinedInstallAction extends ExtensionAction { dispose(): void { super.dispose(); - this.disposables = dispose(this.disposables); + this.disposables.dispose(); } } @@ -667,7 +666,7 @@ export class ExtensionActionViewItem extends ActionViewItem { export abstract class ExtensionDropDownAction extends ExtensionAction { - protected disposables: IDisposable[] = []; + protected readonly disposables = new DisposableStore(); constructor( id: string, @@ -694,14 +693,14 @@ export abstract class ExtensionDropDownAction extends ExtensionAction { } dispose(): void { - dispose(this.disposables); + this.disposables.dispose(); super.dispose(); } } export class DropDownMenuActionViewItem extends ExtensionActionViewItem { - private disposables: IDisposable[] = []; + private readonly disposables = new DisposableStore(); constructor(action: ExtensionDropDownAction, tabOnlyOnFocus: boolean, @@ -734,7 +733,7 @@ export class DropDownMenuActionViewItem extends ExtensionActionViewItem { dispose(): void { super.dispose(); - this.disposables = dispose(this.disposables); + this.disposables.dispose(); } } @@ -1187,7 +1186,7 @@ export class UpdateAllAction extends Action { static readonly ID = 'workbench.extensions.action.updateAllExtensions'; static LABEL = localize('updateAll', "Update All Extensions"); - private disposables: IDisposable[] = []; + private readonly disposables = new DisposableStore(); constructor( id = UpdateAllAction.ID, @@ -1225,7 +1224,7 @@ export class UpdateAllAction extends Action { dispose(): void { super.dispose(); - this.disposables = dispose(this.disposables); + this.disposables.dispose(); } } @@ -1235,7 +1234,7 @@ export class ReloadAction extends ExtensionAction { private static readonly DisabledClass = `${ReloadAction.EnabledClass} disabled`; updateWhenCounterExtensionChanges: boolean = true; - private disposables: IDisposable[] = []; + private readonly disposables = new DisposableStore(); private _runningExtensions: IExtensionDescription[] | null = null; constructor( @@ -1248,7 +1247,7 @@ export class ReloadAction extends ExtensionAction { @IConfigurationService private readonly configurationService: IConfigurationService ) { super('extensions.reload', localize('reloadAction', "Reload"), ReloadAction.DisabledClass, false); - this.extensionService.onDidChangeExtensions(this.updateRunningExtensions, this, this.disposables); + this.disposables.push(this.extensionService.onDidChangeExtensions(this.updateRunningExtensions, this)); this.updateRunningExtensions(); } @@ -1360,7 +1359,7 @@ export class ReloadAction extends ExtensionAction { } dispose(): void { - dispose(this.disposables); + this.disposables.dispose(); super.dispose(); } } @@ -1374,7 +1373,7 @@ export class SetColorThemeAction extends ExtensionAction { private static readonly EnabledClass = 'extension-action theme'; private static readonly DisabledClass = `${SetColorThemeAction.EnabledClass} disabled`; - private disposables: IDisposable[] = []; + private readonly disposables = new DisposableStore(); constructor( private readonly colorThemes: IColorTheme[], @@ -1384,7 +1383,7 @@ export class SetColorThemeAction extends ExtensionAction { @IConfigurationService private readonly configurationService: IConfigurationService ) { super(`extensions.colorTheme`, localize('color theme', "Set Color Theme"), SetColorThemeAction.DisabledClass, false); - Event.any(extensionService.onDidChangeExtensions, workbenchThemeService.onDidColorThemeChange)(() => this.update(), this, this.disposables); + this.disposables.push(Event.any(extensionService.onDidChangeExtensions, workbenchThemeService.onDidColorThemeChange)(() => this.update(), this)); this.update(); } @@ -1432,7 +1431,7 @@ export class SetColorThemeAction extends ExtensionAction { } dispose() { - this.disposables = dispose(this.disposables); + this.disposables.dispose(); super.dispose(); } } @@ -1442,7 +1441,7 @@ export class SetFileIconThemeAction extends ExtensionAction { private static readonly EnabledClass = 'extension-action theme'; private static readonly DisabledClass = `${SetFileIconThemeAction.EnabledClass} disabled`; - private disposables: IDisposable[] = []; + private readonly disposables = new DisposableStore(); static getFileIconThemes(fileIconThemes: IFileIconTheme[], extension: IExtension): IFileIconTheme[] { return fileIconThemes.filter(c => c.extensionData && ExtensionIdentifier.equals(c.extensionData.extensionId, extension.identifier.id)); @@ -1456,7 +1455,7 @@ export class SetFileIconThemeAction extends ExtensionAction { @IConfigurationService private readonly configurationService: IConfigurationService ) { super(`extensions.fileIconTheme`, localize('file icon theme', "Set File Icon Theme"), SetFileIconThemeAction.DisabledClass, false); - Event.any(extensionService.onDidChangeExtensions, workbenchThemeService.onDidFileIconThemeChange)(() => this.update(), this, this.disposables); + this.disposables.push(Event.any(extensionService.onDidChangeExtensions, workbenchThemeService.onDidFileIconThemeChange)(() => this.update(), this)); this.update(); } @@ -1504,7 +1503,7 @@ export class SetFileIconThemeAction extends ExtensionAction { } dispose() { - this.disposables = dispose(this.disposables); + this.disposables.dispose(); super.dispose(); } } @@ -1604,7 +1603,7 @@ export class ClearExtensionsInputAction extends Action { static readonly ID = 'workbench.extensions.action.clearExtensionsInput'; static LABEL = localize('clearExtensionsInput', "Clear Extensions Input"); - private disposables: IDisposable[] = []; + private readonly disposables = new DisposableStore(); constructor( id: string, @@ -1615,7 +1614,7 @@ export class ClearExtensionsInputAction extends Action { ) { super(id, label, 'clear-extensions', true); this.onSearchChange(value); - onSearchChange(this.onSearchChange, this, this.disposables); + this.disposables.push(onSearchChange(this.onSearchChange, this)); } private onSearchChange(value: string): void { @@ -1632,7 +1631,7 @@ export class ClearExtensionsInputAction extends Action { } dispose(): void { - this.disposables = dispose(this.disposables); + this.disposables.dispose(); } } @@ -1837,7 +1836,7 @@ export class IgnoreExtensionRecommendationAction extends Action { private static readonly Class = 'extension-action ignore'; - private disposables: IDisposable[] = []; + private readonly disposables = new DisposableStore(); extension: IExtension; constructor( @@ -1857,7 +1856,7 @@ export class IgnoreExtensionRecommendationAction extends Action { dispose(): void { super.dispose(); - this.disposables = dispose(this.disposables); + this.disposables.dispose(); } } @@ -1867,7 +1866,7 @@ export class UndoIgnoreExtensionRecommendationAction extends Action { private static readonly Class = 'extension-action undo-ignore'; - private disposables: IDisposable[] = []; + private readonly disposables = new DisposableStore(); extension: IExtension; constructor( @@ -1887,7 +1886,7 @@ export class UndoIgnoreExtensionRecommendationAction extends Action { dispose(): void { super.dispose(); - this.disposables = dispose(this.disposables); + this.disposables.dispose(); } } @@ -1964,7 +1963,7 @@ export class ShowAzureExtensionsAction extends Action { export class ChangeSortAction extends Action { private query: Query; - private disposables: IDisposable[] = []; + private readonly disposables = new DisposableStore(); constructor( id: string, @@ -1981,7 +1980,7 @@ export class ChangeSortAction extends Action { this.query = Query.parse(''); this.enabled = false; - onSearchChange(this.onSearchChange, this, this.disposables); + this.disposables.push(onSearchChange(this.onSearchChange, this)); } private onSearchChange(value: string): void { @@ -2286,7 +2285,7 @@ export class ConfigureWorkspaceRecommendedExtensionsAction extends AbstractConfi static readonly ID = 'workbench.extensions.action.configureWorkspaceRecommendedExtensions'; static LABEL = localize('configureWorkspaceRecommendedExtensions', "Configure Recommended Extensions (Workspace)"); - private disposables: IDisposable[] = []; + private readonly disposables = new DisposableStore(); constructor( id: string, @@ -2299,7 +2298,7 @@ export class ConfigureWorkspaceRecommendedExtensionsAction extends AbstractConfi @ITextModelService textModelResolverService: ITextModelService ) { super(id, label, contextService, fileService, textFileService, editorService, jsonEditingService, textModelResolverService); - this.contextService.onDidChangeWorkbenchState(() => this.update(), this, this.disposables); + this.disposables.push(this.contextService.onDidChangeWorkbenchState(() => this.update(), this)); this.update(); } @@ -2318,7 +2317,7 @@ export class ConfigureWorkspaceRecommendedExtensionsAction extends AbstractConfi } dispose(): void { - this.disposables = dispose(this.disposables); + this.disposables.dispose(); super.dispose(); } } @@ -2328,7 +2327,7 @@ export class ConfigureWorkspaceFolderRecommendedExtensionsAction extends Abstrac static readonly ID = 'workbench.extensions.action.configureWorkspaceFolderRecommendedExtensions'; static LABEL = localize('configureWorkspaceFolderRecommendedExtensions', "Configure Recommended Extensions (Workspace Folder)"); - private disposables: IDisposable[] = []; + private readonly disposables = new DisposableStore(); constructor( id: string, @@ -2342,7 +2341,7 @@ export class ConfigureWorkspaceFolderRecommendedExtensionsAction extends Abstrac @ICommandService private readonly commandService: ICommandService ) { super(id, label, contextService, fileService, textFileService, editorService, jsonEditingService, textModelResolverService); - this.contextService.onDidChangeWorkspaceFolders(() => this.update(), this, this.disposables); + this.disposables.push(this.contextService.onDidChangeWorkspaceFolders(() => this.update(), this)); this.update(); } @@ -2363,7 +2362,7 @@ export class ConfigureWorkspaceFolderRecommendedExtensionsAction extends Abstrac } dispose(): void { - this.disposables = dispose(this.disposables); + this.disposables.dispose(); super.dispose(); } } @@ -2654,7 +2653,7 @@ export class DisabledLabelAction extends ExtensionAction { private static readonly Class = 'disable-status'; updateWhenCounterExtensionChanges: boolean = true; - private disposables: IDisposable[] = []; + private readonly disposables = new DisposableStore(); private _runningExtensions: IExtensionDescription[] | null = null; constructor( @@ -2663,8 +2662,8 @@ export class DisabledLabelAction extends ExtensionAction { @IExtensionService private readonly extensionService: IExtensionService, ) { super('extensions.disabledLabel', warningAction.tooltip, `${DisabledLabelAction.Class} hide`, false); - warningAction.onDidChange(() => this.update(), this, this.disposables); - this.extensionService.onDidChangeExtensions(this.updateRunningExtensions, this, this.disposables); + this.disposables.push(warningAction.onDidChange(() => this.update(), this)); + this.disposables.push(this.extensionService.onDidChangeExtensions(this.updateRunningExtensions, this)); this.updateRunningExtensions(); } @@ -2699,7 +2698,7 @@ export class DisabledLabelAction extends ExtensionAction { } dispose(): void { - dispose(this.disposables); + this.disposables.dispose(); super.dispose(); } } @@ -2711,7 +2710,7 @@ export class SystemDisabledWarningAction extends ExtensionAction { private static readonly INFO_CLASS = `${SystemDisabledWarningAction.CLASS} info`; updateWhenCounterExtensionChanges: boolean = true; - private disposables: IDisposable[] = []; + private readonly disposables = new DisposableStore(); private _runningExtensions: IExtensionDescription[] | null = null; constructor( @@ -2723,8 +2722,8 @@ export class SystemDisabledWarningAction extends ExtensionAction { @IExtensionService private readonly extensionService: IExtensionService, ) { super('extensions.install', '', `${SystemDisabledWarningAction.CLASS} hide`, false); - this.labelService.onDidChangeFormatters(() => this.update(), this, this.disposables); - this.extensionService.onDidChangeExtensions(this.updateRunningExtensions, this, this.disposables); + this.disposables.push(this.labelService.onDidChangeFormatters(() => this.update(), this)); + this.disposables.push(this.extensionService.onDidChangeExtensions(this.updateRunningExtensions, this)); this.updateRunningExtensions(); this.update(); } @@ -2797,7 +2796,7 @@ export class SystemDisabledWarningAction extends ExtensionAction { } dispose(): void { - dispose(this.disposables); + this.disposables.dispose(); super.dispose(); } } @@ -2807,7 +2806,7 @@ export class DisableAllAction extends Action { static readonly ID = 'workbench.extensions.action.disableAll'; static LABEL = localize('disableAll', "Disable All Installed Extensions"); - private disposables: IDisposable[] = []; + private readonly disposables = new DisposableStore(); constructor( id: string = DisableAllAction.ID, label: string = DisableAllAction.LABEL, @@ -2829,7 +2828,7 @@ export class DisableAllAction extends Action { dispose(): void { super.dispose(); - this.disposables = dispose(this.disposables); + this.disposables.dispose(); } } @@ -2838,7 +2837,7 @@ export class DisableAllWorkpsaceAction extends Action { static readonly ID = 'workbench.extensions.action.disableAllWorkspace'; static LABEL = localize('disableAllWorkspace', "Disable All Installed Extensions for this Workspace"); - private disposables: IDisposable[] = []; + private readonly disposables = new DisposableStore(); constructor( id: string = DisableAllWorkpsaceAction.ID, label: string = DisableAllWorkpsaceAction.LABEL, @@ -2847,8 +2846,8 @@ export class DisableAllWorkpsaceAction extends Action { ) { super(id, label); this.update(); - this.workspaceContextService.onDidChangeWorkbenchState(() => this.update(), this, this.disposables); - this.extensionsWorkbenchService.onChange(() => this.update(), this, this.disposables); + this.disposables.push(this.workspaceContextService.onDidChangeWorkbenchState(() => this.update(), this)); + this.disposables.push(this.extensionsWorkbenchService.onChange(() => this.update(), this)); } private update(): void { @@ -2861,7 +2860,7 @@ export class DisableAllWorkpsaceAction extends Action { dispose(): void { super.dispose(); - this.disposables = dispose(this.disposables); + this.disposables.dispose(); } } @@ -2870,7 +2869,7 @@ export class EnableAllAction extends Action { static readonly ID = 'workbench.extensions.action.enableAll'; static LABEL = localize('enableAll', "Enable All Extensions"); - private disposables: IDisposable[] = []; + private readonly disposables = new DisposableStore(); constructor( id: string = EnableAllAction.ID, label: string = EnableAllAction.LABEL, @@ -2892,7 +2891,7 @@ export class EnableAllAction extends Action { dispose(): void { super.dispose(); - this.disposables = dispose(this.disposables); + this.disposables.dispose(); } } @@ -2901,7 +2900,7 @@ export class EnableAllWorkpsaceAction extends Action { static readonly ID = 'workbench.extensions.action.enableAllWorkspace'; static LABEL = localize('enableAllWorkspace', "Enable All Extensions for this Workspace"); - private disposables: IDisposable[] = []; + private readonly disposables = new DisposableStore(); constructor( id: string = EnableAllWorkpsaceAction.ID, label: string = EnableAllWorkpsaceAction.LABEL, @@ -2911,8 +2910,8 @@ export class EnableAllWorkpsaceAction extends Action { ) { super(id, label); this.update(); - this.extensionsWorkbenchService.onChange(() => this.update(), this, this.disposables); - this.workspaceContextService.onDidChangeWorkbenchState(() => this.update(), this, this.disposables); + this.disposables.push(this.extensionsWorkbenchService.onChange(() => this.update(), this)); + this.disposables.push(this.workspaceContextService.onDidChangeWorkbenchState(() => this.update(), this)); } private update(): void { @@ -2925,7 +2924,7 @@ export class EnableAllWorkpsaceAction extends Action { dispose(): void { super.dispose(); - this.disposables = dispose(this.disposables); + this.disposables.dispose(); } } diff --git a/src/vs/workbench/contrib/preferences/browser/keybindingsEditor.ts b/src/vs/workbench/contrib/preferences/browser/keybindingsEditor.ts index aa8da6134ca..3813a7ff628 100644 --- a/src/vs/workbench/contrib/preferences/browser/keybindingsEditor.ts +++ b/src/vs/workbench/contrib/preferences/browser/keybindingsEditor.ts @@ -8,7 +8,7 @@ import { localize } from 'vs/nls'; import { Delayer } from 'vs/base/common/async'; import * as DOM from 'vs/base/browser/dom'; import { OS } from 'vs/base/common/platform'; -import { dispose, Disposable, toDisposable, IDisposable } from 'vs/base/common/lifecycle'; +import { dispose, Disposable, toDisposable, IDisposable, combinedDisposable } from 'vs/base/common/lifecycle'; import { CheckboxActionViewItem } from 'vs/base/browser/ui/checkbox/checkbox'; import { HighlightedLabel } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel'; import { KeybindingLabel } from 'vs/base/browser/ui/keybindingLabel/keybindingLabel'; @@ -804,7 +804,7 @@ class KeybindingItemRenderer implements IListRenderer element); this.keybindingsEditor.layoutColumns(elements); @@ -814,7 +814,7 @@ class KeybindingItemRenderer implements IListRenderer dispose(disposables)) + disposable: disposables }; } diff --git a/src/vs/workbench/contrib/scm/browser/dirtydiffDecorator.ts b/src/vs/workbench/contrib/scm/browser/dirtydiffDecorator.ts index 2a22287760a..5e64a44a7ab 100644 --- a/src/vs/workbench/contrib/scm/browser/dirtydiffDecorator.ts +++ b/src/vs/workbench/contrib/scm/browser/dirtydiffDecorator.ts @@ -7,7 +7,7 @@ import * as nls from 'vs/nls'; import 'vs/css!./media/dirtydiffDecorator'; import { ThrottledDelayer, first } from 'vs/base/common/async'; -import { IDisposable, dispose, toDisposable, Disposable, combinedDisposable } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose, toDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle'; import { Event, Emitter } from 'vs/base/common/event'; import * as ext from 'vs/workbench/common/contributions'; import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget'; @@ -554,7 +554,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ } }); -export class DirtyDiffController implements IEditorContribution { +export class DirtyDiffController extends Disposable implements IEditorContribution { private static readonly ID = 'editor.contrib.dirtydiff'; @@ -571,20 +571,20 @@ export class DirtyDiffController implements IEditorContribution { private session: IDisposable = Disposable.None; private mouseDownInfo: { lineNumber: number } | null = null; private enabled = false; - private disposables: IDisposable[] = []; constructor( private editor: ICodeEditor, @IContextKeyService contextKeyService: IContextKeyService, @IInstantiationService private readonly instantiationService: IInstantiationService ) { + super(); this.enabled = !contextKeyService.getContextKeyValue('isInDiffEditor'); if (this.enabled) { this.isDirtyDiffVisible = isDirtyDiffVisible.bindTo(contextKeyService); - this.disposables.push(editor.onMouseDown(e => this.onEditorMouseDown(e))); - this.disposables.push(editor.onMouseUp(e => this.onEditorMouseUp(e))); - this.disposables.push(editor.onDidChangeModel(() => this.close())); + this._register(editor.onMouseDown(e => this.onEditorMouseDown(e))); + this._register(editor.onMouseUp(e => this.onEditorMouseUp(e))); + this._register(editor.onDidChangeModel(() => this.close())); } } @@ -674,22 +674,20 @@ export class DirtyDiffController implements IEditorContribution { this.widget = this.instantiationService.createInstance(DirtyDiffWidget, this.editor, model); this.isDirtyDiffVisible.set(true); - const disposables: IDisposable[] = []; - Event.once(this.widget.onDidClose)(this.close, this, disposables); - model.onDidChange(this.onDidModelChange, this, disposables); + const disposables = new DisposableStore(); + disposables.push(Event.once(this.widget.onDidClose)(this.close, this)); + disposables.push(model.onDidChange(this.onDidModelChange, this)); - disposables.push( - this.widget, - toDisposable(() => { - this.model = null; - this.widget = null; - this.currentIndex = -1; - this.isDirtyDiffVisible.set(false); - this.editor.focus(); - }) - ); + disposables.push(this.widget); + disposables.push(toDisposable(() => { + this.model = null; + this.widget = null; + this.currentIndex = -1; + this.isDirtyDiffVisible.set(false); + this.editor.focus(); + })); - this.session = combinedDisposable(disposables); + this.session = disposables; return true; } @@ -808,10 +806,6 @@ export class DirtyDiffController implements IEditorContribution { return model.changes; } - - dispose(): void { - this.disposables = dispose(this.disposables); - } } export const editorGutterModifiedBackground = registerColor('editorGutter.modifiedBackground', { @@ -837,7 +831,7 @@ export const overviewRulerModifiedForeground = registerColor('editorOverviewRule export const overviewRulerAddedForeground = registerColor('editorOverviewRuler.addedForeground', { dark: overviewRulerDefault, light: overviewRulerDefault, hc: overviewRulerDefault }, nls.localize('overviewRulerAddedForeground', 'Overview ruler marker color for added content.')); export const overviewRulerDeletedForeground = registerColor('editorOverviewRuler.deletedForeground', { dark: overviewRulerDefault, light: overviewRulerDefault, hc: overviewRulerDefault }, nls.localize('overviewRulerDeletedForeground', 'Overview ruler marker color for deleted content.')); -class DirtyDiffDecorator { +class DirtyDiffDecorator extends Disposable { static createDecoration(className: string, foregroundColor: string, options: { gutter: boolean, overview: boolean, isWholeLine: boolean }): ModelDecorationOptions { const decorationOptions: IModelDecorationOptions = { @@ -862,7 +856,6 @@ class DirtyDiffDecorator { private addedOptions: ModelDecorationOptions; private deletedOptions: ModelDecorationOptions; private decorations: string[] = []; - private disposables: IDisposable[] = []; private editorModel: ITextModel | null; constructor( @@ -870,6 +863,7 @@ class DirtyDiffDecorator { private model: DirtyDiffModel, @IConfigurationService configurationService: IConfigurationService ) { + super(); this.editorModel = editorModel; const decorations = configurationService.getValue('scm.diffDecorations'); const gutter = decorations === 'all' || decorations === 'gutter'; @@ -880,7 +874,7 @@ class DirtyDiffDecorator { this.addedOptions = DirtyDiffDecorator.createDecoration('dirty-diff-added', overviewRulerAddedForeground, options); this.deletedOptions = DirtyDiffDecorator.createDecoration('dirty-diff-deleted', overviewRulerDeletedForeground, { ...options, isWholeLine: false }); - model.onDidChange(this.onDidChange, this, this.disposables); + this._register(model.onDidChange(this.onDidChange, this)); } private onDidChange(): void { @@ -924,7 +918,7 @@ class DirtyDiffDecorator { } dispose(): void { - this.disposables = dispose(this.disposables); + super.dispose(); if (this.editorModel && !this.editorModel.isDisposed()) { this.editorModel.deltaDecorations(this.decorations, []); @@ -957,7 +951,7 @@ function compareChanges(a: IChange, b: IChange): number { return a.originalEndLineNumber - b.originalEndLineNumber; } -export class DirtyDiffModel { +export class DirtyDiffModel extends Disposable { private _originalModel: ITextModel | null; get original(): ITextModel | null { return this._originalModel; } @@ -965,9 +959,8 @@ export class DirtyDiffModel { private diffDelayer: ThrottledDelayer | null; private _originalURIPromise?: Promise; - private repositoryDisposables = new Set(); - private originalModelDisposables: IDisposable[] = []; - private disposables: IDisposable[] = []; + private repositoryDisposables = new Set(); + private originalModelDisposables: IDisposable = Disposable.None; private _onDidChange = new Emitter[]>(); readonly onDidChange: Event[]> = this._onDidChange.event; @@ -985,27 +978,28 @@ export class DirtyDiffModel { @IEditorWorkerService private readonly editorWorkerService: IEditorWorkerService, @ITextModelService private readonly textModelResolverService: ITextModelService ) { + super(); this._editorModel = editorModel; this.diffDelayer = new ThrottledDelayer(200); - this.disposables.push(editorModel.onDidChangeContent(() => this.triggerDiff())); - scmService.onDidAddRepository(this.onDidAddRepository, this, this.disposables); + this._register(editorModel.onDidChangeContent(() => this.triggerDiff())); + this._register(scmService.onDidAddRepository(this.onDidAddRepository, this)); scmService.repositories.forEach(r => this.onDidAddRepository(r)); this.triggerDiff(); } private onDidAddRepository(repository: ISCMRepository): void { - const disposables: IDisposable[] = []; + const disposables = new DisposableStore(); this.repositoryDisposables.add(disposables); disposables.push(toDisposable(() => this.repositoryDisposables.delete(disposables))); const onDidChange = Event.any(repository.provider.onDidChange, repository.provider.onDidChangeResources); - onDidChange(this.triggerDiff, this, disposables); + disposables.push(onDidChange(this.triggerDiff, this)); const onDidRemoveThis = Event.filter(this.scmService.onDidRemoveRepository, r => r === repository); - onDidRemoveThis(() => dispose(disposables), null, disposables); + disposables.push(onDidRemoveThis(() => dispose(disposables), null)); this.triggerDiff(); } @@ -1075,11 +1069,11 @@ export class DirtyDiffModel { this._originalModel = ref.object.textEditorModel; - const originalModelDisposables: IDisposable[] = []; + const originalModelDisposables = new DisposableStore(); originalModelDisposables.push(ref); originalModelDisposables.push(ref.object.textEditorModel.onDidChangeContent(() => this.triggerDiff())); - dispose(this.originalModelDisposables); + this.originalModelDisposables.dispose(); this.originalModelDisposables = originalModelDisposables; return originalUri; @@ -1138,7 +1132,7 @@ export class DirtyDiffModel { dispose(): void { this.originalModelDisposables = dispose(this.originalModelDisposables); - this.disposables = dispose(this.disposables); + super.dispose(); this._editorModel = null; this._originalModel = null; @@ -1163,25 +1157,25 @@ class DirtyDiffItem { } } -export class DirtyDiffWorkbenchController implements ext.IWorkbenchContribution, IModelRegistry { +export class DirtyDiffWorkbenchController extends Disposable implements ext.IWorkbenchContribution, IModelRegistry { private enabled = false; private models: ITextModel[] = []; private items: { [modelId: string]: DirtyDiffItem; } = Object.create(null); private transientDisposables: IDisposable[] = []; private stylesheet: HTMLStyleElement; - private disposables: IDisposable[] = []; constructor( @IEditorService private readonly editorService: IEditorService, @IInstantiationService private readonly instantiationService: IInstantiationService, @IConfigurationService private readonly configurationService: IConfigurationService ) { + super(); this.stylesheet = createStyleSheet(); - this.disposables.push(toDisposable(() => this.stylesheet.parentElement!.removeChild(this.stylesheet))); + this._register(toDisposable(() => this.stylesheet.parentElement!.removeChild(this.stylesheet))); const onDidChangeConfiguration = Event.filter(configurationService.onDidChangeConfiguration, e => e.affectsConfiguration('scm.diffDecorations')); - onDidChangeConfiguration(this.onDidChangeConfiguration, this, this.disposables); + this._register(onDidChangeConfiguration(this.onDidChangeConfiguration, this)); this.onDidChangeConfiguration(); const onDidChangeDiffWidthConfiguration = Event.filter(configurationService.onDidChangeConfiguration, e => e.affectsConfiguration('scm.diffDecorationsGutterWidth')); @@ -1284,7 +1278,7 @@ export class DirtyDiffWorkbenchController implements ext.IWorkbenchContribution, dispose(): void { this.disable(); - this.disposables = dispose(this.disposables); + super.dispose(); } } diff --git a/src/vs/workbench/contrib/scm/browser/scmActivity.ts b/src/vs/workbench/contrib/scm/browser/scmActivity.ts index 2bbb403db14..3c64a29beda 100644 --- a/src/vs/workbench/contrib/scm/browser/scmActivity.ts +++ b/src/vs/workbench/contrib/scm/browser/scmActivity.ts @@ -5,7 +5,7 @@ import { localize } from 'vs/nls'; import { basename } from 'vs/base/common/resources'; -import { IDisposable, dispose, Disposable, combinedDisposable } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose, Disposable, DisposableStore, combinedDisposable } from 'vs/base/common/lifecycle'; import { Event } from 'vs/base/common/event'; import { VIEWLET_ID, ISCMService, ISCMRepository } from 'vs/workbench/contrib/scm/common/scm'; import { IActivityService, NumberBadge } from 'vs/workbench/services/activity/common/activity'; @@ -46,7 +46,7 @@ export class StatusUpdater implements IWorkbenchContribution { this.render(); }); - const disposable = combinedDisposable([changeDisposable, removeDisposable]); + const disposable = combinedDisposable(changeDisposable, removeDisposable); this.disposables.push(disposable); } @@ -151,7 +151,7 @@ export class StatusBarController implements IWorkbenchContribution { } }); - const disposable = combinedDisposable([changeDisposable, removeDisposable]); + const disposable = combinedDisposable(changeDisposable, removeDisposable); this.disposables.push(disposable); if (!this.focusedRepository) { @@ -187,14 +187,17 @@ export class StatusBarController implements IWorkbenchContribution { ? `${basename(repository.provider.rootUri)} (${repository.provider.label})` : repository.provider.label; - const disposables = commands.map(c => this.statusbarService.addEntry({ - text: c.title, - tooltip: `${label} - ${c.tooltip}`, - command: c.id, - arguments: c.arguments - }, MainThreadStatusBarAlignment.LEFT, 10000)); + const disposables = new DisposableStore(); + for (const c of commands) { + disposables.push(this.statusbarService.addEntry({ + text: c.title, + tooltip: `${label} - ${c.tooltip}`, + command: c.id, + arguments: c.arguments + }, MainThreadStatusBarAlignment.LEFT, 10000)); + } - this.statusBarDisposable = combinedDisposable(disposables); + this.statusBarDisposable = disposables; } dispose(): void { diff --git a/src/vs/workbench/contrib/scm/browser/scmViewlet.ts b/src/vs/workbench/contrib/scm/browser/scmViewlet.ts index 1efc06338f6..b7a5b0887f8 100644 --- a/src/vs/workbench/contrib/scm/browser/scmViewlet.ts +++ b/src/vs/workbench/contrib/scm/browser/scmViewlet.ts @@ -8,7 +8,7 @@ import { localize } from 'vs/nls'; import { Event, Emitter } from 'vs/base/common/event'; import { domEvent } from 'vs/base/browser/event'; import { basename } from 'vs/base/common/resources'; -import { IDisposable, dispose, combinedDisposable, Disposable } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose, Disposable, DisposableStore, combinedDisposable } from 'vs/base/common/lifecycle'; import { ViewletPanel, IViewletPanelOptions } from 'vs/workbench/browser/parts/views/panelViewlet'; import { append, $, addClass, toggleClass, trackFocus, removeClass, addClasses } from 'vs/base/browser/dom'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; @@ -162,14 +162,14 @@ class ProviderRenderer implements IListRenderer new StatusBarActionViewItem(a as StatusBarAction) }); const disposable = Disposable.None; - const templateDisposable = combinedDisposable([actionBar, badgeStyler]); + const templateDisposable = combinedDisposable(actionBar, badgeStyler); return { title, type, countContainer, count, actionBar, disposable, templateDisposable }; } renderElement(repository: ISCMRepository, index: number, templateData: RepositoryTemplateData): void { templateData.disposable.dispose(); - const disposables: IDisposable[] = []; + const disposables = new DisposableStore(); if (repository.provider.rootUri) { templateData.title.textContent = basename(repository.provider.rootUri); @@ -198,10 +198,10 @@ class ProviderRenderer implements IListRenderer template.count.setCount(group.elements.length); - group.onDidSplice(updateCount, null, disposables); + disposables.push(group.onDidSplice(updateCount, null)); updateCount(); - template.elementDisposable = combinedDisposable(disposables); + template.elementDisposable = disposables; } disposeElement(group: ISCMResourceGroup, index: number, template: ResourceGroupTemplate): void { @@ -489,7 +489,7 @@ class ResourceRenderer implements IListRenderer template.fileLabel.setFile(resource.sourceUri, { fileDecorations: { colors: false, badges: !icon, data: resource.decorations } }); template.actionBar.context = resource; - const disposables: IDisposable[] = []; + const disposables = new DisposableStore(); disposables.push(connectPrimaryMenuToInlineActionBar(this.menus.getResourceMenu(resource.resourceGroup), template.actionBar)); toggleClass(template.name, 'strike-through', resource.decorations.strikeThrough); @@ -505,7 +505,7 @@ class ResourceRenderer implements IListRenderer } template.element.setAttribute('data-tooltip', resource.decorations.tooltip || ''); - template.elementDisposable = combinedDisposable(disposables); + template.elementDisposable = disposables; } disposeElement(resource: ISCMResource, index: number, template: ResourceTemplate): void { @@ -602,10 +602,10 @@ class ResourceGroupSplicer { absoluteToInsert.push(element); } - const disposable = combinedDisposable([ + const disposable = combinedDisposable( group.onDidChange(() => this.onDidChangeGroup(group)), group.onDidSplice(splice => this.onDidSpliceGroup(group, splice)) - ]); + ); itemsToInsert.push({ group, visible, disposable }); } diff --git a/src/vs/workbench/contrib/snippets/browser/snippetsService.ts b/src/vs/workbench/contrib/snippets/browser/snippetsService.ts index b659d7a0b75..73c9839bd60 100644 --- a/src/vs/workbench/contrib/snippets/browser/snippetsService.ts +++ b/src/vs/workbench/contrib/snippets/browser/snippetsService.ts @@ -5,7 +5,7 @@ import { join } from 'vs/base/common/path'; import { IJSONSchema } from 'vs/base/common/jsonSchema'; -import { combinedDisposable, dispose, IDisposable } from 'vs/base/common/lifecycle'; +import { dispose, IDisposable, DisposableStore, combinedDisposable } from 'vs/base/common/lifecycle'; import { values } from 'vs/base/common/map'; import * as resources from 'vs/base/common/resources'; import { endsWith, isFalsyOrWhitespace } from 'vs/base/common/strings'; @@ -114,7 +114,7 @@ namespace snippetExt { } function watch(service: IFileService, resource: URI, callback: (type: FileChangeType, resource: URI) => any): IDisposable { - return combinedDisposable([ + return combinedDisposable( service.watch(resource), service.onFileChanges(e => { for (const change of e.changes) { @@ -123,7 +123,7 @@ function watch(service: IFileService, resource: URI, callback: (type: FileChange } } }) - ]); + ); } class SnippetsService implements ISnippetsService { @@ -295,9 +295,10 @@ class SnippetsService implements ISnippetsService { } private _initFolderSnippets(source: SnippetSource, folder: URI, bucket: IDisposable[]): Promise { - let disposables: IDisposable[] = []; + let disposables = new DisposableStore(); let addFolderSnippets = (type?: FileChangeType) => { - disposables = dispose(disposables); + disposables.dispose(); + disposables = new DisposableStore(); if (type === FileChangeType.DELETED) { return Promise.resolve(); } @@ -311,7 +312,7 @@ class SnippetsService implements ISnippetsService { }; bucket.push(watch(this._fileService, folder, addFolderSnippets)); - bucket.push(combinedDisposable(disposables)); + bucket.push(disposables); return addFolderSnippets(); } diff --git a/src/vs/workbench/contrib/update/electron-browser/update.ts b/src/vs/workbench/contrib/update/electron-browser/update.ts index 785e702c130..cea347aca03 100644 --- a/src/vs/workbench/contrib/update/electron-browser/update.ts +++ b/src/vs/workbench/contrib/update/electron-browser/update.ts @@ -6,7 +6,7 @@ import * as nls from 'vs/nls'; import severity from 'vs/base/common/severity'; import { IAction, Action } from 'vs/base/common/actions'; -import { IDisposable, dispose, Disposable } from 'vs/base/common/lifecycle'; +import { IDisposable, Disposable } from 'vs/base/common/lifecycle'; import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import pkg from 'vs/platform/product/node/package'; import product from 'vs/platform/product/node/product'; @@ -270,7 +270,7 @@ class CommandAction extends Action { } } -export class UpdateContribution implements IGlobalActivity { +export class UpdateContribution extends Disposable implements IGlobalActivity { private static readonly showCommandsId = 'workbench.action.showCommands'; private static readonly openSettingsId = 'workbench.action.openSettings'; @@ -286,7 +286,6 @@ export class UpdateContribution implements IGlobalActivity { private state: UpdateState; private badgeDisposable: IDisposable = Disposable.None; - private disposables: IDisposable[] = []; constructor( @IStorageService private readonly storageService: IStorageService, @@ -298,9 +297,10 @@ export class UpdateContribution implements IGlobalActivity { @IActivityService private readonly activityService: IActivityService, @IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService ) { + super(); this.state = updateService.state; - updateService.onStateChange(this.onUpdateStateChange, this, this.disposables); + this._register(updateService.onStateChange(this.onUpdateStateChange, this)); this.onUpdateStateChange(this.updateService.state); /* @@ -575,8 +575,4 @@ export class UpdateContribution implements IGlobalActivity { this.updateService.quitAndInstall()); } } - - dispose(): void { - this.disposables = dispose(this.disposables); - } } diff --git a/src/vs/workbench/contrib/watermark/browser/watermark.ts b/src/vs/workbench/contrib/watermark/browser/watermark.ts index b63e923abc6..7788f6e36a0 100644 --- a/src/vs/workbench/contrib/watermark/browser/watermark.ts +++ b/src/vs/workbench/contrib/watermark/browser/watermark.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import 'vs/css!./watermark'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { Disposable } from 'vs/base/common/lifecycle'; import { assign } from 'vs/base/common/objects'; import { isMacintosh, OS } from 'vs/base/common/platform'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; @@ -102,9 +102,8 @@ const folderEntries = [ const WORKBENCH_TIPS_ENABLED_KEY = 'workbench.tips.enabled'; -export class WatermarkContribution implements IWorkbenchContribution { +export class WatermarkContribution extends Disposable implements IWorkbenchContribution { - private toDispose: IDisposable[] = []; private watermark: HTMLElement; private enabled: boolean; private workbenchState: WorkbenchState; @@ -117,6 +116,7 @@ export class WatermarkContribution implements IWorkbenchContribution { @IConfigurationService private readonly configurationService: IConfigurationService, @IEditorGroupsService private readonly editorGroupsService: IEditorGroupsService ) { + super(); this.workbenchState = contextService.getWorkbenchState(); lifecycleService.onShutdown(this.dispose, this); @@ -124,7 +124,7 @@ export class WatermarkContribution implements IWorkbenchContribution { if (this.enabled) { this.create(); } - this.toDispose.push(this.configurationService.onDidChangeConfiguration(e => { + this._register(this.configurationService.onDidChangeConfiguration(e => { if (e.affectsConfiguration(WORKBENCH_TIPS_ENABLED_KEY)) { const enabled = this.configurationService.getValue(WORKBENCH_TIPS_ENABLED_KEY); if (enabled !== this.enabled) { @@ -137,7 +137,7 @@ export class WatermarkContribution implements IWorkbenchContribution { } } })); - this.toDispose.push(this.contextService.onDidChangeWorkbenchState(e => { + this._register(this.contextService.onDidChangeWorkbenchState(e => { const previousWorkbenchState = this.workbenchState; this.workbenchState = this.contextService.getWorkbenchState(); @@ -171,8 +171,8 @@ export class WatermarkContribution implements IWorkbenchContribution { }; update(); dom.prepend(container.firstElementChild as HTMLElement, this.watermark); - this.toDispose.push(this.keybindingService.onDidUpdateKeybindings(update)); - this.toDispose.push(this.editorGroupsService.onDidLayout(dimension => this.handleEditorPartSize(container, dimension))); + this._register(this.keybindingService.onDidUpdateKeybindings(update)); + this._register(this.editorGroupsService.onDidLayout(dimension => this.handleEditorPartSize(container, dimension))); this.handleEditorPartSize(container, this.editorGroupsService.dimension); } @@ -197,10 +197,6 @@ export class WatermarkContribution implements IWorkbenchContribution { this.destroy(); this.create(); } - - public dispose(): void { - this.toDispose = dispose(this.toDispose); - } } Registry.as(WorkbenchExtensions.Workbench) diff --git a/src/vs/workbench/contrib/webview/browser/webviewEditor.ts b/src/vs/workbench/contrib/webview/browser/webviewEditor.ts index 079afa85d16..f8384d60d4e 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewEditor.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewEditor.ts @@ -6,7 +6,7 @@ import * as DOM from 'vs/base/browser/dom'; import { CancellationToken } from 'vs/base/common/cancellation'; import { Emitter, Event } from 'vs/base/common/event'; -import { dispose, IDisposable } from 'vs/base/common/lifecycle'; +import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IStorageService } from 'vs/platform/storage/common/storage'; @@ -33,7 +33,7 @@ export class WebviewEditor extends BaseEditor { private _content?: HTMLElement; private _webviewContent: HTMLElement | undefined; - private _webviewFocusTrackerDisposables: IDisposable[] = []; + private _webviewFocusTrackerDisposables = new DisposableStore(); private _onFocusWindowHandler?: IDisposable; private readonly _onDidFocusWebview = this._register(new Emitter()); @@ -89,7 +89,7 @@ export class WebviewEditor extends BaseEditor { this._content = undefined; } - this._webviewFocusTrackerDisposables = dispose(this._webviewFocusTrackerDisposables); + this._webviewFocusTrackerDisposables.dispose(); if (this._onFocusWindowHandler) { this._onFocusWindowHandler.dispose(); @@ -304,7 +304,8 @@ export class WebviewEditor extends BaseEditor { } private trackFocus() { - this._webviewFocusTrackerDisposables = dispose(this._webviewFocusTrackerDisposables); + this._webviewFocusTrackerDisposables.dispose(); + this._webviewFocusTrackerDisposables = new DisposableStore(); // Track focus in webview content const webviewContentFocusTracker = DOM.trackFocus(this._webviewContent!); diff --git a/src/vs/workbench/contrib/welcome/overlay/browser/welcomeOverlay.ts b/src/vs/workbench/contrib/welcome/overlay/browser/welcomeOverlay.ts index 84b1219c443..036cedba11f 100644 --- a/src/vs/workbench/contrib/welcome/overlay/browser/welcomeOverlay.ts +++ b/src/vs/workbench/contrib/welcome/overlay/browser/welcomeOverlay.ts @@ -15,7 +15,7 @@ import { Action } from 'vs/base/common/actions'; import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions'; import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; import { ICommandService } from 'vs/platform/commands/common/commands'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { Disposable } from 'vs/base/common/lifecycle'; import { RawContextKey, IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { KeyCode } from 'vs/base/common/keyCodes'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -150,9 +150,8 @@ export class HideWelcomeOverlayAction extends Action { } } -class WelcomeOverlay { +class WelcomeOverlay extends Disposable { - private _toDispose: IDisposable[] = []; private _overlayVisible: IContextKey; private _overlay: HTMLElement; @@ -163,6 +162,7 @@ class WelcomeOverlay { @IContextKeyService private readonly _contextKeyService: IContextKeyService, @IKeybindingService private readonly keybindingService: IKeybindingService ) { + super(); this._overlayVisible = OVERLAY_VISIBLE.bindTo(this._contextKeyService); this.create(); } @@ -177,7 +177,7 @@ class WelcomeOverlay { this._overlay.style.display = 'none'; this._overlay.tabIndex = -1; - this._toDispose.push(dom.addStandardDisposableListener(this._overlay, 'click', () => this.hide())); + this._register(dom.addStandardDisposableListener(this._overlay, 'click', () => this.hide())); this.commandService.onWillExecuteCommand(() => this.hide()); dom.append(this._overlay, $('.commandPalettePlaceholder')); @@ -237,10 +237,6 @@ class WelcomeOverlay { this._overlayVisible.reset(); } } - - dispose() { - this._toDispose = dispose(this._toDispose); - } } Registry.as(Extensions.WorkbenchActions) diff --git a/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts b/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts index b26ccbb854f..57ec2510560 100644 --- a/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts +++ b/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts @@ -25,7 +25,7 @@ import { getInstalledExtensions, IExtensionStatus, onExtensionChanged, isKeymapE import { IExtensionEnablementService, IExtensionManagementService, IExtensionGalleryService, IExtensionTipsService, EnablementState, ILocalExtension } from 'vs/platform/extensionManagement/common/extensionManagement'; import { used } from 'vs/workbench/contrib/welcome/page/browser/vs_code_welcome_page'; import { ILifecycleService, StartupKind } from 'vs/platform/lifecycle/common/lifecycle'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { Disposable } from 'vs/base/common/lifecycle'; import { splitName } from 'vs/base/common/labels'; import { registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { registerColor, focusBorder, textLinkForeground, textLinkActiveForeground, foreground, descriptionForeground, contrastBorder, activeContrastBorder } from 'vs/platform/theme/common/colorRegistry'; @@ -245,9 +245,7 @@ const keymapStrings: Strings = { const welcomeInputTypeId = 'workbench.editors.welcomePageInput'; -class WelcomePage { - - private disposables: IDisposable[] = []; +class WelcomePage extends Disposable { readonly editorInput: WalkThroughInput; @@ -267,7 +265,8 @@ class WelcomePage { @ILifecycleService lifecycleService: ILifecycleService, @ITelemetryService private readonly telemetryService: ITelemetryService ) { - this.disposables.push(lifecycleService.onShutdown(() => this.dispose())); + super(); + this._register(lifecycleService.onShutdown(() => this.dispose())); const recentlyOpened = this.windowService.getRecentlyOpened(); const installedExtensions = this.instantiationService.invokeFunction(getInstalledExtensions); @@ -321,14 +320,14 @@ class WelcomePage { ul.append(...listEntries, moreRecent); }; updateEntries(); - this.disposables.push(this.labelService.onDidChangeFormatters(updateEntries)); + this._register(this.labelService.onDidChangeFormatters(updateEntries)); }).then(undefined, onUnexpectedError); this.addExtensionList(container, '.extensionPackList', extensionPacks, extensionPackStrings); this.addExtensionList(container, '.keymapList', keymapExtensions, keymapStrings); this.updateInstalledExtensions(container, installedExtensions); - this.disposables.push(this.instantiationService.invokeFunction(onExtensionChanged)(ids => { + this._register(this.instantiationService.invokeFunction(onExtensionChanged)(ids => { for (const id of ids) { if (container.querySelector(`.installExtension[data-extension="${id.id}"], .enabledExtension[data-extension="${id.id}"]`)) { const installedExtensions = this.instantiationService.invokeFunction(getInstalledExtensions); @@ -593,10 +592,6 @@ class WelcomePage { }); }).then(undefined, onUnexpectedError); } - - dispose(): void { - this.disposables = dispose(this.disposables); - } } export class WelcomeInputFactory implements IEditorInputFactory { diff --git a/src/vs/workbench/contrib/welcome/walkThrough/browser/walkThroughPart.ts b/src/vs/workbench/contrib/welcome/walkThrough/browser/walkThroughPart.ts index a51b73abb56..0c84c54382e 100644 --- a/src/vs/workbench/contrib/welcome/walkThrough/browser/walkThroughPart.ts +++ b/src/vs/workbench/contrib/welcome/walkThrough/browser/walkThroughPart.ts @@ -8,7 +8,7 @@ import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableEle import { ScrollbarVisibility } from 'vs/base/common/scrollable'; import * as strings from 'vs/base/common/strings'; import { URI } from 'vs/base/common/uri'; -import { IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose, toDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { EditorOptions, IEditorMemento } from 'vs/workbench/common/editor'; import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; @@ -56,7 +56,7 @@ export class WalkThroughPart extends BaseEditor { static readonly ID: string = 'workbench.editor.walkThroughPart'; - private disposables: IDisposable[] = []; + private readonly disposables = new DisposableStore(); private contentDisposables: IDisposable[] = []; private content: HTMLDivElement; private scrollbar: DomScrollableElement; @@ -514,7 +514,7 @@ export class WalkThroughPart extends BaseEditor { dispose(): void { this.editorFocus.reset(); this.contentDisposables = dispose(this.contentDisposables); - this.disposables = dispose(this.disposables); + this.disposables.dispose(); super.dispose(); } } diff --git a/src/vs/workbench/contrib/welcome/walkThrough/common/walkThroughInput.ts b/src/vs/workbench/contrib/welcome/walkThrough/common/walkThroughInput.ts index 42feb610289..6d69a2758f1 100644 --- a/src/vs/workbench/contrib/welcome/walkThrough/common/walkThroughInput.ts +++ b/src/vs/workbench/contrib/welcome/walkThrough/common/walkThroughInput.ts @@ -6,7 +6,7 @@ import * as strings from 'vs/base/common/strings'; import { EditorInput, EditorModel, ITextEditorModel } from 'vs/workbench/common/editor'; import { URI } from 'vs/base/common/uri'; -import { IReference, IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { IReference } from 'vs/base/common/lifecycle'; import { ITextModelService } from 'vs/editor/common/services/resolverService'; import * as marked from 'vs/base/common/marked/marked'; import { Schemas } from 'vs/base/common/network'; @@ -46,8 +46,6 @@ export interface WalkThroughInputOptions { export class WalkThroughInput extends EditorInput { - private disposables: IDisposable[] = []; - private promise: Promise | null = null; private maxTopScroll = 0; @@ -139,8 +137,6 @@ export class WalkThroughInput extends EditorInput { } dispose(): void { - this.disposables = dispose(this.disposables); - if (this.promise) { this.promise.then(model => model.dispose()); this.promise = null; diff --git a/src/vs/workbench/services/decorations/browser/decorationsService.ts b/src/vs/workbench/services/decorations/browser/decorationsService.ts index 28e5a9f5fe7..b183a2629d8 100644 --- a/src/vs/workbench/services/decorations/browser/decorationsService.ts +++ b/src/vs/workbench/services/decorations/browser/decorationsService.ts @@ -7,7 +7,7 @@ import { URI } from 'vs/base/common/uri'; import { Event, Emitter } from 'vs/base/common/event'; import { IDecorationsService, IDecoration, IResourceDecorationChangeEvent, IDecorationsProvider, IDecorationData } from './decorations'; import { TernarySearchTree } from 'vs/base/common/map'; -import { IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle'; +import { Disposable, IDisposable, toDisposable, dispose } from 'vs/base/common/lifecycle'; import { isThenable } from 'vs/base/common/async'; import { LinkedList } from 'vs/base/common/linkedList'; import { createStyleSheet, createCSSRule, removeCSSRulesContainingSelector } from 'vs/base/browser/dom'; @@ -95,20 +95,20 @@ class DecorationRule { } } -class DecorationStyles { +class DecorationStyles extends Disposable { - private readonly _disposables: IDisposable[]; private readonly _styleElement = createStyleSheet(); private readonly _decorationRules = new Map(); constructor( private _themeService: IThemeService, ) { - this._disposables = [this._themeService.onThemeChange(this._onThemeChange, this)]; + super(); + this._register(this._themeService.onThemeChange(this._onThemeChange, this)); } dispose(): void { - dispose(this._disposables); + super.dispose(); const parent = this._styleElement.parentElement; if (parent) { diff --git a/src/vs/workbench/services/extensions/common/inactiveExtensionUrlHandler.ts b/src/vs/workbench/services/extensions/common/inactiveExtensionUrlHandler.ts index 263a45a9821..351bbe5ddc9 100644 --- a/src/vs/workbench/services/extensions/common/inactiveExtensionUrlHandler.ts +++ b/src/vs/workbench/services/extensions/common/inactiveExtensionUrlHandler.ts @@ -5,7 +5,7 @@ import { localize } from 'vs/nls'; import { Action } from 'vs/base/common/actions'; -import { IDisposable, combinedDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { IDisposable, toDisposable, combinedDisposable } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { EnablementState, IExtensionEnablementService, IExtensionGalleryService, IExtensionIdentifier, IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement'; @@ -70,10 +70,10 @@ export class ExtensionUrlHandler implements IExtensionUrlHandler, IURLHandler { this.handleURL(URI.revive(JSON.parse(urlToHandleValue)), true); } - this.disposable = combinedDisposable([ + this.disposable = combinedDisposable( urlService.registerHandler(this), toDisposable(() => clearInterval(interval)) - ]); + ); } async handleURL(uri: URI, confirmed?: boolean): Promise { diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts index 1707b523b1a..751ab693396 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts @@ -11,7 +11,7 @@ import { getPathFromAmdModule } from 'vs/base/common/amd'; import { timeout } from 'vs/base/common/async'; import { toErrorMessage } from 'vs/base/common/errorMessage'; import { Emitter, Event } from 'vs/base/common/event'; -import { IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle'; +import { toDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import * as objects from 'vs/base/common/objects'; import * as platform from 'vs/base/common/platform'; import pkg from 'vs/platform/product/node/package'; @@ -45,7 +45,7 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter { private readonly _onCrashed: Emitter<[number, string]> = new Emitter<[number, string]>(); public readonly onCrashed: Event<[number, string]> = this._onCrashed.event; - private readonly _toDispose: IDisposable[]; + private readonly _toDispose = new DisposableStore(); private readonly _isExtensionDevHost: boolean; private readonly _isExtensionDevDebug: boolean; @@ -92,7 +92,6 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter { this._extensionHostConnection = null; this._messageProtocol = null; - this._toDispose = []; this._toDispose.push(this._onCrashed); this._toDispose.push(this._lifecycleService.onWillShutdown(e => this._onWillShutdown(e))); this._toDispose.push(this._lifecycleService.onShutdown(reason => this.terminate())); @@ -489,7 +488,7 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter { } this._terminating = true; - dispose(this._toDispose); + this._toDispose.dispose(); if (!this._messageProtocol) { // .start() was not called diff --git a/src/vs/workbench/services/files/common/fileService.ts b/src/vs/workbench/services/files/common/fileService.ts index 7e06caa3de1..cf5291ec6e9 100644 --- a/src/vs/workbench/services/files/common/fileService.ts +++ b/src/vs/workbench/services/files/common/fileService.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Disposable, IDisposable, toDisposable, combinedDisposable, dispose } from 'vs/base/common/lifecycle'; +import { Disposable, IDisposable, toDisposable, dispose } from 'vs/base/common/lifecycle'; import { IFileService, IResolveFileOptions, FileChangesEvent, FileOperationEvent, IFileSystemProviderRegistrationEvent, IFileSystemProvider, IFileStat, IResolveFileResult, ICreateFileOptions, IFileSystemProviderActivationEvent, FileOperationError, FileOperationResult, FileOperation, FileSystemProviderCapabilities, FileType, toFileSystemProviderErrorCode, FileSystemProviderErrorCode, IStat, IFileStatWithMetadata, IResolveMetadataFileOptions, etag, hasReadWriteCapability, hasFileFolderCopyCapability, hasOpenReadWriteCloseCapability, toFileOperationResult, IFileSystemProviderWithOpenReadWriteCloseCapability, IFileSystemProviderWithFileReadWriteCapability, IResolveFileResultWithMetadata, IWatchOptions, IWriteFileOptions, IReadFileOptions, IFileStreamContent, IFileContent, ETAG_DISABLED } from 'vs/platform/files/common/files'; import { URI } from 'vs/base/common/uri'; import { Event, Emitter } from 'vs/base/common/event'; @@ -55,14 +55,12 @@ export class FileService extends Disposable implements IFileService { providerDisposables.push(provider.onDidErrorOccur(error => this._onError.fire(error))); } - return combinedDisposable([ - toDisposable(() => { - this._onDidChangeFileSystemProviderRegistrations.fire({ added: false, scheme, provider }); - this.provider.delete(scheme); + return toDisposable(() => { + this._onDidChangeFileSystemProviderRegistrations.fire({ added: false, scheme, provider }); + this.provider.delete(scheme); - dispose(providerDisposables); - }) - ]); + dispose(providerDisposables); + }); } async activateProvider(scheme: string): Promise { diff --git a/src/vs/workbench/services/files/test/node/diskFileService.test.ts b/src/vs/workbench/services/files/test/node/diskFileService.test.ts index 8068df82ed6..e62697f3a8b 100644 --- a/src/vs/workbench/services/files/test/node/diskFileService.test.ts +++ b/src/vs/workbench/services/files/test/node/diskFileService.test.ts @@ -18,7 +18,7 @@ import { existsSync, statSync, readdirSync, readFileSync, writeFileSync, renameS import { FileOperation, FileOperationEvent, IFileStat, FileOperationResult, FileSystemProviderCapabilities, FileChangeType, IFileChange, FileChangesEvent, FileOperationError, etag, IStat } from 'vs/platform/files/common/files'; import { NullLogService } from 'vs/platform/log/common/log'; import { isLinux, isWindows } from 'vs/base/common/platform'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { DisposableStore } from 'vs/base/common/lifecycle'; import { isEqual } from 'vs/base/common/resources'; import { VSBuffer, VSBufferReadable } from 'vs/base/common/buffer'; @@ -125,7 +125,7 @@ suite('Disk File Service', () => { let testProvider: TestDiskFileSystemProvider; let testDir: string; - let disposables: IDisposable[] = []; + let disposables = new DisposableStore(); setup(async () => { const logService = new NullLogService(); @@ -149,7 +149,8 @@ suite('Disk File Service', () => { }); teardown(async () => { - disposables = dispose(disposables); + disposables.dispose(); + disposables = new DisposableStore(); await rimraf(parentDir, RimRafMode.MOVE); }); diff --git a/src/vs/workbench/services/notification/common/notificationService.ts b/src/vs/workbench/services/notification/common/notificationService.ts index 0861420e86f..e5e95771b4c 100644 --- a/src/vs/workbench/services/notification/common/notificationService.ts +++ b/src/vs/workbench/services/notification/common/notificationService.ts @@ -5,7 +5,7 @@ import { INotificationService, INotification, INotificationHandle, Severity, NotificationMessage, INotificationActions, IPromptChoice, IPromptOptions } from 'vs/platform/notification/common/notification'; import { INotificationsModel, NotificationsModel, ChoiceAction } from 'vs/workbench/common/notifications'; -import { dispose, Disposable, IDisposable } from 'vs/base/common/lifecycle'; +import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; import { Event } from 'vs/base/common/event'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; @@ -54,7 +54,7 @@ export class NotificationService extends Disposable implements INotificationServ } prompt(severity: Severity, message: string, choices: IPromptChoice[], options?: IPromptOptions): INotificationHandle { - const toDispose: IDisposable[] = []; + const toDispose = new DisposableStore(); let choiceClicked = false; let handle: INotificationHandle; @@ -94,7 +94,7 @@ export class NotificationService extends Disposable implements INotificationServ Event.once(handle.onDidClose)(() => { // Cleanup when notification gets disposed - dispose(toDispose); + toDispose.dispose(); // Indicate cancellation to the outside if no action was executed if (options && typeof options.onCancel === 'function' && !choiceClicked) { diff --git a/src/vs/workbench/services/output/common/outputChannelModel.ts b/src/vs/workbench/services/output/common/outputChannelModel.ts index 007ead80d15..6be8813a35c 100644 --- a/src/vs/workbench/services/output/common/outputChannelModel.ts +++ b/src/vs/workbench/services/output/common/outputChannelModel.ts @@ -96,12 +96,11 @@ export abstract class AbstractFileOutputChannelModel extends Disposable implemen } else { this.model = this.modelService.createModel(content, this.modeService.create(this.mimeType), this.modelUri); this.onModelCreated(this.model); - const disposables: IDisposable[] = []; - disposables.push(this.model.onWillDispose(() => { + const disposable = this.model.onWillDispose(() => { this.onModelWillDispose(this.model); this.model = null; - dispose(disposables); - })); + dispose(disposable); + }); } return this.model; } @@ -340,11 +339,10 @@ export class BufferredOutputChannel extends Disposable implements IOutputChannel private createModel(content: string): ITextModel { const model = this.modelService.createModel(content, this.modeService.create(this.mimeType), this.modelUri); - const disposables: IDisposable[] = []; - disposables.push(model.onWillDispose(() => { + const disposable = model.onWillDispose(() => { this.model = null; - dispose(disposables); - })); + dispose(disposable); + }); return model; } diff --git a/src/vs/workbench/services/progress/browser/progressService2.ts b/src/vs/workbench/services/progress/browser/progressService2.ts index d2e4eee1263..81f8137ebb7 100644 --- a/src/vs/workbench/services/progress/browser/progressService2.ts +++ b/src/vs/workbench/services/progress/browser/progressService2.ts @@ -6,7 +6,7 @@ import 'vs/css!./media/progressService2'; import { localize } from 'vs/nls'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose, DisposableStore } from 'vs/base/common/lifecycle'; import { IProgressService2, IProgressOptions, IProgressStep, ProgressLocation, IProgress, emptyProgress, Progress, IProgressNotificationOptions } from 'vs/platform/progress/common/progress'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { StatusbarAlignment, IStatusbarService } from 'vs/platform/statusbar/common/statusbar'; @@ -139,7 +139,7 @@ export class ProgressService2 implements IProgressService2 { } private _withNotificationProgress

, R = unknown>(options: IProgressNotificationOptions, callback: (progress: IProgress<{ message?: string, increment?: number }>) => P, onDidCancel?: () => void): P { - const toDispose: IDisposable[] = []; + const toDispose = new DisposableStore(); const createNotification = (message: string | undefined, increment?: number): INotificationHandle | undefined => { if (!message) { @@ -176,7 +176,7 @@ export class ProgressService2 implements IProgressService2 { updateProgress(handle, increment); Event.once(handle.onDidClose)(() => { - dispose(toDispose); + toDispose.dispose(); }); return handle; @@ -279,7 +279,7 @@ export class ProgressService2 implements IProgressService2 { } private _withDialogProgress

, R = unknown>(options: IProgressOptions, task: (progress: IProgress<{ message?: string, increment?: number }>) => P, onDidCancel?: () => void): P { - const disposables: IDisposable[] = []; + const disposables = new DisposableStore(); const allowableCommands = [ 'workbench.action.quit', 'workbench.action.reloadWindow'