mirror of
https://github.com/swc-project/swc.git
synced 2024-12-24 06:05:02 +03:00
Fix typescript class properties pass (#951)
This commit is contained in:
parent
ca246d3df7
commit
e1f5d681e3
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "swc_ecma_transforms"
|
||||
version = "0.19.1"
|
||||
version = "0.19.2"
|
||||
authors = ["강동윤 <kdy1997.dev@gmail.com>"]
|
||||
license = "Apache-2.0/MIT"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
|
@ -11,9 +11,9 @@ use crate::{
|
||||
undefined, ExprFactory, ModuleItemLike, StmtLike,
|
||||
},
|
||||
};
|
||||
use std::collections::HashSet;
|
||||
use std::{collections::HashSet, mem::take};
|
||||
use swc_atoms::JsWord;
|
||||
use swc_common::{Mark, Spanned, DUMMY_SP};
|
||||
use swc_common::{util::move_map::MoveMap, Mark, Spanned, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith, VisitWith};
|
||||
|
||||
@ -281,6 +281,8 @@ impl ClassProperties {
|
||||
|
||||
let has_super = class.super_class.is_some();
|
||||
|
||||
let mut typescript_constructor_properties = vec![];
|
||||
|
||||
let (mut constructor_exprs, mut vars, mut extra_stmts, mut members, mut constructor) =
|
||||
(vec![], vec![], vec![], vec![], None);
|
||||
let mut used_names = vec![];
|
||||
@ -562,9 +564,60 @@ impl ClassProperties {
|
||||
})));
|
||||
}
|
||||
|
||||
ClassMember::Constructor(c) => constructor = Some(c),
|
||||
ClassMember::Constructor(mut c) => {
|
||||
if self.typescript {
|
||||
let store = |i: &Ident| {
|
||||
Box::new(
|
||||
AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
left: PatOrExpr::Expr(Box::new(Expr::Member(MemberExpr {
|
||||
span: DUMMY_SP,
|
||||
obj: ThisExpr { span: DUMMY_SP }.as_obj(),
|
||||
computed: false,
|
||||
prop: Box::new(i.clone().into()),
|
||||
}))),
|
||||
op: op!("="),
|
||||
right: Box::new(i.clone().into()),
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
};
|
||||
|
||||
c.params = c.params.move_map(|mut param| match &mut param {
|
||||
ParamOrTsParamProp::TsParamProp(p) => match &p.param {
|
||||
TsParamPropParam::Ident(i) => {
|
||||
typescript_constructor_properties.push(store(i));
|
||||
ParamOrTsParamProp::Param(Param {
|
||||
span: p.span,
|
||||
decorators: take(&mut p.decorators),
|
||||
pat: Pat::Ident(i.clone()),
|
||||
})
|
||||
}
|
||||
TsParamPropParam::Assign(pat) => match &*pat.left {
|
||||
Pat::Ident(i) => {
|
||||
typescript_constructor_properties.push(store(i));
|
||||
ParamOrTsParamProp::Param(Param {
|
||||
span: p.span,
|
||||
decorators: take(&mut p.decorators),
|
||||
pat: Pat::Ident(i.clone()),
|
||||
})
|
||||
}
|
||||
_ => param,
|
||||
},
|
||||
},
|
||||
ParamOrTsParamProp::Param(_) => param,
|
||||
});
|
||||
}
|
||||
|
||||
constructor = Some(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let constructor_exprs = {
|
||||
typescript_constructor_properties.extend(constructor_exprs);
|
||||
typescript_constructor_properties
|
||||
};
|
||||
|
||||
let constructor =
|
||||
self.process_constructor(constructor, has_super, &used_names, constructor_exprs);
|
||||
@ -668,19 +721,9 @@ impl ClassProperties {
|
||||
}
|
||||
});
|
||||
|
||||
if let Some(mut c) = constructor {
|
||||
if self.typescript {
|
||||
// Append properties
|
||||
c.body
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.stmts
|
||||
.extend(constructor_exprs.into_iter().map(|v| v.into_stmt()));
|
||||
Some(c)
|
||||
} else {
|
||||
if let Some(c) = constructor {
|
||||
// Prepend properties
|
||||
Some(inject_after_super(c, constructor_exprs))
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
#![cfg_attr(test, feature(test))]
|
||||
#![recursion_limit = "1024"]
|
||||
#![deny(unused)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate swc_ecma_utils;
|
||||
|
@ -705,12 +705,11 @@ to!(
|
||||
|
||||
test!(
|
||||
::swc_ecma_parser::Syntax::Typescript(Default::default()),
|
||||
|_| chain!(tr(), typescript_class_properties()),
|
||||
|_| chain!(typescript_class_properties(), tr()),
|
||||
issue_930_instance,
|
||||
"class A {
|
||||
b = this.a;
|
||||
constructor(a){
|
||||
this.a = a;
|
||||
constructor(readonly a){
|
||||
}
|
||||
}",
|
||||
"class A {
|
||||
@ -723,7 +722,7 @@ test!(
|
||||
|
||||
test!(
|
||||
::swc_ecma_parser::Syntax::Typescript(Default::default()),
|
||||
|_| chain!(tr(), typescript_class_properties()),
|
||||
|_| chain!(typescript_class_properties(), tr()),
|
||||
issue_930_static,
|
||||
"class A {
|
||||
static b = 'foo';
|
||||
@ -736,3 +735,46 @@ test!(
|
||||
}
|
||||
A.b = 'foo';"
|
||||
);
|
||||
|
||||
test!(
|
||||
::swc_ecma_parser::Syntax::Typescript(Default::default()),
|
||||
|_| chain!(typescript_class_properties(), tr()),
|
||||
typescript_001,
|
||||
"class A {
|
||||
foo = new Subject()
|
||||
|
||||
constructor() {
|
||||
this.foo.subscribe()
|
||||
}
|
||||
}",
|
||||
"class A {
|
||||
constructor() {
|
||||
this.foo = new Subject()
|
||||
this.foo.subscribe()
|
||||
}
|
||||
}"
|
||||
);
|
||||
|
||||
test!(
|
||||
::swc_ecma_parser::Syntax::Typescript(Default::default()),
|
||||
|_| chain!(typescript_class_properties(), tr()),
|
||||
typescript_002,
|
||||
"class A extends B {
|
||||
foo = 'foo'
|
||||
b = this.a;
|
||||
|
||||
constructor(readonly a) {
|
||||
super()
|
||||
this.foo.subscribe()
|
||||
}
|
||||
}",
|
||||
"class A extends B {
|
||||
constructor(a) {
|
||||
super();
|
||||
this.a = a;
|
||||
this.foo = 'foo';
|
||||
this.b = this.a;
|
||||
this.foo.subscribe();
|
||||
}
|
||||
}"
|
||||
);
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@swc/core",
|
||||
"version": "1.2.15",
|
||||
"version": "1.2.16",
|
||||
"description": "Super-fast alternative for babel",
|
||||
"main": "./index.js",
|
||||
"author": "강동윤 <kdy1997.dev@gmail.com>",
|
||||
|
@ -88,10 +88,6 @@ impl<'a, 'b, P: swc_ecma_visit::Fold> PassBuilder<'a, 'b, P> {
|
||||
self.then(pass)
|
||||
}
|
||||
|
||||
pub fn strip_typescript(self) -> PassBuilder<'a, 'b, impl swc_ecma_visit::Fold> {
|
||||
self.then(typescript::strip())
|
||||
}
|
||||
|
||||
pub fn target(mut self, target: JscTarget) -> Self {
|
||||
self.target = target;
|
||||
self
|
||||
@ -133,7 +129,10 @@ impl<'a, 'b, P: swc_ecma_visit::Fold> PassBuilder<'a, 'b, P> {
|
||||
|
||||
// compat
|
||||
let compat_pass = if let Some(env) = self.env {
|
||||
Either::Left(swc_ecma_preset_env::preset_env(self.global_mark, env))
|
||||
Either::Left(chain!(
|
||||
Optional::new(typescript::strip(), syntax.typescript()),
|
||||
swc_ecma_preset_env::preset_env(self.global_mark, env)
|
||||
))
|
||||
} else {
|
||||
Either::Right(chain!(
|
||||
Optional::new(
|
||||
@ -144,17 +143,11 @@ impl<'a, 'b, P: swc_ecma_visit::Fold> PassBuilder<'a, 'b, P> {
|
||||
compat::es2020::optional_chaining(),
|
||||
self.target < JscTarget::Es2020
|
||||
),
|
||||
if syntax.typescript() {
|
||||
Either::Left(Optional::new(
|
||||
compat::es2020::typescript_class_properties(),
|
||||
self.target < JscTarget::Es2020,
|
||||
))
|
||||
} else {
|
||||
Either::Right(Optional::new(
|
||||
Optional::new(
|
||||
compat::es2020::class_properties(),
|
||||
self.target < JscTarget::Es2020,
|
||||
))
|
||||
},
|
||||
),
|
||||
Optional::new(typescript::strip(), syntax.typescript()),
|
||||
Optional::new(compat::es2018(), self.target <= JscTarget::Es2018),
|
||||
Optional::new(compat::es2017(), self.target <= JscTarget::Es2017),
|
||||
Optional::new(compat::es2016(), self.target <= JscTarget::Es2016),
|
||||
|
@ -18,6 +18,7 @@ use swc_ecma_ast::{Expr, ExprStmt, ModuleItem, Stmt};
|
||||
pub use swc_ecma_parser::JscTarget;
|
||||
use swc_ecma_parser::{lexer::Lexer, Parser, StringInput, Syntax, TsConfig};
|
||||
use swc_ecma_transforms::{
|
||||
compat::es2020::typescript_class_properties,
|
||||
const_modules, modules,
|
||||
optimization::{simplifier, InlineGlobals, JsonParse},
|
||||
pass::{noop, Optional},
|
||||
@ -234,6 +235,7 @@ impl Options {
|
||||
}),
|
||||
syntax.decorators()
|
||||
),
|
||||
Optional::new(typescript_class_properties(), syntax.typescript()),
|
||||
Optional::new(typescript::strip(), syntax.typescript()),
|
||||
resolver_with_mark(root_mark),
|
||||
const_modules,
|
||||
|
Loading…
Reference in New Issue
Block a user