-
-
Notifications
You must be signed in to change notification settings - Fork 482
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
feat(transformer/class-properties): transform static/instance accessor methods #8132
Conversation
CodSpeed Performance ReportMerging #8132 will not alter performanceComparing Summary
|
f3ee3e1
to
1338938
Compare
56fb20e
to
a7a20d0
Compare
1338938
to
727cba8
Compare
63234f5
to
e0eb011
Compare
727cba8
to
7a754fa
Compare
e0eb011
to
dee1d70
Compare
a66fdb0
to
713db99
Compare
7a754fa
to
3f93847
Compare
64b8f64
to
284522b
Compare
284522b
to
db6c976
Compare
3f93847
to
f70e435
Compare
db6c976
to
55464b6
Compare
f70e435
to
bf6fa4d
Compare
55464b6
to
211e9a7
Compare
b1ab06c
to
e06d6fb
Compare
This PR has changed most of the code before this PR and did a lot of work in this PR because transforming private methods is complicated, It's hard to split this PR into many small PRs. |
Plus, all of the override tests related to private getter/setter methods transformation diverge with Babel |
Merge activity
|
…r methods (#8132) This PR supports transforming private `getter` or `setter` methods, and the output is a little different from Babel's output, For example: Input: ```js 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](https://babeljs.io/repl#?browsers=defaults%2C%20not%20ie%2011%2C%20not%20ie_mob%2011&build=&builtIns=false&corejs=3.21&spec=false&loose=false&code_lz=MYGwhgzhAEDCIwN4ChrQMQAcBOB7T0AvNAAwDcyq0A5gKYAuGYwwtUu2AFAJTQpppsDAK7YAdtHoALAJYQAdFjyYKaAL5UIDJizYQOnAG69-A4LjH6QteSFzVOYbNWEBbWmPoRuqgdLmKOPhE0Ia-GlTmlvTYwsD0BiZUaFFWNnYO_grozKzs2NzJ0ADaWYq5ehwAuiHFAIxV4cgaQA&debug=false&forceAllTransforms=false&modules=false&shippedProposals=false&evaluate=false&fileSize=false&timeTravel=false&sourceType=script&lineWrap=true&presets=&prettier=false&targets=&version=7.26.4&externalPlugins=%40babel%2Fplugin-transform-class-properties%407.25.9%2C%40babel%2Fplugin-transform-private-methods%407.25.9%2C%40babel%2Fplugin-external-helpers%407.25.9&assumptions=%7B%7D): ```js 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: ```js 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 ```diff // 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.
bf6fa4d
to
e405f79
Compare
e06d6fb
to
ad77ad5
Compare
This PR supports transforming private
getter
orsetter
methods, and the output is a little different from Babel's output, For example:Input:
Babel's output:
Oxc's output:
Main difference
From the main differences, we can see that Babel handles
getter
andsetter
methods usingclassPrivateGetter
andclassPrivateSetter
helper functions, which causes all usethis
andarguments
needs to rewrite to use a temp var instead ingetter
andsetter
methods. This is unnecessary and is not an efficient transformation for us.Instead, I adapt binding a
this
instead of passing inthis
, this way we don't need to rewrite anything. We can't control thehelper
library for now, so I just transformed the AST to bindthis
, in the future, we can create a helper function to do the same thing.