From 70a431f61185e28477cd72ed5b2d1e254a61477e Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Thu, 1 Apr 2021 10:37:59 +0200 Subject: [PATCH] fix(async-rewriter2): ensure eval works MONGOSH-665 --- .../async-rewriter2/src/async-writer-babel.spec.ts | 10 ++++++++++ packages/async-rewriter2/src/async-writer-babel.ts | 5 ++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/packages/async-rewriter2/src/async-writer-babel.spec.ts b/packages/async-rewriter2/src/async-writer-babel.spec.ts index 26d6e58f75..388154dd7c 100644 --- a/packages/async-rewriter2/src/async-writer-babel.spec.ts +++ b/packages/async-rewriter2/src/async-writer-babel.spec.ts @@ -307,6 +307,16 @@ describe('AsyncWriter', () => { expect(ret[Symbol.for('@@mongosh.syntheticPromise')]).to.equal(true); expect(await ret).to.equal('bar'); }); + + it('works with eval', async() => { + implicitlyAsyncFn.resolves('yes'); + expect(runTranspiledCode('eval("42")')).to.equal(42); + expect(runTranspiledCode('let a = 43; eval("a");')).to.equal(43); + expect(runTranspiledCode('(() => { let b = 44; return eval("b"); })()')).to.equal(44); + expect(await runTranspiledCode(`(() => { + globalThis.eval = implicitlyAsyncFn; return eval("b"); + })()`)).to.equal('yes'); + }); }); context('error handling', () => { diff --git a/packages/async-rewriter2/src/async-writer-babel.ts b/packages/async-rewriter2/src/async-writer-babel.ts index 1e4dcbaa9a..b240aad5da 100644 --- a/packages/async-rewriter2/src/async-writer-babel.ts +++ b/packages/async-rewriter2/src/async-writer-babel.ts @@ -530,9 +530,12 @@ export const makeMaybeAsyncFunctionPlugin = ({ types: t }: { types: typeof Babel // If we ever do, replacing all function calls with // Function.prototype.call.call(fn, target, ...originalArgs) might be // a feasible solution. + // Additionally, skip calls to 'eval', since literal calls to it + // have semantics that are different from calls to an expressio that + // evaluates to 'eval'. if (path.parentPath.isCallExpression() && path.key === 'callee' && - path.isMemberExpression()) { + (path.isMemberExpression() || (path.isIdentifier() && path.node.name === 'eval'))) { return; }