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

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

Async function properties in subclass result in accessing this before super() call #54

Closed jimmydief closed 2 years ago

jimmydief commented 4 years ago

Came across an issue with async function class properties in a subclass. For this code:

class Base {
    a = Promise.resolve(42)
}

class Sub extends Base {
    f = async () => {
        await this.a;
    }
};

new Sub();

The output is:

function _defineProperty(obj, key, value) {
    ...
}

class Base {
    constructor() {
        _defineProperty(this, "a", Promise.resolve(42));
    }
}

class Sub extends Base {
    constructor(...args) {
        const _this = this;

        super(...args);

        _defineProperty(this, "f", _async(() => _awaitIgnored(_this.a)));
    }
};

new Sub();

The const _this = this; line causes problems at runtime due to the access of this prior to calling the superclass constructor.

It seems like this could potentially have a resolution similar to https://github.com/babel/babel/issues/9609.

Plugin version: 0.8.15

shinvey commented 3 years ago

I really prefer this plugin for building smaller bundle size. Now this issue makes me disable it. Looking forward to a new release.

rpetrich commented 2 years ago

This was a tricky bug to resolve. Babel's Scope.push method will happily push declarations before the call to the super constructor. Resolved in bb666824fa522ab88d29a86c7c5aa4d37c6afc1b