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

feat(transformer/class-properties): transform static/instance accessor methods #8132

Draft
wants to merge 1 commit into
base: 12-26-feat_transformer_class-properties_transform_static_private_method_invoking
Choose a base branch
from

Conversation

Dunqing
Copy link
Member

@Dunqing Dunqing commented Dec 26, 2024

This PR supports transforming private getter or setter methods, and the output is a little different from Babel's output, For example:

Input:

class Cls {
  #prop = 0;

  get #accessor() {
    return this.#prop;
  }
  set #accessor(v) {
    console.log(arguments);
    this.#prop = v;
  }

  constructor() {
    console.log(this.#accessor)
    [this.#accessor] = [1];
  }
}

Babel's output:

var _prop = new WeakMap();
var _Cls_brand = new WeakSet();
class Cls {
  constructor() {
    babelHelpers.classPrivateMethodInitSpec(this, _Cls_brand);
    babelHelpers.classPrivateFieldInitSpec(this, _prop, 0);
    console.log(babelHelpers.classPrivateGetter(_Cls_brand, this, _get_accessor));
    [babelHelpers.classPrivateGetter(_Cls_brand, this, _get_accessor)] = [1];
  }
}
function _get_accessor(_this) {
  return babelHelpers.classPrivateFieldGet(_prop, _this);
}
function _set_accessor(_this2, v) {
  var _arguments = [].slice.call(arguments, 1);
  console.log(_arguments);
  babelHelpers.classPrivateFieldSet(_prop, _this2, v);
}

Oxc's output:

var _prop = new WeakMap();
var _Cls_brand = new WeakSet();
class Cls {
        constructor() {
                babelHelpers.classPrivateMethodInitSpec(this, _Cls_brand);
                babelHelpers.classPrivateFieldInitSpec(this, _prop, 0);
                console.log(_get_accessor.call(babelHelpers.assertClassBrand(_Cls_brand, this)));
                [babelHelpers.toSetter(_set_accessor.bind(babelHelpers.assertClassBrand(_Cls_brand, this)), [])._] = [1];
        }
}
function _get_accessor() {
        return babelHelpers.classPrivateFieldGet2(_prop, this);
}
function _set_accessor(v) {
        console.log(arguments);
        babelHelpers.classPrivateFieldSet2(_prop, this, v);
}

Main difference

// Babel
+ console.log(babelHelpers.classPrivateGetter(_Cls_brand, this, _get_accessor));
+ [babelHelpers.classPrivateGetter(_Cls_brand, this, _get_accessor)] = [1];

+ function _get_accessor(_this) {
+   return babelHelpers.classPrivateFieldGet(_prop, _this);
+ }

+ function _set_accessor(_this2, v) {
+   var _arguments = [].slice.call(arguments, 1);
+   console.log(_arguments);
+   babelHelpers.classPrivateFieldSet(_prop, _this2, v);
+ }

// Oxc
-  console.log(_get_accessor.call(babelHelpers.assertClassBrand(_Cls_brand, this)));- - 
-  [babelHelpers.toSetter(_set_accessor.bind(babelHelpers.assertClassBrand(_Cls_brand, this)), [])._] = [1];

- function _get_accessor() {
-   return babelHelpers.classPrivateFieldGet2(_prop, this);
- }

- function _set_accessor(v) {
-   console.log(arguments);
-   babelHelpers.classPrivateFieldSet2(_prop, this, v);
- }

From the main differences, we can see that Babel handles getter and setter methods using classPrivateGetter and classPrivateSetter helper functions, which causes all use this and arguments needs to rewrite to use a temp var instead in getter and setter methods. This is unnecessary and is not an efficient transformation for us.

Instead, I adapt binding a this instead of passing in this, this way we don't need to rewrite anything. We can't control the helper library for now, so I just transformed the AST to bind this, in the future, we can create a helper function to do the same thing.

Copy link
Member Author

Dunqing commented Dec 26, 2024

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more


How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • 0-merge - adds this PR to the back of the merge queue
  • hotfix - for urgent hot fixes, skip the queue and merge this PR next

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

Copy link

codspeed-hq bot commented Dec 26, 2024

CodSpeed Performance Report

Merging #8132 will not alter performance

Comparing 12-26-feat_transformer_class-properties_transform_static_instance_accessor_methods (0f5cc4d) with 12-26-feat_transformer_class-properties_transform_static_private_method_invoking (727cba8)

Summary

✅ 29 untouched benchmarks

@Dunqing Dunqing force-pushed the 12-26-feat_transformer_class-properties_transform_static_private_method_invoking branch from f3ee3e1 to 1338938 Compare December 26, 2024 16:12
@Dunqing Dunqing force-pushed the 12-26-feat_transformer_class-properties_transform_static_instance_accessor_methods branch from 56fb20e to a7a20d0 Compare December 26, 2024 16:13
@Dunqing Dunqing force-pushed the 12-26-feat_transformer_class-properties_transform_static_private_method_invoking branch from 1338938 to 727cba8 Compare December 26, 2024 16:42
@Dunqing Dunqing force-pushed the 12-26-feat_transformer_class-properties_transform_static_instance_accessor_methods branch from a7a20d0 to 0f5cc4d Compare December 26, 2024 16:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-transformer Area - Transformer / Transpiler C-enhancement Category - New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant