diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 80ed914f68081..162686d769d00 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -21,7 +21,7 @@ "./vs/base/common/diff/diff.ts", "./vs/base/common/diff/diffChange.ts", "./vs/base/common/errors.ts", - // "./vs/base/common/event.ts", + "./vs/base/common/event.ts", "./vs/base/common/functional.ts", "./vs/base/common/idGenerator.ts", "./vs/base/common/iterator.ts", diff --git a/src/vs/base/common/event.ts b/src/vs/base/common/event.ts index 431960a43f2e6..0447231832da4 100644 --- a/src/vs/base/common/event.ts +++ b/src/vs/base/common/event.ts @@ -56,13 +56,16 @@ export class Emitter { private static readonly _noop = function () { }; - private _event: Event; + private _event: Event | null; private _disposed: boolean; - private _deliveryQueue: [Listener, T][]; - protected _listeners: LinkedList; - - constructor(private _options?: EmitterOptions) { - + private _deliveryQueue: [Listener, (T | undefined)][] | null; + protected _listeners: LinkedList | null; + + constructor(private _options: EmitterOptions | null = null) { + this._event = null; + this._disposed = false; + this._deliveryQueue = null; + this._listeners = null; } /** @@ -98,8 +101,11 @@ export class Emitter { result.dispose = Emitter._noop; if (!this._disposed) { remove(); - if (this._options && this._options.onLastListenerRemove && this._listeners.isEmpty()) { - this._options.onLastListenerRemove(this); + if (this._options && this._options.onLastListenerRemove) { + const hasListeners = (this._listeners && !this._listeners.isEmpty()); + if (!hasListeners) { + this._options.onLastListenerRemove(this); + } } } } @@ -133,7 +139,7 @@ export class Emitter { } while (this._deliveryQueue.length > 0) { - const [listener, event] = this._deliveryQueue.shift(); + const [listener, event] = this._deliveryQueue.shift()!; try { if (typeof listener === 'function') { listener.call(undefined, event); @@ -149,7 +155,7 @@ export class Emitter { dispose() { if (this._listeners) { - this._listeners = undefined; + this._listeners = null; } if (this._deliveryQueue) { this._deliveryQueue.length = 0; @@ -184,7 +190,7 @@ export class AsyncEmitter extends Emitter { } while (this._asyncDeliveryQueue.length > 0) { - const [listener, event, thenables] = this._asyncDeliveryQueue.shift(); + const [listener, event, thenables] = this._asyncDeliveryQueue.shift()!; try { if (typeof listener === 'function') { listener.call(undefined, event); @@ -208,7 +214,7 @@ export class EventMultiplexer implements IDisposable { private readonly emitter: Emitter; private hasListeners = false; - private events: { event: Event; listener: IDisposable; }[] = []; + private events: { event: Event; listener: IDisposable | null; }[] = []; constructor() { this.emitter = new Emitter({ @@ -251,12 +257,14 @@ export class EventMultiplexer implements IDisposable { this.events.forEach(e => this.unhook(e)); } - private hook(e: { event: Event; listener: IDisposable; }): void { + private hook(e: { event: Event; listener: IDisposable | null; }): void { e.listener = e.event(r => this.emitter.fire(r)); } - private unhook(e: { event: Event; listener: IDisposable; }): void { - e.listener.dispose(); + private unhook(e: { event: Event; listener: IDisposable | null; }): void { + if (e.listener) { + e.listener.dispose(); + } e.listener = null; } @@ -270,7 +278,7 @@ export function fromPromise(promise: Thenable): Event { let shouldEmit = false; promise - .then(null, () => null) + .then(undefined, () => null) .then(() => { if (!shouldEmit) { setTimeout(() => emitter.fire(), 0); @@ -321,11 +329,11 @@ export function anyEvent(...events: Event[]): Event { } export function debounceEvent(event: Event, merger: (last: T, event: T) => T, delay?: number, leading?: boolean): Event; -export function debounceEvent(event: Event, merger: (last: O, event: I) => O, delay?: number, leading?: boolean): Event; -export function debounceEvent(event: Event, merger: (last: O, event: I) => O, delay: number = 100, leading = false): Event { +export function debounceEvent(event: Event, merger: (last: O | undefined, event: I) => O, delay?: number, leading?: boolean): Event; +export function debounceEvent(event: Event, merger: (last: O | undefined, event: I) => O, delay: number = 100, leading = false): Event { let subscription: IDisposable; - let output: O = undefined; + let output: O | undefined = undefined; let handle: any = undefined; let numDebouncedCalls = 0; @@ -497,10 +505,10 @@ export function stopwatch(event: Event): Event { * // 4 * ``` */ -export function buffer(event: Event, nextTick = false, buffer: T[] = []): Event { - buffer = buffer.slice(); +export function buffer(event: Event, nextTick = false, _buffer: T[] = []): Event { + let buffer: T[] | null = _buffer.slice(); - let listener = event(e => { + let listener: IDisposable | null = event(e => { if (buffer) { buffer.push(e); } else { @@ -509,7 +517,9 @@ export function buffer(event: Event, nextTick = false, buffer: T[] = []): }); const flush = () => { - buffer.forEach(e => emitter.fire(e)); + if (buffer) { + buffer.forEach(e => emitter.fire(e)); + } buffer = null; }; @@ -531,7 +541,9 @@ export function buffer(event: Event, nextTick = false, buffer: T[] = []): }, onLastListenerRemove() { - listener.dispose(); + if (listener) { + listener.dispose(); + } listener = null; } });