Skip to content

Commit 08a5bcc

Browse files
authored
chore(async-rewriter2): add handling for Array.prototype.{sort,flatMap} (#770)
1 parent 13942e4 commit 08a5bcc

File tree

2 files changed

+68
-2
lines changed

2 files changed

+68
-2
lines changed

packages/async-rewriter2/src/async-writer-babel.spec.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,14 @@ describe('AsyncWriter', () => {
386386
for (const value of gen) return value;
387387
})()`)).to.throw('[ASYNC-10012] Result of expression "implicitlyAsyncFn()" cannot be used in this context');
388388
});
389+
390+
it('cannot implicitly await inside of array.sort() callback', () => {
391+
implicitlyAsyncFn.callsFake((x, y) => x.a - y.a);
392+
expect(() => runTranspiledCode(`
393+
const arr = [{ a: 2 }, { a : 1 }];
394+
arr.sort((x, y) => implicitlyAsyncFn(x, y));
395+
`)).to.throw('[ASYNC-10012] Result of expression "compareFn(...args)" cannot be used in this context');
396+
});
389397
});
390398
});
391399

@@ -523,6 +531,15 @@ describe('AsyncWriter', () => {
523531
expect(implicitlyAsyncFn).to.have.been.calledWith(4, 4, set);
524532
expect(implicitlyAsyncFn).to.have.been.calledWith(6, 6, set);
525533
});
534+
535+
it('supports Array.prototype.flatMap', async() => {
536+
implicitlyAsyncFn.callsFake(x => [ x - 1, x ]);
537+
const arr = await runTranspiledCode(`
538+
const arr = [ 2, 4, 6, 8 ];
539+
arr.flatMap(implicitlyAsyncFn)
540+
`);
541+
expect(arr).to.deep.equal([1, 2, 3, 4, 5, 6, 7, 8]);
542+
});
526543
});
527544

528545
context('synchronous', () => {
@@ -630,6 +647,33 @@ describe('AsyncWriter', () => {
630647
expect(plainFn).to.have.been.calledWith(4, 4, set);
631648
expect(plainFn).to.have.been.calledWith(6, 6, set);
632649
});
650+
651+
it('supports Array.prototype.flatMap', () => {
652+
plainFn.callsFake(x => [ x - 1, x ]);
653+
const arr = runTranspiledCode(`
654+
const arr = [ 2, 4, 6, 8 ];
655+
arr.flatMap(plainFn)
656+
`);
657+
expect(arr).to.deep.equal([1, 2, 3, 4, 5, 6, 7, 8]);
658+
});
659+
660+
it('supports Array.prototype.sort', () => {
661+
plainFn.callsFake((x, y) => x.a - y.a);
662+
const arr = runTranspiledCode(`
663+
const arr = [ { a: 1 }, { a: 9 }, { a: 4 }, { a: 16 } ];
664+
arr.sort(plainFn)
665+
`);
666+
expect(arr).to.deep.equal([ { a: 1 }, { a: 4 }, { a: 9 }, { a: 16 } ]);
667+
});
668+
669+
it('supports TypedArray.prototype.sort', () => {
670+
plainFn.callsFake((x, y) => x - y);
671+
const arr = runTranspiledCode(`
672+
const arr = new Uint8Array([1, 9, 4, 16]);
673+
arr.sort(plainFn)
674+
`);
675+
expect(arr).to.deep.equal(new Uint8Array([1, 4, 9, 16]));
676+
});
633677
});
634678

635679
context('Function.prototype.toString', () => {

packages/async-rewriter2/src/runtime-support.nocov.js

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -451,8 +451,30 @@ module.exports = '(' + function() {
451451
});
452452
};
453453

454-
// Currently Missing: (Typed)Array.prototype.sort
455-
// Currently Missing: Array.prototype.flatMap
454+
const origArraySort = Array.prototype.sort;
455+
Array.prototype.sort = function(compareFn) {
456+
return origArraySort.call(this, function(...args) {
457+
// (Ab-)use a generator function as one of the places where using
458+
// implicit async expression results in an error.
459+
return [...(function*() {
460+
yield compareFn(...args);
461+
})()][0];
462+
});
463+
};
464+
const origTypedArraySort = TypedArray.prototype.sort;
465+
TypedArray.prototype.sort = function(compareFn) {
466+
return origTypedArraySort.call(this, function(...args) {
467+
// (Ab-)use a generator function as one of the places where using
468+
// implicit async expression results in an error.
469+
return [...(function*() {
470+
yield compareFn(...args);
471+
})()][0];
472+
});
473+
};
474+
475+
Array.prototype.flatMap = function(...args) {
476+
return Array.prototype.map.call(this, ...args).flat();
477+
};
456478

457479
TypedArray.prototype.reduce = Array.prototype.reduce;
458480
TypedArray.prototype.reduceRight = Array.prototype.reduceRight;

0 commit comments

Comments
 (0)