Skip to content

Commit

Permalink
fix(es/compat): Preserve more class names (#5106)
Browse files Browse the repository at this point in the history
  • Loading branch information
magic-akari committed Jul 6, 2022
1 parent 9385103 commit dd39a79
Show file tree
Hide file tree
Showing 13 changed files with 214 additions and 25 deletions.
5 changes: 5 additions & 0 deletions crates/swc/tests/fixture/issues-5xxx/5102/input/.swcrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"jsc": {
"target": "es5"
}
}
21 changes: 21 additions & 0 deletions crates/swc/tests/fixture/issues-5xxx/5102/input/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
let a = class /* a */ {};
let [b] = [class /* no named */ {}];
let [c = class /* c */ {}] = [];
let [d = class /* d */ {}] = [class /* no named */ {}];

let { e } = { e: class /* e */ {} };
let { f = class /* f */ {} } = {};
let { g = class /* g */ {} } = { g: class /* g */ {} };
let { _: h = class /* h */ {} } = {};

a = class /* a */ {};
b ||= class /* b */ {};
c ??= class /* c */ {};

function foo(bar = class /* bar */ {}) {}

d = {
i: class /* i */ {},
["j"]: class /* j */ {},
"-": class {},
};
79 changes: 79 additions & 0 deletions crates/swc/tests/fixture/issues-5xxx/5102/output/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import _class_call_check from "@swc/helpers/src/_class_call_check.mjs";
import _define_property from "@swc/helpers/src/_define_property.mjs";
var a = function a() {
"use strict";
_class_call_check(this, a);
};
var ref = [
function _class() {
"use strict";
_class_call_check(this, _class);
}
], b = ref[0];
var ref1 = [], tmp = ref1[0], c = tmp === void 0 ? function c() {
"use strict";
_class_call_check(this, c);
} : tmp;
var ref2 = [
function _class() {
"use strict";
_class_call_check(this, _class);
}
], tmp1 = ref2[0], d = tmp1 === void 0 ? function d() {
"use strict";
_class_call_check(this, d);
} : tmp1;
var e = {
e: function e() {
"use strict";
_class_call_check(this, e);
}
}.e;
var ref3 = {}, _f = ref3.f, f = _f === void 0 ? function f() {
"use strict";
_class_call_check(this, f);
} : _f;
var ref4 = {
g: function g() {
"use strict";
_class_call_check(this, g);
}
}, _g = ref4.g, g = _g === void 0 ? function g() {
"use strict";
_class_call_check(this, g);
} : _g;
var ref5 = {}, tmp2 = ref5._, h = tmp2 === void 0 ? function h() {
"use strict";
_class_call_check(this, h);
} : tmp2;
a = function a() {
"use strict";
_class_call_check(this, a);
};
b || (b = function b() {
"use strict";
_class_call_check(this, b);
});
c !== null && c !== void 0 ? c : c = function c() {
"use strict";
_class_call_check(this, c);
};
function foo() {
var bar = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : function bar() {
"use strict";
_class_call_check(this, bar);
};
}
var _obj;
d = (_obj = {
i: function i() {
"use strict";
_class_call_check(this, i);
}
}, _define_property(_obj, "j", function j() {
"use strict";
_class_call_check(this, j);
}), _define_property(_obj, "-", function _class() {
"use strict";
_class_call_check(this, _class);
}), _obj);
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import _class_call_check from "@swc/helpers/src/_class_call_check.mjs";
var _class;
function foo() {
var x = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : function _class() {
var x = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : function x() {
"use strict";
_class_call_check(this, _class);
_class_call_check(this, x);
};
return undefined;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
var _class;
import _class_call_check from "@swc/helpers/src/_class_call_check.mjs";
(function() {
arguments.length > 0 && void 0 !== arguments[0] && arguments[0];
var x = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : function() {
"use strict";
_class_call_check(this, x);
};
})(((_class = function() {
"use strict";
_class_call_check(this, _class);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import _class_call_check from "@swc/helpers/src/_class_call_check.mjs";
var _class;
function foo() {
var x = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : function _class() {
var x = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : function x() {
"use strict";
_class_call_check(this, _class);
_class_call_check(this, x);
};
return undefined;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
var _class;
import _class_call_check from "@swc/helpers/src/_class_call_check.mjs";
(function() {
arguments.length > 0 && void 0 !== arguments[0] && arguments[0];
var x = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : function() {
"use strict";
_class_call_check(this, x);
};
})(((_class = function() {
"use strict";
_class_call_check(this, _class);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import _class_call_check from "@swc/helpers/src/_class_call_check.mjs";
function foo() {
var x = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : function _class() {
var x = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : function x() {
"use strict";
_class_call_check(this, _class);
_class_call_check(this, x);
};
return undefined;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import _class_call_check from "@swc/helpers/src/_class_call_check.mjs";
(function() {
arguments.length > 0 && void 0 !== arguments[0] && arguments[0];
var x = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : function() {
"use strict";
_class_call_check(this, x);
};
})(function _class() {
"use strict";
_class_call_check(this, _class), this.prop = "hello";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ import _class_call_check from "@swc/helpers/src/_class_call_check.mjs";
_class_call_check(this, _class);
};
/** @typedef {number} Baz */ module.exports = {
Baz: function _class() {
Baz: function Baz() {
"use strict";
_class_call_check(this, _class);
_class_call_check(this, Baz);
}
};
// ok
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ exports.Bar = function _class() {
"use strict";
_class_call_check(this, _class);
}, module.exports = {
Baz: function _class() {
Baz: function Baz() {
"use strict";
_class_call_check(this, _class);
_class_call_check(this, Baz);
}
}, exports.Quid = 2, module.exports = {
Quack: 2
Expand Down
79 changes: 72 additions & 7 deletions crates/swc_ecma_transforms_compat/src/es2015/classes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ use swc_ecma_transforms_base::{helper, native::is_native, perf::Check};
use swc_ecma_transforms_classes::super_field::SuperFieldAccessFolder;
use swc_ecma_transforms_macros::fast_path;
use swc_ecma_utils::{
alias_if_required, default_constructor, prepend_stmt, private_ident, prop_name_to_expr,
quote_expr, quote_ident, quote_str, ExprFactory, IsDirective, ModuleItemLike, StmtLike,
alias_if_required, default_constructor, is_valid_prop_ident, prepend_stmt, private_ident,
prop_name_to_expr, quote_expr, quote_ident, quote_str, ExprFactory, IdentExt, IsDirective,
ModuleItemLike, StmtLike,
};
use swc_ecma_visit::{
as_folder, noop_visit_mut_type, noop_visit_type, Fold, Visit, VisitMut, VisitMutWith, VisitWith,
Expand Down Expand Up @@ -260,17 +261,81 @@ where
d.visit_mut_children_with(self)
}

/// `let { f = class /* f */ {} } = {};`
fn visit_mut_assign_pat_prop(&mut self, n: &mut AssignPatProp) {
if let Some(value) = &mut n.value {
if let Expr::Class(c @ ClassExpr { ident: None, .. }) = &mut **value {
c.ident = Some(n.key.clone());
}
}

n.visit_mut_children_with(self);
}

/// `let [c = class /* c */ {}] = [];`
/// `function foo(bar = class /* bar */ {}) {}`
fn visit_mut_assign_pat(&mut self, n: &mut AssignPat) {
if let (
Pat::Ident(BindingIdent { id, .. }),
Expr::Class(c @ ClassExpr { ident: None, .. }),
) = (&*n.left, &mut *n.right)
{
c.ident = Some(id.clone())
}

n.visit_mut_children_with(self);
}

/// {
/// hello: class {},
/// "foo": class {},
/// ["x"]: class {}
/// }
fn visit_mut_key_value_prop(&mut self, n: &mut KeyValueProp) {
if let Expr::Class(c @ ClassExpr { ident: None, .. }) = &mut *n.value {
match &n.key {
PropName::Ident(ident) => {
c.ident = Some(ident.clone().private());
}
PropName::Str(Str { value, span, .. }) => {
if is_valid_prop_ident(value) {
c.ident = Some(private_ident!(*span, value));
}
}
PropName::Computed(ComputedPropName { expr, .. }) => {
if let Expr::Lit(Lit::Str(Str { value, span, .. })) = &**expr {
if is_valid_prop_ident(value) {
c.ident = Some(private_ident!(*span, value));
}
}
}
_ => {}
}
}

n.visit_mut_children_with(self)
}

fn visit_mut_assign_expr(&mut self, a: &mut AssignExpr) {
if let AssignExpr {
op: op!("="),
left: PatOrExpr::Pat(pat),
op: op!("=") | op!("||=") | op!("??="),
left,
right,
..
} = a
{
if let Pat::Ident(i) = &**pat {
if let Expr::Class(c @ ClassExpr { ident: None, .. }) = &mut **right {
c.ident = Some(i.id.clone())
if let Expr::Class(c @ ClassExpr { ident: None, .. }) = &mut **right {
match left {
PatOrExpr::Pat(pat) => {
if let Pat::Ident(i) = &**pat {
c.ident = Some(i.id.clone())
}
}
PatOrExpr::Expr(expr) => {
if let Expr::Ident(ident) = &**expr {
c.ident = Some(ident.clone())
}
}
}
}
}
Expand Down
20 changes: 15 additions & 5 deletions crates/swc_ecma_transforms_compat/tests/es2015_classes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -943,14 +943,14 @@ var x = {
/*#__PURE__*/
function (Foo) {
"use strict";
_inherits(_class, Foo);
var _super = _createSuper(_class);
function _class() {
_classCallCheck(this, _class);
_inherits(Foo1, Foo);
var _super = _createSuper(Foo1);
function Foo1() {
_classCallCheck(this, Foo1);
return _super.apply(this, arguments);
}
return _class;
return Foo1;
}(Foo)
};
Expand Down Expand Up @@ -7356,6 +7356,8 @@ test!(
r#"
let C = class {}
D = class {}
C ||= class /* C */ {};
D ??= class /* D */ {};
"#,
r#"
var C = function C() {
Expand All @@ -7366,5 +7368,13 @@ D = function D() {
"use strict";
_classCallCheck(this, D);
};
C ||= function C() {
"use strict";
_classCallCheck(this, C);
};
D ??= function D() {
"use strict";
_classCallCheck(this, D);
};
"#
);

1 comment on commit dd39a79

@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: dd39a79 Previous: 2ba8b39 Ratio
es/full/minify/libraries/antd 1646693216 ns/iter (± 42992378) 1793059441 ns/iter (± 19419381) 0.92
es/full/minify/libraries/d3 419991444 ns/iter (± 11308004) 458002080 ns/iter (± 8174077) 0.92
es/full/minify/libraries/echarts 1624690627 ns/iter (± 63625476) 1767255416 ns/iter (± 27022818) 0.92
es/full/minify/libraries/jquery 93286225 ns/iter (± 6180797) 105031772 ns/iter (± 1123954) 0.89
es/full/minify/libraries/lodash 121906299 ns/iter (± 3769191) 135658774 ns/iter (± 2026988) 0.90
es/full/minify/libraries/moment 54190797 ns/iter (± 2835075) 58412659 ns/iter (± 1688631) 0.93
es/full/minify/libraries/react 18066217 ns/iter (± 499941) 19025866 ns/iter (± 624079) 0.95
es/full/minify/libraries/terser 604559021 ns/iter (± 14660214) 649137328 ns/iter (± 8763536) 0.93
es/full/minify/libraries/three 549932193 ns/iter (± 12282694) 595689678 ns/iter (± 8260417) 0.92
es/full/minify/libraries/typescript 3508273617 ns/iter (± 107382383) 3794969811 ns/iter (± 41264280) 0.92
es/full/minify/libraries/victory 750310395 ns/iter (± 7102618) 793618184 ns/iter (± 13120719) 0.95
es/full/minify/libraries/vue 153099472 ns/iter (± 6538533) 162883003 ns/iter (± 4093929) 0.94
es/full/codegen/es3 32327 ns/iter (± 1899) 33390 ns/iter (± 2164) 0.97
es/full/codegen/es5 32262 ns/iter (± 964) 33520 ns/iter (± 1437) 0.96
es/full/codegen/es2015 32138 ns/iter (± 768) 33348 ns/iter (± 2453) 0.96
es/full/codegen/es2016 32182 ns/iter (± 914) 33027 ns/iter (± 1400) 0.97
es/full/codegen/es2017 32038 ns/iter (± 858) 33145 ns/iter (± 1905) 0.97
es/full/codegen/es2018 32236 ns/iter (± 1192) 33363 ns/iter (± 1405) 0.97
es/full/codegen/es2019 33178 ns/iter (± 25209) 32743 ns/iter (± 1013) 1.01
es/full/codegen/es2020 32062 ns/iter (± 512) 33653 ns/iter (± 2063) 0.95
es/full/all/es3 190896599 ns/iter (± 11356577) 197204060 ns/iter (± 6765255) 0.97
es/full/all/es5 189274344 ns/iter (± 16881225) 185450433 ns/iter (± 8415012) 1.02
es/full/all/es2015 138263729 ns/iter (± 9507893) 148429370 ns/iter (± 8675163) 0.93
es/full/all/es2016 139098289 ns/iter (± 8272437) 146390049 ns/iter (± 4563200) 0.95
es/full/all/es2017 136272709 ns/iter (± 5169927) 145679691 ns/iter (± 4869048) 0.94
es/full/all/es2018 146240414 ns/iter (± 8021218) 143298322 ns/iter (± 4795651) 1.02
es/full/all/es2019 143316064 ns/iter (± 8130568) 143258353 ns/iter (± 3914855) 1.00
es/full/all/es2020 133615345 ns/iter (± 11135928) 138333891 ns/iter (± 6273466) 0.97
es/full/parser 674579 ns/iter (± 25936) 711277 ns/iter (± 32187) 0.95
es/full/base/fixer 28632 ns/iter (± 746) 29251 ns/iter (± 1188) 0.98
es/full/base/resolver_and_hygiene 86145 ns/iter (± 17866) 90854 ns/iter (± 10016) 0.95
serialization of ast node 217 ns/iter (± 3) 224 ns/iter (± 18) 0.97
serialization of serde 220 ns/iter (± 4) 239 ns/iter (± 23) 0.92

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

Please sign in to comment.