diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 083f4a856b582..80ed914f68081 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -21,6 +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/functional.ts", "./vs/base/common/idGenerator.ts", "./vs/base/common/iterator.ts", @@ -49,6 +50,7 @@ "./vs/base/common/urilpc.ts", "./vs/base/common/uuid.ts", "./vs/base/common/winjs.base.d.ts", + "./vs/base/common/worker/simpleWorker.ts", "./vs/base/node/paths.ts", "./vs/base/node/ports.ts", "./vs/base/parts/contextmenu/common/contextmenu.ts", diff --git a/src/vs/base/common/iterator.ts b/src/vs/base/common/iterator.ts index eb3f9450f0799..038bf2632222d 100644 --- a/src/vs/base/common/iterator.ts +++ b/src/vs/base/common/iterator.ts @@ -3,10 +3,16 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -export interface IteratorResult { - readonly done: boolean; - readonly value: T | undefined; +export interface IteratorDefinedResult { + readonly done: false; + readonly value: T; } +export interface IteratorUndefinedResult { + readonly done: true; + readonly value: undefined; +} +export const FIN: IteratorUndefinedResult = { done: true, value: undefined }; +export type IteratorResult = IteratorDefinedResult | IteratorUndefinedResult; export interface Iterator { next(): IteratorResult; @@ -15,7 +21,7 @@ export interface Iterator { export module Iterator { const _empty: Iterator = { next() { - return { done: true, value: undefined }; + return FIN; } }; @@ -27,7 +33,7 @@ export module Iterator { return { next(): IteratorResult { if (index >= length) { - return { done: true, value: undefined }; + return FIN; } return { done: false, value: array[index++] }; @@ -48,8 +54,12 @@ export module Iterator { export function map(iterator: Iterator, fn: (t: T) => R): Iterator { return { next() { - const { done, value } = iterator.next(); - return { done, value: done ? undefined : fn(value!) }; + const element = iterator.next(); + if (element.done) { + return FIN; + } else { + return { done: false, value: fn(element.value) }; + } } }; } @@ -58,14 +68,12 @@ export module Iterator { return { next() { while (true) { - const { done, value } = iterator.next(); - - if (done) { - return { done, value: undefined }; + const element = iterator.next(); + if (element.done) { + return FIN; } - - if (fn(value!)) { - return { done, value }; + if (fn(element.value)) { + return { done: false, value: element.value }; } } } @@ -74,7 +82,7 @@ export module Iterator { export function forEach(iterator: Iterator, fn: (t: T) => void): void { for (let next = iterator.next(); !next.done; next = iterator.next()) { - fn(next.value!); + fn(next.value); } } diff --git a/src/vs/base/common/linkedList.ts b/src/vs/base/common/linkedList.ts index 5600be4b3bddc..898586f29abb6 100644 --- a/src/vs/base/common/linkedList.ts +++ b/src/vs/base/common/linkedList.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Iterator } from 'vs/base/common/iterator'; +import { Iterator, IteratorResult, FIN } from 'vs/base/common/iterator'; class Node { element: E; @@ -94,26 +94,20 @@ export class LinkedList { } iterator(): Iterator { - let element: { done: boolean; value: E | undefined }; + let element: { done: false; value: E; }; let node = this._first; return { - next(): { done: boolean; value: E | undefined } { + next(): IteratorResult { if (!node) { - if (!element) { - element = { done: true, value: undefined }; - } else { - element.done = true; - element.value = undefined; - } + return FIN; + } + + if (!element) { + element = { done: false, value: node.element }; } else { - if (!element) { - element = { done: false, value: node.element }; - } else { - element.done = false; - element.value = node.element; - } - node = node.next; + element.value = node.element; } + node = node.next; return element; } }; diff --git a/src/vs/base/common/map.ts b/src/vs/base/common/map.ts index 134dfe33cb184..be36c27b255a7 100644 --- a/src/vs/base/common/map.ts +++ b/src/vs/base/common/map.ts @@ -5,7 +5,7 @@ import { URI } from 'vs/base/common/uri'; import { CharCode } from 'vs/base/common/charCode'; -import { Iterator } from './iterator'; +import { Iterator, IteratorResult, FIN } from './iterator'; export function values(set: Set): V[]; export function values(map: Map): V[]; @@ -332,13 +332,10 @@ export class TernarySearchTree { } private _nodeIterator(node: TernarySearchTreeNode): Iterator { - let res = { - done: false, - value: undefined - }; + let res: { done: false; value: E; }; let idx: number; let data: E[]; - let next = () => { + let next = (): IteratorResult => { if (!data) { // lazy till first invocation data = []; @@ -346,10 +343,12 @@ export class TernarySearchTree { this._forEach(node, value => data.push(value)); } if (idx >= data.length) { - res.done = true; - res.value = undefined; + return FIN; + } + + if (!res) { + res = { done: false, value: data[idx++] }; } else { - res.done = false; res.value = data[idx++]; } return res; diff --git a/src/vs/base/common/worker/simpleWorker.ts b/src/vs/base/common/worker/simpleWorker.ts index c55e76ee6f184..08531cd345991 100644 --- a/src/vs/base/common/worker/simpleWorker.ts +++ b/src/vs/base/common/worker/simpleWorker.ts @@ -84,24 +84,18 @@ class SimpleWorkerProtocol { public sendMessage(method: string, args: any[]): Promise { let req = String(++this._lastSentReq); - let reply: IMessageReply = { - resolve: null, - reject: null - }; - let result = new Promise((resolve, reject) => { - reply.resolve = resolve; - reply.reject = reject; - }); - this._pendingReplies[req] = reply; - - this._send({ - vsWorker: this._workerId, - req: req, - method: method, - args: args + return new Promise((resolve, reject) => { + this._pendingReplies[req] = { + resolve: resolve, + reject: reject + }; + this._send({ + vsWorker: this._workerId, + req: req, + method: method, + args: args + }); }); - - return result; } public handleMessage(serializedMessage: string): void { @@ -110,6 +104,7 @@ class SimpleWorkerProtocol { message = JSON.parse(serializedMessage); } catch (e) { // nothing + return; } if (!message || !message.vsWorker) { return; @@ -191,8 +186,7 @@ export class SimpleWorkerClient extends Disposable { constructor(workerFactory: IWorkerFactory, moduleId: string) { super(); - let lazyProxyResolve: (v: T) => void = null; - let lazyProxyReject: (err: any) => void = null; + let lazyProxyReject: ((err: any) => void) | null = null; this._worker = this._register(workerFactory.create( 'vs/base/common/worker/simpleWorker', @@ -202,7 +196,9 @@ export class SimpleWorkerClient extends Disposable { (err: any) => { // in Firefox, web workers fail lazily :( // we will reject the proxy - lazyProxyReject(err); + if (lazyProxyReject) { + lazyProxyReject(err); + } } )); @@ -227,26 +223,25 @@ export class SimpleWorkerClient extends Disposable { loaderConfiguration = (self).requirejs.s.contexts._.config; } - this._lazyProxy = new Promise((resolve, reject) => { - lazyProxyResolve = resolve; - lazyProxyReject = reject; - }); - // Send initialize message this._onModuleLoaded = this._protocol.sendMessage(INITIALIZE, [ this._worker.getId(), moduleId, loaderConfiguration ]); - this._onModuleLoaded.then((availableMethods: string[]) => { - let proxy = {}; - for (let i = 0; i < availableMethods.length; i++) { - (proxy as any)[availableMethods[i]] = createProxyMethod(availableMethods[i], proxyMethodRequest); - } - lazyProxyResolve(proxy); - }, (e) => { - lazyProxyReject(e); - this._onError('Worker failed to load ' + moduleId, e); + + this._lazyProxy = new Promise((resolve, reject) => { + lazyProxyReject = reject; + this._onModuleLoaded.then((availableMethods: string[]) => { + let proxy = {}; + for (let i = 0; i < availableMethods.length; i++) { + (proxy as any)[availableMethods[i]] = createProxyMethod(availableMethods[i], proxyMethodRequest); + } + resolve(proxy); + }, (e) => { + reject(e); + this._onError('Worker failed to load ' + moduleId, e); + }); }); // Create proxy to loaded code @@ -290,10 +285,10 @@ export interface IRequestHandler { */ export class SimpleWorkerServer { - private _requestHandler: IRequestHandler; + private _requestHandler: IRequestHandler | null; private _protocol: SimpleWorkerProtocol; - constructor(postSerializedMessage: (msg: string) => void, requestHandler: IRequestHandler) { + constructor(postSerializedMessage: (msg: string) => void, requestHandler: IRequestHandler | null) { this._requestHandler = requestHandler; this._protocol = new SimpleWorkerProtocol({ sendMessage: (msg: string): void => { @@ -353,29 +348,27 @@ export class SimpleWorkerServer { (self).require.config(loaderConfig); } - let resolve: (value?: string[]) => void; - let reject: (error?: any) => void; - let r = new Promise((_resolve, _reject) => { - resolve = _resolve; - reject = _reject; - }); - - // Use the global require to be sure to get the global config - (self).require([moduleId], (...result: any[]) => { - let handlerModule = result[0]; - this._requestHandler = handlerModule.create(); + return new Promise((resolve, reject) => { + // Use the global require to be sure to get the global config + (self).require([moduleId], (...result: any[]) => { + let handlerModule = result[0]; + this._requestHandler = handlerModule.create(); - let methods: string[] = []; - for (let prop in this._requestHandler) { - if (typeof this._requestHandler[prop] === 'function') { - methods.push(prop); + if (!this._requestHandler) { + reject(new Error(`No RequestHandler!`)); + return; } - } - resolve(methods); - }, reject); + let methods: string[] = []; + for (let prop in this._requestHandler) { + if (typeof this._requestHandler[prop] === 'function') { + methods.push(prop); + } + } - return r; + resolve(methods); + }, reject); + }); } } diff --git a/src/vs/editor/common/services/editorSimpleWorker.ts b/src/vs/editor/common/services/editorSimpleWorker.ts index c38a201b8b883..a2e0e336409f1 100644 --- a/src/vs/editor/common/services/editorSimpleWorker.ts +++ b/src/vs/editor/common/services/editorSimpleWorker.ts @@ -19,7 +19,7 @@ import { getWordAtText, ensureValidWordDefinition } from 'vs/editor/common/model import { createMonacoBaseAPI } from 'vs/editor/common/standalone/standaloneBase'; import { IWordAtPosition, EndOfLineSequence } from 'vs/editor/common/model'; import { globals } from 'vs/base/common/platform'; -import { Iterator } from 'vs/base/common/iterator'; +import { Iterator, IteratorResult, FIN } from 'vs/base/common/iterator'; import { mergeSort } from 'vs/base/common/arrays'; export interface IMirrorModel { @@ -147,24 +147,25 @@ class MirrorModel extends BaseMirrorModel implements ICommonModel { } public createWordIterator(wordDefinition: RegExp): Iterator { - let obj = { - done: false, - value: '' - }; + let obj: { done: false; value: string; }; let lineNumber = 0; let lineText: string; let wordRangesIdx = 0; let wordRanges: IWordRange[] = []; - let next = (): { done: boolean; value: string } => { + let next = (): IteratorResult => { if (wordRangesIdx < wordRanges.length) { - obj.done = false; - obj.value = lineText.substring(wordRanges[wordRangesIdx].start, wordRanges[wordRangesIdx].end); + const value = lineText.substring(wordRanges[wordRangesIdx].start, wordRanges[wordRangesIdx].end); wordRangesIdx += 1; + if (!obj) { + obj = { done: false, value: value }; + } else { + obj.value = value; + } + return obj; } else if (lineNumber >= this._lines.length) { - obj.done = true; - obj.value = undefined; + return FIN; } else { lineText = this._lines[lineNumber]; @@ -173,8 +174,6 @@ class MirrorModel extends BaseMirrorModel implements ICommonModel { lineNumber += 1; return next(); } - - return obj; }; return { next }; }