rpetrich / babel-plugin-transform-async-to-promises

Transform async/await to somewhat idiomatic JavaScript promise chains
MIT License
246 stars 17 forks source link

`yield await ...` leads to TypeError: Path was expected to have a container! #79

Open ROpdebee opened 2 years ago

ROpdebee commented 2 years ago

Although the README says that async generators aren't supported, it appears this information is outdated as the plugin does transform async generators. However, combining yield with await on a single line leads to an error.

Example:

async function test() {
    return [1, 2, 3];
}

async function* test2() {
    yield await test();
}

async function test3() {
    for await (const x of test2()) {
        console.log(x);
    }
}

Stack trace:

TypeError: /Users/ruben/Documents/Projects/OpenSource/mb-userscripts/src/test/index.ts: Path was expected to have a container!
  4 |
  5 | async function* test2() {
> 6 |     yield await test();
    |     ^^^^^^^^^^^^^^^^^^^
  7 | }
  8 |
  9 | async function test3() {
    at File.buildCodeFrameError (/Users/ruben/Documents/Projects/OpenSource/mb-userscripts/node_modules/@babel/core/lib/transformation/file/file.js:249:12)
    at NodePath.buildCodeFrameError (/Users/ruben/Documents/Projects/OpenSource/mb-userscripts/node_modules/@babel/traverse/lib/path/index.js:139:21)
    at checkPathValidity (/Users/ruben/Documents/Projects/OpenSource/mb-userscripts/node_modules/babel-plugin-transform-async-to-promises/async-to-promises.ts:1568:15)
    at relocateTail (/Users/ruben/Documents/Projects/OpenSource/mb-userscripts/node_modules/babel-plugin-transform-async-to-promises/async-to-promises.ts:1595:3)
    at Object.rewriteAwaitOrYieldPath (/Users/ruben/Documents/Projects/OpenSource/mb-userscripts/node_modules/babel-plugin-transform-async-to-promises/async-to-promises.ts:3922:5)
    at NodePath._call (/Users/ruben/Documents/Projects/OpenSource/mb-userscripts/node_modules/@babel/traverse/lib/path/context.js:53:20)
    at NodePath.call (/Users/ruben/Documents/Projects/OpenSource/mb-userscripts/node_modules/@babel/traverse/lib/path/context.js:40:17)
    at NodePath.visit (/Users/ruben/Documents/Projects/OpenSource/mb-userscripts/node_modules/@babel/traverse/lib/path/context.js:100:31)
    at TraversalContext.visitQueue (/Users/ruben/Documents/Projects/OpenSource/mb-userscripts/node_modules/@babel/traverse/lib/context.js:103:16)
    at TraversalContext.visitSingle (/Users/ruben/Documents/Projects/OpenSource/mb-userscripts/node_modules/@babel/traverse/lib/context.js:77:19)

Workaround:

async function* test2() {
    const temp = await test();
    yield temp;
}

babel 7.16.7 babel-plugin-transform-async-to-promises 0.8.18

Babel config:

module.exports = {
    presets: [
        ['@babel/preset-typescript', {
            isTSX: true,
            allExtensions: true,
        }],
        ['@babel/preset-env', {
            corejs: '3.19',
            useBuiltIns: 'entry',
            exclude: [
                '@babel/plugin-transform-async-to-generator',
                '@babel/plugin-proposal-async-generator-functions',
            ],
        }],
    ],
    plugins: [
        '@babel/plugin-syntax-jsx',
        ['babel-plugin-transform-async-to-promises', {
            externalHelpers: true,
        }],
        ['@babel/plugin-transform-runtime', {
            regenerator: true,
            helpers: false,
        }],
    ],
    sourceType: 'unambiguous',
    comments: false,
};