Skip to content

Commit

Permalink
fix(es/decorators): Fix syntax context of decorated classes (#4905)
Browse files Browse the repository at this point in the history
  • Loading branch information
kdy1 committed Jun 8, 2022
1 parent 87cc976 commit 814f72f
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import _class_call_check from "@swc/helpers/lib/_class_call_check.js";
import _ts_decorate from "@swc/helpers/lib/_ts_decorate.js";
var _TestClass;
var TestClass = (_TestClass = function TestClass() {
var TestClass = (_TestClass = function TestClass1() {
"use strict";
_class_call_check(this, TestClass);
_class_call_check(this, TestClass1);
}, _TestClass.Something = "hello", _TestClass.SomeProperties = {
firstProp: _TestClass.Something
}, _TestClass);
Expand Down
22 changes: 22 additions & 0 deletions crates/swc/tests/fixture/issues-4xxx/4899/input/.swcrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"$schema": "http://json.schemastore.org/swcrc",
"exclude": "\\.js$",
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": false,
"decorators": true
},
"target": "es2020",
"loose": false,
"minify": {
"compress": false,
"mangle": false
}
},
"module": {
"type": "amd",
"noInterop": true
},
"minify": false
}
23 changes: 23 additions & 0 deletions crates/swc/tests/fixture/issues-4xxx/4899/input/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
function es5ClassCompat(target: Function): any {
///@ts-expect-error
function _() {
return Reflect.construct(target, arguments, this.constructor);
}
Object.defineProperty(
_,
"name",
Object.getOwnPropertyDescriptor(target, "name")!
);
Object.setPrototypeOf(_, target);
Object.setPrototypeOf(_.prototype, target.prototype);
return _;
}

@es5ClassCompat
class Foo {
static create() {
return new Foo();
}

constructor() {}
}
24 changes: 24 additions & 0 deletions crates/swc/tests/fixture/issues-4xxx/4899/output/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
define([
"require",
"@swc/helpers/lib/_ts_decorate.js"
], function(require, _ts_decorate) {
"use strict";
function es5ClassCompat(target) {
function _() {
return Reflect.construct(target, arguments, this.constructor);
}
Object.defineProperty(_, "name", Object.getOwnPropertyDescriptor(target, "name"));
Object.setPrototypeOf(_, target);
Object.setPrototypeOf(_.prototype, target.prototype);
return _;
}
let Foo = class Foo1 {
static create() {
return new Foo();
}
constructor(){}
};
Foo = _ts_decorate([
es5ClassCompat
], Foo);
});
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
let TestClass = class TestClass {
let TestClass = class TestClass1 {
static Something = "hello";
static SomeProperties = {
firstProp: TestClass.Something
firstProp: TestClass1.Something
};
};
TestClass = __decorate([
Expand Down
19 changes: 17 additions & 2 deletions crates/swc_ecma_transforms_proposal/src/decorators/legacy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use swc_ecma_ast::*;
use swc_ecma_transforms_base::helper;
use swc_ecma_utils::{
constructor::inject_after_super, default_constructor, private_ident, prop_name_to_expr_value,
quote_ident, undefined, ExprFactory, StmtLike,
quote_ident, replace_ident, undefined, ExprFactory, StmtLike,
};
use swc_ecma_visit::{Visit, VisitMut, VisitMutWith, VisitWith};

Expand Down Expand Up @@ -358,11 +358,26 @@ impl VisitMut for TscDecorator {
decl.visit_mut_with(self);

if convert_to_let {
let inner_ident = private_ident!(decl.ident.sym.clone());

decl.class.body.iter_mut().for_each(|m| match m {
ClassMember::PrivateProp(PrivateProp {
is_static: true, ..
})
| ClassMember::StaticBlock(..)
| ClassMember::ClassProp(ClassProp {
is_static: true, ..
}) => {
replace_ident(m, decl.ident.to_id(), &inner_ident);
}
_ => {}
});

let d = VarDeclarator {
span: DUMMY_SP,
name: decl.ident.clone().into(),
init: Some(Box::new(Expr::Class(ClassExpr {
ident: Some(decl.ident.clone()),
ident: Some(inner_ident),
class: decl.class.take(),
}))),
definite: Default::default(),
Expand Down
21 changes: 21 additions & 0 deletions crates/swc_ecma_utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2292,6 +2292,27 @@ impl VisitMut for IdentReplacer<'_> {

visit_mut_obj_and_computed!();

fn visit_mut_prop(&mut self, node: &mut Prop) {
match node {
Prop::Shorthand(i) => {
let cloned = i.clone();
i.visit_mut_with(self);
if i.sym != cloned.sym || i.span.ctxt != cloned.span.ctxt {
*node = Prop::KeyValue(KeyValueProp {
key: PropName::Ident(Ident::new(
cloned.sym,
cloned.span.with_ctxt(SyntaxContext::empty()),
)),
value: Box::new(Expr::Ident(i.clone())),
});
}
}
_ => {
node.visit_mut_children_with(self);
}
}
}

fn visit_mut_ident(&mut self, node: &mut Ident) {
if node.sym == self.from.0 && node.span.ctxt == self.from.1 {
*node = self.to.clone();
Expand Down

1 comment on commit 814f72f

@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: 814f72f Previous: f7c89c5 Ratio
es/full/minify/libraries/antd 2521142714 ns/iter (± 100916014) 2602571695 ns/iter (± 34309510) 0.97
es/full/minify/libraries/d3 489169643 ns/iter (± 23963667) 674372852 ns/iter (± 16584520) 0.73
es/full/minify/libraries/echarts 2638189403 ns/iter (± 38201438) 2820107768 ns/iter (± 27736833) 0.94
es/full/minify/libraries/jquery 109022364 ns/iter (± 4013308) 144626162 ns/iter (± 9398686) 0.75
es/full/minify/libraries/lodash 170950787 ns/iter (± 5420959) 199065142 ns/iter (± 9035612) 0.86
es/full/minify/libraries/moment 67005964 ns/iter (± 2288090) 77779964 ns/iter (± 2622088) 0.86
es/full/minify/libraries/react 22699207 ns/iter (± 833836) 25886198 ns/iter (± 556083) 0.88
es/full/minify/libraries/terser 801108795 ns/iter (± 16993928) 868684216 ns/iter (± 11830606) 0.92
es/full/minify/libraries/three 726524188 ns/iter (± 29290359) 875161774 ns/iter (± 10755874) 0.83
es/full/minify/libraries/typescript 5595548028 ns/iter (± 122691695) 5751138135 ns/iter (± 74844196) 0.97
es/full/minify/libraries/victory 993718386 ns/iter (± 24423730) 1181061817 ns/iter (± 15959137) 0.84
es/full/minify/libraries/vue 175280093 ns/iter (± 5668663) 214553453 ns/iter (± 6247185) 0.82
es/full/codegen/es3 36352 ns/iter (± 1654) 40733 ns/iter (± 1498) 0.89
es/full/codegen/es5 36619 ns/iter (± 2359) 40610 ns/iter (± 1692) 0.90
es/full/codegen/es2015 35218 ns/iter (± 2132) 40428 ns/iter (± 1563) 0.87
es/full/codegen/es2016 35184 ns/iter (± 2774) 40443 ns/iter (± 1387) 0.87
es/full/codegen/es2017 38670 ns/iter (± 3421) 40589 ns/iter (± 2786) 0.95
es/full/codegen/es2018 36462 ns/iter (± 3028) 40593 ns/iter (± 1377) 0.90
es/full/codegen/es2019 35193 ns/iter (± 2277) 40852 ns/iter (± 1472) 0.86
es/full/codegen/es2020 34577 ns/iter (± 2248) 40607 ns/iter (± 2949) 0.85
es/full/all/es3 203035141 ns/iter (± 10398761) 226955434 ns/iter (± 7757847) 0.89
es/full/all/es5 193508669 ns/iter (± 9169565) 213837138 ns/iter (± 8306176) 0.90
es/full/all/es2015 159825648 ns/iter (± 5774608) 170177854 ns/iter (± 6533335) 0.94
es/full/all/es2016 156507752 ns/iter (± 9549881) 168205915 ns/iter (± 6018405) 0.93
es/full/all/es2017 151677426 ns/iter (± 6664354) 166989592 ns/iter (± 4803908) 0.91
es/full/all/es2018 149039917 ns/iter (± 7618413) 165004230 ns/iter (± 5920496) 0.90
es/full/all/es2019 154461824 ns/iter (± 7911854) 163618182 ns/iter (± 4496151) 0.94
es/full/all/es2020 151643882 ns/iter (± 6091073) 158168849 ns/iter (± 5710228) 0.96
es/full/parser 681967 ns/iter (± 49818) 765417 ns/iter (± 48471) 0.89
es/full/base/fixer 37221 ns/iter (± 2064) 36108 ns/iter (± 1419) 1.03
es/full/base/resolver_and_hygiene 165923 ns/iter (± 10949) 179409 ns/iter (± 8530) 0.92
serialization of ast node 175 ns/iter (± 9) 202 ns/iter (± 6) 0.87
serialization of serde 176 ns/iter (± 13) 201 ns/iter (± 7) 0.88

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

Please sign in to comment.