Skip to content

Commit

Permalink
feat(es/compat): Support readonly and writeonly for private fields (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
Austaras committed Oct 18, 2022
1 parent a029ca2 commit aefc11b
Show file tree
Hide file tree
Showing 22 changed files with 290 additions and 125 deletions.
2 changes: 1 addition & 1 deletion crates/swc/tests/exec.rs
Expand Up @@ -57,7 +57,7 @@ fn init_helpers() -> Arc<PathBuf> {
let helper_dir = project_root.join("packages").join("swc-helpers");

let yarn = find_executable("yarn").expect("failed to find yarn");
let npm = find_executable("npm").expect("failed to find yarn");
let npm = find_executable("npm").expect("failed to find npm");
{
let mut cmd = if cfg!(target_os = "windows") {
let mut c = Command::new("cmd");
Expand Down
Expand Up @@ -2,6 +2,7 @@
import _class_private_field_get from "@swc/helpers/src/_class_private_field_get.mjs";
import _class_private_field_init from "@swc/helpers/src/_class_private_field_init.mjs";
import _class_private_field_set from "@swc/helpers/src/_class_private_field_set.mjs";
import _read_only_error from "@swc/helpers/src/_read_only_error.mjs";
var _prop = /*#__PURE__*/ new WeakMap(), _roProp = /*#__PURE__*/ new WeakMap();
class A1 {
constructor(name){
Expand All @@ -14,7 +15,7 @@ class A1 {
set: void 0
});
_class_private_field_set(this, _prop, "");
_class_private_field_set(this, _roProp, ""); // Error
this, _read_only_error("#roProp"); // Error
console.log(_class_private_field_get(this, _prop));
console.log(_class_private_field_get(this, _roProp));
}
Expand Down
@@ -1,18 +1,18 @@
//// [privateNameMethodAssignment.ts]
import _class_private_field_set from "@swc/helpers/src/_class_private_field_set.mjs";
import _class_private_field_update from "@swc/helpers/src/_class_private_field_update.mjs";
import _class_private_method_get from "@swc/helpers/src/_class_private_method_get.mjs";
import _class_private_method_init from "@swc/helpers/src/_class_private_method_init.mjs";
import _read_only_error from "@swc/helpers/src/_read_only_error.mjs";
import _class_private_field_destructure from "@swc/helpers/src/_class_private_field_destructure.mjs";
var _method = /*#__PURE__*/ new WeakSet();
class A3 {
constructor(a, b){
_class_private_method_init(this, _method);
_class_private_field_set(this, _method, ()=>{} // Error, not writable
);
_class_private_field_set(a, _method, ()=>{}); // Error, not writable
_class_private_field_set(b, _method, ()=>{} //Error, not writable
);
this, _read_only_error("#method") // Error, not writable
;
a, _read_only_error("#method"); // Error, not writable
b, _read_only_error("#method") //Error, not writable
;
({ x: _class_private_field_destructure(this, _method).value } = {
x: ()=>{}
}); //Error, not writable
Expand Down
@@ -1,10 +1,10 @@
//// [privateNameReadonly.ts]
import _class_private_field_set from "@swc/helpers/src/_class_private_field_set.mjs";
import _class_private_method_init from "@swc/helpers/src/_class_private_method_init.mjs";
import _read_only_error from "@swc/helpers/src/_read_only_error.mjs";
var _bar, _class;
const C = (_bar = /*#__PURE__*/ new WeakSet(), _class = class {
foo() {
_class_private_field_set(this, _bar, console.log("should log this then throw"));
this, console.log("should log this then throw"), _read_only_error("#bar");
}
constructor(){
_class_private_method_init(this, _bar);
Expand Down
@@ -1,10 +1,10 @@
//// [privateNameReadonly.ts]
var _bar;
import _class_private_field_set from "@swc/helpers/src/_class_private_field_set.mjs";
import _class_private_method_init from "@swc/helpers/src/_class_private_method_init.mjs";
import _read_only_error from "@swc/helpers/src/_read_only_error.mjs";
let C = (_bar = new WeakSet(), class {
foo() {
_class_private_field_set(this, _bar, console.log("should log this then throw"));
console.log("should log this then throw"), _read_only_error("#bar");
}
constructor(){
_class_private_method_init(this, _bar);
Expand Down
@@ -1,11 +1,11 @@
//// [privateNameSetterNoGetter.ts]
import _class_private_field_get from "@swc/helpers/src/_class_private_field_get.mjs";
import _class_private_field_init from "@swc/helpers/src/_class_private_field_init.mjs";
import _class_private_field_set from "@swc/helpers/src/_class_private_field_set.mjs";
import _write_only_error from "@swc/helpers/src/_write_only_error.mjs";
var _x, _class;
const C = (_x = /*#__PURE__*/ new WeakMap(), _class = class {
m() {
_class_private_field_set(this, _x, _class_private_field_get(this, _x) + 2); // Error
_class_private_field_set(this, _x, (this, _write_only_error("#x")) + 2); // Error
}
constructor(){
_class_private_field_init(this, _x, {
Expand Down
@@ -1,11 +1,11 @@
//// [privateNameSetterNoGetter.ts]
var _x;
import _class_private_field_get from "@swc/helpers/src/_class_private_field_get.mjs";
import _class_private_field_init from "@swc/helpers/src/_class_private_field_init.mjs";
import _class_private_field_set from "@swc/helpers/src/_class_private_field_set.mjs";
import _write_only_error from "@swc/helpers/src/_write_only_error.mjs";
let C = (_x = new WeakMap(), class {
m() {
_class_private_field_set(this, _x, _class_private_field_get(this, _x) + 2);
_class_private_field_set(this, _x, _write_only_error("#x") + 2);
}
constructor(){
_class_private_field_init(this, _x, {
Expand Down
@@ -1,23 +1,23 @@
//// [privateWriteOnlyAccessorRead.ts]
import _class_private_field_get from "@swc/helpers/src/_class_private_field_get.mjs";
import _class_private_field_init from "@swc/helpers/src/_class_private_field_init.mjs";
import _class_private_field_set from "@swc/helpers/src/_class_private_field_set.mjs";
import _extends from "@swc/helpers/src/_extends.mjs";
import _write_only_error from "@swc/helpers/src/_write_only_error.mjs";
import _class_private_field_destructure from "@swc/helpers/src/_class_private_field_destructure.mjs";
var _value = /*#__PURE__*/ new WeakMap(), _valueRest = /*#__PURE__*/ new WeakMap(), _valueOne = /*#__PURE__*/ new WeakMap(), _valueCompound = /*#__PURE__*/ new WeakMap();
class Test {
m() {
const foo = {
bar: 1
};
console.log(_class_private_field_get(this, _value)); // error
console.log((this, _write_only_error("#value"))); // error
_class_private_field_set(this, _value, {
foo
}); // ok
_class_private_field_set(this, _value, {
foo
}); // ok
_class_private_field_get(this, _value).foo = foo; // error
(this, _write_only_error("#value")).foo = foo; // error
({ o: _class_private_field_destructure(this, _value).value } = {
o: {
foo
Expand All @@ -27,26 +27,26 @@ class Test {
_tmp = {
foo
}, _class_private_field_destructure(this, _value).value = _extends({}, _tmp), _tmp; //ok
({ foo: _class_private_field_get(this, _value).foo } = {
({ foo: (this, _write_only_error("#value")).foo } = {
foo
}); //error
var _tmp1;
_tmp1 = {
foo
}, _class_private_field_get(this, _value).foo = _extends({}, _tmp1.foo), ({ foo: {} } = _tmp1), _tmp1; //error
}, (this, _write_only_error("#value")).foo = _extends({}, _tmp1.foo), ({ foo: {} } = _tmp1), _tmp1; //error
let r = {
o: _class_private_field_get(this, _value)
o: (this, _write_only_error("#value"))
}; //error
[_class_private_field_destructure(this, _valueOne).value, ..._class_private_field_destructure(this, _valueRest).value] = [
1,
2,
3
];
let arr = [
_class_private_field_get(this, _valueOne),
..._class_private_field_get(this, _valueRest)
(this, _write_only_error("#valueOne")),
...(this, _write_only_error("#valueRest"))
];
_class_private_field_set(this, _valueCompound, _class_private_field_get(this, _valueCompound) + 3);
_class_private_field_set(this, _valueCompound, (this, _write_only_error("#valueCompound")) + 3);
}
constructor(){
_class_private_field_init(this, _value, {
Expand Down
@@ -1,8 +1,8 @@
//// [privateWriteOnlyAccessorRead.ts]
import _class_private_field_get from "@swc/helpers/src/_class_private_field_get.mjs";
import _class_private_field_init from "@swc/helpers/src/_class_private_field_init.mjs";
import _class_private_field_set from "@swc/helpers/src/_class_private_field_set.mjs";
import _extends from "@swc/helpers/src/_extends.mjs";
import _write_only_error from "@swc/helpers/src/_write_only_error.mjs";
import _class_private_field_destructure from "@swc/helpers/src/_class_private_field_destructure.mjs";
var _value = new WeakMap(), _valueRest = new WeakMap(), _valueOne = new WeakMap(), _valueCompound = new WeakMap();
function set_value(v) {}
Expand All @@ -15,28 +15,28 @@ new class {
let foo = {
bar: 1
};
console.log(_class_private_field_get(this, _value)), _class_private_field_set(this, _value, {
console.log(_write_only_error("#value")), _class_private_field_set(this, _value, {
foo
}), _class_private_field_set(this, _value, {
foo
}), _class_private_field_get(this, _value).foo = foo, ({ o: _class_private_field_destructure(this, _value).value } = {
}), _write_only_error("#value").foo = foo, ({ o: _class_private_field_destructure(this, _value).value } = {
o: {
foo
}
}), _class_private_field_destructure(this, _value).value = _extends({}, {
foo
}), ({ foo: _class_private_field_get(this, _value).foo } = {
}), ({ foo: _write_only_error("#value").foo } = {
foo
}), _tmp = {
foo
}, _class_private_field_get(this, _value).foo = _extends({}, _tmp.foo), _class_private_field_get(this, _value), [_class_private_field_destructure(this, _valueOne).value, ..._class_private_field_destructure(this, _valueRest).value] = [
}, _write_only_error("#value").foo = _extends({}, _tmp.foo), _write_only_error("#value"), [_class_private_field_destructure(this, _valueOne).value, ..._class_private_field_destructure(this, _valueRest).value] = [
1,
2,
3
], [
_class_private_field_get(this, _valueOne),
..._class_private_field_get(this, _valueRest)
], _class_private_field_set(this, _valueCompound, _class_private_field_get(this, _valueCompound) + 3);
_write_only_error("#valueOne"),
..._write_only_error("#valueRest")
], _class_private_field_set(this, _valueCompound, _write_only_error("#valueCompound") + 3);
}
constructor(){
_class_private_field_init(this, _value, {
Expand Down
@@ -1,5 +1,8 @@
function _classApplyDescriptorUpdate(receiver, descriptor) {
if (descriptor.set) {
if (!descriptor.get) {
throw new TypeError("attempted to read set only private field");
}
if (!("__destrWrapper" in descriptor)) {
descriptor.__destrWrapper = {
set value(v) {
Expand Down
@@ -1,3 +1,3 @@
function _readOnlyError(name) {
throw new Error("\"" + name + "\" is read-only");
throw new TypeError("\"" + name + "\" is read-only");
}
@@ -0,0 +1,3 @@
function _writeOnlyError(name) {
throw new TypeError("\"" + name + "\" is write-only");
}
1 change: 1 addition & 0 deletions crates/swc_ecma_transforms_base/src/helpers/mod.rs
Expand Up @@ -334,6 +334,7 @@ define_helpers!(Helpers {
set_prototype_of,
is_native_function
),
write_only_error: (),

class_private_field_destructure: (
class_extract_field_descriptor,
Expand Down

1 comment on commit aefc11b

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: aefc11b Previous: 4fba0db Ratio
es/full/minify/libraries/antd 1748109688 ns/iter (± 17480335) 2485867065 ns/iter (± 159117675) 0.70
es/full/minify/libraries/d3 363397620 ns/iter (± 9193663) 516855354 ns/iter (± 47232410) 0.70
es/full/minify/libraries/echarts 1481507695 ns/iter (± 10605396) 2099595453 ns/iter (± 417552009) 0.71
es/full/minify/libraries/jquery 94386628 ns/iter (± 1680940) 162413743 ns/iter (± 19707900) 0.58
es/full/minify/libraries/lodash 107645520 ns/iter (± 1616422) 230163549 ns/iter (± 790197817) 0.47
es/full/minify/libraries/moment 54794340 ns/iter (± 826143) 82876284 ns/iter (± 26986994) 0.66
es/full/minify/libraries/react 18871283 ns/iter (± 366698) 26866982 ns/iter (± 3402301) 0.70
es/full/minify/libraries/terser 283483870 ns/iter (± 7607016) 463832480 ns/iter (± 277141856) 0.61
es/full/minify/libraries/three 524268008 ns/iter (± 13909328) 747342130 ns/iter (± 1147585187) 0.70
es/full/minify/libraries/typescript 3249166309 ns/iter (± 30481272) 4534278015 ns/iter (± 553923193) 0.72
es/full/minify/libraries/victory 771717290 ns/iter (± 11779978) 1032825615 ns/iter (± 114218453) 0.75
es/full/minify/libraries/vue 134482843 ns/iter (± 2097866) 233975306 ns/iter (± 21828558) 0.57
es/full/codegen/es3 32981 ns/iter (± 839) 51360 ns/iter (± 7187) 0.64
es/full/codegen/es5 33087 ns/iter (± 1212) 48971 ns/iter (± 13859) 0.68
es/full/codegen/es2015 33131 ns/iter (± 1707) 41280 ns/iter (± 6505) 0.80
es/full/codegen/es2016 32986 ns/iter (± 1043) 43398 ns/iter (± 6710) 0.76
es/full/codegen/es2017 33028 ns/iter (± 586) 49587 ns/iter (± 16148) 0.67
es/full/codegen/es2018 33112 ns/iter (± 410) 56675 ns/iter (± 20585) 0.58
es/full/codegen/es2019 33275 ns/iter (± 587) 55821 ns/iter (± 141062) 0.60
es/full/codegen/es2020 33022 ns/iter (± 991) 49395 ns/iter (± 10632) 0.67
es/full/all/es3 183541605 ns/iter (± 3262227) 328661105 ns/iter (± 926742030) 0.56
es/full/all/es5 174501016 ns/iter (± 2897174) 279355594 ns/iter (± 114340260) 0.62
es/full/all/es2015 140091322 ns/iter (± 3273654) 252875509 ns/iter (± 327975522) 0.55
es/full/all/es2016 139238713 ns/iter (± 3080109) 227626657 ns/iter (± 34693216) 0.61
es/full/all/es2017 138780063 ns/iter (± 3019447) 201369801 ns/iter (± 25238879) 0.69
es/full/all/es2018 136903211 ns/iter (± 4037907) 172894782 ns/iter (± 22920134) 0.79
es/full/all/es2019 136341740 ns/iter (± 3855380) 194881428 ns/iter (± 31590823) 0.70
es/full/all/es2020 132001929 ns/iter (± 2968557) 199988019 ns/iter (± 40526358) 0.66
es/full/parser 690502 ns/iter (± 23773) 1108369 ns/iter (± 292773) 0.62
es/full/base/fixer 24856 ns/iter (± 369) 35748 ns/iter (± 5385) 0.70
es/full/base/resolver_and_hygiene 89474 ns/iter (± 1416) 122014 ns/iter (± 17063) 0.73
serialization of ast node 204 ns/iter (± 5) 276 ns/iter (± 43) 0.74
serialization of serde 219 ns/iter (± 6) 312 ns/iter (± 52) 0.70

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.