Skip to content

Commit

Permalink
fix(es/decorator): Support for legacy decorators in class expressions (
Browse files Browse the repository at this point in the history
…#8892)

**Related issue:**

- Closes #8515
  • Loading branch information
magic-akari committed Apr 27, 2024
1 parent 0fc70b3 commit 8fe57ad
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 17 deletions.
7 changes: 3 additions & 4 deletions crates/swc/tests/fixture/issues-8xxx/8095/es2020/output/1.js
@@ -1,10 +1,9 @@
import { _ as _ts_decorate } from "@swc/helpers/_/_ts_decorate";
var _class;
const foo = _class = class _class {
const foo = (_class = class _class {
foo(v) {
return v;
}
};
_ts_decorate([
}, _ts_decorate([
foo
], _class.prototype, "foo", null);
], _class.prototype, "foo", null));
7 changes: 3 additions & 4 deletions crates/swc/tests/fixture/issues-8xxx/8095/es2022/output/1.js
@@ -1,10 +1,9 @@
import { _ as _ts_decorate } from "@swc/helpers/_/_ts_decorate";
var _class;
const foo = _class = class _class {
const foo = (_class = class _class {
foo(v) {
return v;
}
};
_ts_decorate([
}, _ts_decorate([
foo
], _class.prototype, "foo", null);
], _class.prototype, "foo", null));
7 changes: 3 additions & 4 deletions crates/swc/tests/fixture/issues-8xxx/8095/es5/output/1.js
Expand Up @@ -2,7 +2,7 @@ import { _ as _class_call_check } from "@swc/helpers/_/_class_call_check";
import { _ as _create_class } from "@swc/helpers/_/_create_class";
import { _ as _ts_decorate } from "@swc/helpers/_/_ts_decorate";
var _class;
var foo = _class = function() {
var foo = (_class = function() {
"use strict";
function _class() {
_class_call_check(this, _class);
Expand All @@ -16,7 +16,6 @@ var foo = _class = function() {
}
]);
return _class;
}();
_ts_decorate([
}(), _ts_decorate([
foo
], _class.prototype, "foo", null);
], _class.prototype, "foo", null));
14 changes: 14 additions & 0 deletions crates/swc/tests/fixture/issues-8xxx/8515/input/.swcrc
@@ -0,0 +1,14 @@
{
"jsc": {
"target": "es2016",
"keepClassNames": true,
"parser": {
"syntax": "ecmascript",
"decorators": true
},
"transform": {
"legacyDecorator": true,
"useDefineForClassFields": true
}
}
}
9 changes: 9 additions & 0 deletions crates/swc/tests/fixture/issues-8xxx/8515/input/index.js
@@ -0,0 +1,9 @@
import { addX, addY } from 'someLib'

var C = @addX @addY class extends Component {
}

@addX @addY
class OtherClass extends Component {

}
14 changes: 14 additions & 0 deletions crates/swc/tests/fixture/issues-8xxx/8515/output/index.js
@@ -0,0 +1,14 @@
import { _ as _ts_decorate } from "@swc/helpers/_/_ts_decorate";
import { addX, addY } from 'someLib';
var _class;
var C = (_class = class _class extends Component {
}, _class = _ts_decorate([
addX,
addY
], _class));
let OtherClass = class OtherClass extends Component {
};
OtherClass = _ts_decorate([
addX,
addY
], OtherClass);
18 changes: 13 additions & 5 deletions crates/swc_ecma_transforms_proposal/src/decorators/legacy/mod.rs
@@ -1,4 +1,4 @@
use std::mem;
use std::{iter, mem};

use swc_atoms::JsWord;
use swc_common::{collections::AHashMap, util::take::Take, DUMMY_SP};
Expand Down Expand Up @@ -268,7 +268,9 @@ impl VisitMut for TscDecorator {
}

fn visit_mut_expr(&mut self, e: &mut Expr) {
let appended_exprs = mem::take(&mut self.appended_exprs);
e.visit_mut_children_with(self);
let appended_exprs = mem::replace(&mut self.appended_exprs, appended_exprs);

if let Some(var_name) = self.assign_class_expr_to.take() {
self.vars.push(VarDeclarator {
Expand All @@ -278,11 +280,17 @@ impl VisitMut for TscDecorator {
definite: Default::default(),
});

*e = Expr::Assign(AssignExpr {
*e = Expr::Seq(SeqExpr {
span: DUMMY_SP,
op: op!("="),
left: var_name.into(),
right: Box::new(e.take()),
exprs: iter::once(AssignExpr {
span: DUMMY_SP,
op: op!("="),
left: var_name.into(),
right: Box::new(e.take()),
})
.map(Into::into)
.chain(appended_exprs)
.collect(),
});
}
}
Expand Down

0 comments on commit 8fe57ad

Please sign in to comment.