mirror of
https://github.com/swc-project/swc.git
synced 2024-12-24 14:16:12 +03:00
fix(es/decorators): Fix a regression about class expressions (#8102)
**Related issue:** - Closes #8095
This commit is contained in:
parent
1183c32e3c
commit
cb4361f293
@ -1 +1 @@
|
||||
export default class t{#t;constructor(t){this.#t=t}#e(){setTimeout(()=>{this.#t.textContent="TESTED"},1e3)}run(){this.#e()}}
|
||||
var t;t=class{#t;constructor(t){this.#t=t}#e(){setTimeout(()=>{this.#t.textContent="TESTED"},1e3)}run(){this.#e()}};export{t as default};
|
||||
|
@ -17,13 +17,14 @@ define([
|
||||
function state() {}
|
||||
class Controller {
|
||||
}
|
||||
class _class extends Controller {
|
||||
var _class;
|
||||
_class = class _$class extends Controller {
|
||||
onChange() {}
|
||||
constructor(...args){
|
||||
super(...args);
|
||||
_define_property._(this, "isTest", false);
|
||||
}
|
||||
}
|
||||
};
|
||||
_ts_decorate._([
|
||||
state
|
||||
], _class.prototype, "isTest", void 0);
|
||||
|
@ -12,7 +12,8 @@ const _ts_decorate = require("@swc/helpers/_/_ts_decorate");
|
||||
function test(constructor) {
|
||||
console.log(constructor);
|
||||
}
|
||||
let _class = class _class {
|
||||
var _class;
|
||||
_class = class _$class {
|
||||
};
|
||||
_class = _ts_decorate._([
|
||||
test
|
||||
|
@ -2,7 +2,8 @@ import { _ as _ts_decorate } from "@swc/helpers/_/_ts_decorate";
|
||||
function test(constructor) {
|
||||
console.log(constructor);
|
||||
}
|
||||
let _class = class _class {
|
||||
var _class;
|
||||
_class = class _$class {
|
||||
};
|
||||
_class = _ts_decorate([
|
||||
test
|
||||
|
@ -5,13 +5,14 @@ import { _ as _ts_metadata } from "@swc/helpers/_/_ts_metadata";
|
||||
function Prop() {
|
||||
return function() {};
|
||||
}
|
||||
var Example = function Example() {
|
||||
var Example;
|
||||
Example = function Example() {
|
||||
"use strict";
|
||||
_class_call_check(this, Example);
|
||||
_define_property(this, "prop", void 0);
|
||||
};
|
||||
export { Example as default };
|
||||
_ts_decorate([
|
||||
Prop(),
|
||||
_ts_metadata("design:type", typeof BigInt === "undefined" ? Object : BigInt)
|
||||
], Example.prototype, "prop", void 0);
|
||||
export { Example as default };
|
||||
|
@ -5,7 +5,8 @@ import { _ as _create_super } from "@swc/helpers/_/_create_super";
|
||||
import { _ as _ts_decorate } from "@swc/helpers/_/_ts_decorate";
|
||||
import React from "react";
|
||||
import { withRouter } from "react-router-dom";
|
||||
var App = /*#__PURE__*/ function(_React_Component) {
|
||||
var App;
|
||||
App = /*#__PURE__*/ function(_React_Component) {
|
||||
"use strict";
|
||||
_inherits(App, _React_Component);
|
||||
var _super = _create_super(App);
|
||||
|
@ -0,0 +1,20 @@
|
||||
{
|
||||
"jsc": {
|
||||
"parser": {
|
||||
"syntax": "typescript",
|
||||
"tsx": false,
|
||||
"decorators": true
|
||||
},
|
||||
"target": "es2020",
|
||||
"loose": false,
|
||||
"minify": {
|
||||
"compress": false,
|
||||
"mangle": false
|
||||
}
|
||||
},
|
||||
"module": {
|
||||
"type": "es6"
|
||||
},
|
||||
"minify": false,
|
||||
"isModule": true
|
||||
}
|
@ -0,0 +1 @@
|
||||
const foo = class { @foo foo(v) { return v } }
|
10
crates/swc/tests/fixture/issues-8xxx/8095/es2020/output/1.js
Normal file
10
crates/swc/tests/fixture/issues-8xxx/8095/es2020/output/1.js
Normal file
@ -0,0 +1,10 @@
|
||||
import { _ as _ts_decorate } from "@swc/helpers/_/_ts_decorate";
|
||||
var _class;
|
||||
const foo = _class = class _$class {
|
||||
foo(v) {
|
||||
return v;
|
||||
}
|
||||
};
|
||||
_ts_decorate([
|
||||
foo
|
||||
], _class.prototype, "foo", null);
|
@ -0,0 +1,20 @@
|
||||
{
|
||||
"jsc": {
|
||||
"parser": {
|
||||
"syntax": "typescript",
|
||||
"tsx": false,
|
||||
"decorators": true
|
||||
},
|
||||
"target": "es2022",
|
||||
"loose": false,
|
||||
"minify": {
|
||||
"compress": false,
|
||||
"mangle": false
|
||||
}
|
||||
},
|
||||
"module": {
|
||||
"type": "es6"
|
||||
},
|
||||
"minify": false,
|
||||
"isModule": true
|
||||
}
|
@ -0,0 +1 @@
|
||||
const foo = class { @foo foo(v) { return v } }
|
10
crates/swc/tests/fixture/issues-8xxx/8095/es2022/output/1.js
Normal file
10
crates/swc/tests/fixture/issues-8xxx/8095/es2022/output/1.js
Normal file
@ -0,0 +1,10 @@
|
||||
import { _ as _ts_decorate } from "@swc/helpers/_/_ts_decorate";
|
||||
var _class;
|
||||
const foo = _class = class _$class {
|
||||
foo(v) {
|
||||
return v;
|
||||
}
|
||||
};
|
||||
_ts_decorate([
|
||||
foo
|
||||
], _class.prototype, "foo", null);
|
20
crates/swc/tests/fixture/issues-8xxx/8095/es5/input/.swcrc
Normal file
20
crates/swc/tests/fixture/issues-8xxx/8095/es5/input/.swcrc
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"jsc": {
|
||||
"parser": {
|
||||
"syntax": "typescript",
|
||||
"tsx": false,
|
||||
"decorators": true
|
||||
},
|
||||
"target": "es5",
|
||||
"loose": false,
|
||||
"minify": {
|
||||
"compress": false,
|
||||
"mangle": false
|
||||
}
|
||||
},
|
||||
"module": {
|
||||
"type": "es6"
|
||||
},
|
||||
"minify": false,
|
||||
"isModule": true
|
||||
}
|
1
crates/swc/tests/fixture/issues-8xxx/8095/es5/input/1.js
Normal file
1
crates/swc/tests/fixture/issues-8xxx/8095/es5/input/1.js
Normal file
@ -0,0 +1 @@
|
||||
const foo = class { @foo foo(v) { return v } }
|
22
crates/swc/tests/fixture/issues-8xxx/8095/es5/output/1.js
Normal file
22
crates/swc/tests/fixture/issues-8xxx/8095/es5/output/1.js
Normal file
@ -0,0 +1,22 @@
|
||||
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 = /*#__PURE__*/ function() {
|
||||
"use strict";
|
||||
function _$class() {
|
||||
_class_call_check(this, _$class);
|
||||
}
|
||||
_create_class(_$class, [
|
||||
{
|
||||
key: "foo",
|
||||
value: function foo(v) {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
]);
|
||||
return _$class;
|
||||
}();
|
||||
_ts_decorate([
|
||||
foo
|
||||
], _class.prototype, "foo", null);
|
@ -1,4 +1,5 @@
|
||||
let A = class A {
|
||||
var A;
|
||||
A = class A {
|
||||
};
|
||||
A = _ts_decorate([
|
||||
dec
|
||||
|
@ -1,6 +1,7 @@
|
||||
export default class A {
|
||||
var A;
|
||||
A = class A {
|
||||
foo() {}
|
||||
}
|
||||
};
|
||||
_ts_decorate([
|
||||
dec
|
||||
], A.prototype, "foo", null);
|
||||
@ -10,3 +11,4 @@ class B {
|
||||
_ts_decorate([
|
||||
dec
|
||||
], B.prototype, "foo", null);
|
||||
export { A as default };
|
||||
|
@ -1,6 +1,8 @@
|
||||
export default class X {
|
||||
var X;
|
||||
X = class X {
|
||||
prop: string = "";
|
||||
}
|
||||
};
|
||||
_ts_decorate([
|
||||
networked
|
||||
], X.prototype, "prop", void 0);
|
||||
export { X as default };
|
||||
|
@ -1,5 +1,6 @@
|
||||
function myDecorator(decoratee) {}
|
||||
let _class = class _class {
|
||||
var _class;
|
||||
_class = class _$class {
|
||||
};
|
||||
_class = _ts_decorate([
|
||||
myDecorator
|
||||
|
@ -1,6 +1,8 @@
|
||||
export default class _class {
|
||||
var _class;
|
||||
_class = class _$class {
|
||||
bar() {}
|
||||
}
|
||||
};
|
||||
_ts_decorate([
|
||||
foo
|
||||
], _class.prototype, "bar", null);
|
||||
export { _class as default };
|
||||
|
@ -30,6 +30,7 @@ pub(super) fn new(metadata: bool) -> TscDecorator {
|
||||
class_name: Default::default(),
|
||||
constructor_exprs: Default::default(),
|
||||
exports: Default::default(),
|
||||
assign_class_expr_to: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,6 +50,8 @@ pub(super) struct TscDecorator {
|
||||
constructor_exprs: Vec<Box<Expr>>,
|
||||
|
||||
exports: Vec<ExportSpecifier>,
|
||||
|
||||
assign_class_expr_to: Option<Ident>,
|
||||
}
|
||||
|
||||
impl TscDecorator {
|
||||
@ -291,14 +294,49 @@ impl VisitMut for TscDecorator {
|
||||
self.class_name = old;
|
||||
}
|
||||
|
||||
fn visit_mut_expr(&mut self, e: &mut Expr) {
|
||||
e.visit_mut_children_with(self);
|
||||
|
||||
if let Some(var_name) = self.assign_class_expr_to.take() {
|
||||
*e = Expr::Assign(AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("="),
|
||||
left: var_name.into(),
|
||||
right: Box::new(e.take()),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_mut_class_expr(&mut self, n: &mut ClassExpr) {
|
||||
let old = self.class_name.take();
|
||||
if contains_decorator(n) && n.ident.is_none() {
|
||||
n.ident = Some(private_ident!("_class"));
|
||||
}
|
||||
|
||||
if contains_decorator(n) && n.ident.is_none() {
|
||||
let ident = private_ident!("_$class");
|
||||
|
||||
let var_name = private_ident!("_class");
|
||||
|
||||
self.vars.push(VarDeclarator {
|
||||
span: DUMMY_SP,
|
||||
name: Pat::Ident(var_name.clone().into()),
|
||||
init: None,
|
||||
definite: Default::default(),
|
||||
});
|
||||
|
||||
self.class_name = Some(var_name.clone());
|
||||
n.ident = Some(ident);
|
||||
|
||||
n.visit_mut_children_with(self);
|
||||
|
||||
self.class_name = old;
|
||||
|
||||
self.assign_class_expr_to = Some(var_name);
|
||||
|
||||
return;
|
||||
}
|
||||
if let Some(ident) = &n.ident {
|
||||
self.class_name = Some(ident.clone());
|
||||
if self.class_name.is_none() {
|
||||
self.class_name = Some(ident.clone());
|
||||
}
|
||||
}
|
||||
|
||||
n.visit_mut_children_with(self);
|
||||
@ -405,6 +443,46 @@ impl VisitMut for TscDecorator {
|
||||
|
||||
fn visit_mut_module_item(&mut self, module_item: &mut ModuleItem) {
|
||||
match module_item {
|
||||
ModuleItem::ModuleDecl(ModuleDecl::ExportDefaultDecl(ExportDefaultDecl {
|
||||
decl: DefaultDecl::Class(c),
|
||||
..
|
||||
})) => {
|
||||
c.visit_mut_with(self);
|
||||
|
||||
if self.assign_class_expr_to.is_none() {
|
||||
if let Some(var_name) = c.ident.clone() {
|
||||
self.vars.push(VarDeclarator {
|
||||
span: DUMMY_SP,
|
||||
name: Pat::Ident(var_name.clone().into()),
|
||||
init: None,
|
||||
definite: Default::default(),
|
||||
});
|
||||
|
||||
self.assign_class_expr_to = Some(var_name);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(var_name) = self.assign_class_expr_to.take() {
|
||||
*module_item = ModuleItem::Stmt(
|
||||
Expr::Assign(AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("="),
|
||||
left: var_name.clone().into(),
|
||||
right: Box::new(Expr::Class(c.take())),
|
||||
})
|
||||
.into_stmt(),
|
||||
);
|
||||
|
||||
self.exports
|
||||
.push(ExportSpecifier::Named(ExportNamedSpecifier {
|
||||
span: DUMMY_SP,
|
||||
orig: ModuleExportName::Ident(var_name),
|
||||
exported: Some(ModuleExportName::Ident(quote_ident!("default"))),
|
||||
is_type_only: Default::default(),
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(n)) => {
|
||||
let export_decl_span = n.span;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user