Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use native iterators instead of Lumino iterators #346

Merged
merged 62 commits into from
Aug 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
8639b66
Refactor some of the public API for iterators
afshin Aug 10, 2022
a935f6a
More iterator refactoring
afshin Aug 10, 2022
029bcc3
Update each<T>() function
afshin Aug 10, 2022
c88f20b
Remove ArrayIterator<T>
afshin Aug 10, 2022
f5176d6
Remove KeyIterator, ValueIterator<T>, ItemIterator<T>, and FnIterator<T>
afshin Aug 10, 2022
150738a
Remove zip<T>() and ZipIterator<T>
afshin Aug 10, 2022
ddeab32
Remove take<T>() and TakeIterator<T>
afshin Aug 10, 2022
ebc44cc
Remove toArray<T>()
afshin Aug 10, 2022
d40cc10
Remove ChainIterator<T> and reimplement chain<T>() with native iterators
afshin Aug 10, 2022
77a44ae
Remove RepeatIterator<T> and reimplement repeat<T>() and once<T>() wi…
afshin Aug 11, 2022
d1b6e2e
Reimplement take<T>() with native iterators
afshin Aug 11, 2022
4c13c6f
Reimplment zip<T>() with native iterators
afshin Aug 11, 2022
588e666
Reimplment stride<T>() with native iterators
afshin Aug 11, 2022
346cd2a
Update topologicSort<T>() to accept native iterable
afshin Aug 11, 2022
de3de59
Reimplment retro<T>() with native iterators
afshin Aug 11, 2022
acaa6ed
Update reduce() to use native iterables
afshin Aug 11, 2022
fb48177
Reimplment range() with native iterators
afshin Aug 11, 2022
e6964f3
Reimplement empty() with native iterators
afshin Aug 11, 2022
462f495
Reimplement filter<T>() with native interators
afshin Aug 11, 2022
6abfc62
Reimplement map<T>() with native interators
afshin Aug 11, 2022
298ac8c
Update find(), findIndex(), min(), max(), and minmax() to use native …
afshin Aug 11, 2022
9380340
Reimplement enumerate() with native types
afshin Aug 11, 2022
ccbb647
Fix algorithm package tests
afshin Aug 11, 2022
518079c
Update LinkedList to use native iterators
afshin Aug 11, 2022
481cfb7
Fix LinkedList tests
afshin Aug 11, 2022
82d9b28
Update disposable
afshin Aug 11, 2022
b4c1250
Update widgets to use native iterators
afshin Aug 11, 2022
3ab8cb1
Fix widget tests
afshin Aug 11, 2022
3d633c4
Update data grid to use native iterators
afshin Aug 11, 2022
4f1a5c1
Update API report
afshin Aug 11, 2022
797ea47
Fix doc strings
afshin Aug 11, 2022
fbc612a
Minor tweak of `LinkedList` iterator methods
afshin Aug 13, 2022
720ce2e
Simplify `chain<T>()`
afshin Aug 13, 2022
35d6f40
Simplify `take<T>()`
afshin Aug 13, 2022
050daeb
[Symbol.iterator]() and Array.from() should almost never need invoked
afshin Aug 13, 2022
d6012a4
Third parameter for comparator functions is superfluous when they are…
afshin Aug 13, 2022
0f2ec49
Simplify stride<T>()
afshin Aug 13, 2022
68eb1dd
Re-enable zip() tests
afshin Aug 13, 2022
a5bc2c3
Simplify iterating through selections in data grid.
afshin Aug 13, 2022
f0189cc
Tweak retro<T>() for readability
afshin Aug 13, 2022
8a9574a
Use for...of for minmax<T>()
afshin Aug 14, 2022
fbf1317
Use `IterableIterator` as return type for all generators
afshin Aug 14, 2022
654aef5
Use for...of instead of each() in disposable and update generated API
afshin Aug 15, 2022
14aa4da
Use for...of instead of each() in LinkedList and topologicSort
afshin Aug 15, 2022
eba5225
Use for...of instead of each in signaling
afshin Aug 15, 2022
688cb0f
Use for...of instead of each() in messaging
afshin Aug 15, 2022
ad8e19b
In almost all cases, prefer native for..of or .forEach to Lumino util…
afshin Aug 15, 2022
00e6855
Fix examples
afshin Aug 15, 2022
b9a0b1b
Fine.
afshin Aug 15, 2022
0f747de
Add iteration notes to migration.md
afshin Aug 16, 2022
9caca56
Add test for take() where count=0
afshin Aug 16, 2022
d74f6c2
Remove duplicate repeat() test
afshin Aug 16, 2022
929b6d9
Better label for stride() test
afshin Aug 16, 2022
1fbfcae
Better labels for zip() tests
afshin Aug 16, 2022
bc2b48f
Clean up test labels as per review comments
afshin Aug 16, 2022
84ec11b
Change rangeLength signature back
afshin Aug 16, 2022
1442576
Reimplement toObject() using iterables and toArray() as a deprecated …
afshin Aug 16, 2022
da91b28
Better toObject() test
afshin Aug 16, 2022
c6673e8
Fix logic bug in take() that @vidartf noticed
afshin Aug 16, 2022
071756a
Fix typo
afshin Aug 16, 2022
1197d76
Another .forEach() => for...of
afshin Aug 16, 2022
c340bd6
Update packages/algorithm/src/iter.ts
afshin Aug 17, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Lumino
changelog
api
examples
migration

Indices and tables
==================
Expand Down
146 changes: 146 additions & 0 deletions docs/source/migration.md

Large diffs are not rendered by default.

19 changes: 11 additions & 8 deletions examples/example-dockpanel-amd/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,18 @@ define(['@lumino/commands', '@lumino/widgets'], function (
return root;
}

function ContentWidget(name) {
Widget.call(this, { node: ContentWidget.prototype.createNode() });
this.setFlag(Widget.Flag.DisallowLayout);
this.addClass('content');
this.addClass(name.toLowerCase());
this.title.label = name;
this.title.closable = true;
this.title.caption = 'Long description for: ' + name;
class ContentWidget extends Widget {
constructor(name) {
super({ node: ContentWidget.prototype.createNode() });
this.setFlag(Widget.Flag.DisallowLayout);
this.addClass('content');
this.addClass(name.toLowerCase());
this.title.label = name;
this.title.closable = true;
this.title.caption = 'Long description for: ' + name;
}
}

ContentWidget.prototype = Object.create(Widget.prototype);

ContentWidget.prototype.createNode = function () {
Expand Down
4 changes: 2 additions & 2 deletions examples/example-dockpanel/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
"sourceMap": true,
"module": "commonjs",
"moduleResolution": "node",
"target": "ES5",
"target": "ES6",
"outDir": "./build",
"lib": ["ES5", "ES2015.Promise", "ES2015.Iterable", "DOM"],
"lib": ["ES6", "DOM"],
"types": []
},
"include": ["src/*"]
Expand Down
73 changes: 7 additions & 66 deletions packages/algorithm/src/chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,90 +7,31 @@
|
| The full license is in the file LICENSE, distributed with this software.
|----------------------------------------------------------------------------*/
import { IIterator, iter, IterableOrArrayLike } from './iter';

/**
* Chain together several iterables.
*
* @param objects - The iterable or array-like objects of interest.
* @param objects - The iterable objects of interest.
*
* @returns An iterator which yields the values of the iterables
* in the order in which they are supplied.
*
* #### Example
* ```typescript
* import { chain, toArray } from '@lumino/algorithm';
* import { chain } from '@lumino/algorithm';
*
* let data1 = [1, 2, 3];
* let data2 = [4, 5, 6];
*
* let stream = chain(data1, data2);
*
* toArray(stream); // [1, 2, 3, 4, 5, 6]
* Array.from(stream); // [1, 2, 3, 4, 5, 6]
* ```
*/
export function chain<T>(...objects: IterableOrArrayLike<T>[]): IIterator<T> {
return new ChainIterator<T>(iter(objects.map(iter)));
}

/**
* An iterator which chains together several iterators.
*/
export class ChainIterator<T> implements IIterator<T> {
/**
* Construct a new chain iterator.
*
* @param source - The iterator of iterators of interest.
*/
constructor(source: IIterator<IIterator<T>>) {
this._source = source;
this._active = undefined;
}

/**
* Get an iterator over the object's values.
*
* @returns An iterator which yields the object's values.
*/
iter(): IIterator<T> {
return this;
}

/**
* Create an independent clone of the iterator.
*
* @returns A new independent clone of the iterator.
*/
clone(): IIterator<T> {
let result = new ChainIterator<T>(this._source.clone());
result._active = this._active && this._active.clone();
result._cloned = true;
this._cloned = true;
return result;
}

/**
* Get the next value from the iterator.
*
* @returns The next value from the iterator, or `undefined`.
*/
next(): T | undefined {
if (this._active === undefined) {
let active = this._source.next();
if (active === undefined) {
return undefined;
}
this._active = this._cloned ? active.clone() : active;
}
let value = this._active.next();
if (value !== undefined) {
return value;
export function* chain<T>(...objects: Iterable<T>[]): IterableIterator<T> {
for (const object of objects) {
for (const value of object) {
yield value;
}
this._active = undefined;
return this.next();
}

private _source: IIterator<IIterator<T>>;
private _active: IIterator<T> | undefined;
private _cloned = false;
}
42 changes: 5 additions & 37 deletions packages/algorithm/src/empty.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
|
| The full license is in the file LICENSE, distributed with this software.
|----------------------------------------------------------------------------*/
import { IIterator } from './iter';

/**
* Create an empty iterator.
Expand All @@ -16,45 +15,14 @@ import { IIterator } from './iter';
*
* #### Example
* ```typescript
* import { empty, toArray } from '@lumino/algorithm';
* import { empty } from '@lumino/algorithm';
*
* let stream = empty<number>();
*
* toArray(stream); // []
* Array.from(stream); // []
* ```
*/
export function empty<T>(): IIterator<T> {
return new EmptyIterator<T>();
}

/**
* An iterator which is always empty.
*/
export class EmptyIterator<T> implements IIterator<T> {
/**
* Get an iterator over the object's values.
*
* @returns An iterator which yields the object's values.
*/
iter(): IIterator<T> {
return this;
}

/**
* Create an independent clone of the iterator.
*
* @returns A new independent clone of the iterator.
*/
clone(): IIterator<T> {
return new EmptyIterator<T>();
}

/**
* Get the next value from the iterator.
*
* @returns The next value from the iterator, or `undefined`.
*/
next(): T | undefined {
return undefined;
}
// eslint-disable-next-line require-yield, @typescript-eslint/no-unused-vars
export function* empty<T>(): IterableIterator<T> {
return;
}
66 changes: 8 additions & 58 deletions packages/algorithm/src/enumerate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,82 +7,32 @@
|
| The full license is in the file LICENSE, distributed with this software.
|----------------------------------------------------------------------------*/
import { IIterator, iter, IterableOrArrayLike } from './iter';

/**
* Enumerate an iterable object.
*
* @param object - The iterable or array-like object of interest.
* @param object - The iterable object of interest.
*
* @param start - The starting enum value. The default is `0`.
*
* @returns An iterator which yields the enumerated values.
*
* #### Example
* ```typescript
* import { enumerate, toArray } from '@lumino/algorithm';
* import { enumerate } from '@lumino/algorithm';
*
* let data = ['foo', 'bar', 'baz'];
*
* let stream = enumerate(data, 1);
*
* toArray(stream); // [[1, 'foo'], [2, 'bar'], [3, 'baz']]
* Array.from(stream); // [[1, 'foo'], [2, 'bar'], [3, 'baz']]
* ```
*/
export function enumerate<T>(
object: IterableOrArrayLike<T>,
export function* enumerate<T>(
object: Iterable<T>,
start = 0
): IIterator<[number, T]> {
return new EnumerateIterator<T>(iter(object), start);
}

/**
* An iterator which enumerates the source values.
*/
export class EnumerateIterator<T> implements IIterator<[number, T]> {
/**
* Construct a new enumerate iterator.
*
* @param source - The iterator of values of interest.
*
* @param start - The starting enum value.
*/
constructor(source: IIterator<T>, start: number) {
this._source = source;
this._index = start;
}

/**
* Get an iterator over the object's values.
*
* @returns An iterator which yields the object's values.
*/
iter(): IIterator<[number, T]> {
return this;
): IterableIterator<[number, T]> {
for (const value of object) {
yield [start++, value];
}

/**
* Create an independent clone of the iterator.
*
* @returns A new independent clone of the iterator.
*/
clone(): IIterator<[number, T]> {
return new EnumerateIterator<T>(this._source.clone(), this._index);
}

/**
* Get the next value from the iterator.
*
* @returns The next value from the iterator, or `undefined`.
*/
next(): [number, T] | undefined {
let value = this._source.next();
if (value === undefined) {
return undefined;
}
return [this._index++, value];
}

private _source: IIterator<T>;
private _index: number;
}
74 changes: 10 additions & 64 deletions packages/algorithm/src/filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,89 +7,35 @@
|
| The full license is in the file LICENSE, distributed with this software.
|----------------------------------------------------------------------------*/
import { IIterator, iter, IterableOrArrayLike } from './iter';

/**
* Filter an iterable for values which pass a test.
*
* @param object - The iterable or array-like object of interest.
* @param object - The iterable object of interest.
*
* @param fn - The predicate function to invoke for each value.
*
* @returns An iterator which yields the values which pass the test.
*
* #### Example
* ```typescript
* import { filter, toArray } from '@lumino/algorithm';
* import { filter } from '@lumino/algorithm';
*
* let data = [1, 2, 3, 4, 5, 6];
*
* let stream = filter(data, value => value % 2 === 0);
*
* toArray(stream); // [2, 4, 6]
* Array.from(stream); // [2, 4, 6]
* ```
*/
export function filter<T>(
object: IterableOrArrayLike<T>,
export function* filter<T>(
object: Iterable<T>,
fn: (value: T, index: number) => boolean
): IIterator<T> {
return new FilterIterator<T>(iter(object), fn);
}

/**
* An iterator which yields values which pass a test.
*/
export class FilterIterator<T> implements IIterator<T> {
/**
* Construct a new filter iterator.
*
* @param source - The iterator of values of interest.
*
* @param fn - The predicate function to invoke for each value.
*/
constructor(source: IIterator<T>, fn: (value: T, index: number) => boolean) {
this._source = source;
this._fn = fn;
}

/**
* Get an iterator over the object's values.
*
* @returns An iterator which yields the object's values.
*/
iter(): IIterator<T> {
return this;
}

/**
* Create an independent clone of the iterator.
*
* @returns A new independent clone of the iterator.
*/
clone(): IIterator<T> {
let result = new FilterIterator<T>(this._source.clone(), this._fn);
result._index = this._index;
return result;
}

/**
* Get the next value from the iterator.
*
* @returns The next value from the iterator, or `undefined`.
*/
next(): T | undefined {
let fn = this._fn;
let it = this._source;
let value: T | undefined;
while ((value = it.next()) !== undefined) {
if (fn(value, this._index++)) {
return value;
}
): IterableIterator<T> {
let index = 0;
for (const value of object) {
if (fn(value, index++)) {
yield value;
}
return undefined;
}

private _index = 0;
private _source: IIterator<T>;
private _fn: (value: T, index: number) => boolean;
}
Loading