Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace static blocks with private static field initializers #17

Merged
merged 2 commits into from
Apr 16, 2024

Conversation

davidtaylorhq
Copy link
Contributor

@davidtaylorhq davidtaylorhq commented Jan 16, 2024

Private static field initializers offer the same timing as class static blocks, while offering better browser support. For example, private static field initializers are supported on Safari >= 14.5 while static blocks are only supported in Safari >= 16.4.

Given this input:

class MyClass {
  @myDecorator
  decoratedField = 'field value';

  @myDecorator
  decoratedMethod() {
    return 'method response';
  }
}

This commit changes the output from:

class MyClass {
  static {
    dt7948.g(this.prototype, "decoratedField", [myDecorator], function () {
      return 'field value';
    });
  }
  #decoratedField = (dt7948.i(this, "decoratedField"), void 0);
  decoratedMethod() {
    return 'method response';
  }
  static {
    dt7948.n(this.prototype, "decoratedMethod", [myDecorator]);
  }
}

to this:

class MyClass {
  static #decoratedField = (dt7948.g(this.prototype, "decoratedField", [myDecorator], function () {
    return 'field value';
  }), void 0);
  #decoratedField_ = (dt7948.i(this, "decoratedField"), void 0);
  decoratedMethod() {
    return 'method response2';
  }
  static #decoratedMethod = (dt7948.n(this.prototype, "decoratedMethod", [myDecorator]), void 0);
}

Resolves #3

Private static field initializers offer the same timing as class static blocks, while offering better browser support. For example, private static field initializers are supported on Safari >= 14.5 while static blocks are only supported in Safari >= 16.4.

Given this input:

```js
class MyClass {
  @myDecorator
  decoratedField = 'field value';

  @myDecorator
  decoratedMethod() {
    return 'method response';
  }
}
```

This commit changes the output from:

```js
const myDecorator = klass => klass;
class MyClass {
  static {
    dt7948.g(this.prototype, "decoratedField", [myDecorator], function () {
      return 'field value';
    });
  }
  #decoratedField = (dt7948.i(this, "decoratedField"), void 0);
  decoratedMethod() {
    return 'method response';
  }
  static {
    dt7948.n(this.prototype, "decoratedMethod", [myDecorator]);
  }
}
```

to this:

```js
class MyClass {
  static #decoratedField = (dt7948.g(this.prototype, "decoratedField", [myDecorator], function () {
    return 'field value';
  }), void 0);
  #decoratedField_ = (dt7948.i(this, "decoratedField"), void 0);
  decoratedMethod() {
    return 'method response2';
  }
  static #decoratedMethod = (dt7948.n(this.prototype, "decoratedMethod", [myDecorator]), void 0);
}
```

Resolves ef4#3
@davidtaylorhq
Copy link
Contributor Author

The current implementation of unusedPrivateNameLike() means that a field named decoratedField will result in two private fields: #decoratedField and static #decoratedField_.

I think it would be beneficial to make the names more human-friendly like this:

static #_decorate_decoratedField = (...);
#_deferred_decorate_decoratedField = (...);

and for methods, something like:

someMethod(){}
static #_decorate_someMethod = (...);

If adding those prefixes would be welcome, let me know and I can either push it here or make a followup PR.

The default behavior is to output native `static { }` blocks. Setting `staticBlock: "field"` will enable the private-static-field-based implementation for wider browser support.
@davidtaylorhq
Copy link
Contributor Author

@ef4 I've introduced a statickBlock: "native" | "field" feature flag here (defaults to 'native'). Please let me know if there's anything else I can do to help get this across the finish line.

@ef4 ef4 merged commit f1d0668 into ef4:main Apr 16, 2024
@github-actions github-actions bot mentioned this pull request Apr 16, 2024
@ef4 ef4 added the enhancement New feature or request label Apr 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Idea for wider browser support
2 participants