Skip to content

Commit 3e5bdc4

Browse files
committed
Better typings for IteratorResult (#60565)
1 parent 4ad3ac0 commit 3e5bdc4

File tree

6 files changed

+102
-107
lines changed

6 files changed

+102
-107
lines changed

Diff for: src/tsconfig.strictNullChecks.json

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"./vs/base/common/diff/diff.ts",
2222
"./vs/base/common/diff/diffChange.ts",
2323
"./vs/base/common/errors.ts",
24+
// "./vs/base/common/event.ts",
2425
"./vs/base/common/functional.ts",
2526
"./vs/base/common/idGenerator.ts",
2627
"./vs/base/common/iterator.ts",
@@ -49,6 +50,7 @@
4950
"./vs/base/common/urilpc.ts",
5051
"./vs/base/common/uuid.ts",
5152
"./vs/base/common/winjs.base.d.ts",
53+
"./vs/base/common/worker/simpleWorker.ts",
5254
"./vs/base/node/paths.ts",
5355
"./vs/base/node/ports.ts",
5456
"./vs/base/parts/contextmenu/common/contextmenu.ts",

Diff for: src/vs/base/common/iterator.ts

+23-15
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,16 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
export interface IteratorResult<T> {
7-
readonly done: boolean;
8-
readonly value: T | undefined;
6+
export interface IteratorDefinedResult<T> {
7+
readonly done: false;
8+
readonly value: T;
99
}
10+
export interface IteratorUndefinedResult {
11+
readonly done: true;
12+
readonly value: undefined;
13+
}
14+
export const FIN: IteratorUndefinedResult = { done: true, value: undefined };
15+
export type IteratorResult<T> = IteratorDefinedResult<T> | IteratorUndefinedResult;
1016

1117
export interface Iterator<T> {
1218
next(): IteratorResult<T>;
@@ -15,7 +21,7 @@ export interface Iterator<T> {
1521
export module Iterator {
1622
const _empty: Iterator<any> = {
1723
next() {
18-
return { done: true, value: undefined };
24+
return FIN;
1925
}
2026
};
2127

@@ -27,7 +33,7 @@ export module Iterator {
2733
return {
2834
next(): IteratorResult<T> {
2935
if (index >= length) {
30-
return { done: true, value: undefined };
36+
return FIN;
3137
}
3238

3339
return { done: false, value: array[index++] };
@@ -48,8 +54,12 @@ export module Iterator {
4854
export function map<T, R>(iterator: Iterator<T>, fn: (t: T) => R): Iterator<R> {
4955
return {
5056
next() {
51-
const { done, value } = iterator.next();
52-
return { done, value: done ? undefined : fn(value!) };
57+
const element = iterator.next();
58+
if (element.done) {
59+
return FIN;
60+
} else {
61+
return { done: false, value: fn(element.value) };
62+
}
5363
}
5464
};
5565
}
@@ -58,14 +68,12 @@ export module Iterator {
5868
return {
5969
next() {
6070
while (true) {
61-
const { done, value } = iterator.next();
62-
63-
if (done) {
64-
return { done, value: undefined };
71+
const element = iterator.next();
72+
if (element.done) {
73+
return FIN;
6574
}
66-
67-
if (fn(value!)) {
68-
return { done, value };
75+
if (fn(element.value)) {
76+
return { done: false, value: element.value };
6977
}
7078
}
7179
}
@@ -74,7 +82,7 @@ export module Iterator {
7482

7583
export function forEach<T>(iterator: Iterator<T>, fn: (t: T) => void): void {
7684
for (let next = iterator.next(); !next.done; next = iterator.next()) {
77-
fn(next.value!);
85+
fn(next.value);
7886
}
7987
}
8088

Diff for: src/vs/base/common/linkedList.ts

+10-16
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { Iterator } from 'vs/base/common/iterator';
6+
import { Iterator, IteratorResult, FIN } from 'vs/base/common/iterator';
77

88
class Node<E> {
99
element: E;
@@ -94,26 +94,20 @@ export class LinkedList<E> {
9494
}
9595

9696
iterator(): Iterator<E> {
97-
let element: { done: boolean; value: E | undefined };
97+
let element: { done: false; value: E; };
9898
let node = this._first;
9999
return {
100-
next(): { done: boolean; value: E | undefined } {
100+
next(): IteratorResult<E> {
101101
if (!node) {
102-
if (!element) {
103-
element = { done: true, value: undefined };
104-
} else {
105-
element.done = true;
106-
element.value = undefined;
107-
}
102+
return FIN;
103+
}
104+
105+
if (!element) {
106+
element = { done: false, value: node.element };
108107
} else {
109-
if (!element) {
110-
element = { done: false, value: node.element };
111-
} else {
112-
element.done = false;
113-
element.value = node.element;
114-
}
115-
node = node.next;
108+
element.value = node.element;
116109
}
110+
node = node.next;
117111
return element;
118112
}
119113
};

Diff for: src/vs/base/common/map.ts

+8-9
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import { URI } from 'vs/base/common/uri';
77
import { CharCode } from 'vs/base/common/charCode';
8-
import { Iterator } from './iterator';
8+
import { Iterator, IteratorResult, FIN } from './iterator';
99

1010
export function values<V = any>(set: Set<V>): V[];
1111
export function values<K = any, V = any>(map: Map<K, V>): V[];
@@ -332,24 +332,23 @@ export class TernarySearchTree<E> {
332332
}
333333

334334
private _nodeIterator(node: TernarySearchTreeNode<E>): Iterator<E> {
335-
let res = {
336-
done: false,
337-
value: undefined
338-
};
335+
let res: { done: false; value: E; };
339336
let idx: number;
340337
let data: E[];
341-
let next = () => {
338+
let next = (): IteratorResult<E> => {
342339
if (!data) {
343340
// lazy till first invocation
344341
data = [];
345342
idx = 0;
346343
this._forEach(node, value => data.push(value));
347344
}
348345
if (idx >= data.length) {
349-
res.done = true;
350-
res.value = undefined;
346+
return FIN;
347+
}
348+
349+
if (!res) {
350+
res = { done: false, value: data[idx++] };
351351
} else {
352-
res.done = false;
353352
res.value = data[idx++];
354353
}
355354
return res;

Diff for: src/vs/base/common/worker/simpleWorker.ts

+48-55
Original file line numberDiff line numberDiff line change
@@ -84,24 +84,18 @@ class SimpleWorkerProtocol {
8484

8585
public sendMessage(method: string, args: any[]): Promise<any> {
8686
let req = String(++this._lastSentReq);
87-
let reply: IMessageReply = {
88-
resolve: null,
89-
reject: null
90-
};
91-
let result = new Promise<any>((resolve, reject) => {
92-
reply.resolve = resolve;
93-
reply.reject = reject;
94-
});
95-
this._pendingReplies[req] = reply;
96-
97-
this._send({
98-
vsWorker: this._workerId,
99-
req: req,
100-
method: method,
101-
args: args
87+
return new Promise<any>((resolve, reject) => {
88+
this._pendingReplies[req] = {
89+
resolve: resolve,
90+
reject: reject
91+
};
92+
this._send({
93+
vsWorker: this._workerId,
94+
req: req,
95+
method: method,
96+
args: args
97+
});
10298
});
103-
104-
return result;
10599
}
106100

107101
public handleMessage(serializedMessage: string): void {
@@ -110,6 +104,7 @@ class SimpleWorkerProtocol {
110104
message = JSON.parse(serializedMessage);
111105
} catch (e) {
112106
// nothing
107+
return;
113108
}
114109
if (!message || !message.vsWorker) {
115110
return;
@@ -191,8 +186,7 @@ export class SimpleWorkerClient<T> extends Disposable {
191186
constructor(workerFactory: IWorkerFactory, moduleId: string) {
192187
super();
193188

194-
let lazyProxyResolve: (v: T) => void = null;
195-
let lazyProxyReject: (err: any) => void = null;
189+
let lazyProxyReject: ((err: any) => void) | null = null;
196190

197191
this._worker = this._register(workerFactory.create(
198192
'vs/base/common/worker/simpleWorker',
@@ -202,7 +196,9 @@ export class SimpleWorkerClient<T> extends Disposable {
202196
(err: any) => {
203197
// in Firefox, web workers fail lazily :(
204198
// we will reject the proxy
205-
lazyProxyReject(err);
199+
if (lazyProxyReject) {
200+
lazyProxyReject(err);
201+
}
206202
}
207203
));
208204

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

230-
this._lazyProxy = new Promise<T>((resolve, reject) => {
231-
lazyProxyResolve = resolve;
232-
lazyProxyReject = reject;
233-
});
234-
235226
// Send initialize message
236227
this._onModuleLoaded = this._protocol.sendMessage(INITIALIZE, [
237228
this._worker.getId(),
238229
moduleId,
239230
loaderConfiguration
240231
]);
241-
this._onModuleLoaded.then((availableMethods: string[]) => {
242-
let proxy = <T>{};
243-
for (let i = 0; i < availableMethods.length; i++) {
244-
(proxy as any)[availableMethods[i]] = createProxyMethod(availableMethods[i], proxyMethodRequest);
245-
}
246-
lazyProxyResolve(proxy);
247-
}, (e) => {
248-
lazyProxyReject(e);
249-
this._onError('Worker failed to load ' + moduleId, e);
232+
233+
this._lazyProxy = new Promise<T>((resolve, reject) => {
234+
lazyProxyReject = reject;
235+
this._onModuleLoaded.then((availableMethods: string[]) => {
236+
let proxy = <T>{};
237+
for (let i = 0; i < availableMethods.length; i++) {
238+
(proxy as any)[availableMethods[i]] = createProxyMethod(availableMethods[i], proxyMethodRequest);
239+
}
240+
resolve(proxy);
241+
}, (e) => {
242+
reject(e);
243+
this._onError('Worker failed to load ' + moduleId, e);
244+
});
250245
});
251246

252247
// Create proxy to loaded code
@@ -290,10 +285,10 @@ export interface IRequestHandler {
290285
*/
291286
export class SimpleWorkerServer {
292287

293-
private _requestHandler: IRequestHandler;
288+
private _requestHandler: IRequestHandler | null;
294289
private _protocol: SimpleWorkerProtocol;
295290

296-
constructor(postSerializedMessage: (msg: string) => void, requestHandler: IRequestHandler) {
291+
constructor(postSerializedMessage: (msg: string) => void, requestHandler: IRequestHandler | null) {
297292
this._requestHandler = requestHandler;
298293
this._protocol = new SimpleWorkerProtocol({
299294
sendMessage: (msg: string): void => {
@@ -353,29 +348,27 @@ export class SimpleWorkerServer {
353348
(<any>self).require.config(loaderConfig);
354349
}
355350

356-
let resolve: (value?: string[]) => void;
357-
let reject: (error?: any) => void;
358-
let r = new Promise<string[]>((_resolve, _reject) => {
359-
resolve = _resolve;
360-
reject = _reject;
361-
});
362-
363-
// Use the global require to be sure to get the global config
364-
(<any>self).require([moduleId], (...result: any[]) => {
365-
let handlerModule = result[0];
366-
this._requestHandler = handlerModule.create();
351+
return new Promise<string[]>((resolve, reject) => {
352+
// Use the global require to be sure to get the global config
353+
(<any>self).require([moduleId], (...result: any[]) => {
354+
let handlerModule = result[0];
355+
this._requestHandler = handlerModule.create();
367356

368-
let methods: string[] = [];
369-
for (let prop in this._requestHandler) {
370-
if (typeof this._requestHandler[prop] === 'function') {
371-
methods.push(prop);
357+
if (!this._requestHandler) {
358+
reject(new Error(`No RequestHandler!`));
359+
return;
372360
}
373-
}
374361

375-
resolve(methods);
376-
}, reject);
362+
let methods: string[] = [];
363+
for (let prop in this._requestHandler) {
364+
if (typeof this._requestHandler[prop] === 'function') {
365+
methods.push(prop);
366+
}
367+
}
377368

378-
return r;
369+
resolve(methods);
370+
}, reject);
371+
});
379372
}
380373
}
381374

0 commit comments

Comments
 (0)