diff --git a/src/vs/base/browser/ui/actionbar/actionbar.ts b/src/vs/base/browser/ui/actionbar/actionbar.ts index 8c9d5b6315c..49642edad5f 100644 --- a/src/vs/base/browser/ui/actionbar/actionbar.ts +++ b/src/vs/base/browser/ui/actionbar/actionbar.ts @@ -33,7 +33,7 @@ export interface IActionItem extends IEventEmitter { export class BaseActionItem extends EventEmitter implements IActionItem { public builder: Builder; - public _callOnDispose: Function[]; + public _callOnDispose: lifecycle.IDisposable[]; public _context: any; public _action: IAction; @@ -48,7 +48,7 @@ export class BaseActionItem extends EventEmitter implements IActionItem { this._action = action; if (action instanceof Action) { - let l = (action).addBulkListener((events: IEmitterEvent[]) => { + let l = (action).addBulkListener2((events: IEmitterEvent[]) => { if (!this.builder) { // we have not been rendered yet, so there @@ -187,7 +187,7 @@ export class BaseActionItem extends EventEmitter implements IActionItem { this.gesture = null; } - lifecycle.cAll(this._callOnDispose); + this._callOnDispose = lifecycle.dispose(this._callOnDispose); } } @@ -333,13 +333,13 @@ export class ProgressItem extends BaseActionItem { error.textContent = '!'; $(error).addClass('tag', 'error'); - this.callOnDispose.push(this.addListener(CommonEventType.BEFORE_RUN, () => { + this.callOnDispose.push(this.addListener2(CommonEventType.BEFORE_RUN, () => { $(progress).addClass('active'); $(done).removeClass('active'); $(error).removeClass('active'); })); - this.callOnDispose.push(this.addListener(CommonEventType.RUN, (result) => { + this.callOnDispose.push(this.addListener2(CommonEventType.RUN, (result) => { $(progress).removeClass('active'); if (result.error) { $(done).removeClass('active'); @@ -358,7 +358,6 @@ export class ProgressItem extends BaseActionItem { } public dispose(): void { - lifecycle.cAll(this.callOnDispose); super.dispose(); } } diff --git a/src/vs/base/common/actions.ts b/src/vs/base/common/actions.ts index 58f9b721b0f..840d99fec32 100644 --- a/src/vs/base/common/actions.ts +++ b/src/vs/base/common/actions.ts @@ -5,7 +5,7 @@ 'use strict'; import {TPromise} from 'vs/base/common/winjs.base'; -import { IEventEmitter, EventEmitter, ListenerCallback, IBulkListenerCallback, ListenerUnbind } from 'vs/base/common/eventEmitter'; +import { IEventEmitter, EventEmitter } from 'vs/base/common/eventEmitter'; import {IDisposable} from 'vs/base/common/lifecycle'; import * as Events from 'vs/base/common/events'; @@ -199,74 +199,6 @@ export class Action extends EventEmitter implements IAction { } } -class ProxyAction extends Action implements IEventEmitter { - - constructor(private delegate: Action, private runHandler: (e: any) => void) { - super(delegate.id, delegate.label, delegate.class, delegate.enabled, null); - } - - public get id(): string { - return this.delegate.id; - } - - public get label(): string { - return this.delegate.label; - } - - public set label(value: string) { - this.delegate.label = value; - } - - public get class(): string { - return this.delegate.class; - } - - public set class(value: string) { - this.delegate.class = value; - } - - public get enabled(): boolean { - return this.delegate.enabled; - } - - public set enabled(value: boolean) { - this.delegate.enabled = value; - } - - public get checked(): boolean { - return this.delegate.checked; - } - - public set checked(value: boolean) { - this.delegate.checked = value; - } - - public run(event?: any): TPromise { - this.runHandler(event); - return this.delegate.run(event); - } - - public addListener(eventType: string, listener: ListenerCallback): ListenerUnbind { - return this.delegate.addListener(eventType, listener); - } - - public addBulkListener(listener: IBulkListenerCallback): ListenerUnbind { - return this.delegate.addBulkListener(listener); - } - - public addEmitter(eventEmitter: IEventEmitter, emitterType?: string): ListenerUnbind { - return this.delegate.addEmitter(eventEmitter, emitterType); - } - - public addEmitterTypeListener(eventType: string, emitterType: string, listener: ListenerCallback): ListenerUnbind { - return this.delegate.addEmitterTypeListener(eventType, emitterType, listener); - } - - public emit(eventType: string, data?: any): void { - this.delegate.emit(eventType, data); - } -} - export interface IRunEvent { action: IAction; result?: any; diff --git a/src/vs/base/common/eventEmitter.ts b/src/vs/base/common/eventEmitter.ts index 246af9b88df..424cfae60c1 100644 --- a/src/vs/base/common/eventEmitter.ts +++ b/src/vs/base/common/eventEmitter.ts @@ -50,7 +50,6 @@ export interface ListenerUnbind { } export interface IEventEmitter extends IDisposable { - addListener(eventType:string, listener:ListenerCallback):ListenerUnbind; addListener2(eventType:string, listener:ListenerCallback):IDisposable; addOneTimeListener(eventType:string, listener:ListenerCallback):ListenerUnbind; @@ -60,7 +59,6 @@ export interface IEventEmitter extends IDisposable { addEmitter(eventEmitter:IEventEmitter, emitterType?:string):ListenerUnbind; addEmitter2(eventEmitter:IEventEmitter, emitterType?:string):IDisposable; - addEmitterTypeListener(eventType:string, emitterType:string, listener:ListenerCallback):ListenerUnbind; emit(eventType:string, data?:any):void; } @@ -99,7 +97,7 @@ export class EventEmitter implements IEventEmitter { this._allowedEventTypes = null; } - public addListener(eventType:string, listener:ListenerCallback):ListenerUnbind { + private addListener(eventType:string, listener:ListenerCallback):ListenerUnbind { if (eventType === '*') { throw new Error('Use addBulkListener(listener) to register your listener!'); } @@ -199,18 +197,6 @@ export class EventEmitter implements IEventEmitter { }; } - public addEmitterTypeListener(eventType:string, emitterType:string, listener:ListenerCallback):ListenerUnbind { - if (emitterType) { - if (eventType === '*') { - throw new Error('Bulk listeners cannot specify an emitter type'); - } - - return this.addListener(eventType + '/' + emitterType, listener); - } else { - return this.addListener(eventType, listener); - } - } - private _removeListener(eventType:string, listener:ListenerCallback): void { if (this._listeners.hasOwnProperty(eventType)) { var listeners = this._listeners[eventType]; diff --git a/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts b/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts index 97500cc6efb..9485bff2531 100644 --- a/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts +++ b/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts @@ -80,7 +80,7 @@ export class QuickOpenWidget implements IModelProvider { private visible: boolean; private isLoosingFocus: boolean; private callbacks: IQuickOpenCallbacks; - private toUnbind: { (): void; }[]; + private toUnbind: IDisposable[]; private currentInputToken: string; private quickNavigateConfiguration: IQuickNavigateConfiguration; private container: HTMLElement; @@ -198,11 +198,11 @@ export class QuickOpenWidget implements IModelProvider { this.treeElement = this.tree.getHTMLElement(); // Handle Focus and Selection event - this.toUnbind.push(this.tree.addListener(EventType.FOCUS, (event: IFocusEvent) => { + this.toUnbind.push(this.tree.addListener2(EventType.FOCUS, (event: IFocusEvent) => { this.elementFocused(event.focus, event); })); - this.toUnbind.push(this.tree.addListener(EventType.SELECTION, (event: ISelectionEvent) => { + this.toUnbind.push(this.tree.addListener2(EventType.SELECTION, (event: ISelectionEvent) => { if (event.selection && event.selection.length > 0) { this.elementSelected(event.selection[0], event); } @@ -835,9 +835,7 @@ export class QuickOpenWidget implements IModelProvider { } public dispose(): void { - while (this.toUnbind.length) { - this.toUnbind.pop()(); - } + this.toUnbind = dispose(this.toUnbind); this.progressBar.dispose(); this.inputBox.dispose(); diff --git a/src/vs/base/parts/tree/test/browser/treeModel.test.ts b/src/vs/base/parts/tree/test/browser/treeModel.test.ts index 8a797e1bab8..de245ea490a 100644 --- a/src/vs/base/parts/tree/test/browser/treeModel.test.ts +++ b/src/vs/base/parts/tree/test/browser/treeModel.test.ts @@ -1302,23 +1302,23 @@ suite('TreeModel - Dynamic data model', () => { model.collapse('father'); var times = 0; - var listener = dataModel.addListener('getChildren', (element) => { + var listener = dataModel.addListener2('getChildren', (element) => { times++; assert.equal(element, 'grandfather'); }); model.refresh('grandfather').done(() => { assert.equal(times, 1); - listener(); + listener.dispose(); - listener = dataModel.addListener('getChildren', (element) => { + listener = dataModel.addListener2('getChildren', (element) => { times++; assert.equal(element, 'father'); }); model.expand('father').done(() => { assert.equal(times, 2); - listener(); + listener.dispose(); done(); }); }); @@ -1351,8 +1351,8 @@ suite('TreeModel - Dynamic data model', () => { var getTimes = 0; var gotTimes = 0; - var getListener = dataModel.addListener('getChildren', (element) => { getTimes++; }); - var gotListener = dataModel.addListener('gotChildren', (element) => { gotTimes++; }); + var getListener = dataModel.addListener2('getChildren', (element) => { getTimes++; }); + var gotListener = dataModel.addListener2('gotChildren', (element) => { gotTimes++; }); var p1 = model.refresh('father'); assert.equal(getTimes, 1); @@ -1373,8 +1373,8 @@ suite('TreeModel - Dynamic data model', () => { assert.equal(nav.next().id, 'sister'); assert.equal(nav.next() && false, null); - getListener(); - gotListener(); + getListener.dispose(); + gotListener.dispose(); done(); }); }); @@ -1399,10 +1399,10 @@ suite('TreeModel - Dynamic data model', () => { counter.listen(model, 'item:refresh', (e) => { refreshTimes++; }); var getTimes = 0; - var getListener = dataModel.addListener('getChildren', (element) => { getTimes++; }); + var getListener = dataModel.addListener2('getChildren', (element) => { getTimes++; }); var gotTimes = 0; - var gotListener = dataModel.addListener('gotChildren', (element) => { gotTimes++; }); + var gotListener = dataModel.addListener2('gotChildren', (element) => { gotTimes++; }); var p1, p2; @@ -1455,8 +1455,8 @@ suite('TreeModel - Dynamic data model', () => { assert.equal(nav.next().id, 'son'); assert.equal(nav.next() && false, null); - getListener(); - gotListener(); + getListener.dispose(); + gotListener.dispose(); done(); }); }); @@ -1479,8 +1479,8 @@ suite('TreeModel - Dynamic data model', () => { var getTimes = 0; var gotTimes = 0; - var getListener = dataModel.addListener('getChildren', (element) => { getTimes++; }); - var gotListener = dataModel.addListener('gotChildren', (element) => { gotTimes++; }); + var getListener = dataModel.addListener2('getChildren', (element) => { getTimes++; }); + var gotListener = dataModel.addListener2('gotChildren', (element) => { gotTimes++; }); var p1, p2; @@ -1521,8 +1521,8 @@ suite('TreeModel - Dynamic data model', () => { assert.equal(nav.next().id, 'son'); assert.equal(nav.next() && false, null); - getListener(); - gotListener(); + getListener.dispose(); + gotListener.dispose(); done(); }); }); diff --git a/src/vs/base/test/common/eventEmitter.test.ts b/src/vs/base/test/common/eventEmitter.test.ts index 19dcc0e6c9e..12edf4acda5 100644 --- a/src/vs/base/test/common/eventEmitter.test.ts +++ b/src/vs/base/test/common/eventEmitter.test.ts @@ -21,7 +21,7 @@ suite('EventEmitter', () => { test('add listener, emit other event type', function () { var didCall = false; - eventEmitter.addListener('eventType1', function (e) { + eventEmitter.addListener2('eventType1', function (e) { didCall = true; }); eventEmitter.emit('eventType2', {}); @@ -30,7 +30,7 @@ suite('EventEmitter', () => { test('add listener, emit event', function () { var didCall = false; - eventEmitter.addListener('eventType', function (e) { + eventEmitter.addListener2('eventType', function (e) { didCall = true; }); eventEmitter.emit('eventType', {}); @@ -39,11 +39,11 @@ suite('EventEmitter', () => { test('add 2 listeners, emit event', function () { var didCallFirst = false; - eventEmitter.addListener('eventType', function (e) { + eventEmitter.addListener2('eventType', function (e) { didCallFirst = true; }); var didCallSecond = false; - eventEmitter.addListener('eventType', function (e) { + eventEmitter.addListener2('eventType', function (e) { didCallSecond = true; }); eventEmitter.emit('eventType', {}); @@ -53,22 +53,22 @@ suite('EventEmitter', () => { test('add 1 listener, remove it, emit event', function () { var didCall = false; - var remove = eventEmitter.addListener('eventType', function (e) { + var remove = eventEmitter.addListener2('eventType', function (e) { didCall = true; }); - remove(); + remove.dispose(); eventEmitter.emit('eventType', {}); assert(!didCall); }); test('add 2 listeners, emit event, remove one while processing', function () { var firstCallCount = 0; - var remove1 = eventEmitter.addListener('eventType', function (e) { + var remove1 = eventEmitter.addListener2('eventType', function (e) { firstCallCount++; - remove1(); + remove1.dispose(); }); var secondCallCount = 0; - eventEmitter.addListener('eventType', function (e) { + eventEmitter.addListener2('eventType', function (e) { secondCallCount++; }); eventEmitter.emit('eventType', {}); @@ -79,7 +79,7 @@ suite('EventEmitter', () => { test('event object is assert', function () { var data: any; - eventEmitter.addListener('eventType', function (e) { + eventEmitter.addListener2('eventType', function (e) { data = e.data; }); eventEmitter.emit('eventType', { data: 5 }); @@ -88,7 +88,7 @@ suite('EventEmitter', () => { test('deferred emit', function () { var calledCount = 0; - eventEmitter.addListener('eventType', function (e) { + eventEmitter.addListener2('eventType', function (e) { calledCount++; }); eventEmitter.deferredEmit(function () { @@ -103,11 +103,11 @@ suite('EventEmitter', () => { test('deferred emit maintains events order', function () { var order = 0; - eventEmitter.addListener('eventType2', function (e) { + eventEmitter.addListener2('eventType2', function (e) { order++; assert.equal(order, 1); }); - eventEmitter.addListener('eventType1', function (e) { + eventEmitter.addListener2('eventType1', function (e) { order++; assert.equal(order, 2); }); @@ -147,11 +147,11 @@ suite('EventEmitter', () => { eventBus.addEmitter(emitter, 'emitter1'); var didCallFirst = false; - eventBus.addListener('eventType', function (e) { + eventBus.addListener2('eventType', function (e) { didCallFirst = true; }); var didCallSecond = false; - eventBus.addListener('eventType/emitter1', function (e) { + eventBus.addListener2('eventType/emitter1', function (e) { didCallSecond = true; }); @@ -168,15 +168,11 @@ suite('EventEmitter', () => { eventBus.addEmitter(emitter1, 'emitter1'); eventBus.addEmitter(emitter2, 'emitter2'); - eventBus.addListener('eventType1', function (e) { + eventBus.addListener2('eventType1', function (e) { assert(true); callCnt++; }); - eventBus.addListener('eventType1/emitter1', function (e) { - assert(true); - callCnt++; - }); - eventBus.addEmitterTypeListener('eventType1', 'emitter1', function (e) { + eventBus.addListener2('eventType1/emitter1', function (e) { assert(true); callCnt++; }); @@ -187,7 +183,7 @@ suite('EventEmitter', () => { emitter2.emit('eventType1', {}); assert.equal(callCnt, 0); }); - assert.equal(callCnt, 4); + assert.equal(callCnt, 3); }); test('cascading emitters', function () { @@ -201,7 +197,7 @@ suite('EventEmitter', () => { emitter4.addEmitter(emitter3); var didCall = false; - emitter4.addListener('eventType', function (e) { + emitter4.addListener2('eventType', function (e) { didCall = true; }); @@ -213,16 +209,16 @@ suite('EventEmitter', () => { var emitter = new EventEmitter(); var actualCallOrder: string[] = []; - emitter.addListener('foo', function() { + emitter.addListener2('foo', function() { actualCallOrder.push('listener1-foo'); emitter.emit('bar'); }); - emitter.addListener('foo', function() { + emitter.addListener2('foo', function() { actualCallOrder.push('listener2-foo'); }); - emitter.addListener('bar', function() { + emitter.addListener2('bar', function() { actualCallOrder.push('listener2-bar'); }); @@ -239,7 +235,7 @@ suite('EventEmitter', () => { var emitter = new EventEmitter(); var actualCallOrder: string[] = []; - emitter.addListener('foo', function() { + emitter.addListener2('foo', function() { actualCallOrder.push('listener1-foo'); emitter.deferredEmit(() => { emitter.emit('bar'); @@ -247,10 +243,10 @@ suite('EventEmitter', () => { }); - emitter.addListener('foo', function() { + emitter.addListener2('foo', function() { actualCallOrder.push('listener2-foo'); }); - emitter.addListener('bar', function() { + emitter.addListener2('bar', function() { actualCallOrder.push('listener2-bar'); }); @@ -269,16 +265,16 @@ suite('EventEmitter', () => { var emitter = new OrderGuaranteeEventEmitter(); var actualCallOrder: string[] = []; - emitter.addListener('foo', function() { + emitter.addListener2('foo', function() { actualCallOrder.push('listener1-foo'); emitter.emit('bar'); }); - emitter.addListener('foo', function() { + emitter.addListener2('foo', function() { actualCallOrder.push('listener2-foo'); }); - emitter.addListener('bar', function() { + emitter.addListener2('bar', function() { actualCallOrder.push('listener2-bar'); }); @@ -295,7 +291,7 @@ suite('EventEmitter', () => { var emitter = new OrderGuaranteeEventEmitter(); var actualCallOrder: string[] = []; - emitter.addListener('foo', function() { + emitter.addListener2('foo', function() { actualCallOrder.push('listener1-foo'); emitter.deferredEmit(() => { emitter.emit('bar'); @@ -303,10 +299,10 @@ suite('EventEmitter', () => { }); - emitter.addListener('foo', function() { + emitter.addListener2('foo', function() { actualCallOrder.push('listener2-foo'); }); - emitter.addListener('bar', function() { + emitter.addListener2('bar', function() { actualCallOrder.push('listener2-bar'); }); diff --git a/src/vs/editor/common/editorActionEnablement.ts b/src/vs/editor/common/editorActionEnablement.ts index 934b4214fcf..bec60445e86 100644 --- a/src/vs/editor/common/editorActionEnablement.ts +++ b/src/vs/editor/common/editorActionEnablement.ts @@ -168,18 +168,18 @@ class InternalEnablementState extends CachingEnablementState { */ class DescentEnablementState extends CachingEnablementState { - private _callOnDispose:Function[] = []; + private _callOnDispose:IDisposable[] = []; constructor(behaviour:Behaviour, private editor:ICommonCodeEditor, private _action:IEditorAction) { super(); if (behaviour & Behaviour.UpdateOnModelChange) { - this._callOnDispose.push(this.editor.addListener(EventType.ModelChanged, () => this.reset())); - this._callOnDispose.push(this.editor.addListener(EventType.ModelModeChanged, () => this.reset())); - this._callOnDispose.push(this.editor.addListener(EventType.ModelModeSupportChanged, () => this.reset())); + this._callOnDispose.push(this.editor.addListener2(EventType.ModelChanged, () => this.reset())); + this._callOnDispose.push(this.editor.addListener2(EventType.ModelModeChanged, () => this.reset())); + this._callOnDispose.push(this.editor.addListener2(EventType.ModelModeSupportChanged, () => this.reset())); } if (behaviour & Behaviour.UpdateOnCursorPositionChange) { - this._callOnDispose.push(this.editor.addListener(EventType.CursorPositionChanged, () => this.reset())); + this._callOnDispose.push(this.editor.addListener2(EventType.CursorPositionChanged, () => this.reset())); } } diff --git a/src/vs/editor/common/services/bulkEdit.ts b/src/vs/editor/common/services/bulkEdit.ts index d468b19f7a2..8f093d66197 100644 --- a/src/vs/editor/common/services/bulkEdit.ts +++ b/src/vs/editor/common/services/bulkEdit.ts @@ -42,7 +42,7 @@ class ChangeRecorder { var changes: IStringDictionary = Object.create(null); - var stop = this._eventService.addListener(FileEventType.FILE_CHANGES,(event: FileChangesEvent) => { + var stop = this._eventService.addListener2(FileEventType.FILE_CHANGES,(event: FileChangesEvent) => { event.changes.forEach(change => { var key = String(change.resource), @@ -57,7 +57,7 @@ class ChangeRecorder { }); return { - stop, + stop: () => { stop.dispose(); }, hasChanged: (resource: URI) => !!changes[resource.toString()], allChanges: () => merge(values(changes)) }; diff --git a/src/vs/editor/common/services/resourceService.ts b/src/vs/editor/common/services/resourceService.ts index 932f5b7082d..f1aa222e7fb 100644 --- a/src/vs/editor/common/services/resourceService.ts +++ b/src/vs/editor/common/services/resourceService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import {IEmitterEvent, ListenerCallback, ListenerUnbind} from 'vs/base/common/eventEmitter'; +import {IEmitterEvent, ListenerCallback} from 'vs/base/common/eventEmitter'; import {IDisposable} from 'vs/base/common/lifecycle'; import URI from 'vs/base/common/uri'; import {ServiceIdentifier, createDecorator} from 'vs/platform/instantiation/common/instantiation'; @@ -42,10 +42,6 @@ export interface IResourceService { all(): IMirrorModel[]; contains(url: URI): boolean; remove(url: URI): void; - addListener_(eventType: 'resource.added', listener: (event: IResourceAddedEvent) => void): ListenerUnbind; - addListener_(eventType: 'resource.removed', listener: (event: IResourceRemovedEvent) => void): ListenerUnbind; - addListener_(eventType: 'resource.changed', listener: (event: IResourceChangedEvent) => void): ListenerUnbind; - addListener_(eventType: string, listener: ListenerCallback): ListenerUnbind; addListener2_(eventType: 'resource.added', listener: (event: IResourceAddedEvent) => void): IDisposable; addListener2_(eventType: 'resource.removed', listener: (event: IResourceRemovedEvent) => void): IDisposable; addListener2_(eventType: 'resource.changed', listener: (event: IResourceChangedEvent) => void): IDisposable; diff --git a/src/vs/editor/common/services/resourceServiceImpl.ts b/src/vs/editor/common/services/resourceServiceImpl.ts index 9b8543cc553..820b92bd88a 100644 --- a/src/vs/editor/common/services/resourceServiceImpl.ts +++ b/src/vs/editor/common/services/resourceServiceImpl.ts @@ -21,10 +21,6 @@ export class ResourceService extends EventEmitter implements IResourceService { this.unbinds = {}; } - public addListener_(eventType: string, listener: ListenerCallback): ListenerUnbind { - return super.addListener(eventType, listener); - } - public addListener2_(eventType: string, listener: ListenerCallback): IDisposable { return super.addListener2(eventType, listener); } diff --git a/src/vs/editor/contrib/clipboard/browser/clipboard.ts b/src/vs/editor/contrib/clipboard/browser/clipboard.ts index fe2234238d0..e1a835ed313 100644 --- a/src/vs/editor/contrib/clipboard/browser/clipboard.ts +++ b/src/vs/editor/contrib/clipboard/browser/clipboard.ts @@ -8,7 +8,7 @@ import 'vs/css!./clipboard'; import * as nls from 'vs/nls'; import {KeyCode, KeyMod} from 'vs/base/common/keyCodes'; -import {cAll} from 'vs/base/common/lifecycle'; +import {dispose, IDisposable} from 'vs/base/common/lifecycle'; import {TPromise} from 'vs/base/common/winjs.base'; import * as browser from 'vs/base/browser/browser'; import {ServicesAccessor} from 'vs/platform/instantiation/common/instantiation'; @@ -21,18 +21,18 @@ import {CommonEditorRegistry, ContextKey, EditorActionDescriptor} from 'vs/edito class ClipboardWritingAction extends EditorAction { - private toUnhook:Function[]; + private toUnhook:IDisposable[]; constructor(descriptor:editorCommon.IEditorActionDescriptorData, editor:editorCommon.ICommonCodeEditor, condition:Behaviour) { super(descriptor, editor, condition); this.toUnhook = []; - this.toUnhook.push(this.editor.addListener(editorCommon.EventType.CursorSelectionChanged, (e:editorCommon.ICursorSelectionChangedEvent) => { + this.toUnhook.push(this.editor.addListener2(editorCommon.EventType.CursorSelectionChanged, (e:editorCommon.ICursorSelectionChangedEvent) => { this.resetEnablementState(); })); } public dispose(): void { - this.toUnhook = cAll(this.toUnhook); + this.toUnhook = dispose(this.toUnhook); super.dispose(); } diff --git a/src/vs/editor/contrib/color/browser/color.ts b/src/vs/editor/contrib/color/browser/color.ts index db75b3dd8ae..7e03121c13c 100644 --- a/src/vs/editor/contrib/color/browser/color.ts +++ b/src/vs/editor/contrib/color/browser/color.ts @@ -8,7 +8,7 @@ import 'vs/css!./color'; import {RunOnceScheduler} from 'vs/base/common/async'; import {onUnexpectedError} from 'vs/base/common/errors'; -import {IDisposable, cAll, dispose} from 'vs/base/common/lifecycle'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; import * as strings from 'vs/base/common/strings'; import {TPromise} from 'vs/base/common/winjs.base'; import * as dom from 'vs/base/browser/dom'; @@ -73,7 +73,7 @@ export class ColorContribution implements editorCommon.IEditorContribution { private _decorationsChangedScheduler:RunOnceScheduler; private _callOnDispose:IDisposable[]; - private _callOnModelChange:IFunction[]; + private _callOnModelChange:IDisposable[]; private _currentFindColorDeclarationsPromise:TPromise<{range:editorCommon.IRange; value:string; }[]>; private _currentDecorations:ColorDecoration[]; @@ -126,7 +126,7 @@ export class ColorContribution implements editorCommon.IEditorContribution { } private onModelChange(): void { - cAll(this._callOnModelChange); + this._callOnModelChange = dispose(this._callOnModelChange); var model = this._editor.getModel(); if(!model) { @@ -158,18 +158,22 @@ export class ColorContribution implements editorCommon.IEditorContribution { this._contentChangedScheduler.schedule(); - this._callOnModelChange.push(() => { - this._contentChangedScheduler.cancel(); - this._decorationsChangedScheduler.cancel(); - }); - this._callOnModelChange.push(() => { - if (this._currentFindColorDeclarationsPromise) { - this._currentFindColorDeclarationsPromise.cancel(); + this._callOnModelChange.push({ + dispose: () => { + this._contentChangedScheduler.cancel(); + this._decorationsChangedScheduler.cancel(); } - this._currentFindColorDeclarationsPromise = null; }); - this._callOnModelChange.push(this._editor.addListener(editorCommon.EventType.ModelContentChanged, (event) => this._contentChangedScheduler.schedule())); - this._callOnModelChange.push(model.addListener(editorCommon.EventType.ModelDecorationsChanged, (event) => this._decorationsChangedScheduler.schedule())); + this._callOnModelChange.push({ + dispose: () => { + if (this._currentFindColorDeclarationsPromise) { + this._currentFindColorDeclarationsPromise.cancel(); + } + this._currentFindColorDeclarationsPromise = null; + } + }); + this._callOnModelChange.push(this._editor.addListener2(editorCommon.EventType.ModelContentChanged, (event) => this._contentChangedScheduler.schedule())); + this._callOnModelChange.push(model.addListener2(editorCommon.EventType.ModelDecorationsChanged, (event) => this._decorationsChangedScheduler.schedule())); } private renderAndTrackColors(colors:{range:editorCommon.IRange; value:string; }[]): void { diff --git a/src/vs/editor/contrib/diffNavigator/common/diffNavigator.ts b/src/vs/editor/contrib/diffNavigator/common/diffNavigator.ts index 6c8731de2a7..0b448e364e2 100644 --- a/src/vs/editor/contrib/diffNavigator/common/diffNavigator.ts +++ b/src/vs/editor/contrib/diffNavigator/common/diffNavigator.ts @@ -5,10 +5,11 @@ 'use strict'; import * as assert from 'vs/base/common/assert'; -import {EventEmitter, ListenerUnbind} from 'vs/base/common/eventEmitter'; +import {EventEmitter} from 'vs/base/common/eventEmitter'; import * as objects from 'vs/base/common/objects'; import {Range} from 'vs/editor/common/core/range'; import {EventType, ICommonDiffEditor, ICursorPositionChangedEvent, IEditorRange, ILineChange} from 'vs/editor/common/editorCommon'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; interface IDiffRange { rhs:boolean; @@ -39,7 +40,7 @@ export class DiffNavigator extends EventEmitter { private editor:ICommonDiffEditor; private options:Options; private disposed:boolean; - private toUnbind:ListenerUnbind[]; + private toUnbind:IDisposable[]; private nextIdx:number; private ranges:IDiffRange[]; @@ -62,11 +63,11 @@ export class DiffNavigator extends EventEmitter { this.revealFirst = this.options.alwaysRevealFirst; // hook up to diff editor for diff, disposal, and caret move - this.toUnbind.push(this.editor.addListener(EventType.Disposed, () => this.dispose() )); - this.toUnbind.push(this.editor.addListener(EventType.DiffUpdated, () => this.onDiffUpdated() )); + this.toUnbind.push(this.editor.addListener2(EventType.Disposed, () => this.dispose() )); + this.toUnbind.push(this.editor.addListener2(EventType.DiffUpdated, () => this.onDiffUpdated() )); if(this.options.followsCaret) { - this.toUnbind.push(this.editor.getModifiedEditor().addListener(EventType.CursorPositionChanged, (e:ICursorPositionChangedEvent) => { + this.toUnbind.push(this.editor.getModifiedEditor().addListener2(EventType.CursorPositionChanged, (e:ICursorPositionChangedEvent) => { if(this.ignoreSelectionChange) { return; } @@ -74,7 +75,7 @@ export class DiffNavigator extends EventEmitter { })); } if(this.options.alwaysRevealFirst) { - this.toUnbind.push(this.editor.getModifiedEditor().addListener(EventType.ModelChanged, (e) => { + this.toUnbind.push(this.editor.getModifiedEditor().addListener2(EventType.ModelChanged, (e) => { this.revealFirst = true; })); } @@ -214,9 +215,7 @@ export class DiffNavigator extends EventEmitter { } public dispose():void { - while(this.toUnbind.length > 0) { - this.toUnbind.pop()(); - } + this.toUnbind = dispose(this.toUnbind); this.ranges = null; this.disposed = true; diff --git a/src/vs/editor/contrib/format/common/formatActions.ts b/src/vs/editor/contrib/format/common/formatActions.ts index 1e5aeb7e8cb..36f6acc3aed 100644 --- a/src/vs/editor/contrib/format/common/formatActions.ts +++ b/src/vs/editor/contrib/format/common/formatActions.ts @@ -84,7 +84,7 @@ class FormatOnType implements editorCommon.IEditorContribution { // install a listener that checks if edits happens before the // position on which we format right now. Iff so, we won't // apply the format edits - var unbind = this.editor.addListener(editorCommon.EventType.ModelContentChanged,(e: editorCommon.IModelContentChangedEvent) => { + var unbind = this.editor.addListener2(editorCommon.EventType.ModelContentChanged,(e: editorCommon.IModelContentChangedEvent) => { if (e.changeType === editorCommon.EventType.ModelContentChangedFlush) { // a model.setValue() was called canceled = true; @@ -103,7 +103,7 @@ class FormatOnType implements editorCommon.IEditorContribution { if (canceled) { // cancel only once - unbind(); + unbind.dispose(); } }); @@ -114,7 +114,7 @@ class FormatOnType implements editorCommon.IEditorContribution { insertSpaces: modelOpts.insertSpaces }).then(edits => { - unbind(); + unbind.dispose(); if (canceled || arrays.isFalsyOrEmpty(edits)) { return; @@ -123,7 +123,7 @@ class FormatOnType implements editorCommon.IEditorContribution { this.editor.executeCommand(this.getId(), new EditOperationsCommand(edits, this.editor.getSelection())); },(err) => { - unbind(); + unbind.dispose(); throw err; }); } diff --git a/src/vs/editor/contrib/goToDeclaration/browser/goToDeclaration.ts b/src/vs/editor/contrib/goToDeclaration/browser/goToDeclaration.ts index 7dee1b38888..d3e8a85076f 100644 --- a/src/vs/editor/contrib/goToDeclaration/browser/goToDeclaration.ts +++ b/src/vs/editor/contrib/goToDeclaration/browser/goToDeclaration.ts @@ -9,7 +9,6 @@ import 'vs/css!./goToDeclaration'; import * as nls from 'vs/nls'; import {Throttler} from 'vs/base/common/async'; import {onUnexpectedError} from 'vs/base/common/errors'; -import {ListenerUnbind} from 'vs/base/common/eventEmitter'; import {IHTMLContentElement} from 'vs/base/common/htmlContent'; import {KeyCode, KeyMod} from 'vs/base/common/keyCodes'; import * as platform from 'vs/base/common/platform'; @@ -32,6 +31,7 @@ import {EditorBrowserRegistry} from 'vs/editor/browser/editorBrowserExtensions'; import {getDeclarationsAtPosition} from 'vs/editor/contrib/goToDeclaration/common/goToDeclaration'; import {ReferencesController} from 'vs/editor/contrib/referenceSearch/browser/referencesController'; import {ReferencesModel} from 'vs/editor/contrib/referenceSearch/browser/referencesModel'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; export class DefinitionActionConfig { @@ -206,7 +206,7 @@ class GotoDefinitionWithMouseEditorContribution implements editorCommon.IEditorC static MAX_SOURCE_PREVIEW_LINES = 7; private editor: ICodeEditor; - private toUnhook: ListenerUnbind[]; + private toUnhook: IDisposable[]; private decorations: string[]; private currentWordUnderMouse: editorCommon.IWordAtPosition; private throttler: Throttler; @@ -222,15 +222,15 @@ class GotoDefinitionWithMouseEditorContribution implements editorCommon.IEditorC this.editor = editor; this.throttler = new Throttler(); - this.toUnhook.push(this.editor.addListener(editorCommon.EventType.MouseDown, (e: IEditorMouseEvent) => this.onEditorMouseDown(e))); - this.toUnhook.push(this.editor.addListener(editorCommon.EventType.MouseUp, (e: IEditorMouseEvent) => this.onEditorMouseUp(e))); - this.toUnhook.push(this.editor.addListener(editorCommon.EventType.MouseMove, (e: IEditorMouseEvent) => this.onEditorMouseMove(e))); - this.toUnhook.push(this.editor.addListener(editorCommon.EventType.KeyDown, (e: IKeyboardEvent) => this.onEditorKeyDown(e))); - this.toUnhook.push(this.editor.addListener(editorCommon.EventType.KeyUp, (e: IKeyboardEvent) => this.onEditorKeyUp(e))); + this.toUnhook.push(this.editor.addListener2(editorCommon.EventType.MouseDown, (e: IEditorMouseEvent) => this.onEditorMouseDown(e))); + this.toUnhook.push(this.editor.addListener2(editorCommon.EventType.MouseUp, (e: IEditorMouseEvent) => this.onEditorMouseUp(e))); + this.toUnhook.push(this.editor.addListener2(editorCommon.EventType.MouseMove, (e: IEditorMouseEvent) => this.onEditorMouseMove(e))); + this.toUnhook.push(this.editor.addListener2(editorCommon.EventType.KeyDown, (e: IKeyboardEvent) => this.onEditorKeyDown(e))); + this.toUnhook.push(this.editor.addListener2(editorCommon.EventType.KeyUp, (e: IKeyboardEvent) => this.onEditorKeyUp(e))); - this.toUnhook.push(this.editor.addListener(editorCommon.EventType.ModelChanged, (e: editorCommon.IModelContentChangedEvent) => this.resetHandler())); - this.toUnhook.push(this.editor.addListener('change', (e: editorCommon.IModelContentChangedEvent) => this.resetHandler())); - this.toUnhook.push(this.editor.addListener('scroll', () => this.resetHandler())); + this.toUnhook.push(this.editor.addListener2(editorCommon.EventType.ModelChanged, (e: editorCommon.IModelContentChangedEvent) => this.resetHandler())); + this.toUnhook.push(this.editor.addListener2('change', (e: editorCommon.IModelContentChangedEvent) => this.resetHandler())); + this.toUnhook.push(this.editor.addListener2('scroll', () => this.resetHandler())); } private onEditorMouseMove(mouseEvent: IEditorMouseEvent, withKey?: IKeyboardEvent): void { @@ -457,9 +457,7 @@ class GotoDefinitionWithMouseEditorContribution implements editorCommon.IEditorC } public dispose(): void { - while (this.toUnhook.length > 0) { - this.toUnhook.pop()(); - } + this.toUnhook = dispose(this.toUnhook); } } diff --git a/src/vs/editor/contrib/gotoError/browser/gotoError.ts b/src/vs/editor/contrib/gotoError/browser/gotoError.ts index 468f7735892..f0916def727 100644 --- a/src/vs/editor/contrib/gotoError/browser/gotoError.ts +++ b/src/vs/editor/contrib/gotoError/browser/gotoError.ts @@ -10,7 +10,7 @@ import * as nls from 'vs/nls'; import {onUnexpectedError} from 'vs/base/common/errors'; import {Emitter} from 'vs/base/common/event'; import {CommonKeybindings, KeyCode, KeyMod} from 'vs/base/common/keyCodes'; -import {IDisposable, cAll, dispose} from 'vs/base/common/lifecycle'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; import Severity from 'vs/base/common/severity'; import * as strings from 'vs/base/common/strings'; import URI from 'vs/base/common/uri'; @@ -36,7 +36,7 @@ class MarkerModel { private _editor: ICodeEditor; private _markers: IMarker[]; private _nextIdx: number; - private _toUnbind: Function[]; + private _toUnbind: IDisposable[]; private _ignoreSelectionChange: boolean; private _onCurrentMarkerChanged: Emitter; private _onMarkerSetChanged: Emitter; @@ -52,8 +52,8 @@ class MarkerModel { this.setMarkers(markers); // listen on editor - this._toUnbind.push(this._editor.addListener(editorCommon.EventType.Disposed, () => this.dispose())); - this._toUnbind.push(this._editor.addListener(editorCommon.EventType.CursorPositionChanged, () => { + this._toUnbind.push(this._editor.addListener2(editorCommon.EventType.Disposed, () => this.dispose())); + this._toUnbind.push(this._editor.addListener2(editorCommon.EventType.CursorPositionChanged, () => { if (!this._ignoreSelectionChange) { this._nextIdx = -1; } @@ -177,7 +177,7 @@ class MarkerModel { } public dispose(): void { - this._toUnbind = cAll(this._toUnbind); + this._toUnbind = dispose(this._toUnbind); } } diff --git a/src/vs/editor/contrib/hover/browser/hover.ts b/src/vs/editor/contrib/hover/browser/hover.ts index bb55f292fab..daf30b2de24 100644 --- a/src/vs/editor/contrib/hover/browser/hover.ts +++ b/src/vs/editor/contrib/hover/browser/hover.ts @@ -7,7 +7,6 @@ import 'vs/css!./hover'; import * as nls from 'vs/nls'; -import {ListenerUnbind} from 'vs/base/common/eventEmitter'; import {KeyCode, KeyMod} from 'vs/base/common/keyCodes'; import * as platform from 'vs/base/common/platform'; import {TPromise} from 'vs/base/common/winjs.base'; @@ -23,13 +22,14 @@ import {ICodeEditor, IEditorMouseEvent} from 'vs/editor/browser/editorBrowser'; import {EditorBrowserRegistry} from 'vs/editor/browser/editorBrowserExtensions'; import {ModesContentHoverWidget} from './modesContentHover'; import {ModesGlyphHoverWidget} from './modesGlyphHover'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; class ModesHoverController implements editorCommon.IEditorContribution { static ID = 'editor.contrib.hover'; private _editor: ICodeEditor; - private _toUnhook:ListenerUnbind[]; + private _toUnhook:IDisposable[]; private _contentWidget: ModesContentHoverWidget; private _glyphWidget: ModesGlyphHoverWidget; @@ -46,13 +46,13 @@ class ModesHoverController implements editorCommon.IEditorContribution { this._toUnhook = []; if (editor.getConfiguration().contribInfo.hover) { - this._toUnhook.push(this._editor.addListener(editorCommon.EventType.MouseDown, (e: IEditorMouseEvent) => this._onEditorMouseDown(e))); - this._toUnhook.push(this._editor.addListener(editorCommon.EventType.MouseMove, (e: IEditorMouseEvent) => this._onEditorMouseMove(e))); - this._toUnhook.push(this._editor.addListener(editorCommon.EventType.MouseLeave, (e: IEditorMouseEvent) => this._hideWidgets())); - this._toUnhook.push(this._editor.addListener(editorCommon.EventType.KeyDown, (e:IKeyboardEvent) => this._onKeyDown(e))); - this._toUnhook.push(this._editor.addListener(editorCommon.EventType.ModelChanged, () => this._hideWidgets())); - this._toUnhook.push(this._editor.addListener(editorCommon.EventType.ModelDecorationsChanged, () => this._onModelDecorationsChanged())); - this._toUnhook.push(this._editor.addListener('scroll', () => this._hideWidgets())); + this._toUnhook.push(this._editor.addListener2(editorCommon.EventType.MouseDown, (e: IEditorMouseEvent) => this._onEditorMouseDown(e))); + this._toUnhook.push(this._editor.addListener2(editorCommon.EventType.MouseMove, (e: IEditorMouseEvent) => this._onEditorMouseMove(e))); + this._toUnhook.push(this._editor.addListener2(editorCommon.EventType.MouseLeave, (e: IEditorMouseEvent) => this._hideWidgets())); + this._toUnhook.push(this._editor.addListener2(editorCommon.EventType.KeyDown, (e:IKeyboardEvent) => this._onKeyDown(e))); + this._toUnhook.push(this._editor.addListener2(editorCommon.EventType.ModelChanged, () => this._hideWidgets())); + this._toUnhook.push(this._editor.addListener2(editorCommon.EventType.ModelDecorationsChanged, () => this._onModelDecorationsChanged())); + this._toUnhook.push(this._editor.addListener2('scroll', () => this._hideWidgets())); this._contentWidget = new ModesContentHoverWidget(editor, openerService); this._glyphWidget = new ModesGlyphHoverWidget(editor); @@ -127,9 +127,7 @@ class ModesHoverController implements editorCommon.IEditorContribution { } public dispose(): void { - while(this._toUnhook.length > 0) { - this._toUnhook.pop()(); - } + this._toUnhook = dispose(this._toUnhook); if (this._glyphWidget) { this._glyphWidget.dispose(); this._glyphWidget = null; diff --git a/src/vs/editor/contrib/links/browser/links.ts b/src/vs/editor/contrib/links/browser/links.ts index 7312b99d64e..f59b5485c50 100644 --- a/src/vs/editor/contrib/links/browser/links.ts +++ b/src/vs/editor/contrib/links/browser/links.ts @@ -8,7 +8,6 @@ import 'vs/css!./links'; import * as nls from 'vs/nls'; import {onUnexpectedError} from 'vs/base/common/errors'; -import {ListenerUnbind} from 'vs/base/common/eventEmitter'; import {KeyCode} from 'vs/base/common/keyCodes'; import * as platform from 'vs/base/common/platform'; import Severity from 'vs/base/common/severity'; @@ -26,6 +25,7 @@ import {ILink, LinkProviderRegistry} from 'vs/editor/common/modes'; import {IEditorWorkerService} from 'vs/editor/common/services/editorWorkerService'; import {IEditorMouseEvent} from 'vs/editor/browser/editorBrowser'; import {getLinks} from 'vs/editor/contrib/links/common/links'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; class LinkOccurence { @@ -93,7 +93,7 @@ class LinkDetector { static CLASS_NAME_ACTIVE = 'detected-link-active'; private editor:editorCommon.ICommonCodeEditor; - private listenersToRemove:ListenerUnbind[]; + private listenersToRemove:IDisposable[]; private timeoutPromise:TPromise; private computePromise:TPromise; private activeLinkDecorationId:string; @@ -114,13 +114,13 @@ class LinkDetector { this.messageService = messageService; this.editorWorkerService = editorWorkerService; this.listenersToRemove = []; - this.listenersToRemove.push(editor.addListener('change', (e:editorCommon.IModelContentChangedEvent) => this.onChange())); - this.listenersToRemove.push(editor.addListener(editorCommon.EventType.ModelChanged, (e:editorCommon.IModelContentChangedEvent) => this.onModelChanged())); - this.listenersToRemove.push(editor.addListener(editorCommon.EventType.ModelModeChanged, (e:editorCommon.IModelModeChangedEvent) => this.onModelModeChanged())); - this.listenersToRemove.push(this.editor.addListener(editorCommon.EventType.MouseUp, (e:IEditorMouseEvent) => this.onEditorMouseUp(e))); - this.listenersToRemove.push(this.editor.addListener(editorCommon.EventType.MouseMove, (e:IEditorMouseEvent) => this.onEditorMouseMove(e))); - this.listenersToRemove.push(this.editor.addListener(editorCommon.EventType.KeyDown, (e:IKeyboardEvent) => this.onEditorKeyDown(e))); - this.listenersToRemove.push(this.editor.addListener(editorCommon.EventType.KeyUp, (e:IKeyboardEvent) => this.onEditorKeyUp(e))); + this.listenersToRemove.push(editor.addListener2('change', (e:editorCommon.IModelContentChangedEvent) => this.onChange())); + this.listenersToRemove.push(editor.addListener2(editorCommon.EventType.ModelChanged, (e:editorCommon.IModelContentChangedEvent) => this.onModelChanged())); + this.listenersToRemove.push(editor.addListener2(editorCommon.EventType.ModelModeChanged, (e:editorCommon.IModelModeChangedEvent) => this.onModelModeChanged())); + this.listenersToRemove.push(this.editor.addListener2(editorCommon.EventType.MouseUp, (e:IEditorMouseEvent) => this.onEditorMouseUp(e))); + this.listenersToRemove.push(this.editor.addListener2(editorCommon.EventType.MouseMove, (e:IEditorMouseEvent) => this.onEditorMouseMove(e))); + this.listenersToRemove.push(this.editor.addListener2(editorCommon.EventType.KeyDown, (e:IKeyboardEvent) => this.onEditorKeyDown(e))); + this.listenersToRemove.push(this.editor.addListener2(editorCommon.EventType.KeyUp, (e:IKeyboardEvent) => this.onEditorKeyUp(e))); this.timeoutPromise = null; this.computePromise = null; this.currentOccurences = {}; @@ -397,10 +397,7 @@ class LinkDetector { } public dispose():void { - this.listenersToRemove.forEach((element) => { - element(); - }); - this.listenersToRemove = []; + this.listenersToRemove = dispose(this.listenersToRemove); this.stop(); } } diff --git a/src/vs/editor/contrib/quickFix/browser/quickFixSelectionWidget.ts b/src/vs/editor/contrib/quickFix/browser/quickFixSelectionWidget.ts index 1b09c084ae4..f236f8036e6 100644 --- a/src/vs/editor/contrib/quickFix/browser/quickFixSelectionWidget.ts +++ b/src/vs/editor/contrib/quickFix/browser/quickFixSelectionWidget.ts @@ -8,7 +8,6 @@ import 'vs/css!./quickFix'; import * as nls from 'vs/nls'; import {illegalArgument, onUnexpectedError} from 'vs/base/common/errors'; -import {ListenerUnbind} from 'vs/base/common/eventEmitter'; import * as timer from 'vs/base/common/timer'; import {TPromise} from 'vs/base/common/winjs.base'; import * as dom from 'vs/base/browser/dom'; @@ -23,6 +22,7 @@ import {IQuickFix2} from '../common/quickFix'; import {QuickFixModel} from './quickFixModel'; import {alert} from 'vs/base/browser/ui/aria/aria'; import {ScrollbarVisibility} from 'vs/base/browser/ui/scrollbar/scrollableElementOptions'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; var $ = dom.emmet; @@ -207,8 +207,8 @@ export class QuickFixSelectionWidget implements IContentWidget { private isActive: boolean; private isLoading: boolean; private isAuto: boolean; - private listenersToRemove: ListenerUnbind[]; - private modelListenersToRemove: ListenerUnbind[]; + private listenersToRemove: IDisposable[]; + private modelListenersToRemove: IDisposable[]; private model: QuickFixModel; private telemetryData: ITelemetryData; @@ -259,7 +259,7 @@ export class QuickFixSelectionWidget implements IContentWidget { ariaLabel: nls.localize('treeAriaLabel', "Quick Fix") }); - this.listenersToRemove.push(this.tree.addListener('selection', (e:ISelectionEvent) => { + this.listenersToRemove.push(this.tree.addListener2('selection', (e:ISelectionEvent) => { if (e.selection && e.selection.length > 0) { var element = e.selection[0]; if (isQuickFix(element) && !(element instanceof MessageRoot) && !(element instanceof Message)) { @@ -278,7 +278,7 @@ export class QuickFixSelectionWidget implements IContentWidget { var oldFocus: any = null; - this.listenersToRemove.push(this.tree.addListener('focus', (e:IFocusEvent) => { + this.listenersToRemove.push(this.tree.addListener2('focus', (e:IFocusEvent) => { var focus = e.focus; var payload = e.payload; @@ -313,7 +313,7 @@ export class QuickFixSelectionWidget implements IContentWidget { this.editor.addContentWidget(this); - this.listenersToRemove.push(this.editor.addListener(EventType.CursorSelectionChanged, (e: ICursorSelectionChangedEvent) => { + this.listenersToRemove.push(this.editor.addListener2(EventType.CursorSelectionChanged, (e: ICursorSelectionChangedEvent) => { if (this.isActive) { this.editor.layoutContentWidget(this); } @@ -340,7 +340,7 @@ export class QuickFixSelectionWidget implements IContentWidget { var timer : timer.ITimerEvent = null, loadingHandle:number; - this.modelListenersToRemove.push(this.model.addListener('loading', (e: any) => { + this.modelListenersToRemove.push(this.model.addListener2('loading', (e: any) => { if (!this.isActive) { timer = this.telemetryService.timedPublicLog('QuickFixSelectionWidgetLoadingTime'); this.isLoading = true; @@ -363,7 +363,7 @@ export class QuickFixSelectionWidget implements IContentWidget { } })); - this.modelListenersToRemove.push(this.model.addListener('suggest',(e: { fixes: IQuickFix2[]; range: IRange; auto:boolean; }) => { + this.modelListenersToRemove.push(this.model.addListener2('suggest',(e: { fixes: IQuickFix2[]; range: IRange; auto:boolean; }) => { this.isLoading = false; if(typeof loadingHandle !== 'undefined') { @@ -405,7 +405,7 @@ export class QuickFixSelectionWidget implements IContentWidget { } })); - this.modelListenersToRemove.push(this.model.addListener('empty', (e: { auto:boolean; }) => { + this.modelListenersToRemove.push(this.model.addListener2('empty', (e: { auto:boolean; }) => { var wasLoading = this.isLoading; this.isLoading = false; @@ -436,7 +436,7 @@ export class QuickFixSelectionWidget implements IContentWidget { } })); - this.modelListenersToRemove.push(this.model.addListener('cancel', (e:any) => { + this.modelListenersToRemove.push(this.model.addListener2('cancel', (e:any) => { this.isLoading = false; if(typeof loadingHandle !== 'undefined') { @@ -532,10 +532,7 @@ export class QuickFixSelectionWidget implements IContentWidget { } private releaseModel() : void { - var listener:()=>void; - while (listener = this.modelListenersToRemove.pop()) { - listener(); - } + this.modelListenersToRemove = dispose(this.modelListenersToRemove); this.model = null; } @@ -603,9 +600,6 @@ export class QuickFixSelectionWidget implements IContentWidget { this.tree.dispose(); this.tree = null; - this.listenersToRemove.forEach((element) => { - element(); - }); - this.listenersToRemove = null; + this.listenersToRemove = dispose(this.listenersToRemove); } } \ No newline at end of file diff --git a/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.ts b/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.ts index 7010f7e1cc7..ee0676a814b 100644 --- a/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.ts +++ b/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.ts @@ -10,7 +10,7 @@ import * as collections from 'vs/base/common/collections'; import {onUnexpectedError} from 'vs/base/common/errors'; import {getPathLabel} from 'vs/base/common/labels'; import Event, {Emitter} from 'vs/base/common/event'; -import {IDisposable, cAll, dispose, Disposables} from 'vs/base/common/lifecycle'; +import {IDisposable, dispose, Disposables} from 'vs/base/common/lifecycle'; import {Schemas} from 'vs/base/common/network'; import * as strings from 'vs/base/common/strings'; import {TPromise} from 'vs/base/common/winjs.base'; @@ -48,24 +48,24 @@ class DecorationsManager implements IDisposable { private _decorationSet = collections.createStringDictionary(); private _decorationIgnoreSet = collections.createStringDictionary(); - private _callOnDispose:Function[] = []; - private _callOnModelChange:Function[] = []; + private _callOnDispose:IDisposable[] = []; + private _callOnModelChange:IDisposable[] = []; constructor(private editor:ICodeEditor, private model:ReferencesModel) { - this._callOnDispose.push(this.editor.addListener(editorCommon.EventType.ModelChanged, () => this._onModelChanged())); + this._callOnDispose.push(this.editor.addListener2(editorCommon.EventType.ModelChanged, () => this._onModelChanged())); this._onModelChanged(); } public dispose(): void { - this._callOnModelChange = cAll(this._callOnModelChange); - this._callOnDispose = cAll(this._callOnDispose); + this._callOnModelChange = dispose(this._callOnModelChange); + this._callOnDispose = dispose(this._callOnDispose); this.removeDecorations(); } private _onModelChanged():void { this.removeDecorations(); - this._callOnModelChange = cAll(this._callOnModelChange); + this._callOnModelChange = dispose(this._callOnModelChange); var model = this.editor.getModel(); if(!model) { @@ -81,7 +81,7 @@ class DecorationsManager implements IDisposable { } private _addDecorations(reference:FileReferences):void { - this._callOnModelChange.push(this.editor.getModel().addListener(editorCommon.EventType.ModelDecorationsChanged, (event) => this._onDecorationChanged(event))); + this._callOnModelChange.push(this.editor.getModel().addListener2(editorCommon.EventType.ModelDecorationsChanged, (event) => this._onDecorationChanged(event))); this.editor.getModel().changeDecorations((accessor) => { var newDecorations: editorCommon.IModelDeltaDecoration[] = []; diff --git a/src/vs/editor/contrib/smartSelect/common/smartSelect.ts b/src/vs/editor/contrib/smartSelect/common/smartSelect.ts index b7db51d062f..229d68c20ac 100644 --- a/src/vs/editor/contrib/smartSelect/common/smartSelect.ts +++ b/src/vs/editor/contrib/smartSelect/common/smartSelect.ts @@ -98,12 +98,12 @@ class SmartSelect extends EditorAction { state = editorState; // listen to caret move and forget about state - var unhook: () => void = this.editor.addListener(EventType.CursorPositionChanged,(e: ICursorPositionChangedEvent) => { + var unhook = this.editor.addListener2(EventType.CursorPositionChanged,(e: ICursorPositionChangedEvent) => { if (ignoreSelection) { return; } state = null; - unhook(); + unhook.dispose(); }); }); } diff --git a/src/vs/editor/contrib/snippet/common/snippet.ts b/src/vs/editor/contrib/snippet/common/snippet.ts index 1471788d328..722d4bb992c 100644 --- a/src/vs/editor/contrib/snippet/common/snippet.ts +++ b/src/vs/editor/contrib/snippet/common/snippet.ts @@ -6,7 +6,6 @@ 'use strict'; import * as collections from 'vs/base/common/collections'; -import {ListenerUnbind} from 'vs/base/common/eventEmitter'; import {KeyCode, KeyMod} from 'vs/base/common/keyCodes'; import * as strings from 'vs/base/common/strings'; import {IKeybindingContextKey, IKeybindingService} from 'vs/platform/keybinding/common/keybindingService'; @@ -15,6 +14,7 @@ import {Range} from 'vs/editor/common/core/range'; import {Selection} from 'vs/editor/common/core/selection'; import * as editorCommon from 'vs/editor/common/editorCommon'; import {CommonEditorRegistry} from 'vs/editor/common/editorCommonExtensions'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; interface IParsedLinePlaceHolderInfo { id: string; @@ -384,7 +384,7 @@ class InsertSnippetController { private model: editorCommon.IModel; private finishPlaceHolderIndex:number; - private listenersToRemove:ListenerUnbind[]; + private listenersToRemove:IDisposable[]; private trackedPlaceHolders:ITrackedPlaceHolder[]; private placeHolderDecorations: string[]; private currentPlaceHolderIndex:number; @@ -460,7 +460,7 @@ class InsertSnippetController { }); this.listenersToRemove = []; - this.listenersToRemove.push(this.editor.addListener(editorCommon.EventType.ModelContentChanged, (e:editorCommon.IModelContentChangedEvent) => { + this.listenersToRemove.push(this.editor.addListener2(editorCommon.EventType.ModelContentChanged, (e:editorCommon.IModelContentChangedEvent) => { if (this.isFinished) { return; } @@ -502,7 +502,7 @@ class InsertSnippetController { } })); - this.listenersToRemove.push(this.editor.addListener(editorCommon.EventType.CursorPositionChanged, (e:editorCommon.ICursorPositionChangedEvent) => { + this.listenersToRemove.push(this.editor.addListener2(editorCommon.EventType.CursorPositionChanged, (e:editorCommon.ICursorPositionChangedEvent) => { if (this.isFinished) { return; } @@ -513,19 +513,19 @@ class InsertSnippetController { } })); - this.listenersToRemove.push(this.editor.addListener(editorCommon.EventType.ModelChanged, () => { + this.listenersToRemove.push(this.editor.addListener2(editorCommon.EventType.ModelChanged, () => { this.stopAll(); })); var blurTimeout = -1; - this.listenersToRemove.push(this.editor.addListener(editorCommon.EventType.EditorBlur, () => { + this.listenersToRemove.push(this.editor.addListener2(editorCommon.EventType.EditorBlur, () => { // Blur if within 100ms we do not focus back blurTimeout = setTimeout(() => { this.stopAll(); }, 100); })); - this.listenersToRemove.push(this.editor.addListener(editorCommon.EventType.EditorFocus, () => { + this.listenersToRemove.push(this.editor.addListener2(editorCommon.EventType.EditorFocus, () => { // Cancel the blur timeout (if any) if (blurTimeout !== -1) { clearTimeout(blurTimeout); @@ -533,7 +533,7 @@ class InsertSnippetController { } })); - this.listenersToRemove.push(this.model.addListener(editorCommon.EventType.ModelDecorationsChanged, (e: editorCommon.IModelDecorationsChangedEvent) => { + this.listenersToRemove.push(this.model.addListener2(editorCommon.EventType.ModelDecorationsChanged, (e: editorCommon.IModelDecorationsChangedEvent) => { if (this.isFinished) { return; } @@ -676,10 +676,7 @@ class InsertSnippetController { this.isFinished = true; - this.listenersToRemove.forEach((element) => { - element(); - }); - this.listenersToRemove = []; + this.listenersToRemove = dispose(this.listenersToRemove); for (var i = 0; i < this.trackedPlaceHolders.length; i++) { var ranges = this.trackedPlaceHolders[i].ranges; diff --git a/src/vs/editor/contrib/wordHighlighter/common/wordHighlighter.ts b/src/vs/editor/contrib/wordHighlighter/common/wordHighlighter.ts index 1edf78e99df..f79ad75e933 100644 --- a/src/vs/editor/contrib/wordHighlighter/common/wordHighlighter.ts +++ b/src/vs/editor/contrib/wordHighlighter/common/wordHighlighter.ts @@ -11,6 +11,7 @@ import {Range} from 'vs/editor/common/core/range'; import * as editorCommon from 'vs/editor/common/editorCommon'; import {CommonEditorRegistry} from 'vs/editor/common/editorCommonExtensions'; import {DocumentHighlight, DocumentHighlightKind, DocumentHighlightProviderRegistry} from 'vs/editor/common/modes'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; export function getOccurrencesAtPosition(model: editorCommon.IReadOnlyModel, position: editorCommon.IEditorPosition):TPromise { @@ -48,7 +49,7 @@ class WordHighlighter { private model: editorCommon.IModel; private _lastWordRange: editorCommon.IEditorRange; private _decorationIds: string[]; - private toUnhook: Function[]; + private toUnhook: IDisposable[]; private workerRequestTokenId:number = 0; private workerRequest:TPromise = null; @@ -62,14 +63,14 @@ class WordHighlighter { this.editor = editor; this.model = this.editor.getModel(); this.toUnhook = []; - this.toUnhook.push(editor.addListener(editorCommon.EventType.CursorPositionChanged, (e:editorCommon.ICursorPositionChangedEvent) => { + this.toUnhook.push(editor.addListener2(editorCommon.EventType.CursorPositionChanged, (e:editorCommon.ICursorPositionChangedEvent) => { this._onPositionChanged(e); })); - this.toUnhook.push(editor.addListener(editorCommon.EventType.ModelChanged, (e) => { + this.toUnhook.push(editor.addListener2(editorCommon.EventType.ModelChanged, (e) => { this._stopAll(); this.model = this.editor.getModel(); })); - this.toUnhook.push(editor.addListener('change', (e) => { + this.toUnhook.push(editor.addListener2('change', (e) => { this._stopAll(); })); @@ -265,9 +266,7 @@ class WordHighlighter { public destroy(): void { this._stopAll(); - while(this.toUnhook.length > 0) { - this.toUnhook.pop()(); - } + this.toUnhook = dispose(this.toUnhook); } } diff --git a/src/vs/editor/test/common/controller/cursor.test.ts b/src/vs/editor/test/common/controller/cursor.test.ts index 0221c68b9ea..fe9d121ba2f 100644 --- a/src/vs/editor/test/common/controller/cursor.test.ts +++ b/src/vs/editor/test/common/controller/cursor.test.ts @@ -722,10 +722,10 @@ suite('Editor Controller - Cursor', () => { // --------- eventing test('no move doesn\'t trigger event', () => { - thisCursor.addListener(EventType.CursorPositionChanged, (e) => { + thisCursor.addListener2(EventType.CursorPositionChanged, (e) => { assert.ok(false, 'was not expecting event'); }); - thisCursor.addListener(EventType.CursorSelectionChanged, (e) => { + thisCursor.addListener2(EventType.CursorSelectionChanged, (e) => { assert.ok(false, 'was not expecting event'); }); moveTo(thisCursor, 1, 1); @@ -733,11 +733,11 @@ suite('Editor Controller - Cursor', () => { test('move eventing', () => { let events = 0; - thisCursor.addListener(EventType.CursorPositionChanged, (e) => { + thisCursor.addListener2(EventType.CursorPositionChanged, (e) => { events++; positionEqual(e.position, 1, 2); }); - thisCursor.addListener(EventType.CursorSelectionChanged, (e) => { + thisCursor.addListener2(EventType.CursorSelectionChanged, (e) => { events++; selectionEqual(e.selection, 1, 2, 1, 2); }); @@ -747,11 +747,11 @@ suite('Editor Controller - Cursor', () => { test('move in selection mode eventing', () => { let events = 0; - thisCursor.addListener(EventType.CursorPositionChanged, (e) => { + thisCursor.addListener2(EventType.CursorPositionChanged, (e) => { events++; positionEqual(e.position, 1, 2); }); - thisCursor.addListener(EventType.CursorSelectionChanged, (e) => { + thisCursor.addListener2(EventType.CursorSelectionChanged, (e) => { events++; selectionEqual(e.selection, 1, 2, 1, 1); }); diff --git a/src/vs/editor/test/common/model/editableTextModel.test.ts b/src/vs/editor/test/common/model/editableTextModel.test.ts index 6cbdafa02b7..95e81cd4030 100644 --- a/src/vs/editor/test/common/model/editableTextModel.test.ts +++ b/src/vs/editor/test/common/model/editableTextModel.test.ts @@ -1370,7 +1370,7 @@ suite('EditorModel - EditableTextModel.applyEdits', () => { }, (model) => { var isFirstTime = true; - model.addListener(EventType.ModelContentChanged2, (e:IModelContentChangedEvent2) => { + model.addListener2(EventType.ModelContentChanged2, (e:IModelContentChangedEvent2) => { if (!isFirstTime) { return; } @@ -1393,7 +1393,7 @@ suite('EditorModel - EditableTextModel.applyEdits', () => { let mirrorModel2 = new MirrorModel2(null, model.toRawText().lines, model.toRawText().EOL, model.getVersionId()); let mirrorModel2PrevVersionId = model.getVersionId(); - model.addListener(EventType.ModelContentChanged2, (e:IModelContentChangedEvent2) => { + model.addListener2(EventType.ModelContentChanged2, (e:IModelContentChangedEvent2) => { let versionId = e.versionId; if (versionId < mirrorModel2PrevVersionId) { console.warn('Model version id did not advance between edits (2)'); diff --git a/src/vs/editor/test/common/model/editableTextModelTestUtils.ts b/src/vs/editor/test/common/model/editableTextModelTestUtils.ts index 90c86bab9ce..0a8a5bd0460 100644 --- a/src/vs/editor/test/common/model/editableTextModelTestUtils.ts +++ b/src/vs/editor/test/common/model/editableTextModelTestUtils.ts @@ -51,7 +51,7 @@ export function assertSyncedModels(text:string, callback:(model:EditableTextMod var mirrorModel2 = new MirrorModel2(null, model.toRawText().lines, model.toRawText().EOL, model.getVersionId()); var mirrorModel2PrevVersionId = model.getVersionId(); - model.addListener(editorCommon.EventType.ModelContentChanged, (e:editorCommon.IModelContentChangedEvent) => { + model.addListener2(editorCommon.EventType.ModelContentChanged, (e:editorCommon.IModelContentChangedEvent) => { let versionId = e.versionId; if (versionId < mirrorModel1PrevVersionId) { console.warn('Model version id did not advance between edits (1)'); @@ -63,7 +63,7 @@ export function assertSyncedModels(text:string, callback:(model:EditableTextMod mirrorModel1.onEvents(mirrorModelEvents); }); - model.addListener(editorCommon.EventType.ModelContentChanged2, (e:editorCommon.IModelContentChangedEvent2) => { + model.addListener2(editorCommon.EventType.ModelContentChanged2, (e:editorCommon.IModelContentChangedEvent2) => { let versionId = e.versionId; if (versionId < mirrorModel2PrevVersionId) { console.warn('Model version id did not advance between edits (2)'); diff --git a/src/vs/editor/test/common/model/model.test.ts b/src/vs/editor/test/common/model/model.test.ts index 501b4d97e69..42a39ecbd53 100644 --- a/src/vs/editor/test/common/model/model.test.ts +++ b/src/vs/editor/test/common/model/model.test.ts @@ -109,7 +109,7 @@ suite('Editor Model - Model', () => { // --------- insert text eventing test('model insert empty text does not trigger eventing', () => { - thisModel.addListener(EventType.ModelContentChanged, (e) => { + thisModel.addListener2(EventType.ModelContentChanged, (e) => { assert.ok(false, 'was not expecting event'); }); thisModel.applyEdits([EditOperation.insert(new Position(1, 1), '')]); @@ -117,7 +117,7 @@ suite('Editor Model - Model', () => { test('model insert text without newline eventing', () => { var listenerCalls = 0; - thisModel.addListener(EventType.ModelContentChanged, (e) => { + thisModel.addListener2(EventType.ModelContentChanged, (e) => { listenerCalls++; assert.equal(e.changeType, EventType.ModelContentChangedLineChanged); assert.equal(e.lineNumber, 1); @@ -130,7 +130,7 @@ suite('Editor Model - Model', () => { var listenerCalls = 0; var order = 0; - thisModel.addListener(EventType.ModelContentChanged, (e) => { + thisModel.addListener2(EventType.ModelContentChanged, (e) => { listenerCalls++; if (e.changeType === EventType.ModelContentChangedLineChanged) { @@ -206,7 +206,7 @@ suite('Editor Model - Model', () => { // --------- delete text eventing test('model delete empty text does not trigger eventing', () => { - thisModel.addListener(EventType.ModelContentChanged, (e) => { + thisModel.addListener2(EventType.ModelContentChanged, (e) => { assert.ok(false, 'was not expecting event'); }); thisModel.applyEdits([EditOperation.delete(new Range(1, 1, 1, 1))]); @@ -214,7 +214,7 @@ suite('Editor Model - Model', () => { test('model delete text from one line eventing', () => { var listenerCalls = 0; - thisModel.addListener(EventType.ModelContentChanged, (e) => { + thisModel.addListener2(EventType.ModelContentChanged, (e) => { listenerCalls++; assert.equal(e.changeType, EventType.ModelContentChangedLineChanged); assert.equal(e.lineNumber, 1); @@ -225,7 +225,7 @@ suite('Editor Model - Model', () => { test('model delete all text from a line eventing', () => { var listenerCalls = 0; - thisModel.addListener(EventType.ModelContentChanged, (e) => { + thisModel.addListener2(EventType.ModelContentChanged, (e) => { listenerCalls++; assert.equal(e.changeType, EventType.ModelContentChangedLineChanged); assert.equal(e.lineNumber, 1); @@ -237,7 +237,7 @@ suite('Editor Model - Model', () => { test('model delete text from two lines eventing', () => { var listenerCalls = 0; var order = 0; - thisModel.addListener(EventType.ModelContentChanged, (e) => { + thisModel.addListener2(EventType.ModelContentChanged, (e) => { listenerCalls++; if (e.changeType === EventType.ModelContentChangedLineChanged) { @@ -265,7 +265,7 @@ suite('Editor Model - Model', () => { var listenerCalls = 0; var order = 0; - thisModel.addListener(EventType.ModelContentChanged, (e) => { + thisModel.addListener2(EventType.ModelContentChanged, (e) => { listenerCalls++; if (e.changeType === EventType.ModelContentChangedLineChanged) { diff --git a/src/vs/editor/test/common/model/modelDecorations.test.ts b/src/vs/editor/test/common/model/modelDecorations.test.ts index f3a96344a13..b6dde6fbf63 100644 --- a/src/vs/editor/test/common/model/modelDecorations.test.ts +++ b/src/vs/editor/test/common/model/modelDecorations.test.ts @@ -200,7 +200,7 @@ suite('Editor Model - Model Decorations', () => { test('decorations emit event on add', () => { var listenerCalled = 0; - thisModel.addListener(EventType.ModelDecorationsChanged, (e) => { + thisModel.addListener2(EventType.ModelDecorationsChanged, (e) => { listenerCalled++; assert.equal(e.ids.length, 1); assert.equal(e.addedOrChangedDecorations.length, 1); @@ -219,7 +219,7 @@ suite('Editor Model - Model Decorations', () => { test('decorations emit event on change', () => { var listenerCalled = 0; var decId = addDecoration(thisModel, 1, 2, 3, 2, 'myType'); - thisModel.addListener(EventType.ModelDecorationsChanged, (e) => { + thisModel.addListener2(EventType.ModelDecorationsChanged, (e) => { listenerCalled++; assert.equal(e.ids.length, 1); assert.equal(e.addedOrChangedDecorations.length, 1); @@ -246,7 +246,7 @@ suite('Editor Model - Model Decorations', () => { test('decorations emit event on remove', () => { var listenerCalled = 0; var decId = addDecoration(thisModel, 1, 2, 3, 2, 'myType'); - thisModel.addListener(EventType.ModelDecorationsChanged, (e) => { + thisModel.addListener2(EventType.ModelDecorationsChanged, (e) => { listenerCalled++; assert.equal(e.ids.length, 1); assert.equal(e.addedOrChangedDecorations.length, 0); @@ -269,7 +269,7 @@ suite('Editor Model - Model Decorations', () => { var listenerCalled = 0; var decId = addDecoration(thisModel, 1, 2, 3, 2, 'myType'); - thisModel.addListener(EventType.ModelDecorationsChanged, (e) => { + thisModel.addListener2(EventType.ModelDecorationsChanged, (e) => { listenerCalled++; assert.equal(e.ids.length, 1); assert.equal(e.addedOrChangedDecorations.length, 1); diff --git a/src/vs/editor/test/common/services/resourceService.test.ts b/src/vs/editor/test/common/services/resourceService.test.ts index ea053ffa0a4..44172029950 100644 --- a/src/vs/editor/test/common/services/resourceService.test.ts +++ b/src/vs/editor/test/common/services/resourceService.test.ts @@ -39,11 +39,11 @@ suite('Editor Services - ResourceService', () => { var url = URI.parse('far'); var element = createTestMirrorModelFromString('hi'); var service = new ResourceService(); - service.addListener(ResourceEvents.ADDED, () => { + service.addListener2(ResourceEvents.ADDED, () => { eventCnt++; assert.ok(true); }); - service.addListener(ResourceEvents.REMOVED, () => { + service.addListener2(ResourceEvents.REMOVED, () => { eventCnt++; assert.ok(true); }); diff --git a/src/vs/languages/css/common/services/cssLanguageService.ts b/src/vs/languages/css/common/services/cssLanguageService.ts index 0d920140ba0..99669545561 100644 --- a/src/vs/languages/css/common/services/cssLanguageService.ts +++ b/src/vs/languages/css/common/services/cssLanguageService.ts @@ -10,6 +10,7 @@ import nodes = require('vs/languages/css/common/parser/cssNodes'); import parser = require('vs/languages/css/common/parser/cssParser'); import EditorCommon = require('vs/editor/common/editorCommon'); import resourceService = require('vs/editor/common/services/resourceService'); +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; interface Entry { node:nodes.Stylesheet; @@ -50,7 +51,7 @@ export class CSSLanguageService implements ILanguageService { private entries:{[url:string]:Entry;}; private activeDelay:PromiseWithTrigger; private onChangeHandle:number; - private callOnDispose:Function[]; + private callOnDispose:IDisposable[]; private createParser: () => parser.Parser; constructor(service:resourceService.IResourceService, createParser: () => parser.Parser, private _cssModeId:string) { @@ -60,15 +61,13 @@ export class CSSLanguageService implements ILanguageService { this.createParser = createParser; this.updateResources(); - this.callOnDispose.push(this.resourceService.addListener_(resourceService.ResourceEvents.ADDED, (e: resourceService.IResourceAddedEvent) => this.onResourceAdded(e))); - this.callOnDispose.push(this.resourceService.addListener_(resourceService.ResourceEvents.REMOVED, (e: resourceService.IResourceRemovedEvent) => this.onResourceRemoved(e))); - this.callOnDispose.push(this.resourceService.addListener_(resourceService.ResourceEvents.CHANGED, (e: resourceService.IResourceChangedEvent) => this.onResourceChange(e))); + this.callOnDispose.push(this.resourceService.addListener2_(resourceService.ResourceEvents.ADDED, (e: resourceService.IResourceAddedEvent) => this.onResourceAdded(e))); + this.callOnDispose.push(this.resourceService.addListener2_(resourceService.ResourceEvents.REMOVED, (e: resourceService.IResourceRemovedEvent) => this.onResourceRemoved(e))); + this.callOnDispose.push(this.resourceService.addListener2_(resourceService.ResourceEvents.CHANGED, (e: resourceService.IResourceChangedEvent) => this.onResourceChange(e))); } public dispose():void { - while(this.callOnDispose.length > 0) { - this.callOnDispose.pop()(); - } + this.callOnDispose = dispose(this.callOnDispose); clearTimeout(this.onChangeHandle); this.onChangeHandle = null; this.entries = null; diff --git a/src/vs/languages/json/common/jsonSchemaService.ts b/src/vs/languages/json/common/jsonSchemaService.ts index 8d2a52329ab..4ea938fc81f 100644 --- a/src/vs/languages/json/common/jsonSchemaService.ts +++ b/src/vs/languages/json/common/jsonSchemaService.ts @@ -19,6 +19,7 @@ import {IResourceService, ResourceEvents, IResourceChangedEvent} from 'vs/editor import {IRequestService} from 'vs/platform/request/common/request'; import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace'; import {ISchemaContributions} from 'vs/platform/jsonschemas/common/jsonContributionRegistry'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; export interface IJSONSchemaService { @@ -213,7 +214,7 @@ export class JSONSchemaService implements IJSONSchemaService { private requestService: IRequestService; private contextService : IWorkspaceContextService; - private callOnDispose:Function[]; + private callOnDispose:IDisposable[]; constructor(@IRequestService requestService: IRequestService, @IWorkspaceContextService contextService?: IWorkspaceContextService, @@ -223,7 +224,7 @@ export class JSONSchemaService implements IJSONSchemaService { this.callOnDispose = []; if (resourceService) { - this.callOnDispose.push(resourceService.addListener_(ResourceEvents.CHANGED, (e: IResourceChangedEvent) => this.onResourceChange(e))); + this.callOnDispose.push(resourceService.addListener2_(ResourceEvents.CHANGED, (e: IResourceChangedEvent) => this.onResourceChange(e))); } this.contributionSchemas = {}; @@ -234,9 +235,7 @@ export class JSONSchemaService implements IJSONSchemaService { } public dispose(): void { - while(this.callOnDispose.length > 0) { - this.callOnDispose.pop()(); - } + this.callOnDispose = dispose(this.callOnDispose); } private onResourceChange(e: IResourceChangedEvent): void { diff --git a/src/vs/platform/configuration/common/configurationService.ts b/src/vs/platform/configuration/common/configurationService.ts index 5370b6a8fef..9f3a972bb7f 100644 --- a/src/vs/platform/configuration/common/configurationService.ts +++ b/src/vs/platform/configuration/common/configurationService.ts @@ -78,10 +78,10 @@ export abstract class ConfigurationService implements IConfigurationService, IDi } protected registerListeners(): void { - let unbind = this.eventService.addListener(EventType.FILE_CHANGES, (events) => this.handleFileEvents(events)); + let unbind = this.eventService.addListener2(EventType.FILE_CHANGES, (events) => this.handleFileEvents(events)); let subscription = Registry.as(Extensions.Configuration).onDidRegisterConfiguration(() => this.onDidRegisterConfiguration()); this.callOnDispose = () => { - unbind(); + unbind.dispose(); subscription.dispose(); }; } diff --git a/src/vs/platform/event/common/event.ts b/src/vs/platform/event/common/event.ts index 42930f0aa9b..75a865648d2 100644 --- a/src/vs/platform/event/common/event.ts +++ b/src/vs/platform/event/common/event.ts @@ -13,26 +13,16 @@ export const IEventService = createDecorator('eventService'); export interface IEventService { serviceId: ServiceIdentifier; - /** - * Allows to add a listener to the platform event bus for all emitters that are known to the platform. - */ - addListener(eventType: string, listener: (event: any) => void): () => void; - /** * Allows to add a listener to the platform event bus for all emitters that are known to the platform. */ addListener2(eventType: string, listener: (event: any) => void): IDisposable; - /** - * Allows to add a listener to an emitter on the platform event bus with the given type identifier. - */ - addEmitterTypeListener(eventType: string, emitterType: string, listener: (event: any) => void): () => void; - /** * Allows to add an event emitter to the platform bus such as Events from the emitter * can be received from all listeners on the bus. */ - addEmitter(eventEmitter: IEventEmitter, emitterType?: string): () => void; + addEmitter2(eventEmitter: IEventEmitter, emitterType?: string): IDisposable; /** * Emits an event of the given type into the platform event bus. diff --git a/src/vs/workbench/api/node/extHostFileSystemEventService.ts b/src/vs/workbench/api/node/extHostFileSystemEventService.ts index aba21f14e52..c78706a6d6e 100644 --- a/src/vs/workbench/api/node/extHostFileSystemEventService.ts +++ b/src/vs/workbench/api/node/extHostFileSystemEventService.ts @@ -132,7 +132,7 @@ export class MainThreadFileSystemEventService { events.deleted.length = 0; }, 100); - eventService.addListener('files:fileChanges', (event: FileChangesEvent) => { + eventService.addListener2('files:fileChanges', (event: FileChangesEvent) => { for (let change of event.changes) { switch (change.type) { case FileChangeType.ADDED: diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index 12eaa95e436..877689dba5b 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -131,17 +131,17 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal let startX: number = 0; let startY: number = 0; - this.sashX.addListener('start', (e: ISashEvent) => { + this.sashX.addListener2('start', (e: ISashEvent) => { this.startSidebarWidth = this.sidebarWidth; startX = e.startX; }); - this.sashY.addListener('start', (e: ISashEvent) => { + this.sashY.addListener2('start', (e: ISashEvent) => { this.startPanelHeight = this.panelHeight; startY = e.startY; }); - this.sashX.addListener('change', (e: ISashEvent) => { + this.sashX.addListener2('change', (e: ISashEvent) => { let doLayout = false; let sidebarPosition = this.partService.getSideBarPosition(); let isSidebarHidden = this.partService.isSideBarHidden(); @@ -180,7 +180,7 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal } }); - this.sashY.addListener('change', (e: ISashEvent) => { + this.sashY.addListener2('change', (e: ISashEvent) => { let doLayout = false; let isPanelHidden = this.partService.isPanelHidden(); let newSashHeight = this.startPanelHeight - (e.currentY - startY); @@ -216,22 +216,22 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal } }); - this.sashX.addListener('end', () => { + this.sashX.addListener2('end', () => { this.storageService.store(WorkbenchLayout.sashXWidthSettingsKey, this.sidebarWidth, StorageScope.GLOBAL); }); - this.sashY.addListener('end', () => { + this.sashY.addListener2('end', () => { this.storageService.store(WorkbenchLayout.sashYHeightSettingsKey, this.panelHeight, StorageScope.GLOBAL); }); - this.sashY.addListener('reset', () => { + this.sashY.addListener2('reset', () => { this.panelHeight = DEFAULT_MIN_PANEL_PART_HEIGHT; this.storageService.store(WorkbenchLayout.sashYHeightSettingsKey, this.panelHeight, StorageScope.GLOBAL); this.partService.setPanelHidden(false); this.layout(); }); - this.sashX.addListener('reset', () => { + this.sashX.addListener2('reset', () => { let activeViewlet = this.viewletService.getActiveViewlet(); let optimalWidth = activeViewlet && activeViewlet.getOptimalWidth(); this.sidebarWidth = Math.max(DEFAULT_MIN_PART_WIDTH, optimalWidth || 0); diff --git a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts index 07f3e6f8b48..8900a724e12 100644 --- a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts +++ b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts @@ -56,10 +56,10 @@ export class ActivitybarPart extends Part implements IActivityService { private registerListeners(): void { // Activate viewlet action on opening of a viewlet - this.toUnbind.push(this.eventService.addListener(EventType.COMPOSITE_OPENING, (e: CompositeEvent) => this.onCompositeOpening(e))); + this.toUnbind.push(this.eventService.addListener2(EventType.COMPOSITE_OPENING, (e: CompositeEvent) => this.onCompositeOpening(e))); // Deactivate viewlet action on close - this.toUnbind.push(this.eventService.addListener(EventType.COMPOSITE_CLOSED, (e: CompositeEvent) => this.onCompositeClosed(e))); + this.toUnbind.push(this.eventService.addListener2(EventType.COMPOSITE_CLOSED, (e: CompositeEvent) => this.onCompositeClosed(e))); } private onCompositeOpening(e: CompositeEvent): void { diff --git a/src/vs/workbench/browser/parts/compositePart.ts b/src/vs/workbench/browser/parts/compositePart.ts index 4b49e031cd7..47485b404a3 100644 --- a/src/vs/workbench/browser/parts/compositePart.ts +++ b/src/vs/workbench/browser/parts/compositePart.ts @@ -9,7 +9,7 @@ import timer = require('vs/base/common/timer'); import uuid = require('vs/base/common/uuid'); import {TPromise} from 'vs/base/common/winjs.base'; import {Registry} from 'vs/platform/platform'; -import {IDisposable} from 'vs/base/common/lifecycle'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; import {Dimension, Builder, $} from 'vs/base/browser/builder'; import events = require('vs/base/common/events'); import strings = require('vs/base/common/strings'); @@ -38,8 +38,8 @@ import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry'; import {IKeybindingService} from 'vs/platform/keybinding/common/keybindingService'; export abstract class CompositePart extends Part { - private activeCompositeListeners: { (): void; }[]; - private instantiatedCompositeListeners: { (): void; }[]; + private activeCompositeListeners: IDisposable[]; + private instantiatedCompositeListeners: IDisposable[]; private mapCompositeToCompositeContainer: { [compositeId: string]: Builder; }; private mapActionsBindingToComposite: { [compositeId: string]: () => void; }; private mapProgressServiceToComposite: { [compositeId: string]: IProgressService; }; @@ -181,7 +181,7 @@ export abstract class CompositePart extends Part { this.instantiatedComposits.push(composite); // Register to title area update events from the composite - this.instantiatedCompositeListeners.push(composite.addListener(CompositeEventType.INTERNAL_COMPOSITE_TITLE_AREA_UPDATE, (e) => { this.onTitleAreaUpdate(e); })); + this.instantiatedCompositeListeners.push(composite.addListener2(CompositeEventType.INTERNAL_COMPOSITE_TITLE_AREA_UPDATE, (e) => { this.onTitleAreaUpdate(e); })); // Remove from Promises Cache since Loaded delete this.compositeLoaderPromises[id]; @@ -214,7 +214,7 @@ export abstract class CompositePart extends Part { this.lastActiveCompositeId = this.activeComposite.getId(); // Register as Emitter to Workbench Bus - this.activeCompositeListeners.push(this.eventService.addEmitter(this.activeComposite, this.activeComposite.getId())); + this.activeCompositeListeners.push(this.eventService.addEmitter2(this.activeComposite, this.activeComposite.getId())); let createCompositePromise: TPromise; @@ -405,9 +405,7 @@ export abstract class CompositePart extends Part { this.toolBar.setActions([])(); // Clear Listeners - while (this.activeCompositeListeners.length) { - this.activeCompositeListeners.pop()(); - } + this.activeCompositeListeners = dispose(this.activeCompositeListeners); // Emit Composite Closed Event this.emit(WorkbenchEventType.COMPOSITE_CLOSED, new CompositeEvent(composite.getId())); @@ -512,13 +510,9 @@ export abstract class CompositePart extends Part { this.instantiatedComposits = []; - while (this.activeCompositeListeners.length) { - this.activeCompositeListeners.pop()(); - } + this.activeCompositeListeners = dispose(this.activeCompositeListeners); - while (this.instantiatedCompositeListeners.length) { - this.instantiatedCompositeListeners.pop()(); - } + this.instantiatedCompositeListeners = dispose(this.instantiatedCompositeListeners); this.progressBar.dispose(); this.toolBar.dispose(); diff --git a/src/vs/workbench/browser/parts/editor/binaryDiffEditor.ts b/src/vs/workbench/browser/parts/editor/binaryDiffEditor.ts index c2f2a4eee80..408d290aa9c 100644 --- a/src/vs/workbench/browser/parts/editor/binaryDiffEditor.ts +++ b/src/vs/workbench/browser/parts/editor/binaryDiffEditor.ts @@ -65,10 +65,10 @@ export class BinaryResourceDiffEditor extends BaseEditor implements IVerticalSas // Sash this.sash = new Sash(parent.getHTMLElement(), this); - this.sash.addListener('start', () => this.onSashDragStart()); - this.sash.addListener('change', (e: ISashEvent) => this.onSashDrag(e)); - this.sash.addListener('end', () => this.onSashDragEnd()); - this.sash.addListener('reset', () => this.onSashReset()); + this.sash.addListener2('start', () => this.onSashDragStart()); + this.sash.addListener2('change', (e: ISashEvent) => this.onSashDrag(e)); + this.sash.addListener2('end', () => this.onSashDragEnd()); + this.sash.addListener2('reset', () => this.onSashReset()); // Right Container for Binary let rightBinaryContainerElement = document.createElement('div'); diff --git a/src/vs/workbench/browser/parts/editor/editorPart.ts b/src/vs/workbench/browser/parts/editor/editorPart.ts index 63c00f6f939..5dfbf6091e7 100644 --- a/src/vs/workbench/browser/parts/editor/editorPart.ts +++ b/src/vs/workbench/browser/parts/editor/editorPart.ts @@ -40,6 +40,7 @@ import {ServiceCollection} from 'vs/platform/instantiation/common/serviceCollect import {IMessageService, IMessageWithAction, Severity} from 'vs/platform/message/common/message'; import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry'; import {IProgressService} from 'vs/platform/progress/common/progress'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; const EDITOR_STATE_STORAGE_KEY = 'editorpart.editorState'; @@ -70,9 +71,9 @@ export class EditorPart extends Part implements IEditorPart { // The following data structures are partitioned into array of Position as provided by Services.POSITION array private visibleInputs: EditorInput[]; - private visibleInputListeners: { (): void; }[]; + private visibleInputListeners: IDisposable[]; private visibleEditors: BaseEditor[]; - private visibleEditorListeners: { (): void; }[][]; + private visibleEditorListeners: IDisposable[][]; private instantiatedEditors: BaseEditor[][]; private mapEditorToEditorContainers: { [editorId: string]: Builder; }[]; private mapActionsToEditors: { [editorId: string]: IEditorActions; }[]; @@ -212,13 +213,13 @@ export class EditorPart extends Part implements IEditorPart { // Dispose previous input listener if any if (this.visibleInputListeners[position]) { - this.visibleInputListeners[position](); + this.visibleInputListeners[position].dispose(); this.visibleInputListeners[position] = null; } // Close editor when input provided and input gets disposed if (input) { - this.visibleInputListeners[position] = input.addListener(EventType.DISPOSE, () => { + this.visibleInputListeners[position] = input.addListener2(EventType.DISPOSE, () => { // Keep the inputs to close. We use this to support multiple inputs closing // right after each other and this helps avoid layout issues with the delayed @@ -373,7 +374,7 @@ export class EditorPart extends Part implements IEditorPart { this.visibleEditors[position] = editor; // Register as Emitter to Workbench Bus - this.visibleEditorListeners[position].push(this.eventService.addEmitter(this.visibleEditors[position], this.visibleEditors[position].getId())); + this.visibleEditorListeners[position].push(this.eventService.addEmitter2(this.visibleEditors[position], this.visibleEditors[position].getId())); let createEditorPromise: TPromise; if (newlyCreatedEditorContainerBuilder) { // Editor created for the first time @@ -777,9 +778,7 @@ export class EditorPart extends Part implements IEditorPart { this.sideBySideControl.getProgressBar(position).stop().getContainer().hide(); // Clear Listeners - while (this.visibleEditorListeners[position].length) { - this.visibleEditorListeners[position].pop()(); - } + this.visibleEditorListeners[position] = dispose(this.visibleEditorListeners[position]); // Indicate to Editor editor.clearInput(); @@ -875,7 +874,7 @@ export class EditorPart extends Part implements IEditorPart { // Side by Side Control this.sideBySideControl = this.instantiationService.createInstance(SideBySideEditorControl, contentArea); - this.toUnbind.push(this.sideBySideControl.addListener(SideBySideEventType.EDITOR_FOCUS_CHANGED, () => { this.onEditorFocusChanged(); })); + this.toUnbind.push(this.sideBySideControl.addListener2(SideBySideEventType.EDITOR_FOCUS_CHANGED, () => { this.onEditorFocusChanged(); })); // get settings this.memento = this.getMemento(this.storageService, MementoScope.WORKSPACE); @@ -1090,16 +1089,14 @@ export class EditorPart extends Part implements IEditorPart { // Editor listeners for (let i = 0; i < this.visibleEditorListeners.length; i++) { - while (this.visibleEditorListeners[i].length) { - this.visibleEditorListeners[i].pop()(); - } + this.visibleEditorListeners[i] = dispose(this.visibleEditorListeners[i]); } // Input listeners for (let i = 0; i < this.visibleInputListeners.length; i++) { let listener = this.visibleInputListeners[i]; if (listener) { - listener(); + listener.dispose(); } this.visibleInputListeners = []; diff --git a/src/vs/workbench/browser/parts/editor/sideBySideEditorControl.ts b/src/vs/workbench/browser/parts/editor/sideBySideEditorControl.ts index 536e43becf0..8198c97a732 100644 --- a/src/vs/workbench/browser/parts/editor/sideBySideEditorControl.ts +++ b/src/vs/workbench/browser/parts/editor/sideBySideEditorControl.ts @@ -35,6 +35,7 @@ import {Position, POSITIONS} from 'vs/platform/editor/common/editor'; import {IEventService} from 'vs/platform/event/common/event'; import {IMessageService, Severity} from 'vs/platform/message/common/message'; import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry'; +import {IDisposable} from 'vs/base/common/lifecycle'; export enum Rochade { NONE, @@ -86,7 +87,7 @@ export class SideBySideEditorControl extends EventEmitter implements IVerticalSa private lastActivePosition: Position; private visibleEditorFocusTrackers: DOM.IFocusTracker[]; - private editorInputStateChangeListener: () => void; + private editorInputStateChangeListener: IDisposable; constructor( parent: Builder, @@ -134,7 +135,7 @@ export class SideBySideEditorControl extends EventEmitter implements IVerticalSa private registerListeners(): void { // Update editor input state indicators on state changes - this.editorInputStateChangeListener = this.eventService.addListener(WorkbenchEventType.EDITOR_INPUT_STATE_CHANGED, (event: EditorInputEvent) => { + this.editorInputStateChangeListener = this.eventService.addListener2(WorkbenchEventType.EDITOR_INPUT_STATE_CHANGED, (event: EditorInputEvent) => { this.updateEditorInputStateIndicator(event); }); } @@ -725,10 +726,10 @@ export class SideBySideEditorControl extends EventEmitter implements IVerticalSa // Left Sash this.leftSash = new Sash(parent.getHTMLElement(), this, { baseSize: 5 }); - this.leftSash.addListener('start', () => this.onLeftSashDragStart()); - this.leftSash.addListener('change', (e: ISashEvent) => this.onLeftSashDrag(e)); - this.leftSash.addListener('end', () => this.onLeftSashDragEnd()); - this.leftSash.addListener('reset', () => this.onLeftSashReset()); + this.leftSash.addListener2('start', () => this.onLeftSashDragStart()); + this.leftSash.addListener2('change', (e: ISashEvent) => this.onLeftSashDrag(e)); + this.leftSash.addListener2('end', () => this.onLeftSashDragEnd()); + this.leftSash.addListener2('reset', () => this.onLeftSashReset()); this.leftSash.hide(); // Center Container @@ -736,10 +737,10 @@ export class SideBySideEditorControl extends EventEmitter implements IVerticalSa // Right Sash this.rightSash = new Sash(parent.getHTMLElement(), this, { baseSize: 5 }); - this.rightSash.addListener('start', () => this.onRightSashDragStart()); - this.rightSash.addListener('change', (e: ISashEvent) => this.onRightSashDrag(e)); - this.rightSash.addListener('end', () => this.onRightSashDragEnd()); - this.rightSash.addListener('reset', () => this.onRightSashReset()); + this.rightSash.addListener2('start', () => this.onRightSashDragStart()); + this.rightSash.addListener2('change', (e: ISashEvent) => this.onRightSashDrag(e)); + this.rightSash.addListener2('end', () => this.onRightSashDragEnd()); + this.rightSash.addListener2('reset', () => this.onRightSashReset()); this.rightSash.hide(); // Right Container @@ -1044,7 +1045,7 @@ export class SideBySideEditorControl extends EventEmitter implements IVerticalSa }); // Action Run Handling - this.editorActionsToolbar[position].actionRunner.addListener(BaseEventType.RUN, (e: any) => { + this.editorActionsToolbar[position].actionRunner.addListener2(BaseEventType.RUN, (e: any) => { // Check for Error if (e.error && !errors.isPromiseCanceledError(e.error)) { @@ -1560,7 +1561,7 @@ export class SideBySideEditorControl extends EventEmitter implements IVerticalSa }); if (this.editorInputStateChangeListener) { - this.editorInputStateChangeListener(); + this.editorInputStateChangeListener.dispose(); } this.lastActiveEditor = null; diff --git a/src/vs/workbench/browser/parts/editor/stringEditor.ts b/src/vs/workbench/browser/parts/editor/stringEditor.ts index b30d47755ab..1812f99ac25 100644 --- a/src/vs/workbench/browser/parts/editor/stringEditor.ts +++ b/src/vs/workbench/browser/parts/editor/stringEditor.ts @@ -51,7 +51,7 @@ export class StringEditor extends BaseTextEditor { this.mapResourceToEditorViewState = Object.create(null); - this.toUnbind.push(this.eventService.addListener(EventType.UNTITLED_FILE_DELETED, (e: UntitledEditorEvent) => this.onUntitledDeletedEvent(e))); + this.toUnbind.push(this.eventService.addListener2(EventType.UNTITLED_FILE_DELETED, (e: UntitledEditorEvent) => this.onUntitledDeletedEvent(e))); } private onUntitledDeletedEvent(e: UntitledEditorEvent): void { diff --git a/src/vs/workbench/browser/parts/editor/textDiffEditor.ts b/src/vs/workbench/browser/parts/editor/textDiffEditor.ts index ea9f6fd7d4d..e08811c8036 100644 --- a/src/vs/workbench/browser/parts/editor/textDiffEditor.ts +++ b/src/vs/workbench/browser/parts/editor/textDiffEditor.ts @@ -169,7 +169,7 @@ export class TextDiffEditor extends BaseTextEditor { this.diffNavigator = new DiffNavigator(diffEditor, { alwaysRevealFirst: autoRevealFirstChange }); - this.diffNavigator.addListener(DiffNavigator.Events.UPDATED, () => { + this.diffNavigator.addListener2(DiffNavigator.Events.UPDATED, () => { this.nextDiffAction.updateEnablement(); this.previousDiffAction.updateEnablement(); }); diff --git a/src/vs/workbench/browser/parts/editor/textEditor.ts b/src/vs/workbench/browser/parts/editor/textEditor.ts index 02e670f488d..3cd5bafbec5 100644 --- a/src/vs/workbench/browser/parts/editor/textEditor.ts +++ b/src/vs/workbench/browser/parts/editor/textEditor.ts @@ -54,10 +54,10 @@ export abstract class BaseTextEditor extends BaseEditor { ) { super(id, telemetryService); - this.toUnbind.push(this._eventService.addListener(WorkbenchEventType.WORKBENCH_OPTIONS_CHANGED, (e) => this.onOptionsChanged(e))); - this.toUnbind.push(this.configurationService.onDidUpdateConfiguration(e => this.applyConfiguration(e.config)).dispose); + this.toUnbind.push(this._eventService.addListener2(WorkbenchEventType.WORKBENCH_OPTIONS_CHANGED, (e) => this.onOptionsChanged(e))); + this.toUnbind.push(this.configurationService.onDidUpdateConfiguration(e => this.applyConfiguration(e.config))); - this.toUnbind.push(_themeService.onDidThemeChange(_ => this.onThemeChanged()).dispose); + this.toUnbind.push(_themeService.onDidThemeChange(_ => this.onThemeChanged())); } public get instantiationService(): IInstantiationService { @@ -133,28 +133,28 @@ export abstract class BaseTextEditor extends BaseEditor { this.editorControl = this.createEditorControl(parent); // Hook Listener for Selection changes - this.toUnbind.push(this.editorControl.addListener(EventType.CursorPositionChanged, (event: ICursorPositionChangedEvent) => { + this.toUnbind.push(this.editorControl.addListener2(EventType.CursorPositionChanged, (event: ICursorPositionChangedEvent) => { let selection = this.editorControl.getSelection(); this.eventService.emit(WorkbenchEventType.TEXT_EDITOR_SELECTION_CHANGED, new TextEditorSelectionEvent(selection, this, this.getId(), this.input, null, this.position, event)); })); // Hook Listener for mode changes - this.toUnbind.push(this.editorControl.addListener(EventType.ModelModeChanged, (event: IModelModeChangedEvent) => { + this.toUnbind.push(this.editorControl.addListener2(EventType.ModelModeChanged, (event: IModelModeChangedEvent) => { this.eventService.emit(WorkbenchEventType.TEXT_EDITOR_MODE_CHANGED, new EditorEvent(this, this.getId(), this.input, null, this.position, event)); })); // Hook Listener for content changes - this.toUnbind.push(this.editorControl.addListener(EventType.ModelContentChanged, (event: IModelContentChangedEvent) => { + this.toUnbind.push(this.editorControl.addListener2(EventType.ModelContentChanged, (event: IModelContentChangedEvent) => { this.eventService.emit(WorkbenchEventType.TEXT_EDITOR_CONTENT_CHANGED, new EditorEvent(this, this.getId(), this.input, null, this.position, event)); })); // Hook Listener for content options changes - this.toUnbind.push(this.editorControl.addListener(EventType.ModelOptionsChanged, (event: IModelOptionsChangedEvent) => { + this.toUnbind.push(this.editorControl.addListener2(EventType.ModelOptionsChanged, (event: IModelOptionsChangedEvent) => { this.eventService.emit(WorkbenchEventType.TEXT_EDITOR_CONTENT_OPTIONS_CHANGED, new EditorEvent(this, this.getId(), this.input, null, this.position, event)); })); // Hook Listener for options changes - this.toUnbind.push(this.editorControl.addListener(EventType.ConfigurationChanged, (event: IConfigurationChangedEvent) => { + this.toUnbind.push(this.editorControl.addListener2(EventType.ConfigurationChanged, (event: IConfigurationChangedEvent) => { this.eventService.emit(WorkbenchEventType.TEXT_EDITOR_CONFIGURATION_CHANGED, new EditorEvent(this, this.getId(), this.input, null, this.position, event)); })); diff --git a/src/vs/workbench/browser/parts/quickopen/editorHistoryModel.ts b/src/vs/workbench/browser/parts/quickopen/editorHistoryModel.ts index 0af1dcad780..62e12c4ec60 100644 --- a/src/vs/workbench/browser/parts/quickopen/editorHistoryModel.ts +++ b/src/vs/workbench/browser/parts/quickopen/editorHistoryModel.ts @@ -125,9 +125,9 @@ export class EditorHistoryModel extends QuickOpenModel { } // Remove on Dispose - let unbind = entry.addListener(EventType.DISPOSE, () => { + let unbind = entry.addListener2(EventType.DISPOSE, () => { this.remove(entry); - unbind(); + unbind.dispose(); }); // Remove any existing entry and add to the beginning @@ -206,7 +206,7 @@ export class EditorHistoryModel extends QuickOpenModel { public getResults(searchValue: string): QuickOpenEntry[] { searchValue = searchValue.replace(/ /g, ''); // get rid of all whitespace - + const searchInPath = searchValue.indexOf(paths.nativeSep) >= 0; let results: QuickOpenEntry[] = []; diff --git a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts index 88c29e93239..9b0f46c58de 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts @@ -124,8 +124,8 @@ export class QuickOpenController extends WorkbenchComponent implements IQuickOpe public create(): void { // Listen on Editor Input Changes to show in MRU List - this.toUnbind.push(this.eventService.addListener(EventType.EDITOR_INPUT_CHANGING, (e: EditorEvent) => this.onEditorInputChanging(e))); - this.toUnbind.push(this.eventService.addListener(EventType.EDITOR_SET_INPUT_ERROR, (e: EditorEvent) => this.onEditorInputSetError(e))); + this.toUnbind.push(this.eventService.addListener2(EventType.EDITOR_INPUT_CHANGING, (e: EditorEvent) => this.onEditorInputChanging(e))); + this.toUnbind.push(this.eventService.addListener2(EventType.EDITOR_SET_INPUT_ERROR, (e: EditorEvent) => this.onEditorInputSetError(e))); // Editor History Model this.editorHistoryModel = new EditorHistoryModel(this.editorService, this.instantiationService, this.contextService); diff --git a/src/vs/workbench/browser/viewlet.ts b/src/vs/workbench/browser/viewlet.ts index a19eb252126..795dd1553a1 100644 --- a/src/vs/workbench/browser/viewlet.ts +++ b/src/vs/workbench/browser/viewlet.ts @@ -51,8 +51,8 @@ export abstract class ViewerViewlet extends Viewlet { this.viewer = this.createViewer(this.viewerContainer); // Eventing - this.toUnbind.push(this.viewer.addListener('selection', (e: ISelectionEvent) => this.onSelection(e))); - this.toUnbind.push(this.viewer.addListener('focus', (e: IFocusEvent) => this.onFocus(e))); + this.toUnbind.push(this.viewer.addListener2('selection', (e: ISelectionEvent) => this.onSelection(e))); + this.toUnbind.push(this.viewer.addListener2('focus', (e: IFocusEvent) => this.onFocus(e))); return TPromise.as(null); } diff --git a/src/vs/workbench/browser/workbench.ts b/src/vs/workbench/browser/workbench.ts index a1301c08d84..dcaeae42269 100644 --- a/src/vs/workbench/browser/workbench.ts +++ b/src/vs/workbench/browser/workbench.ts @@ -618,14 +618,14 @@ export class Workbench implements IPartService { } private hookPartListeners(part: Part): void { - this.toDispose.push(this.toDisposable(this.eventService.addEmitter(part, part.getId()))); + this.toDispose.push(this.eventService.addEmitter2(part, part.getId())); } private registerListeners(): void { // Listen to editor changes - this.toDispose.push(this.toDisposable(this.eventService.addListener(EventType.EDITOR_CLOSED, () => this.onEditorOpenedOrClosed()))); - this.toDispose.push(this.toDisposable(this.eventService.addListener(EventType.EDITOR_OPENED, () => this.onEditorOpenedOrClosed()))); + this.toDispose.push(this.eventService.addListener2(EventType.EDITOR_CLOSED, () => this.onEditorOpenedOrClosed())); + this.toDispose.push(this.eventService.addListener2(EventType.EDITOR_OPENED, () => this.onEditorOpenedOrClosed())); // Handle message service and quick open events if (this.messageService instanceof WorkbenchMessageService) { @@ -652,14 +652,6 @@ export class Workbench implements IPartService { } } - private toDisposable(fn: () => void): IDisposable { - return { - dispose: function () { - fn(); - } - }; - } - private createWorkbenchLayout(): void { let options = new LayoutOptions(); options.setMargin(new Box(0, 0, 0, 0)); diff --git a/src/vs/workbench/common/component.ts b/src/vs/workbench/common/component.ts index e9f660903f6..691a5302656 100644 --- a/src/vs/workbench/common/component.ts +++ b/src/vs/workbench/common/component.ts @@ -5,7 +5,7 @@ 'use strict'; import {EventEmitter, IEventEmitter} from 'vs/base/common/eventEmitter'; -import {IDisposable} from 'vs/base/common/lifecycle'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; import {Scope, Memento} from 'vs/workbench/common/memento'; import {IStorageService} from 'vs/platform/storage/common/storage'; @@ -56,7 +56,7 @@ export interface IWorkbenchComponent extends IDisposable, IEventEmitter { } export class WorkbenchComponent extends EventEmitter implements IWorkbenchComponent { - private _toUnbind: { (): void; }[]; + private _toUnbind: IDisposable[]; private id: string; private componentMemento: Memento; @@ -91,9 +91,7 @@ export class WorkbenchComponent extends EventEmitter implements IWorkbenchCompon } public dispose(): void { - while (this._toUnbind.length) { - this._toUnbind.pop()(); - } + this._toUnbind = dispose(this._toUnbind); super.dispose(); } diff --git a/src/vs/workbench/common/editor/diffEditorInput.ts b/src/vs/workbench/common/editor/diffEditorInput.ts index 69e236f12c9..b1e3310e8df 100644 --- a/src/vs/workbench/common/editor/diffEditorInput.ts +++ b/src/vs/workbench/common/editor/diffEditorInput.ts @@ -15,6 +15,7 @@ import {EditorModel, IFileEditorInput, EditorInput, IInputStatus, BaseDiffEditor import {BaseTextEditorModel} from 'vs/workbench/common/editor/textEditorModel'; import {DiffEditorModel} from 'vs/workbench/common/editor/diffEditorModel'; import {TextDiffEditorModel} from 'vs/workbench/common/editor/textDiffEditorModel'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; /** * The base editor input for the diff editor. It is made up of two editor inputs, the original version @@ -24,7 +25,7 @@ export class DiffEditorInput extends BaseDiffEditorInput { public static ID = 'workbench.editors.diffEditorInput'; - private _toUnbind: { (): void; }[]; + private _toUnbind: IDisposable[]; private name: string; private description: string; private cachedModel: DiffEditorModel; @@ -45,13 +46,13 @@ export class DiffEditorInput extends BaseDiffEditorInput { private registerListeners(): void { // When the original or modified input gets disposed, dispose this diff editor input - this._toUnbind.push(this.originalInput.addListener(EventType.DISPOSE, () => { + this._toUnbind.push(this.originalInput.addListener2(EventType.DISPOSE, () => { if (!this.isDisposed()) { this.dispose(); } })); - this._toUnbind.push(this.modifiedInput.addListener(EventType.DISPOSE, () => { + this._toUnbind.push(this.modifiedInput.addListener2(EventType.DISPOSE, () => { if (!this.isDisposed()) { this.dispose(); } @@ -187,9 +188,7 @@ export class DiffEditorInput extends BaseDiffEditorInput { } public dispose(): void { - while (this._toUnbind.length) { - this._toUnbind.pop()(); - } + this._toUnbind = dispose(this._toUnbind); // Dispose Model if (this.cachedModel) { diff --git a/src/vs/workbench/common/editor/resourceEditorInput.ts b/src/vs/workbench/common/editor/resourceEditorInput.ts index 9c687ef8587..01314f3e445 100644 --- a/src/vs/workbench/common/editor/resourceEditorInput.ts +++ b/src/vs/workbench/common/editor/resourceEditorInput.ts @@ -155,9 +155,9 @@ export class ResourceEditorInput extends EditorInput { // Otherwise Create Model and handle dispose event return ResourceEditorInput.getOrCreateModel(this.modelService, this.resource).then(() => { let model = this.instantiationService.createInstance(ResourceEditorModel, this.resource); - const unbind = model.addListener(EventType.DISPOSE, () => { + const unbind = model.addListener2(EventType.DISPOSE, () => { this.cachedModel = null; // make sure we do not dispose model again - unbind(); + unbind.dispose(); this.dispose(); }); diff --git a/src/vs/workbench/common/editor/textEditorModel.ts b/src/vs/workbench/common/editor/textEditorModel.ts index cd4a43613be..00b2d8827e8 100644 --- a/src/vs/workbench/common/editor/textEditorModel.ts +++ b/src/vs/workbench/common/editor/textEditorModel.ts @@ -40,9 +40,9 @@ export abstract class BaseTextEditorModel extends EditorModel implements ITextEd // Since we did not create the model, we need to listen to it disposing // and properly trigger our dispose function so that events get emitted - const unbind = model.addListener(EventType.ModelDispose, () => { + const unbind = model.addListener2(EventType.ModelDispose, () => { this.textEditorModelHandle = null; // make sure we do not dispose code editor model again - unbind(); + unbind.dispose(); this.dispose(); }); } diff --git a/src/vs/workbench/common/editor/untitledEditorModel.ts b/src/vs/workbench/common/editor/untitledEditorModel.ts index a5a59833004..ad427541811 100644 --- a/src/vs/workbench/common/editor/untitledEditorModel.ts +++ b/src/vs/workbench/common/editor/untitledEditorModel.ts @@ -18,7 +18,7 @@ import {IModeService} from 'vs/editor/common/services/modeService'; import {IModelService} from 'vs/editor/common/services/modelService'; export class UntitledEditorModel extends StringEditorModel implements IEncodingSupport { - private textModelChangeListener: () => void; + private textModelChangeListener: IDisposable; private configurationChangeListener: IDisposable; private dirty: boolean; @@ -94,7 +94,7 @@ export class UntitledEditorModel extends StringEditorModel implements IEncodingS this.configuredEncoding = configuration && configuration.files && configuration.files.encoding; // Listen to content changes - this.textModelChangeListener = this.textEditorModel.addListener(EventType.ModelContentChanged, (e: IModelContentChangedEvent) => this.onModelContentChanged(e)); + this.textModelChangeListener = this.textEditorModel.addListener2(EventType.ModelContentChanged, (e: IModelContentChangedEvent) => this.onModelContentChanged(e)); // Emit initial dirty event if we are if (this.dirty) { @@ -118,7 +118,7 @@ export class UntitledEditorModel extends StringEditorModel implements IEncodingS super.dispose(); if (this.textModelChangeListener) { - this.textModelChangeListener(); + this.textModelChangeListener.dispose(); this.textModelChangeListener = null; } diff --git a/src/vs/workbench/electron-browser/window.ts b/src/vs/workbench/electron-browser/window.ts index d37937887d0..9dfe97c57c9 100644 --- a/src/vs/workbench/electron-browser/window.ts +++ b/src/vs/workbench/electron-browser/window.ts @@ -52,7 +52,7 @@ export class ElectronWindow { // React to editor input changes (Mac only) if (platform.platform === platform.Platform.Mac) { - this.eventService.addListener(EventType.EDITOR_INPUT_CHANGED, (e: EditorEvent) => { + this.eventService.addListener2(EventType.EDITOR_INPUT_CHANGED, (e: EditorEvent) => { let fileInput = workbenchEditorCommon.asFileEditorInput(e.editorInput, true); let representedFilename = ''; if (fileInput) { diff --git a/src/vs/workbench/parts/files/browser/editors/textFileEditor.ts b/src/vs/workbench/parts/files/browser/editors/textFileEditor.ts index cfaaba453b2..3c093b5f0e8 100644 --- a/src/vs/workbench/parts/files/browser/editors/textFileEditor.ts +++ b/src/vs/workbench/parts/files/browser/editors/textFileEditor.ts @@ -64,7 +64,7 @@ export class TextFileEditor extends BaseTextEditor { TextFileEditorModel.setSaveErrorHandler(instantiationService.createInstance(SaveErrorHandler)); // Clear view state for deleted files - this.toUnbind.push(this.eventService.addListener(EventType.FILE_CHANGES, (e: FileChangesEvent) => this.onFilesChanged(e))); + this.toUnbind.push(this.eventService.addListener2(EventType.FILE_CHANGES, (e: FileChangesEvent) => this.onFilesChanged(e))); } private onFilesChanged(e: FileChangesEvent): void { diff --git a/src/vs/workbench/parts/files/browser/fileActions.ts b/src/vs/workbench/parts/files/browser/fileActions.ts index e7f9d78b743..71bdb7400f0 100644 --- a/src/vs/workbench/parts/files/browser/fileActions.ts +++ b/src/vs/workbench/parts/files/browser/fileActions.ts @@ -66,7 +66,7 @@ export interface IFileViewletState { export class BaseFileAction extends Action { private _element: FileStat; - private listenerToUnbind: () => void; + private listenerToUnbind: IDisposable; constructor( id: string, @@ -83,7 +83,7 @@ export class BaseFileAction extends Action { this.enabled = false; // update enablement when options change - this.listenerToUnbind = this._eventService.addListener(WorkbenchEventType.WORKBENCH_OPTIONS_CHANGED, () => this._updateEnablement()); + this.listenerToUnbind = this._eventService.addListener2(WorkbenchEventType.WORKBENCH_OPTIONS_CHANGED, () => this._updateEnablement()); } public get contextService() { @@ -170,7 +170,7 @@ export class BaseFileAction extends Action { } public dispose(): void { - this.listenerToUnbind(); + this.listenerToUnbind.dispose(); super.dispose(); } @@ -241,11 +241,11 @@ export class TriggerRenameFileAction extends BaseFileAction { this.tree.refresh(stat, false).then(() => { this.tree.setHighlight(stat); - let unbind = this.tree.addListener(CommonEventType.HIGHLIGHT, (e: IHighlightEvent) => { + let unbind = this.tree.addListener2(CommonEventType.HIGHLIGHT, (e: IHighlightEvent) => { if (!e.highlight) { viewletState.clearEditable(stat); this.tree.refresh(stat).done(null, errors.onUnexpectedError); - unbind(); + unbind.dispose(); } }); }).done(null, errors.onUnexpectedError); @@ -453,11 +453,11 @@ export class BaseNewAction extends BaseFileAction { return this.tree.reveal(stat, 0.5).then(() => { this.tree.setHighlight(stat); - let unbind: () => void = this.tree.addListener(CommonEventType.HIGHLIGHT, (e: IHighlightEvent) => { + let unbind = this.tree.addListener2(CommonEventType.HIGHLIGHT, (e: IHighlightEvent) => { if (!e.highlight) { stat.destroy(); this.tree.refresh(folder).done(null, errors.onUnexpectedError); - unbind(); + unbind.dispose(); } }); }); @@ -1237,8 +1237,8 @@ export class GlobalCompareResourcesAction extends Action { globalResourceToCompare = fileInput.getResource(); // Listen for next editor to open - let unbind = this.eventService.addListener(WorkbenchEventType.EDITOR_INPUT_OPENING, (e: EditorEvent) => { - unbind(); // listen once + let unbind = this.eventService.addListener2(WorkbenchEventType.EDITOR_INPUT_OPENING, (e: EditorEvent) => { + unbind.dispose(); // listen once let otherFileInput = asFileEditorInput(e.editorInput); if (otherFileInput) { @@ -1255,7 +1255,7 @@ export class GlobalCompareResourcesAction extends Action { // Bring up quick open this.quickOpenService.show().then(() => { - unbind(); // make sure to unbind if quick open is closing + unbind.dispose(); // make sure to unbind if quick open is closing }); } else { diff --git a/src/vs/workbench/parts/files/browser/fileTracker.ts b/src/vs/workbench/parts/files/browser/fileTracker.ts index 33587ba1ef4..dc518d67491 100644 --- a/src/vs/workbench/parts/files/browser/fileTracker.ts +++ b/src/vs/workbench/parts/files/browser/fileTracker.ts @@ -28,6 +28,7 @@ import {IActivityService, NumberBadge} from 'vs/workbench/services/activity/comm import {IEditorInput} from 'vs/platform/editor/common/editor'; import {IEventService} from 'vs/platform/event/common/event'; import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; // This extension tracks files for changes to update editors and inputs accordingly. export class FileTracker implements IWorkbenchContribution { @@ -39,7 +40,7 @@ export class FileTracker implements IWorkbenchContribution { private lastDirtyCount: number; private workingFiles: IWorkingFilesModel; - private toUnbind: { (): void; }[]; + private toUnbind: IDisposable[]; constructor( @IEventService private eventService: IEventService, @@ -63,18 +64,18 @@ export class FileTracker implements IWorkbenchContribution { private registerListeners(): void { // Update editors and inputs from local changes and saves - this.toUnbind.push(this.eventService.addListener(WorkbenchEventType.EDITOR_INPUT_CHANGED, (e: EditorInputEvent) => this.onEditorInputChanged(e))); - this.toUnbind.push(this.eventService.addListener(WorkbenchEventType.UNTITLED_FILE_DELETED, (e: UntitledEditorEvent) => this.onUntitledEditorDeleted(e))); - this.toUnbind.push(this.eventService.addListener(WorkbenchEventType.UNTITLED_FILE_DIRTY, (e: UntitledEditorEvent) => this.onUntitledEditorDirty(e))); - this.toUnbind.push(this.eventService.addListener(FileEventType.FILE_DIRTY, (e: TextFileChangeEvent) => this.onTextFileDirty(e))); - this.toUnbind.push(this.eventService.addListener(FileEventType.FILE_SAVING, (e: TextFileChangeEvent) => this.onTextFileSaving(e))); - this.toUnbind.push(this.eventService.addListener(FileEventType.FILE_SAVE_ERROR, (e: TextFileChangeEvent) => this.onTextFileSaveError(e))); - this.toUnbind.push(this.eventService.addListener(FileEventType.FILE_SAVED, (e: TextFileChangeEvent) => this.onTextFileSaved(e))); - this.toUnbind.push(this.eventService.addListener(FileEventType.FILE_REVERTED, (e: TextFileChangeEvent) => this.onTextFileReverted(e))); - this.toUnbind.push(this.eventService.addListener('files.internal:fileChanged', (e: LocalFileChangeEvent) => this.onLocalFileChange(e))); + this.toUnbind.push(this.eventService.addListener2(WorkbenchEventType.EDITOR_INPUT_CHANGED, (e: EditorInputEvent) => this.onEditorInputChanged(e))); + this.toUnbind.push(this.eventService.addListener2(WorkbenchEventType.UNTITLED_FILE_DELETED, (e: UntitledEditorEvent) => this.onUntitledEditorDeleted(e))); + this.toUnbind.push(this.eventService.addListener2(WorkbenchEventType.UNTITLED_FILE_DIRTY, (e: UntitledEditorEvent) => this.onUntitledEditorDirty(e))); + this.toUnbind.push(this.eventService.addListener2(FileEventType.FILE_DIRTY, (e: TextFileChangeEvent) => this.onTextFileDirty(e))); + this.toUnbind.push(this.eventService.addListener2(FileEventType.FILE_SAVING, (e: TextFileChangeEvent) => this.onTextFileSaving(e))); + this.toUnbind.push(this.eventService.addListener2(FileEventType.FILE_SAVE_ERROR, (e: TextFileChangeEvent) => this.onTextFileSaveError(e))); + this.toUnbind.push(this.eventService.addListener2(FileEventType.FILE_SAVED, (e: TextFileChangeEvent) => this.onTextFileSaved(e))); + this.toUnbind.push(this.eventService.addListener2(FileEventType.FILE_REVERTED, (e: TextFileChangeEvent) => this.onTextFileReverted(e))); + this.toUnbind.push(this.eventService.addListener2('files.internal:fileChanged', (e: LocalFileChangeEvent) => this.onLocalFileChange(e))); // Update editors and inputs from disk changes - this.toUnbind.push(this.eventService.addListener(CommonFileEventType.FILE_CHANGES, (e: FileChangesEvent) => this.onFileChanges(e))); + this.toUnbind.push(this.eventService.addListener2(CommonFileEventType.FILE_CHANGES, (e: FileChangesEvent) => this.onFileChanges(e))); } private onEditorInputChanged(e: EditorInputEvent): void { @@ -514,8 +515,6 @@ export class FileTracker implements IWorkbenchContribution { } public dispose(): void { - while (this.toUnbind.length) { - this.toUnbind.pop()(); - } + this.toUnbind = dispose(this.toUnbind); } } \ No newline at end of file diff --git a/src/vs/workbench/parts/files/browser/saveErrorHandler.ts b/src/vs/workbench/parts/files/browser/saveErrorHandler.ts index d711d10fcee..066015be350 100644 --- a/src/vs/workbench/parts/files/browser/saveErrorHandler.ts +++ b/src/vs/workbench/parts/files/browser/saveErrorHandler.ts @@ -44,8 +44,8 @@ export class SaveErrorHandler implements ISaveErrorHandler { } private registerListeners(): void { - this.eventService.addListener(FileEventType.FILE_SAVED, (e: TextFileChangeEvent) => this.onFileSavedOrReverted(e.resource)); - this.eventService.addListener(FileEventType.FILE_REVERTED, (e: TextFileChangeEvent) => this.onFileSavedOrReverted(e.resource)); + this.eventService.addListener2(FileEventType.FILE_SAVED, (e: TextFileChangeEvent) => this.onFileSavedOrReverted(e.resource)); + this.eventService.addListener2(FileEventType.FILE_REVERTED, (e: TextFileChangeEvent) => this.onFileSavedOrReverted(e.resource)); } private onFileSavedOrReverted(resource: URI): void { diff --git a/src/vs/workbench/parts/files/browser/textFileServices.ts b/src/vs/workbench/parts/files/browser/textFileServices.ts index 479167cd06b..e169000cb3d 100644 --- a/src/vs/workbench/parts/files/browser/textFileServices.ts +++ b/src/vs/workbench/parts/files/browser/textFileServices.ts @@ -7,7 +7,6 @@ import {TPromise} from 'vs/base/common/winjs.base'; import URI from 'vs/base/common/uri'; import errors = require('vs/base/common/errors'); -import {ListenerUnbind} from 'vs/base/common/eventEmitter'; import Event, {Emitter} from 'vs/base/common/event'; import {FileEditorInput} from 'vs/workbench/parts/files/browser/editors/fileEditorInput'; import {CACHE, TextFileEditorModel} from 'vs/workbench/parts/files/common/editors/textFileEditorModel'; @@ -20,6 +19,7 @@ import {IInstantiationService} from 'vs/platform/instantiation/common/instantiat import {IEventService} from 'vs/platform/event/common/event'; import {IConfigurationService} from 'vs/platform/configuration/common/configuration'; import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; /** * The workbench file service implementation implements the raw file service spec and adds additional methods on top. @@ -30,7 +30,7 @@ export abstract class TextFileService implements ITextFileService { public serviceId = ITextFileService; - private listenerToUnbind: ListenerUnbind[]; + private listenerToUnbind: IDisposable[]; private _workingFilesModel: WorkingFilesModel; private _onAutoSaveConfigurationChange: Emitter; @@ -74,11 +74,11 @@ export abstract class TextFileService implements ITextFileService { protected registerListeners(): void { // Configuration changes - this.listenerToUnbind.push(this.configurationService.onDidUpdateConfiguration(e => this.onConfigurationChange(e.config)).dispose); + this.listenerToUnbind.push(this.configurationService.onDidUpdateConfiguration(e => this.onConfigurationChange(e.config))); // Editor focus change window.addEventListener('blur', () => this.onEditorFocusChange(), true); - this.listenerToUnbind.push(this.eventService.addListener(EventType.EDITOR_INPUT_CHANGED, () => this.onEditorFocusChange())); + this.listenerToUnbind.push(this.eventService.addListener2(EventType.EDITOR_INPUT_CHANGED, () => this.onEditorFocusChange())); } private onEditorFocusChange(): void { @@ -250,9 +250,7 @@ export abstract class TextFileService implements ITextFileService { } public dispose(): void { - while (this.listenerToUnbind.length) { - this.listenerToUnbind.pop()(); - } + this.listenerToUnbind = dispose(this.listenerToUnbind); this.workingFilesModel.dispose(); diff --git a/src/vs/workbench/parts/files/common/editors/textFileEditorModel.ts b/src/vs/workbench/parts/files/common/editors/textFileEditorModel.ts index c938f162646..5a2ad8fadeb 100644 --- a/src/vs/workbench/parts/files/common/editors/textFileEditorModel.ts +++ b/src/vs/workbench/parts/files/common/editors/textFileEditorModel.ts @@ -77,7 +77,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements IEncodin private resource: URI; private contentEncoding: string; // encoding as reported from disk private preferredEncoding: string; // encoding as chosen by the user - private textModelChangeListener: () => void; + private textModelChangeListener: IDisposable; private textFileServiceListener: IDisposable; private dirty: boolean; private versionId: number; @@ -283,7 +283,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements IEncodin this.createTextEditorModelPromise = null; this.setDirty(false); // Ensure we are not tracking a stale state - this.textModelChangeListener = this.textEditorModel.addListener(EditorEventType.ModelContentChanged, (e: IModelContentChangedEvent) => this.onModelContentChanged(e)); + this.textModelChangeListener = this.textEditorModel.addListener2(EditorEventType.ModelContentChanged, (e: IModelContentChangedEvent) => this.onModelContentChanged(e)); return this; }, (error) => { @@ -723,7 +723,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements IEncodin this.createTextEditorModelPromise = null; if (this.textModelChangeListener) { - this.textModelChangeListener(); + this.textModelChangeListener.dispose(); this.textModelChangeListener = null; } diff --git a/src/vs/workbench/parts/files/electron-browser/electronFileTracker.ts b/src/vs/workbench/parts/files/electron-browser/electronFileTracker.ts index 945ad389d95..2be5e4262dd 100644 --- a/src/vs/workbench/parts/files/electron-browser/electronFileTracker.ts +++ b/src/vs/workbench/parts/files/electron-browser/electronFileTracker.ts @@ -23,6 +23,7 @@ import {IResourceInput} from 'vs/platform/editor/common/editor'; import {IEventService} from 'vs/platform/event/common/event'; import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation'; import {ILifecycleService} from 'vs/platform/lifecycle/common/lifecycle'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; import {ipcRenderer as ipc} from 'electron'; @@ -42,7 +43,7 @@ export interface IOpenFileRequest { export class FileTracker implements IWorkbenchContribution { private activeOutOfWorkspaceWatchers: { [resource: string]: boolean; }; private isDocumentedEdited: boolean; - private toUnbind: { (): void; }[]; + private toUnbind: IDisposable[]; constructor( @IWorkspaceContextService private contextService: IWorkspaceContextService, @@ -71,12 +72,12 @@ export class FileTracker implements IWorkbenchContribution { private registerListeners(): void { // Local text file changes - this.toUnbind.push(this.eventService.addListener(WorkbenchEventType.UNTITLED_FILE_DELETED, () => this.onUntitledDeletedEvent())); - this.toUnbind.push(this.eventService.addListener(WorkbenchEventType.UNTITLED_FILE_DIRTY, () => this.onUntitledDirtyEvent())); - this.toUnbind.push(this.eventService.addListener(FileEventType.FILE_DIRTY, (e: TextFileChangeEvent) => this.onTextFileDirty(e))); - this.toUnbind.push(this.eventService.addListener(FileEventType.FILE_SAVED, (e: TextFileChangeEvent) => this.onTextFileSaved(e))); - this.toUnbind.push(this.eventService.addListener(FileEventType.FILE_SAVE_ERROR, (e: TextFileChangeEvent) => this.onTextFileSaveError(e))); - this.toUnbind.push(this.eventService.addListener(FileEventType.FILE_REVERTED, (e: TextFileChangeEvent) => this.onTextFileReverted(e))); + this.toUnbind.push(this.eventService.addListener2(WorkbenchEventType.UNTITLED_FILE_DELETED, () => this.onUntitledDeletedEvent())); + this.toUnbind.push(this.eventService.addListener2(WorkbenchEventType.UNTITLED_FILE_DIRTY, () => this.onUntitledDirtyEvent())); + this.toUnbind.push(this.eventService.addListener2(FileEventType.FILE_DIRTY, (e: TextFileChangeEvent) => this.onTextFileDirty(e))); + this.toUnbind.push(this.eventService.addListener2(FileEventType.FILE_SAVED, (e: TextFileChangeEvent) => this.onTextFileSaved(e))); + this.toUnbind.push(this.eventService.addListener2(FileEventType.FILE_SAVE_ERROR, (e: TextFileChangeEvent) => this.onTextFileSaveError(e))); + this.toUnbind.push(this.eventService.addListener2(FileEventType.FILE_REVERTED, (e: TextFileChangeEvent) => this.onTextFileReverted(e))); // Support openFiles event for existing and new files ipc.on('vscode:openFiles', (event, request: IOpenFileRequest) => { @@ -104,7 +105,7 @@ export class FileTracker implements IWorkbenchContribution { }); // Editor input changes - this.toUnbind.push(this.eventService.addListener(WorkbenchEventType.EDITOR_INPUT_CHANGED, () => this.onEditorInputChanged())); + this.toUnbind.push(this.eventService.addListener2(WorkbenchEventType.EDITOR_INPUT_CHANGED, () => this.onEditorInputChanged())); // Lifecycle this.lifecycleService.onShutdown(this.dispose, this); @@ -205,9 +206,7 @@ export class FileTracker implements IWorkbenchContribution { } public dispose(): void { - while (this.toUnbind.length) { - this.toUnbind.pop()(); - } + this.toUnbind = dispose(this.toUnbind); // Dispose watchers if any for (let key in this.activeOutOfWorkspaceWatchers) { diff --git a/src/vs/workbench/parts/files/test/browser/fileEditorModel.test.ts b/src/vs/workbench/parts/files/test/browser/fileEditorModel.test.ts index f4c1b7c75b8..8038a87e808 100644 --- a/src/vs/workbench/parts/files/test/browser/fileEditorModel.test.ts +++ b/src/vs/workbench/parts/files/test/browser/fileEditorModel.test.ts @@ -104,15 +104,15 @@ suite('Files - TextFileEditorModel', () => { test('Load does not trigger save', function (done) { let m1 = baseInstantiationService.createInstance(TextFileEditorModel, toResource('/path/index.txt'), 'utf8'); - eventService.addListener('files:internalFileChanged', () => { + eventService.addListener2('files:internalFileChanged', () => { assert.ok(false); }); - eventService.addListener(EventType.FILE_DIRTY, () => { + eventService.addListener2(EventType.FILE_DIRTY, () => { assert.ok(false); }); - eventService.addListener(EventType.FILE_SAVED, () => { + eventService.addListener2(EventType.FILE_SAVED, () => { assert.ok(false); }); @@ -145,7 +145,7 @@ suite('Files - TextFileEditorModel', () => { test('Revert', function (done) { let eventCounter = 0; - eventService.addListener('files:fileReverted', () => { + eventService.addListener2('files:fileReverted', () => { eventCounter++; }); @@ -200,11 +200,11 @@ suite('Files - TextFileEditorModel', () => { (m1).autoSaveAfterMillies = 10; (m1).autoSaveAfterMilliesEnabled = true; - eventService.addListener(EventType.FILE_DIRTY, () => { + eventService.addListener2(EventType.FILE_DIRTY, () => { eventCounter++; }); - eventService.addListener(EventType.FILE_SAVED, () => { + eventService.addListener2(EventType.FILE_SAVED, () => { eventCounter++; }); @@ -285,13 +285,13 @@ suite('Files - TextFileEditorModel', () => { let eventCounter = 0; let m1 = baseInstantiationService.createInstance(TextFileEditorModel, toResource('/path/index_async.txt'), 'utf8'); - eventService.addListener(EventType.FILE_SAVED, (e) => { + eventService.addListener2(EventType.FILE_SAVED, (e) => { assert.equal(m1.getValue(), 'bar'); assert.ok(!m1.isDirty()); eventCounter++; }); - eventService.addListener(EventType.FILE_SAVING, (e) => { + eventService.addListener2(EventType.FILE_SAVING, (e) => { assert.ok(m1.isDirty()); m1.textEditorModel.setValue('bar'); assert.ok(m1.isDirty()); diff --git a/src/vs/workbench/parts/git/browser/gitActions.contribution.ts b/src/vs/workbench/parts/git/browser/gitActions.contribution.ts index 825c2a6d384..a4b62014185 100644 --- a/src/vs/workbench/parts/git/browser/gitActions.contribution.ts +++ b/src/vs/workbench/parts/git/browser/gitActions.contribution.ts @@ -255,8 +255,8 @@ export class StageRangesAction extends baseeditor.EditorInputAction { this.editorService = editorService; this.gitService = gitService; this.editor = editor.getControl(); - this.editor.addListener(editorcommon.EventType.CursorSelectionChanged, this.updateEnablement.bind(this)); - this.editor.addListener(editorcommon.EventType.DiffUpdated, this.updateEnablement.bind(this)); + this.editor.addListener2(editorcommon.EventType.CursorSelectionChanged, this.updateEnablement.bind(this)); + this.editor.addListener2(editorcommon.EventType.DiffUpdated, this.updateEnablement.bind(this)); this.class = 'git-action stage-ranges'; } diff --git a/src/vs/workbench/parts/git/browser/gitEditorContributions.ts b/src/vs/workbench/parts/git/browser/gitEditorContributions.ts index dd260638370..07b260aa2d7 100644 --- a/src/vs/workbench/parts/git/browser/gitEditorContributions.ts +++ b/src/vs/workbench/parts/git/browser/gitEditorContributions.ts @@ -4,12 +4,11 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import ee = require('vs/base/common/eventEmitter'); import editorbrowser = require('vs/editor/browser/editorBrowser'); import common = require('vs/editor/common/editorCommon'); import git = require('vs/workbench/parts/git/common/git'); import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace'; -import {Disposable} from 'vs/base/common/lifecycle'; +import {Disposable, IDisposable, dispose} from 'vs/base/common/lifecycle'; import {RunOnceScheduler} from 'vs/base/common/async'; import IGitService = git.IGitService; @@ -91,7 +90,7 @@ export class MergeDecorator implements common.IEditorContribution { private editor: editorbrowser.ICodeEditor; private gitService: git.IGitService; private contextService: IWorkspaceContextService; - private toUnbind: ee.ListenerUnbind[]; + private toUnbind: IDisposable[]; private mergeDecorator: MergeDecoratorBoundToModel; @@ -99,7 +98,7 @@ export class MergeDecorator implements common.IEditorContribution { this.gitService = gitService; this.contextService = contextService; this.editor = editor; - this.toUnbind = [ this.editor.addListener(common.EventType.ModelChanged, this.onModelChanged.bind(this)) ]; + this.toUnbind = [ this.editor.addListener2(common.EventType.ModelChanged, () => this.onModelChanged()) ]; this.mergeDecorator = null; } @@ -140,8 +139,6 @@ export class MergeDecorator implements common.IEditorContribution { this.mergeDecorator.dispose(); this.mergeDecorator = null; } - while(this.toUnbind.length) { - this.toUnbind.pop()(); - } + this.toUnbind = dispose(this.toUnbind); } } diff --git a/src/vs/workbench/parts/git/browser/gitViewlet.ts b/src/vs/workbench/parts/git/browser/gitViewlet.ts index ad6dc9ed7f4..9c56bcd9bb0 100644 --- a/src/vs/workbench/parts/git/browser/gitViewlet.ts +++ b/src/vs/workbench/parts/git/browser/gitViewlet.ts @@ -69,7 +69,7 @@ export class GitViewlet this.toDispose.push(v); }); - this.toUnbind.push(this.gitService.addBulkListener(() => this.onGitServiceChanges())); + this.toUnbind.push(this.gitService.addBulkListener2(() => this.onGitServiceChanges())); } // GitView.IController diff --git a/src/vs/workbench/parts/markdown/browser/markdownExtension.ts b/src/vs/workbench/parts/markdown/browser/markdownExtension.ts index 7aa23d58944..8da42410e3e 100644 --- a/src/vs/workbench/parts/markdown/browser/markdownExtension.ts +++ b/src/vs/workbench/parts/markdown/browser/markdownExtension.ts @@ -23,7 +23,7 @@ import {IEventService} from 'vs/platform/event/common/event'; import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation'; import {IModeService} from 'vs/editor/common/services/modeService'; import {IThemeService} from 'vs/workbench/services/themes/common/themeService'; -import {IDisposable} from 'vs/base/common/lifecycle'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; interface ILanguageConfiguration { markdown: { @@ -36,10 +36,10 @@ export class MarkdownFileTracker implements IWorkbenchContribution { private static RELOAD_MARKDOWN_DELAY = 300; // delay before reloading markdown preview after user typing - private fileChangeListener: () => void; + private fileChangeListener: IDisposable; private configFileChangeListener: IDisposable; private themeChangeListener: IDisposable; - private editorInputChangeListener: () => void; + private editorInputChangeListener: IDisposable; private markdownConfigurationThumbprint: string; private markdownConfigurationPaths: string[]; private reloadTimeout: number; @@ -64,11 +64,11 @@ export class MarkdownFileTracker implements IWorkbenchContribution { } private registerListeners(): void { - this.fileChangeListener = this.eventService.addListener(FileEventType.FILE_CHANGES, (e: FileChangesEvent) => this.onFileChanges(e)); + this.fileChangeListener = this.eventService.addListener2(FileEventType.FILE_CHANGES, (e: FileChangesEvent) => this.onFileChanges(e)); this.configFileChangeListener = this.configurationService.onDidUpdateConfiguration(e => this.onConfigFileChange(e)); // reload markdown editors when their resources change - this.editorInputChangeListener = this.eventService.addListener(WorkbenchEventType.EDITOR_INPUT_CHANGED, (e: EditorEvent) => this.onEditorInputChanged(e)); + this.editorInputChangeListener = this.eventService.addListener2(WorkbenchEventType.EDITOR_INPUT_CHANGED, (e: EditorEvent) => this.onEditorInputChanged(e)); // initially read the config for CSS styles in preview this.readMarkdownConfiguration(this.configurationService.getConfiguration()); @@ -86,17 +86,15 @@ export class MarkdownFileTracker implements IWorkbenchContribution { let markdownResource = input.getResource(); let editorModel = this.modelService.getModel(markdownResource); if (editorModel && !this.hasModelListenerOnResourcePath[markdownResource.toString()]) { - let toUnbind: Function[] = []; + let toUnbind: IDisposable[] = []; let unbind = () => { - while (toUnbind.length) { - toUnbind.pop()(); - } + toUnbind = dispose(toUnbind); this.hasModelListenerOnResourcePath[markdownResource.toString()] = false; }; // Listen on changes to the underlying resource of the markdown preview - toUnbind.push(editorModel.addListener(EditorEventType.ModelContentChanged, (modelEvent: IModelContentChangedEvent) => { + toUnbind.push(editorModel.addListener2(EditorEventType.ModelContentChanged, (modelEvent: IModelContentChangedEvent) => { if (this.reloadTimeout) { window.clearTimeout(this.reloadTimeout); } @@ -112,8 +110,8 @@ export class MarkdownFileTracker implements IWorkbenchContribution { this.hasModelListenerOnResourcePath[markdownResource.toString()] = true; // Unbind when input or model gets disposed - toUnbind.push(input.addListener(EventType.DISPOSE, unbind)); - toUnbind.push(editorModel.addListener(EditorEventType.ModelDispose, unbind)); + toUnbind.push(input.addListener2(EventType.DISPOSE, unbind)); + toUnbind.push(editorModel.addListener2(EditorEventType.ModelDispose, unbind)); } } } @@ -190,7 +188,7 @@ export class MarkdownFileTracker implements IWorkbenchContribution { public dispose(): void { if (this.fileChangeListener) { - this.fileChangeListener(); + this.fileChangeListener.dispose(); this.fileChangeListener = null; } @@ -200,7 +198,7 @@ export class MarkdownFileTracker implements IWorkbenchContribution { } if (this.editorInputChangeListener) { - this.editorInputChangeListener(); + this.editorInputChangeListener.dispose(); this.editorInputChangeListener = null; } } diff --git a/src/vs/workbench/parts/search/browser/searchViewlet.ts b/src/vs/workbench/parts/search/browser/searchViewlet.ts index af02900fbda..8c3feff3d40 100644 --- a/src/vs/workbench/parts/search/browser/searchViewlet.ts +++ b/src/vs/workbench/parts/search/browser/searchViewlet.ts @@ -644,7 +644,7 @@ export class SearchViewlet extends Viewlet { private loading: boolean; private queryBuilder: QueryBuilder; private viewModel: SearchResult; - private callOnModelChange: Function[]; + private callOnModelChange: lifecycle.IDisposable[]; private viewletVisible: IKeybindingContextKey; private actionRegistry: { [key: string]: Action; }; @@ -685,9 +685,9 @@ export class SearchViewlet extends Viewlet { this.queryBuilder = this.instantiationService.createInstance(QueryBuilder); this.viewletSettings = this.getMemento(storageService, Scope.WORKSPACE); - this.toUnbind.push(this.eventService.addListener(FileEventType.FILE_CHANGES, (e) => this.onFilesChanged(e))); - this.toUnbind.push(this.eventService.addListener(WorkbenchEventType.UNTITLED_FILE_DELETED, (e) => this.onUntitledFileDeleted(e))); - this.toUnbind.push(this.configurationService.onDidUpdateConfiguration(e => this.onConfigurationUpdated(e.config)).dispose); + this.toUnbind.push(this.eventService.addListener2(FileEventType.FILE_CHANGES, (e) => this.onFilesChanged(e))); + this.toUnbind.push(this.eventService.addListener2(WorkbenchEventType.UNTITLED_FILE_DELETED, (e) => this.onUntitledFileDeleted(e))); + this.toUnbind.push(this.configurationService.onDidUpdateConfiguration(e => this.onConfigurationUpdated(e.config))); } private onConfigurationUpdated(configuration: any): void { @@ -881,9 +881,9 @@ export class SearchViewlet extends Viewlet { ariaLabel: nls.localize('treeAriaLabel', "Search Results") }); - this.toUnbind.push(() => renderer.dispose()); + this.toUnbind.push(renderer); - this.toUnbind.push(this.tree.addListener('selection', (event: any) => { + this.toUnbind.push(this.tree.addListener2('selection', (event: any) => { let element: any, keyboard = event.payload && event.payload.origin === 'keyboard'; if (keyboard) { element = this.tree.getFocus(); @@ -1364,7 +1364,7 @@ export class SearchViewlet extends Viewlet { this.viewModel = this.instantiationService.createInstance(SearchResult, query.contentPattern); this.tree.setInput(this.viewModel).then(() => { autoExpand(false); - this.callOnModelChange.push(this.viewModel.addListener('changed', (e: any) => this.tree.refresh(e, true))); + this.callOnModelChange.push(this.viewModel.addListener2('changed', (e: any) => this.tree.refresh(e, true))); }).done(null, errors.onUnexpectedError); } @@ -1500,6 +1500,6 @@ export class SearchViewlet extends Viewlet { this.viewModel.dispose(); this.viewModel = null; } - lifecycle.cAll(this.callOnModelChange); + this.callOnModelChange = lifecycle.dispose(this.callOnModelChange); } } diff --git a/src/vs/workbench/parts/search/common/searchModel.ts b/src/vs/workbench/parts/search/common/searchModel.ts index 4eba048d32c..ac153b98877 100644 --- a/src/vs/workbench/parts/search/common/searchModel.ts +++ b/src/vs/workbench/parts/search/common/searchModel.ts @@ -139,7 +139,7 @@ export class LiveFileMatch extends FileMatch implements lifecycle.IDisposable { private _query: Search.IPatternInfo; private _updateScheduler: RunOnceScheduler; private _modelDecorations: string[] = []; - private _unbind: Function[] = []; + private _unbind: lifecycle.IDisposable[] = []; _diskFileMatch: FileMatch; constructor(parent: SearchResult, resource: URI, query: Search.IPatternInfo, model: IModel, fileMatch: FileMatch) { @@ -149,12 +149,12 @@ export class LiveFileMatch extends FileMatch implements lifecycle.IDisposable { this._model = model; this._diskFileMatch = fileMatch; this._updateScheduler = new RunOnceScheduler(this._updateMatches.bind(this), 250); - this._unbind.push(this._model.addListener(EventType.ModelContentChanged, _ => this._updateScheduler.schedule())); + this._unbind.push(this._model.addListener2(EventType.ModelContentChanged, _ => this._updateScheduler.schedule())); this._updateMatches(); } public dispose(): void { - this._unbind = lifecycle.cAll(this._unbind); + this._unbind = lifecycle.dispose(this._unbind); if (!this._isTextModelDisposed()) { this._model.deltaDecorations(this._modelDecorations, []); } diff --git a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts index c4177de6bf8..7d1982212df 100644 --- a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts +++ b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts @@ -17,7 +17,7 @@ import { IStringDictionary } from 'vs/base/common/collections'; import { Action } from 'vs/base/common/actions'; import * as Dom from 'vs/base/browser/dom'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; -import { EventEmitter, ListenerUnbind } from 'vs/base/common/eventEmitter'; +import { EventEmitter } from 'vs/base/common/eventEmitter'; import * as Builder from 'vs/base/browser/builder'; import * as Types from 'vs/base/common/types'; import { KeyMod, KeyCode } from 'vs/base/common/keyCodes'; @@ -560,11 +560,11 @@ class TaskService extends EventEmitter implements ITaskService { private _taskSystemPromise: TPromise; private _taskSystem: ITaskSystem; - private taskSystemListeners: ListenerUnbind[]; + private taskSystemListeners: IDisposable[]; private clearTaskSystemPromise: boolean; private outputChannel: IOutputChannel; - private fileChangesListener: ListenerUnbind; + private fileChangesListener: IDisposable; constructor(@IModeService modeService: IModeService, @IConfigurationService configurationService: IConfigurationService, @IMarkerService markerService: IMarkerService, @IOutputService outputService: IOutputService, @@ -609,13 +609,12 @@ class TaskService extends EventEmitter implements ITaskService { } private disposeTaskSystemListeners(): void { - this.taskSystemListeners.forEach(unbind => unbind()); - this.taskSystemListeners = []; + this.taskSystemListeners = dispose(this.taskSystemListeners); } private disposeFileChangesListener(): void { if (this.fileChangesListener) { - this.fileChangesListener(); + this.fileChangesListener.dispose(); this.fileChangesListener = null; } } @@ -694,8 +693,8 @@ class TaskService extends EventEmitter implements ITaskService { this._taskSystemPromise = null; throw new TaskError(Severity.Info, nls.localize('TaskSystem.noBuildType', "No valid task runner configured. Supported task runners are 'service' and 'program'."), TaskErrors.NoValidTaskRunner); } - this.taskSystemListeners.push(result.addListener(TaskSystemEvents.Active, (event) => this.emit(TaskServiceEvents.Active, event))); - this.taskSystemListeners.push(result.addListener(TaskSystemEvents.Inactive, (event) => this.emit(TaskServiceEvents.Inactive, event))); + this.taskSystemListeners.push(result.addListener2(TaskSystemEvents.Active, (event) => this.emit(TaskServiceEvents.Active, event))); + this.taskSystemListeners.push(result.addListener2(TaskSystemEvents.Inactive, (event) => this.emit(TaskServiceEvents.Inactive, event))); this._taskSystem = result; return result; }, (err: any) => { @@ -773,7 +772,7 @@ class TaskService extends EventEmitter implements ITaskService { then((runResult: ITaskRunResult) => { if (runResult.restartOnFileChanges) { let pattern = runResult.restartOnFileChanges; - this.fileChangesListener = this.eventService.addListener(FileEventType.FILE_CHANGES, (event: FileChangesEvent) => { + this.fileChangesListener = this.eventService.addListener2(FileEventType.FILE_CHANGES, (event: FileChangesEvent) => { let needsRestart = event.changes.some((change) => { return (change.type === FileChangeType.ADDED || change.type === FileChangeType.DELETED) && !!match(pattern, change.resource.fsPath); }); diff --git a/src/vs/workbench/services/configuration/node/configurationService.ts b/src/vs/workbench/services/configuration/node/configurationService.ts index 30d2229072e..d49469db3ed 100644 --- a/src/vs/workbench/services/configuration/node/configurationService.ts +++ b/src/vs/workbench/services/configuration/node/configurationService.ts @@ -18,6 +18,7 @@ import {IWorkspaceContextService} from 'vs/workbench/services/workspace/common/c import {OptionsChangeEvent, EventType} from 'vs/workbench/common/events'; import {IEventService} from 'vs/platform/event/common/event'; import {IConfigurationService} from 'vs/platform/configuration/common/configuration'; +import {IDisposable} from 'vs/base/common/lifecycle'; import fs = require('fs'); @@ -26,7 +27,7 @@ export class ConfigurationService extends CommonConfigurationService { public serviceId = IConfigurationService; protected contextService: IWorkspaceContextService; - private toDispose: Function; + private toDispose: IDisposable; constructor(contextService: IWorkspaceContextService, eventService: IEventService) { super(contextService, eventService); @@ -37,7 +38,7 @@ export class ConfigurationService extends CommonConfigurationService { protected registerListeners(): void { super.registerListeners(); - this.toDispose = this.eventService.addListener(EventType.WORKBENCH_OPTIONS_CHANGED, (e) => this.onOptionsChanged(e)); + this.toDispose = this.eventService.addListener2(EventType.WORKBENCH_OPTIONS_CHANGED, (e) => this.onOptionsChanged(e)); } private onOptionsChanged(e: OptionsChangeEvent): void { @@ -129,6 +130,6 @@ export class ConfigurationService extends CommonConfigurationService { public dispose(): void { super.dispose(); - this.toDispose(); + this.toDispose.dispose(); } } \ No newline at end of file diff --git a/src/vs/workbench/services/history/browser/history.ts b/src/vs/workbench/services/history/browser/history.ts index 979ce5f3d12..27559f1e0f1 100644 --- a/src/vs/workbench/services/history/browser/history.ts +++ b/src/vs/workbench/services/history/browser/history.ts @@ -20,6 +20,7 @@ import {Selection} from 'vs/editor/common/core/selection'; import {Position, IEditorInput} from 'vs/platform/editor/common/editor'; import {IEventService} from 'vs/platform/event/common/event'; import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; /** * Stores the selection & view state of an editor and allows to compare it to other selection states. @@ -68,7 +69,7 @@ interface IInputWithPath { } export abstract class BaseHistoryService { - protected toUnbind: { (): void; }[]; + protected toUnbind: IDisposable[]; constructor( private eventService: IEventService, @@ -81,13 +82,13 @@ export abstract class BaseHistoryService { window.document.title = this.getWindowTitle(null); // Editor Input Changes - this.toUnbind.push(this.eventService.addListener(WorkbenchEventType.EDITOR_INPUT_CHANGED, (e: EditorEvent) => this.onEditorInputChanged(e))); + this.toUnbind.push(this.eventService.addListener2(WorkbenchEventType.EDITOR_INPUT_CHANGED, (e: EditorEvent) => this.onEditorInputChanged(e))); // Editor Input State Changes - this.toUnbind.push(this.eventService.addListener(WorkbenchEventType.EDITOR_INPUT_STATE_CHANGED, (e: EditorInputEvent) => this.onEditorInputStateChanged(e.editorInput))); + this.toUnbind.push(this.eventService.addListener2(WorkbenchEventType.EDITOR_INPUT_STATE_CHANGED, (e: EditorInputEvent) => this.onEditorInputStateChanged(e.editorInput))); // Text Editor Selection Changes - this.toUnbind.push(this.eventService.addListener(WorkbenchEventType.TEXT_EDITOR_SELECTION_CHANGED, (event: TextEditorSelectionEvent) => this.onTextEditorSelectionChanged(event))); + this.toUnbind.push(this.eventService.addListener2(WorkbenchEventType.TEXT_EDITOR_SELECTION_CHANGED, (event: TextEditorSelectionEvent) => this.onTextEditorSelectionChanged(event))); } private onEditorInputStateChanged(input: IEditorInput): void { @@ -220,9 +221,7 @@ export abstract class BaseHistoryService { } public dispose(): void { - while (this.toUnbind.length) { - this.toUnbind.pop()(); - } + this.toUnbind = dispose(this.toUnbind); } } diff --git a/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts b/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts index de8a32c51a3..88bda1e3cee 100644 --- a/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts +++ b/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts @@ -26,6 +26,7 @@ import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace'; import {EventType, OptionsChangeEvent} from 'vs/workbench/common/events'; import {getNativeLabelProvider, getNativeAriaLabelProvider} from 'vs/workbench/services/keybinding/electron-browser/nativeKeymap'; import {IMessageService} from 'vs/platform/message/common/message'; +import {IDisposable} from 'vs/base/common/lifecycle'; interface ContributedKeyBinding { command: string; @@ -119,7 +120,7 @@ export class WorkbenchKeybindingService extends KeybindingService { private contextService: IWorkspaceContextService; private eventService: IEventService; private telemetryService: ITelemetryService; - private toDispose: Function; + private toDispose: IDisposable; private _extensionService: IExtensionService; private _eventService: IEventService; @@ -129,7 +130,7 @@ export class WorkbenchKeybindingService extends KeybindingService { this.eventService = eventService; this.telemetryService = telemetryService; this._extensionService = extensionService; - this.toDispose = this.eventService.addListener(EventType.WORKBENCH_OPTIONS_CHANGED, (e) => this.onOptionsChanged(e)); + this.toDispose = this.eventService.addListener2(EventType.WORKBENCH_OPTIONS_CHANGED, (e) => this.onOptionsChanged(e)); this._eventService = eventService; keybindingsExtPoint.setHandler((extensions) => { let commandAdded = false; @@ -181,7 +182,7 @@ export class WorkbenchKeybindingService extends KeybindingService { } public dispose(): void { - this.toDispose(); + this.toDispose.dispose(); } public getLabelFor(keybinding: Keybinding): string { diff --git a/src/vs/workbench/services/progress/browser/progressService.ts b/src/vs/workbench/services/progress/browser/progressService.ts index 99624b0c092..4feaca0399e 100644 --- a/src/vs/workbench/services/progress/browser/progressService.ts +++ b/src/vs/workbench/services/progress/browser/progressService.ts @@ -35,25 +35,25 @@ export abstract class ScopedService { } public registerListeners(): void { - this.eventService.addListener(EventType.EDITOR_CLOSED, (e: EditorEvent) => { + this.eventService.addListener2(EventType.EDITOR_CLOSED, (e: EditorEvent) => { if (e.editorId === this.scopeId) { this.onScopeDeactivated(); } }); - this.eventService.addListener(EventType.EDITOR_OPENED, (e: EditorEvent) => { + this.eventService.addListener2(EventType.EDITOR_OPENED, (e: EditorEvent) => { if (e.editorId === this.scopeId) { this.onScopeActivated(); } }); - this.eventService.addListener(EventType.COMPOSITE_CLOSED, (e: CompositeEvent) => { + this.eventService.addListener2(EventType.COMPOSITE_CLOSED, (e: CompositeEvent) => { if (e.compositeId === this.scopeId) { this.onScopeDeactivated(); } }); - this.eventService.addListener(EventType.COMPOSITE_OPENED, (e: CompositeEvent) => { + this.eventService.addListener2(EventType.COMPOSITE_OPENED, (e: CompositeEvent) => { if (e.compositeId === this.scopeId) { this.onScopeActivated(); } diff --git a/src/vs/workbench/test/browser/parts/editor/baseEditor.test.ts b/src/vs/workbench/test/browser/parts/editor/baseEditor.test.ts index 210402f022c..14c8ae8b36d 100644 --- a/src/vs/workbench/test/browser/parts/editor/baseEditor.test.ts +++ b/src/vs/workbench/test/browser/parts/editor/baseEditor.test.ts @@ -140,7 +140,7 @@ suite('Workbench BaseEditor', () => { return e.setVisible(true).then(function () { assert(e.isVisible()); - input.addListener('dispose', function () { + input.addListener2('dispose', function () { assert(false); }); e.dispose(); diff --git a/src/vs/workbench/test/browser/parts/editor/editorInput.test.ts b/src/vs/workbench/test/browser/parts/editor/editorInput.test.ts index 5150134ab02..fba70bf7374 100644 --- a/src/vs/workbench/test/browser/parts/editor/editorInput.test.ts +++ b/src/vs/workbench/test/browser/parts/editor/editorInput.test.ts @@ -35,7 +35,7 @@ suite('Workbench - EditorInput', () => { assert(!input.matches(null)); assert(!input.getName()); - input.addListener('dispose', function () { + input.addListener2('dispose', function () { assert(true); counter++; }); @@ -47,13 +47,13 @@ suite('Workbench - EditorInput', () => { test('DiffEditorInput', function () { let counter = 0; let input = new MyEditorInput(); - input.addListener('dispose', function () { + input.addListener2('dispose', function () { assert(true); counter++; }); let otherInput = new MyEditorInput(); - otherInput.addListener('dispose', function () { + otherInput.addListener2('dispose', function () { assert(true); counter++; }); @@ -76,7 +76,7 @@ suite('Workbench - EditorInput', () => { let otherInput = new MyEditorInput(); let diffInput = new DiffEditorInput('name', 'description', input, otherInput); - diffInput.addListener('dispose', function () { + diffInput.addListener2('dispose', function () { counter++; assert(true); }); @@ -87,7 +87,7 @@ suite('Workbench - EditorInput', () => { otherInput = new MyEditorInput(); let diffInput2 = new DiffEditorInput('name', 'description', input, otherInput); - diffInput2.addListener('dispose', function () { + diffInput2.addListener2('dispose', function () { counter++; assert(true); });