|
1 | | -declare var Iterator: {}; |
2 | | - |
3 | | -if (typeof Iterator === 'undefined' || Iterator == null) { |
4 | | - globalThis.Iterator = function() {}; |
5 | | -} |
6 | | - |
7 | | -function concatImpl<A>(...iterables: Array<Iterable<A>>): Generator<A> |
8 | | -function concatImpl(): Generator<never> |
9 | | -function concatImpl<A>(iterableA: Iterable<A>): Generator<A> |
10 | | -function concatImpl<A, B>(iterableA: Iterable<A>, iterableB: Iterable<B>): Generator<A | B> |
11 | | -function concatImpl<A, B, C>(iterableA: Iterable<A>, iterableB: Iterable<B>, iterableC: Iterable<C>): Generator<A | B | C> |
12 | | -function concatImpl<A, B, C, D>(iterableA: Iterable<A>, iterableB: Iterable<B>, iterableC: Iterable<C>, iterableD: Iterable<D>): Generator<A | B | C | D> |
13 | | -function concatImpl<A, B, C, D, E>(iterableA: Iterable<A>, iterableB: Iterable<B>, iterableC: Iterable<C>, iterableD: Iterable<D>, iterableE: Iterable<E>): Generator<A | B | C | D | E> |
14 | | -function concatImpl(...iterables: Array<Iterable<unknown>>): Generator<unknown> |
15 | | -function concatImpl(...iterables: Array<unknown>): Generator<unknown> { |
16 | | - const openMethods = []; |
17 | | - for (let iterable of iterables) { |
18 | | - if (iterable == null || Object(iterable) !== iterable) throw new TypeError; |
19 | | - let openMethod = (iterable as any)[Symbol.iterator]; |
| 1 | +function concatImpl(): Iterator<never> |
| 2 | +function concatImpl<A>(...iterables: Array<Iterable<A>>): Iterator<A> |
| 3 | +function concatImpl<A>(iterableA: Iterable<A>): Iterator<A> |
| 4 | +function concatImpl<A, B>(iterableA: Iterable<A>, iterableB: Iterable<B>): Iterator<A | B> |
| 5 | +function concatImpl<A, B, C>(iterableA: Iterable<A>, iterableB: Iterable<B>, iterableC: Iterable<C>): Iterator<A | B | C> |
| 6 | +function concatImpl<A, B, C, D>(iterableA: Iterable<A>, iterableB: Iterable<B>, iterableC: Iterable<C>, iterableD: Iterable<D>): Iterator<A | B | C | D> |
| 7 | +function concatImpl<A, B, C, D, E>(iterableA: Iterable<A>, iterableB: Iterable<B>, iterableC: Iterable<C>, iterableD: Iterable<D>, iterableE: Iterable<E>): Iterator<A | B | C | D | E> |
| 8 | +function concatImpl(...iterables: Array<Iterable<unknown>>): Iterator<unknown> |
| 9 | +function concatImpl(...iterables: Array<unknown>): Iterator<unknown> { |
| 10 | + const openMethods: Array<{ openMethod: () => Iterator<unknown>, iterable: Iterable<unknown>}> = []; |
| 11 | + for (let val of iterables) { |
| 12 | + if (val == null || Object(val) !== val) throw new TypeError; |
| 13 | + let iterable: Iterable<unknown> = val as Iterable<unknown>; |
| 14 | + let openMethod = iterable[Symbol.iterator]; |
20 | 15 | if (typeof openMethod !== 'function') throw new TypeError; |
21 | 16 | openMethods.push({openMethod, iterable}); |
22 | 17 | } |
23 | | - return function*() { |
24 | | - for (let { openMethod, iterable } of openMethods) { |
25 | | - yield* { [Symbol.iterator]() { return openMethod.call(iterable); } } |
26 | | - } |
27 | | - }(); |
| 18 | + let done = false; |
| 19 | + let iterator: Iterator<unknown> | null = null; |
| 20 | + let nextMethod: Iterator<unknown>["next"] | null = null; |
| 21 | + return Iterator.from({ |
| 22 | + next() { |
| 23 | + while (!done) { |
| 24 | + if (iterator != null && nextMethod != null) { |
| 25 | + let iterResult = nextMethod.call(iterator); |
| 26 | + if (!iterResult.done) { |
| 27 | + return iterResult; |
| 28 | + } |
| 29 | + iterator = null; |
| 30 | + nextMethod = null; |
| 31 | + } |
| 32 | + if (openMethods.length > 0) { |
| 33 | + let { openMethod, iterable } = openMethods.shift()!; |
| 34 | + let val = openMethod.call(iterable); |
| 35 | + if (val == null || Object(val) !== val) throw new TypeError; |
| 36 | + iterator = val as Iterator<unknown>; |
| 37 | + nextMethod = iterator.next; |
| 38 | + continue; |
| 39 | + } |
| 40 | + done = true; |
| 41 | + } |
| 42 | + return { done: true, value: void 0 }; |
| 43 | + }, |
| 44 | + return() { |
| 45 | + if (!done) { |
| 46 | + if (iterator != null) { |
| 47 | + iterator.return?.().value; |
| 48 | + } |
| 49 | + done = true; |
| 50 | + } |
| 51 | + return { done: true, value: void 0, }; |
| 52 | + }, |
| 53 | + }); |
28 | 54 | } |
29 | 55 |
|
30 | 56 | // NOTE: this line makes concat non-constructible, and gives it the appropriate name and length |
|
0 commit comments