esbuild icon indicating copy to clipboard operation
esbuild copied to clipboard

Invalid code generated when static properties are used in combination with decorators

Open jrieken opened this issue 1 year ago • 2 comments

  • open https://esbuild.github.io/try/#YgAwLjIzLjAAe2J1bmRsZTp0cnVlLCBmb3JtYXQ6ICdlc20nLCBtaW5pZnk6IGZhbHNlLCBwbGF0Zm9ybTogJ2Jyb3dzZXInfQBlAGVudHJ5LmpzAGltcG9ydCB7Rm9vfSBmcm9tICcuL2ZpbGUyLnRzJzsKCm5ldyBGb28oKTsAAHRzY29uZmlnLmpzb24AewogICJjb21waWxlck9wdGlvbnMiOiB7CiAgICAiZXhwZXJpbWVudGFsRGVjb3JhdG9ycyI6IHRydWUsCiAgICAidXNlRGVmaW5lRm9yQ2xhc3NGaWVsZHMiOiBmYWxzZQogIH0KfQoAAGZpbGUyLnRzAGV4cG9ydCBjbGFzcyBGb28gZXh0ZW5kcyBEaXNwb3NhYmxlIHsKCXByaXZhdGUgc3RhdGljIHJlYWRvbmx5IEEgPSAxNTsKCXB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgQiA9IEZvby5BICogMjsKCXB1YmxpYyByZWFkb25seSB3aWR0aCA9IEZvby5COwoKCWNvbnN0cnVjdG9yKAoJCUBJVGhlbWVTZXJ2aWNlIHByaXZhdGUgcmVhZG9ubHkgX3RoZW1lU2VydmljZTogSVRoZW1lU2VydmljZSwKCSkgewoJCXN1cGVyKCk7Cgl9Cn0K
  • notice the last/second static-initialise block referencing A before being declared
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __decorateClass = (decorators, target, key, kind) => {
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
    if (decorator = decorators[i])
      result = (kind ? decorator(target, key, result) : decorator(result)) || result;
  if (kind && result) __defProp(target, key, result);
  return result;
};
var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);

// file2.ts
var Foo = class extends Disposable {
  constructor(_themeService) {
    super();
    this._themeService = _themeService;
    this.width = Foo.B;
  }
  static {
    this.A = 15;
  }
  static {
    this.B = Foo.A * 2;
//     ^^^^^^^^^^
// Foo doesn't exist
  }
};
Foo = __decorateClass([
  __decorateParam(0, IThemeService)
], Foo);

// entry.js
new Foo();

jrieken avatar Jul 02 '24 10:07 jrieken

Sorry about this. The class lowering transforms are extremely complicated as they all interact with each other. I'm not surprised to hear that there's another edge case like this. FWIW it's possible that using supported: { 'class-static-blocks': false } may fix this problem (by telling esbuild to avoid lowering static class fields into static blocks). Here's a live link.

evanw avatar Sep 22 '24 01:09 evanw

Thanks @evanw! That trick works nicely, didn't even know supported exists.

jrieken avatar Oct 01 '24 14:10 jrieken