Skip to content

Commit

Permalink
Better typings for IteratorResult (#60565)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexdima committed Oct 11, 2018
1 parent 4ad3ac0 commit 3e5bdc4
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 107 deletions.
2 changes: 2 additions & 0 deletions src/tsconfig.strictNullChecks.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
38 changes: 23 additions & 15 deletions src/vs/base/common/iterator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,16 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

export interface IteratorResult<T> {
readonly done: boolean;
readonly value: T | undefined;
export interface IteratorDefinedResult<T> {
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<T> = IteratorDefinedResult<T> | IteratorUndefinedResult;

export interface Iterator<T> {
next(): IteratorResult<T>;
Expand All @@ -15,7 +21,7 @@ export interface Iterator<T> {
export module Iterator {
const _empty: Iterator<any> = {
next() {
return { done: true, value: undefined };
return FIN;
}
};

Expand All @@ -27,7 +33,7 @@ export module Iterator {
return {
next(): IteratorResult<T> {
if (index >= length) {
return { done: true, value: undefined };
return FIN;
}

return { done: false, value: array[index++] };
Expand All @@ -48,8 +54,12 @@ export module Iterator {
export function map<T, R>(iterator: Iterator<T>, fn: (t: T) => R): Iterator<R> {
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) };
}
}
};
}
Expand All @@ -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 };
}
}
}
Expand All @@ -74,7 +82,7 @@ export module Iterator {

export function forEach<T>(iterator: Iterator<T>, fn: (t: T) => void): void {
for (let next = iterator.next(); !next.done; next = iterator.next()) {
fn(next.value!);
fn(next.value);
}
}

Expand Down
26 changes: 10 additions & 16 deletions src/vs/base/common/linkedList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<E> {
element: E;
Expand Down Expand Up @@ -94,26 +94,20 @@ export class LinkedList<E> {
}

iterator(): Iterator<E> {
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<E> {
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;
}
};
Expand Down
17 changes: 8 additions & 9 deletions src/vs/base/common/map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<V = any>(set: Set<V>): V[];
export function values<K = any, V = any>(map: Map<K, V>): V[];
Expand Down Expand Up @@ -332,24 +332,23 @@ export class TernarySearchTree<E> {
}

private _nodeIterator(node: TernarySearchTreeNode<E>): Iterator<E> {
let res = {
done: false,
value: undefined
};
let res: { done: false; value: E; };
let idx: number;
let data: E[];
let next = () => {
let next = (): IteratorResult<E> => {
if (!data) {
// lazy till first invocation
data = [];
idx = 0;
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;
Expand Down
103 changes: 48 additions & 55 deletions src/vs/base/common/worker/simpleWorker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,24 +84,18 @@ class SimpleWorkerProtocol {

public sendMessage(method: string, args: any[]): Promise<any> {
let req = String(++this._lastSentReq);
let reply: IMessageReply = {
resolve: null,
reject: null
};
let result = new Promise<any>((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<any>((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 {
Expand All @@ -110,6 +104,7 @@ class SimpleWorkerProtocol {
message = JSON.parse(serializedMessage);
} catch (e) {
// nothing
return;
}
if (!message || !message.vsWorker) {
return;
Expand Down Expand Up @@ -191,8 +186,7 @@ export class SimpleWorkerClient<T> 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',
Expand All @@ -202,7 +196,9 @@ export class SimpleWorkerClient<T> extends Disposable {
(err: any) => {
// in Firefox, web workers fail lazily :(
// we will reject the proxy
lazyProxyReject(err);
if (lazyProxyReject) {
lazyProxyReject(err);
}
}
));

Expand All @@ -227,26 +223,25 @@ export class SimpleWorkerClient<T> extends Disposable {
loaderConfiguration = (<any>self).requirejs.s.contexts._.config;
}

this._lazyProxy = new Promise<T>((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 = <T>{};
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<T>((resolve, reject) => {
lazyProxyReject = reject;
this._onModuleLoaded.then((availableMethods: string[]) => {
let proxy = <T>{};
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
Expand Down Expand Up @@ -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 => {
Expand Down Expand Up @@ -353,29 +348,27 @@ export class SimpleWorkerServer {
(<any>self).require.config(loaderConfig);
}

let resolve: (value?: string[]) => void;
let reject: (error?: any) => void;
let r = new Promise<string[]>((_resolve, _reject) => {
resolve = _resolve;
reject = _reject;
});

// Use the global require to be sure to get the global config
(<any>self).require([moduleId], (...result: any[]) => {
let handlerModule = result[0];
this._requestHandler = handlerModule.create();
return new Promise<string[]>((resolve, reject) => {
// Use the global require to be sure to get the global config
(<any>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);
});
}
}

Expand Down
Loading

0 comments on commit 3e5bdc4

Please sign in to comment.