From 3ba326658d0dba29f238175fb79a6ddab08001af Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Thu, 11 Oct 2018 17:35:06 +0200 Subject: [PATCH] More strict null sources (#60565) --- src/tsconfig.strictNullChecks.json | 24 ++++++- src/vs/base/browser/mouseEvent.ts | 4 +- src/vs/base/common/arrays.ts | 31 +++++---- src/vs/base/common/async.ts | 64 +++++++++++++------ src/vs/base/common/cancellation.ts | 4 +- src/vs/base/common/collections.ts | 2 +- src/vs/base/common/glob.ts | 26 +++++--- src/vs/base/common/hash.ts | 4 +- src/vs/base/common/map.ts | 28 ++++---- src/vs/base/common/scrollable.ts | 7 +- src/vs/base/worker/defaultWorkerFactory.ts | 6 +- src/vs/editor/common/core/range.ts | 2 +- src/vs/editor/contrib/find/findState.ts | 8 +-- src/vs/monaco.d.ts | 2 +- .../platform/contextkey/common/contextkey.ts | 30 +++++---- src/vs/platform/files/common/files.ts | 13 ++-- src/vs/platform/theme/common/colorRegistry.ts | 22 +++---- 17 files changed, 174 insertions(+), 103 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index e8bfbf58937..fc6894a77b1 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -6,14 +6,22 @@ }, "include": [ "./typings", + "./vs/base/browser/browser.ts", + "./vs/base/browser/event.ts", "./vs/base/browser/history.ts", "./vs/base/browser/iframe.ts", + "./vs/base/browser/keyboardEvent.ts", + "./vs/base/browser/mouseEvent.ts", "./vs/base/browser/ui/octiconLabel/octiconLabel.mock.ts", "./vs/base/browser/ui/octiconLabel/octiconLabel.ts", "./vs/base/browser/ui/scrollbar/scrollbarState.ts", "./vs/base/common/amd.ts", + "./vs/base/common/arrays.ts", "./vs/base/common/assert.ts", + "./vs/base/common/async.ts", + "./vs/base/common/cancellation.ts", "./vs/base/common/charCode.ts", + "./vs/base/common/collections.ts", "./vs/base/common/color.ts", "./vs/base/common/comparers.ts", "./vs/base/common/date.ts", @@ -23,6 +31,9 @@ "./vs/base/common/errors.ts", "./vs/base/common/event.ts", "./vs/base/common/functional.ts", + "./vs/base/common/glob.ts", + "./vs/base/common/hash.ts", + "./vs/base/common/htmlContent.ts", "./vs/base/common/idGenerator.ts", "./vs/base/common/iterator.ts", "./vs/base/common/jsonSchema.ts", @@ -30,6 +41,7 @@ "./vs/base/common/keyCodes.ts", "./vs/base/common/lifecycle.ts", "./vs/base/common/linkedList.ts", + "./vs/base/common/map.ts", "./vs/base/common/marshalling.ts", "./vs/base/common/network.ts", "./vs/base/common/numbers.ts", @@ -41,6 +53,8 @@ "./vs/base/common/range.ts", "./vs/base/common/resources.ts", "./vs/base/common/scanCode.ts", + "./vs/base/common/scrollable.ts", + "./vs/base/common/sequence.ts", "./vs/base/common/severity.ts", "./vs/base/common/stopwatch.ts", "./vs/base/common/strings.ts", @@ -57,7 +71,9 @@ "./vs/base/parts/contextmenu/electron-main/contextmenu.ts", "./vs/base/parts/quickopen/common/quickOpen.ts", "./vs/base/test/node/uri.test.perf.ts", + "./vs/base/worker/defaultWorkerFactory.ts", "./vs/base/worker/workerMain.ts", + "./vs/editor/common/config/editorZoom.ts", "./vs/editor/common/controller/cursorEvents.ts", "./vs/editor/common/controller/wordCharacterClassifier.ts", "./vs/editor/common/core/characterClassifier.ts", @@ -67,12 +83,13 @@ "./vs/editor/common/core/selection.ts", "./vs/editor/common/core/stringBuilder.ts", "./vs/editor/common/core/uint.ts", + "./vs/editor/common/model/mirrorTextModel.ts", "./vs/editor/common/model/textModelEvents.ts", "./vs/editor/common/view/overviewZoneManager.ts", "./vs/editor/common/viewLayout/whitespaceComputer.ts", "./vs/editor/common/viewModel/prefixSumComputer.ts", - "./vs/editor/common/model/mirrorTextModel.ts", "./vs/editor/contrib/codeAction/codeActionTrigger.ts", + "./vs/editor/contrib/find/findState.ts", "./vs/editor/contrib/find/replacePattern.ts", "./vs/editor/contrib/indentation/indentUtils.ts", "./vs/editor/standalone/common/monarch/monarchCommon.ts", @@ -81,20 +98,25 @@ "./vs/nls.mock.ts", "./vs/platform/clipboard/common/clipboardService.ts", "./vs/platform/clipboard/electron-browser/clipboardService.ts", + "./vs/platform/contextkey/common/contextkey.ts", + "./vs/platform/editor/common/editor.ts", "./vs/platform/environment/common/environment.ts", "./vs/platform/extensions/common/extensionHost.ts", "./vs/platform/extensions/common/extensions.ts", + "./vs/platform/files/common/files.ts", "./vs/platform/files/node/files.ts", "./vs/platform/instantiation/common/descriptors.ts", "./vs/platform/instantiation/common/extensions.ts", "./vs/platform/instantiation/common/instantiation.ts", "./vs/platform/instantiation/common/serviceCollection.ts", "./vs/platform/integrity/common/integrity.ts", + "./vs/platform/markers/common/markers.ts", "./vs/platform/node/package.ts", "./vs/platform/node/product.ts", "./vs/platform/opener/common/opener.ts", "./vs/platform/registry/common/platform.ts", "./vs/platform/state/common/state.ts", + "./vs/platform/theme/common/colorRegistry.ts", "./vs/workbench/api/shared/tasks.ts", "./vs/workbench/common/extensionHostProtocol.ts", "./vs/workbench/parts/execution/common/execution.ts", diff --git a/src/vs/base/browser/mouseEvent.ts b/src/vs/base/browser/mouseEvent.ts index cba7c60fb6b..871506af1f2 100644 --- a/src/vs/base/browser/mouseEvent.ts +++ b/src/vs/base/browser/mouseEvent.ts @@ -66,8 +66,8 @@ export class StandardMouseEvent implements IMouseEvent { this.posy = e.pageY; } else { // Probably hit by MSGestureEvent - this.posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; - this.posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; + this.posx = e.clientX + document.body.scrollLeft + document.documentElement!.scrollLeft; + this.posy = e.clientY + document.body.scrollTop + document.documentElement!.scrollTop; } // Find the position of the iframe this code is executing in relative to the iframe where the event was captured. diff --git a/src/vs/base/common/arrays.ts b/src/vs/base/common/arrays.ts index 0abb4867d9a..e8b6ef67004 100644 --- a/src/vs/base/common/arrays.ts +++ b/src/vs/base/common/arrays.ts @@ -138,7 +138,7 @@ function _sort(a: T[], compare: Compare, lo: number, hi: number, aux: T[]) export function groupBy(data: T[], compare: (a: T, b: T) => number): T[][] { const result: T[][] = []; - let currentGroup: T[]; + let currentGroup: T[] | undefined = undefined; for (const element of mergeSort(data.slice(0), compare)) { if (!currentGroup || compare(currentGroup[0], element) !== 0) { currentGroup = [element]; @@ -388,7 +388,9 @@ export function firstIndex(array: T[] | ReadonlyArray, fn: (item: T) => bo return -1; } -export function first(array: T[] | ReadonlyArray, fn: (item: T) => boolean, notFoundValue: T = null): T { +export function first(array: T[] | ReadonlyArray, fn: (item: T) => boolean, notFoundValue: T): T; +export function first(array: T[] | ReadonlyArray, fn: (item: T) => boolean): T | null; +export function first(array: T[] | ReadonlyArray, fn: (item: T) => boolean, notFoundValue: T | null = null): T | null { const index = firstIndex(array, fn); return index < 0 ? notFoundValue : array[index]; } @@ -404,7 +406,7 @@ export function commonPrefixLength(one: T[], other: T[], equals: (a: T, b: T) } export function flatten(arr: T[][]): T[] { - return [].concat(...arr); + return ([]).concat(...arr); } export function range(to: number): number[]; @@ -481,15 +483,20 @@ export function arrayInsert(target: T[], insertIndex: number, insertArr: T[]) * Uses Fisher-Yates shuffle to shuffle the given array * @param array */ -export function shuffle(array: T[], seed?: number): void { - // Seeded random number generator in JS. Modified from: - // https://stackoverflow.com/questions/521295/seeding-the-random-number-generator-in-javascript - const random = () => { - var x = Math.sin(seed++) * 179426549; // throw away most significant digits and reduce any potential bias - return x - Math.floor(x); - }; - - const rand = typeof seed === 'number' ? random : Math.random; +export function shuffle(array: T[], _seed?: number): void { + let rand: () => number; + + if (typeof _seed === 'number') { + let seed = _seed; + // Seeded random number generator in JS. Modified from: + // https://stackoverflow.com/questions/521295/seeding-the-random-number-generator-in-javascript + rand = () => { + var x = Math.sin(seed++) * 179426549; // throw away most significant digits and reduce any potential bias + return x - Math.floor(x); + }; + } else { + rand = Math.random; + } for (let i = array.length - 1; i > 0; i -= 1) { let j = Math.floor(rand() * (i + 1)); diff --git a/src/vs/base/common/async.ts b/src/vs/base/common/async.ts index bcf32e22066..d67bfdc8b4c 100644 --- a/src/vs/base/common/async.ts +++ b/src/vs/base/common/async.ts @@ -91,9 +91,9 @@ export interface ITask { */ export class Throttler { - private activePromise: TPromise; - private queuedPromise: TPromise; - private queuedPromiseFactory: ITask; + private activePromise: TPromise | null; + private queuedPromise: TPromise | null; + private queuedPromiseFactory: ITask | null; constructor() { this.activePromise = null; @@ -109,26 +109,26 @@ export class Throttler { const onComplete = () => { this.queuedPromise = null; - const result = this.queue(this.queuedPromiseFactory); + const result = this.queue(this.queuedPromiseFactory!); this.queuedPromiseFactory = null; return result; }; this.queuedPromise = new TPromise(c => { - this.activePromise.then(onComplete, onComplete).then(c); + this.activePromise!.then(onComplete, onComplete).then(c); }); } return new TPromise((c, e) => { - this.queuedPromise.then(c, e); + this.queuedPromise!.then(c, e); }); } this.activePromise = promiseFactory(); return new TPromise((c, e) => { - this.activePromise.then((result: any) => { + this.activePromise!.then((result: any) => { this.activePromise = null; c(result); }, (err: any) => { @@ -175,10 +175,10 @@ export class SimpleThrottler { export class Delayer { private timeout: any; - private completionPromise: TPromise; - private doResolve: ValueCallback; + private completionPromise: TPromise | null; + private doResolve: ValueCallback | null; private doReject: (err: any) => void; - private task: ITask>; + private task: ITask> | null; constructor(public defaultDelay: number) { this.timeout = null; @@ -198,7 +198,7 @@ export class Delayer { }).then(() => { this.completionPromise = null; this.doResolve = null; - const task = this.task; + const task = this.task!; this.task = null; return task(); @@ -207,7 +207,7 @@ export class Delayer { this.timeout = setTimeout(() => { this.timeout = null; - this.doResolve(null); + this.doResolve!(null); }, delay); return this.completionPromise; @@ -363,11 +363,11 @@ export function sequence(promiseFactories: ITask>[]): Promise(promiseFactories: ITask>[], shouldStop: (t: T) => boolean = t => !!t, defaultValue: T = null): Promise { +export function first(promiseFactories: ITask>[], shouldStop: (t: T) => boolean = t => !!t, defaultValue: T | null = null): Promise { let index = 0; const len = promiseFactories.length; - const loop: () => Promise = () => { + const loop: () => Promise = () => { if (index >= len) { return Promise.resolve(defaultValue); } @@ -429,7 +429,7 @@ export class Limiter { private consume(): void { while (this.outstandingPromises.length && this.runningPromises < this.maxDegreeOfParalellism) { - const iLimitedTask = this.outstandingPromises.shift(); + const iLimitedTask = this.outstandingPromises.shift()!; this.runningPromises++; const promise = iLimitedTask.factory(); @@ -567,7 +567,7 @@ export class IntervalTimer extends Disposable { export class RunOnceScheduler { - protected runner: (...args: any[]) => void; + protected runner: ((...args: any[]) => void) | null; private timeoutToken: any; private timeout: number; @@ -621,7 +621,9 @@ export class RunOnceScheduler { } protected doRun(): void { - this.runner(); + if (this.runner) { + this.runner(); + } } } @@ -644,7 +646,9 @@ export class RunOnceWorker extends RunOnceScheduler { const units = this.units; this.units = []; - this.runner(units); + if (this.runner) { + this.runner(units); + } } dispose(): void { @@ -689,12 +693,30 @@ declare function cancelIdleCallback(handle: number): void; }); runWhenIdle = (runner, timeout = 0) => { let handle = setTimeout(() => runner(dummyIdle), timeout); - return { dispose() { clearTimeout(handle); handle = undefined; } }; + let disposed = false; + return { + dispose() { + if (disposed) { + return; + } + disposed = true; + clearTimeout(handle); + } + }; }; } else { runWhenIdle = (runner, timeout?) => { - let handle = requestIdleCallback(runner, typeof timeout === 'number' ? { timeout } : undefined); - return { dispose() { cancelIdleCallback(handle); handle = undefined; } }; + let handle: number = requestIdleCallback(runner, typeof timeout === 'number' ? { timeout } : undefined); + let disposed = false; + return { + dispose() { + if (disposed) { + return; + } + disposed = true; + cancelIdleCallback(handle); + } + }; }; } })(); diff --git a/src/vs/base/common/cancellation.ts b/src/vs/base/common/cancellation.ts index a68d1f3b3f7..39f672c9751 100644 --- a/src/vs/base/common/cancellation.ts +++ b/src/vs/base/common/cancellation.ts @@ -51,7 +51,7 @@ export namespace CancellationToken { class MutableToken implements CancellationToken { private _isCancelled: boolean = false; - private _emitter: Emitter; + private _emitter: Emitter | null = null; public cancel() { if (!this._isCancelled) { @@ -80,7 +80,7 @@ class MutableToken implements CancellationToken { public dispose(): void { if (this._emitter) { this._emitter.dispose(); - this._emitter = undefined; + this._emitter = null; } } } diff --git a/src/vs/base/common/collections.ts b/src/vs/base/common/collections.ts index 00feeb38739..05758a81246 100644 --- a/src/vs/base/common/collections.ts +++ b/src/vs/base/common/collections.ts @@ -45,7 +45,7 @@ export function size(from: IStringDictionary | INumberDictionary): numb return count; } -export function first(from: IStringDictionary | INumberDictionary): T { +export function first(from: IStringDictionary | INumberDictionary): T | undefined { for (let key in from) { if (hasOwnProperty.call(from, key)) { return from[key]; diff --git a/src/vs/base/common/glob.ts b/src/vs/base/common/glob.ts index 09853098d2e..cb4771b2d3c 100644 --- a/src/vs/base/common/glob.ts +++ b/src/vs/base/common/glob.ts @@ -248,7 +248,7 @@ const T5 = /^([\w\.-]+(\/[\w\.-]+)*)\/?$/; // something/else export type ParsedPattern = (path: string, basename?: string) => boolean; // The ParsedExpression returns a Promise iff hasSibling returns a Promise. -export type ParsedExpression = (path: string, basename?: string, hasSibling?: (name: string) => boolean | TPromise) => string | TPromise /* the matching pattern */; +export type ParsedExpression = (path: string, basename?: string, hasSibling?: (name: string) => boolean | TPromise) => string | null | TPromise /* the matching pattern */; export interface IGlobOptions { /** @@ -258,14 +258,14 @@ export interface IGlobOptions { } interface ParsedStringPattern { - (path: string, basename: string): string | TPromise /* the matching pattern */; + (path: string, basename: string): string | null | TPromise /* the matching pattern */; basenames?: string[]; patterns?: string[]; allBasenames?: string[]; allPaths?: string[]; } interface ParsedExpressionPattern { - (path: string, basename: string, name: string, hasSibling: (name: string) => boolean | TPromise): string | TPromise /* the matching pattern */; + (path: string, basename: string, name?: string, hasSibling?: (name: string) => boolean | TPromise): string | null | TPromise /* the matching pattern */; requiresSiblings?: boolean; allBasenames?: string[]; allPaths?: string[]; @@ -277,7 +277,7 @@ const FALSE = function () { return false; }; -const NULL = function (): string { +const NULL = function (): string | null { return null; }; @@ -305,7 +305,7 @@ function parsePattern(arg1: string | IRelativePattern, options: IGlobOptions): P } // Check for Trivias - let match: RegExpExecArray; + let match: RegExpExecArray | null; if (T1.test(pattern)) { // common pattern: **/*.txt just need endsWith check const base = pattern.substr(4); // '**/*'.length === 4 parsedPattern = function (path, basename) { @@ -530,7 +530,7 @@ export function isRelativePattern(obj: any): obj is IRelativePattern { */ export function parseToAsync(expression: IExpression, options?: IGlobOptions): ParsedExpression { const parsedExpression = parse(expression, options); - return (path: string, basename?: string, hasSibling?: (name: string) => boolean | TPromise): string | TPromise => { + return (path: string, basename?: string, hasSibling?: (name: string) => boolean | TPromise): string | null | TPromise => { const result = parsedExpression(path, basename, hasSibling); return result instanceof TPromise ? result : TPromise.as(result); }; @@ -554,7 +554,7 @@ function parsedExpression(expression: IExpression, options: IGlobOptions): Parse return NULL; } - if (!parsedPatterns.some(parsedPattern => (parsedPattern).requiresSiblings)) { + if (!parsedPatterns.some(parsedPattern => !!(parsedPattern).requiresSiblings)) { if (n === 1) { return parsedPatterns[0]; } @@ -585,7 +585,7 @@ function parsedExpression(expression: IExpression, options: IGlobOptions): Parse } const resultExpression: ParsedStringPattern = function (path: string, basename: string, hasSibling?: (name: string) => boolean | TPromise) { - let name: string; + let name: string | undefined = undefined; for (let i = 0, n = parsedPatterns.length; i < n; i++) { // Pattern matches path @@ -665,7 +665,10 @@ function aggregateBasenameMatches(parsedPatterns: (ParsedStringPattern | ParsedE return parsedPatterns; } - const basenames = basenamePatterns.reduce((all, current) => all.concat((current).basenames), []); + const basenames = basenamePatterns.reduce((all, current) => { + const basenames = (current).basenames; + return basenames ? all.concat(basenames) : all; + }, []); let patterns: string[]; if (result) { patterns = []; @@ -673,7 +676,10 @@ function aggregateBasenameMatches(parsedPatterns: (ParsedStringPattern | ParsedE patterns.push(result); } } else { - patterns = basenamePatterns.reduce((all, current) => all.concat((current).patterns), []); + patterns = basenamePatterns.reduce((all, current) => { + const patterns = (current).patterns; + return patterns ? all.concat(patterns) : all; + }, []); } const aggregate: ParsedStringPattern = function (path, basename) { if (!path) { diff --git a/src/vs/base/common/hash.ts b/src/vs/base/common/hash.ts index 18aac042f16..613c5e307fc 100644 --- a/src/vs/base/common/hash.ts +++ b/src/vs/base/common/hash.ts @@ -22,9 +22,9 @@ export function hash(obj: any, hashVal = 0): number { case 'number': return numberHash(obj, hashVal); case 'undefined': - return numberHash(obj, 937); + return numberHash(0, 937); default: - return numberHash(obj, 617); + return numberHash(0, 617); } } diff --git a/src/vs/base/common/map.ts b/src/vs/base/common/map.ts index be36c27b255..99b858b68c6 100644 --- a/src/vs/base/common/map.ts +++ b/src/vs/base/common/map.ts @@ -139,11 +139,11 @@ export class PathIterator implements IKeyIterator { class TernarySearchTreeNode { segment: string; - value: E; + value: E | undefined; key: string; - left: TernarySearchTreeNode; - mid: TernarySearchTreeNode; - right: TernarySearchTreeNode; + left: TernarySearchTreeNode | undefined; + mid: TernarySearchTreeNode | undefined; + right: TernarySearchTreeNode | undefined; isEmpty(): boolean { return !this.left && !this.mid && !this.right && !this.value; @@ -161,7 +161,7 @@ export class TernarySearchTree { } private _iter: IKeyIterator; - private _root: TernarySearchTreeNode; + private _root: TernarySearchTreeNode | undefined; constructor(segments: IKeyIterator) { this._iter = segments; @@ -171,7 +171,7 @@ export class TernarySearchTree { this._root = undefined; } - set(key: string, element: E): E { + set(key: string, element: E): E | undefined { let iter = this._iter.reset(key); let node: TernarySearchTreeNode; @@ -217,7 +217,7 @@ export class TernarySearchTree { return oldElement; } - get(key: string): E { + get(key: string): E | undefined { let iter = this._iter.reset(key); let node = this._root; while (node) { @@ -267,7 +267,7 @@ export class TernarySearchTree { // clean up empty nodes while (stack.length > 0 && node.isEmpty()) { - let [dir, parent] = stack.pop(); + let [dir, parent] = stack.pop()!; switch (dir) { case 1: parent.left = undefined; break; case 0: parent.mid = undefined; break; @@ -280,10 +280,10 @@ export class TernarySearchTree { } } - findSubstr(key: string): E { + findSubstr(key: string): E | undefined { let iter = this._iter.reset(key); let node = this._root; - let candidate: E; + let candidate: E | undefined = undefined; while (node) { let val = iter.cmp(node.segment); if (val > 0) { @@ -304,7 +304,7 @@ export class TernarySearchTree { return node && node.value || candidate; } - findSuperstr(key: string): Iterator { + findSuperstr(key: string): Iterator | undefined { let iter = this._iter.reset(key); let node = this._root; while (node) { @@ -360,7 +360,7 @@ export class TernarySearchTree { this._forEach(this._root, callback); } - private _forEach(node: TernarySearchTreeNode, callback: (value: E, index: string) => any) { + private _forEach(node: TernarySearchTreeNode | undefined, callback: (value: E, index: string) => any) { if (node) { // left this._forEach(node.left, callback); @@ -639,11 +639,11 @@ export class LinkedMap { this.clear(); return; } - let current = this._head; + let current = this._head!; let currentSize = this.size; while (current && currentSize > newSize) { this._map.delete(current.key); - current = current.next; + current = current.next!; currentSize--; } this._head = current; diff --git a/src/vs/base/common/scrollable.ts b/src/vs/base/common/scrollable.ts index 398ced04031..b31cc9f5223 100644 --- a/src/vs/base/common/scrollable.ts +++ b/src/vs/base/common/scrollable.ts @@ -182,7 +182,7 @@ export class Scrollable extends Disposable { private _smoothScrollDuration: number; private readonly _scheduleAtNextAnimationFrame: (callback: () => void) => IDisposable; private _state: ScrollState; - private _smoothScrolling: SmoothScrollingOperation; + private _smoothScrolling: SmoothScrollingOperation | null; private _onScroll = this._register(new Emitter()); public readonly onScroll: Event = this._onScroll.event; @@ -300,6 +300,9 @@ export class Scrollable extends Disposable { } private _performSmoothScrolling(): void { + if (!this._smoothScrolling) { + return; + } const update = this._smoothScrolling.tick(); const newState = this._state.withScrollPosition(update); @@ -372,7 +375,7 @@ export class SmoothScrollingOperation { public to: ISmoothScrollPosition; public readonly duration: number; private readonly _startTime: number; - public animationFrameDisposable: IDisposable; + public animationFrameDisposable: IDisposable | null; private scrollLeft: IAnimation; private scrollTop: IAnimation; diff --git a/src/vs/base/worker/defaultWorkerFactory.ts b/src/vs/base/worker/defaultWorkerFactory.ts index d14213cb98a..a089a443094 100644 --- a/src/vs/base/worker/defaultWorkerFactory.ts +++ b/src/vs/base/worker/defaultWorkerFactory.ts @@ -31,7 +31,7 @@ function getWorker(workerId: string, label: string): Worker { class WebWorker implements IWorker { private id: number; - private worker: Worker; + private worker: Worker | null; constructor(moduleId: string, id: number, label: string, onMessageCallback: IWorkerCallback, onErrorCallback: (err: any) => void) { this.id = id; @@ -56,7 +56,9 @@ class WebWorker implements IWorker { } public dispose(): void { - this.worker.terminate(); + if (this.worker) { + this.worker.terminate(); + } this.worker = null; } } diff --git a/src/vs/editor/common/core/range.ts b/src/vs/editor/common/core/range.ts index 7a6bb5ec36f..864cc041bca 100644 --- a/src/vs/editor/common/core/range.ts +++ b/src/vs/editor/common/core/range.ts @@ -223,7 +223,7 @@ export class Range { /** * Test if range `a` equals `b`. */ - public static equalsRange(a: IRange, b: IRange): boolean { + public static equalsRange(a: IRange | null, b: IRange | null): boolean { return ( !!a && !!b && diff --git a/src/vs/editor/contrib/find/findState.ts b/src/vs/editor/contrib/find/findState.ts index 09641dec6df..fdd0b9093ba 100644 --- a/src/vs/editor/contrib/find/findState.ts +++ b/src/vs/editor/contrib/find/findState.ts @@ -65,10 +65,10 @@ export class FindReplaceState implements IDisposable { private _wholeWordOverride: FindOptionOverride; private _matchCase: boolean; private _matchCaseOverride: FindOptionOverride; - private _searchScope: Range; + private _searchScope: Range | null; private _matchesPosition: number; private _matchesCount: number; - private _currentMatch: Range; + private _currentMatch: Range | null; private readonly _onFindReplaceStateChange: Emitter; public get searchString(): string { return this._searchString; } @@ -83,10 +83,10 @@ export class FindReplaceState implements IDisposable { public get actualWholeWord(): boolean { return this._wholeWord; } public get actualMatchCase(): boolean { return this._matchCase; } - public get searchScope(): Range { return this._searchScope; } + public get searchScope(): Range | null { return this._searchScope; } public get matchesPosition(): number { return this._matchesPosition; } public get matchesCount(): number { return this._matchesCount; } - public get currentMatch(): Range { return this._currentMatch; } + public get currentMatch(): Range | null { return this._currentMatch; } public get onFindReplaceStateChange(): Event { return this._onFindReplaceStateChange.event; } constructor() { diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index b0d56c0f4ab..293a553d05a 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -624,7 +624,7 @@ declare namespace monaco { /** * Test if range `a` equals `b`. */ - static equalsRange(a: IRange, b: IRange): boolean; + static equalsRange(a: IRange | null, b: IRange | null): boolean; /** * Return the end position (which will be after or equal to the start position) */ diff --git a/src/vs/platform/contextkey/common/contextkey.ts b/src/vs/platform/contextkey/common/contextkey.ts index 678c3d109d0..77f7de8a67e 100644 --- a/src/vs/platform/contextkey/common/contextkey.ts +++ b/src/vs/platform/contextkey/common/contextkey.ts @@ -42,7 +42,7 @@ export abstract class ContextKeyExpr { return new ContextKeyAndExpr(expr); } - public static deserialize(serialized: string): ContextKeyExpr { + public static deserialize(serialized: string): ContextKeyExpr | null { if (!serialized) { return null; } @@ -96,7 +96,7 @@ export abstract class ContextKeyExpr { return serializedValue; } - private static _deserializeRegexValue(serializedValue: string): RegExp { + private static _deserializeRegexValue(serializedValue: string): RegExp | null { if (isFalsyOrWhitespace(serializedValue)) { console.warn('missing regexp-value for =~-expression'); @@ -123,7 +123,7 @@ export abstract class ContextKeyExpr { public abstract getType(): ContextKeyExprType; public abstract equals(other: ContextKeyExpr): boolean; public abstract evaluate(context: IContext): boolean; - public abstract normalize(): ContextKeyExpr; + public abstract normalize(): ContextKeyExpr | null; public abstract serialize(): string; public abstract keys(): string[]; } @@ -358,7 +358,7 @@ export class ContextKeyNotExpr implements ContextKeyExpr { export class ContextKeyRegexExpr implements ContextKeyExpr { - constructor(private key: string, private regexp: RegExp) { + constructor(private key: string, private regexp: RegExp | null) { // } @@ -373,11 +373,12 @@ export class ContextKeyRegexExpr implements ContextKeyExpr { if (this.key > other.key) { return 1; } - const source = this.regexp ? this.regexp.source : undefined; - if (source < other.regexp.source) { + const thisSource = this.regexp ? this.regexp.source : ''; + const otherSource = other.regexp ? other.regexp.source : ''; + if (thisSource < otherSource) { return -1; } - if (source > other.regexp.source) { + if (thisSource > otherSource) { return 1; } return 0; @@ -385,8 +386,9 @@ export class ContextKeyRegexExpr implements ContextKeyExpr { public equals(other: ContextKeyExpr): boolean { if (other instanceof ContextKeyRegexExpr) { - const source = this.regexp ? this.regexp.source : undefined; - return (this.key === other.key && source === other.regexp.source); + const thisSource = this.regexp ? this.regexp.source : ''; + const otherSource = other.regexp ? other.regexp.source : ''; + return (this.key === other.key && thisSource === otherSource); } return false; } @@ -451,7 +453,7 @@ export class ContextKeyAndExpr implements ContextKeyExpr { if (arr) { for (let i = 0, len = arr.length; i < len; i++) { - let e = arr[i]; + let e: ContextKeyExpr | null = arr[i]; if (!e) { continue; } @@ -475,7 +477,7 @@ export class ContextKeyAndExpr implements ContextKeyExpr { return expr; } - public normalize(): ContextKeyExpr { + public normalize(): ContextKeyExpr | null { if (this.expr.length === 0) { return null; } @@ -492,7 +494,11 @@ export class ContextKeyAndExpr implements ContextKeyExpr { return ''; } if (this.expr.length === 1) { - return this.normalize().serialize(); + const normalized = this.normalize(); + if (!normalized) { + return ''; + } + return normalized.serialize(); } return this.expr.map(e => e.serialize()).join(' && '); } diff --git a/src/vs/platform/files/common/files.ts b/src/vs/platform/files/common/files.ts index 49c461690f2..514c81e594e 100644 --- a/src/vs/platform/files/common/files.ts +++ b/src/vs/platform/files/common/files.ts @@ -236,7 +236,7 @@ export class FileOperationEvent { return this._resource; } - get target(): IFileStat { + get target(): IFileStat | undefined { return this._target; } @@ -484,12 +484,15 @@ export interface IStringStream { * Will return null when finished. */ export interface ITextSnapshot { - read(): string; + read(): string | null; } export class StringSnapshot implements ITextSnapshot { - constructor(private _value: string) { } - read(): string { + private _value: string | null; + constructor(value: string) { + this._value = value; + } + read(): string | null { let ret = this._value; this._value = null; return ret; @@ -500,7 +503,7 @@ export class StringSnapshot implements ITextSnapshot { */ export function snapshotToString(snapshot: ITextSnapshot): string { const chunks: string[] = []; - let chunk: string; + let chunk: string | null; while (typeof (chunk = snapshot.read()) === 'string') { chunks.push(chunk); } diff --git a/src/vs/platform/theme/common/colorRegistry.ts b/src/vs/platform/theme/common/colorRegistry.ts index cebda41a9c4..9a185a68f15 100644 --- a/src/vs/platform/theme/common/colorRegistry.ts +++ b/src/vs/platform/theme/common/colorRegistry.ts @@ -19,18 +19,18 @@ export interface ColorContribution { readonly description: string; readonly defaults: ColorDefaults; readonly needsTransparency: boolean; - readonly deprecationMessage: string; + readonly deprecationMessage: string | undefined; } export interface ColorFunction { - (theme: ITheme): Color; + (theme: ITheme): Color | null; } export interface ColorDefaults { - light: ColorValue; - dark: ColorValue; - hc: ColorValue; + light: ColorValue | null; + dark: ColorValue | null; + hc: ColorValue | null; } /** @@ -61,7 +61,7 @@ export interface IColorRegistry { /** * Gets the default color of the given id */ - resolveDefaultColor(id: ColorIdentifier, theme: ITheme): Color; + resolveDefaultColor(id: ColorIdentifier, theme: ITheme): Color | null; /** * JSON schema for an object to assign color values to one of the color contrbutions. @@ -93,9 +93,9 @@ class ColorRegistry implements IColorRegistry { if (deprecationMessage) { propertySchema.deprecationMessage = deprecationMessage; } - this.colorSchema.properties[id] = propertySchema; - this.colorReferenceSchema.enum.push(id); - this.colorReferenceSchema.enumDescriptions.push(description); + this.colorSchema.properties![id] = propertySchema; + this.colorReferenceSchema.enum!.push(id); + this.colorReferenceSchema.enumDescriptions!.push(description); return id; } @@ -103,7 +103,7 @@ class ColorRegistry implements IColorRegistry { return Object.keys(this.colorsById).map(id => this.colorsById[id]); } - public resolveDefaultColor(id: ColorIdentifier, theme: ITheme): Color { + public resolveDefaultColor(id: ColorIdentifier, theme: ITheme): Color | null { let colorDesc = this.colorsById[id]; if (colorDesc && colorDesc.defaults) { let colorValue = colorDesc.defaults[theme.type]; @@ -412,7 +412,7 @@ function lessProminent(colorValue: ColorValue, backgroundColorValue: ColorValue, /** * @param colorValue Resolve a color value in the context of a theme */ -function resolveColorValue(colorValue: ColorValue, theme: ITheme): Color { +function resolveColorValue(colorValue: ColorValue | null, theme: ITheme): Color | null { if (colorValue === null) { return null; } else if (typeof colorValue === 'string') { -- GitLab