From ed951255c764db370e1327d9ca1c3125f1493a92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 Aug 2020 15:49:34 +0900 Subject: [PATCH 01/31] WIP: emitDecoratorMetadata --- .../transforms/src/proposals/decorators.rs | 5 + .../transforms/tests/proposal_decorators.rs | 168 ++++++++++++++---- 2 files changed, 140 insertions(+), 33 deletions(-) diff --git a/ecmascript/transforms/src/proposals/decorators.rs b/ecmascript/transforms/src/proposals/decorators.rs index 22cce50445cc..289b67ffbf26 100644 --- a/ecmascript/transforms/src/proposals/decorators.rs +++ b/ecmascript/transforms/src/proposals/decorators.rs @@ -57,6 +57,9 @@ pub fn decorators(c: Config) -> impl Fold { if c.legacy { Either::Left(Legacy::default()) } else { + if c.emit_metadata { + unimplemented!("emitting decorator metadata while using new proposal") + } Either::Right(Decorators { is_in_strict: false, }) @@ -66,6 +69,8 @@ pub fn decorators(c: Config) -> impl Fold { #[derive(Debug, Default, Deserialize)] pub struct Config { pub legacy: bool, + #[serde(default)] + pub emit_metadata: bool, } #[derive(Debug, Default)] diff --git a/ecmascript/transforms/tests/proposal_decorators.rs b/ecmascript/transforms/tests/proposal_decorators.rs index 2a1fcb0799c5..d02309cdd57c 100644 --- a/ecmascript/transforms/tests/proposal_decorators.rs +++ b/ecmascript/transforms/tests/proposal_decorators.rs @@ -2049,7 +2049,10 @@ let A = _decorate([], function(_initialize) { test_exec!( syntax(true), |_| chain!( - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), class_properties(), ), legacy_class_constructors_return_new_constructor_exec, @@ -2076,7 +2079,10 @@ test!( syntax(true), |_| chain!( typescript::strip(), - decorators(decorators::Config { legacy: true }) + decorators(decorators::Config { + legacy: true, + ..Default::default() + }) ), legacy_regression_10264, r#" @@ -2481,7 +2487,10 @@ export { _class1 as default } // legacy_decl_to_expression_class_decorators test!( syntax(false), - |_| decorators(Config { legacy: true }), + |_| decorators(Config { + legacy: true, + ..Default::default() + }), legacy_decl_to_expression_class_decorators, r#" export default @dec class A {} @@ -2500,7 +2509,10 @@ let B = dec((_class1 = class B{ test_exec!( syntax(false), |_| chain!( - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), class_properties(), ), legacy_class_prototype_methods_numeric_props_exec, @@ -2523,7 +2535,10 @@ class Example { test_exec!( syntax(false), |_| chain!( - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), class_properties(), ), legacy_class_static_properties_mutate_descriptor_exec, @@ -2635,7 +2650,10 @@ expect(Example._).toBe("__8__"); test_exec!( syntax(false), |_| chain!( - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), class_properties(), ), legacy_class_static_methods_string_props_exec, @@ -2658,7 +2676,10 @@ class Example { test_exec!( syntax(false), |_| chain!( - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), class_properties(), ), legacy_class_prototype_properties_string_literal_properties_exec, @@ -2700,7 +2721,10 @@ expect(descs["a-prop"].configurable).toBeTruthy(); test_exec!( syntax(false), |_| chain!( - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), class_properties(), ), legacy_class_prototype_methods_mutate_descriptor_exec, @@ -2830,7 +2854,10 @@ test_exec!( ignore, syntax(false), |_| chain!( - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), class_properties(), ), legacy_object_properties_numeric_props_exec, @@ -2852,7 +2879,10 @@ const inst = { // legacy_decl_to_expression_method_decorators test!( syntax(false), - |_| decorators(Config { legacy: true }), + |_| decorators(Config { + legacy: true, + ..Default::default() + }), legacy_decl_to_expression_method_decorators, r#" export default class A { @@ -2881,7 +2911,10 @@ export { A as default } test_exec!( syntax(false), |_| chain!( - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), class_properties(), ), legacy_class_prototype_properties_return_descriptor_exec, @@ -2995,7 +3028,10 @@ test_exec!( ignore, syntax(false), |_| chain!( - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), class_properties(), ), legacy_object_properties_string_props_exec, @@ -3020,7 +3056,10 @@ test_exec!( ignore, syntax(false), |_| chain!( - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), class_properties(), ), legacy_object_properties_return_descriptor_exec, @@ -3130,7 +3169,10 @@ expect(inst._).toBe("__8__"); test_exec!( syntax(false), |_| chain!( - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), class_properties(), ), legacy_class_prototype_methods_string_props_exec, @@ -3153,7 +3195,10 @@ class Example { test!( syntax(false), |_| chain!( - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), class_properties(), ), legacy_regression_8041, @@ -3181,7 +3226,10 @@ export { _class1 as default } test_exec!( syntax(false), |_| chain!( - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), class_properties(), ), legacy_class_prototype_methods_return_descriptor_exec, @@ -3313,7 +3361,10 @@ test_exec!( ignore, syntax(false), |_| chain!( - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), class_properties(), ), legacy_object_ordering_reverse_order_exec, @@ -3354,7 +3405,10 @@ test_exec!( ignore, syntax(false), |_| chain!( - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), class_properties(), ), legacy_object_methods_numeric_props_exec, @@ -3378,7 +3432,10 @@ const inst = { test_exec!( syntax(false), |_| chain!( - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), class_properties(), ), legacy_class_static_properties_return_descriptor_exec, @@ -3495,7 +3552,10 @@ test_exec!( ignore, syntax(true), |_| chain!( - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), class_properties(), ), legacy_class_export_default_exec, @@ -3522,7 +3582,10 @@ expect(calls).toEqual(["Foo"]); test_exec!( syntax(true), |_| chain!( - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), class_properties(), ), legacy_class_ordering_reverse_order_exec, @@ -3566,7 +3629,10 @@ test_exec!( ignore, syntax(true), |_| chain!( - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), class_properties(), ), legacy_object_methods_mutate_descriptor_exec, @@ -3692,7 +3758,10 @@ expect(inst._()).toBe("__8__"); test_exec!( syntax(false), |_| chain!( - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), class_properties(), ), legacy_class_static_methods_return_descriptor_exec, @@ -3821,7 +3890,10 @@ test_exec!( ignore, syntax(false), |_| chain!( - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), class_properties(), ), legacy_object_methods_return_descriptor_exec, @@ -3949,7 +4021,10 @@ test_exec!( ignore, syntax(false), |_| chain!( - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), class_properties(), ), legacy_object_methods_string_props_exec, @@ -3974,7 +4049,10 @@ const inst = { test_exec!( syntax(false), |_| chain!( - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), class_properties(), ), legacy_class_prototype_properties_child_classes_properties_exec, @@ -4014,7 +4092,10 @@ expect(inst.prop2).toBe("__4__"); test_exec!( syntax(false), |_| chain!( - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), class_properties(), ), legacy_class_static_methods_mutate_descriptor_exec, @@ -4139,7 +4220,10 @@ expect(Example._()).toBe("__8__"); // legacy_regression_8512 test_exec!( syntax(false), - |_| decorators(Config { legacy: true }), + |_| decorators(Config { + legacy: true, + ..Default::default() + }), legacy_regression_8512_exec, r#" function dec(Class, key, desc) { @@ -4156,7 +4240,10 @@ class Foo { test!( syntax(false), - |_| decorators(Config { legacy: true }), + |_| decorators(Config { + legacy: true, + ..Default::default() + }), issue_591_1, " export class Example { @@ -4190,7 +4277,10 @@ export let Example = ((_class = class Example{ test!( syntax(false), - |_| decorators(Config { legacy: true }), + |_| decorators(Config { + legacy: true, + ..Default::default() + }), issue_591_2, "class Example { @foo() bar = '1'; @@ -4226,7 +4316,13 @@ test!( decorators: true, ..Default::default() }), - |_| chain!(typescript::strip(), decorators(Config { legacy: true })), + |_| chain!( + typescript::strip(), + decorators(Config { + legacy: true, + ..Default::default() + }) + ), issue_823_1, "import {Debounce} from 'lodash-decorators'; class Person { @@ -4262,7 +4358,10 @@ test!( }), |_| chain!( typescript::strip(), - decorators(Config { legacy: true }), + decorators(Config { + legacy: true, + ..Default::default() + }), class_properties(), // Classes::default(), ), @@ -4305,7 +4404,10 @@ test!( }), |_| chain!( typescript::strip(), - decorators(Config { legacy: true }), + decorators(Config { + legacy: true, + ..Default::default() + }), class_properties(), Classes::default(), ), From d2a73d2a2abb602b25cdb902d3769c73e447cbad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 Aug 2020 15:54:32 +0900 Subject: [PATCH 02/31] Tests for decorator metadatas --- .../transforms/tests/proposal_decorators.rs | 166 ++++++++++++++++++ 1 file changed, 166 insertions(+) diff --git a/ecmascript/transforms/tests/proposal_decorators.rs b/ecmascript/transforms/tests/proposal_decorators.rs index d02309cdd57c..ee5b76cf48c4 100644 --- a/ecmascript/transforms/tests/proposal_decorators.rs +++ b/ecmascript/transforms/tests/proposal_decorators.rs @@ -4713,3 +4713,169 @@ let X = ((_class = function() { export { X as default }; " ); + +test!( + ts(), + |_| decorators(Config { + legacy: true, + emit_metadata: true, + }), + legacy_metadata_generics, + "@Decorate + class MyClass { + constructor( + private generic: Generic, + generic2: Generic + ) {} + + @Run + method( + generic: Inter, + @Arg() generic2: InterGen + ) {} + }", + "" +); + +test!( + ts(), + |_| decorators(Config { + legacy: true, + emit_metadata: true, + }), + legacy_metadata_nest_injection, + "import { AppService } from './app.service'; + + @Controller() + export class AppController { + constructor(private appService: AppService) {} + + @Inject() + appService: AppService; + + @Inject() + private appService2: AppService; + + @Get() + getHello(): string { + return this.appService.getHello(); + } + }", + "" +); + +test!( + ts(), + |_| decorators(Config { + legacy: true, + emit_metadata: true, + }), + legacy_metadata_parameter_decorated_types, + "class Injected {} + + class MyClass { + constructor(@inject() parameter: Injected) {} + } + + class MyOtherClass { + constructor( + @inject() private readonly parameter: Injected, + @inject('KIND') otherParam: Injected + ) {} + + methodUndecorated(@demo() param: string, otherParam) {} + + @decorate('named') + method(@inject() param: Injected, @arg() schema: Schema) {} + } + + @Decorate + class DecoratedClass { + constructor( + @inject() private readonly module: Injected, + @inject() otherModule: Injected + ) {} + + @decorate('example') + method(@inject() param: string) {} + }", + "" +); + +test!( + ts(), + |_| decorators(Config { + legacy: true, + emit_metadata: true, + }), + legacy_metadata_type_serialization, + "import { Service } from './service'; + import { Decorate } from './Decorate'; + + const sym = Symbol(); + + @Decorate() + class Sample { + constructor( + private p0: String, + p1: Number, + p2: 10, + p3: 'ABC', + p4: boolean, + p5: string, + p6: number, + p7: Object, + p8: () => any, + p9: 'abc' | 'def', + p10: String | Number, + p11: Function, + p12: null, + p13: undefined, + p14: any, + p15: (abc: any) => void, + p16: false, + p17: true, + p18: string = 'abc' + ) {} + + @Decorate + method( + @Arg() p0: Symbol, + p1: typeof sym, + p2: string | null, + p3: never, + p4: string | never, + p5: (string | null), + p6: Maybe, + p7: Object | string, + p8: string & MyStringType, + p9: string[], + p10: [string, number], + p11: void, + p12: this is number, + p13: null | undefined, + p14: (string | (string | null)), + p15: Object, + p16: any, + p17: bigint, + ) {} + + /** + * Member Expression + */ + @Decorate() + method2( + p0: Decorate.Name = 'abc', + p1: Decorate.Name + ) {} + + /** + * Assignments + */ + @Decorate() + assignments( + p0: string = 'abc' + ) {} + }", + "" +); From c7db8ce5309e782b022b4d5d4096cbaf24dd7764 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 Aug 2020 16:05:42 +0900 Subject: [PATCH 03/31] Config --- .../transforms/src/proposals/decorators.rs | 4 ++-- .../src/proposals/decorators/legacy.rs | 12 +++++++++- .../transforms/tests/proposal_decorators.rs | 23 ++++++++++++++++++- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/ecmascript/transforms/src/proposals/decorators.rs b/ecmascript/transforms/src/proposals/decorators.rs index 289b67ffbf26..d0c86746a637 100644 --- a/ecmascript/transforms/src/proposals/decorators.rs +++ b/ecmascript/transforms/src/proposals/decorators.rs @@ -1,4 +1,3 @@ -use self::legacy::Legacy; use crate::util::{ alias_ident_for, constructor::inject_after_super, prop_name_to_expr_value, undefined, ExprFactory, IdentExt, @@ -55,7 +54,7 @@ mod usage; /// ``` pub fn decorators(c: Config) -> impl Fold { if c.legacy { - Either::Left(Legacy::default()) + Either::Left(self::legacy::new(c.emit_metadata)) } else { if c.emit_metadata { unimplemented!("emitting decorator metadata while using new proposal") @@ -67,6 +66,7 @@ pub fn decorators(c: Config) -> impl Fold { } #[derive(Debug, Default, Deserialize)] +#[serde(rename_all = "camelCase")] pub struct Config { pub legacy: bool, #[serde(default)] diff --git a/ecmascript/transforms/src/proposals/decorators/legacy.rs b/ecmascript/transforms/src/proposals/decorators/legacy.rs index 7f36851d5ae4..75f71028c6c4 100644 --- a/ecmascript/transforms/src/proposals/decorators/legacy.rs +++ b/ecmascript/transforms/src/proposals/decorators/legacy.rs @@ -9,13 +9,23 @@ use swc_common::{util::move_map::MoveMap, DUMMY_SP}; use swc_ecma_ast::*; use swc_ecma_visit::{Fold, FoldWith, VisitWith}; -#[derive(Debug, Default)] +#[derive(Debug)] pub(super) struct Legacy { + metadata: bool, uninitialized_vars: Vec, initialized_vars: Vec, exports: Vec, } +pub(super) fn new(metadata: bool) -> Legacy { + Legacy { + metadata, + uninitialized_vars: Default::default(), + initialized_vars: Default::default(), + exports: Default::default(), + } +} + noop_fold_type!(Legacy); impl Fold for Legacy { diff --git a/ecmascript/transforms/tests/proposal_decorators.rs b/ecmascript/transforms/tests/proposal_decorators.rs index ee5b76cf48c4..951e1c92f212 100644 --- a/ecmascript/transforms/tests/proposal_decorators.rs +++ b/ecmascript/transforms/tests/proposal_decorators.rs @@ -4720,7 +4720,7 @@ test!( legacy: true, emit_metadata: true, }), - legacy_metadata_generics, + legacy_metadata_generics_base, "@Decorate class MyClass { constructor( @@ -4737,6 +4737,27 @@ test!( "" ); +test!( + ts(), + |_| decorators(Config { + legacy: true, + emit_metadata: true, + }), + legacy_metadata_generics_1, + "@Decorate +class MyClass {}", + r##"let MyClass = (_dec = Reflect.metadata("design:type", Function), _dec2 = Reflect.metadata("design:paramtypes", [typeof Generic === "undefined" ? Object : Generic, typeof Generic === "undefined" ? Object : Generic]), _dec3 = function (target, key) { + return Arg()(target, key, 1); + }, _dec4 = Reflect.metadata("design:type", Function), _dec5 = Reflect.metadata("design:paramtypes", [typeof Inter === "undefined" ? Object : Inter, typeof InterGen === "undefined" ? Object : InterGen]), Decorate(_class = _dec(_class = _dec2(_class = (_class2 = class MyClass { + constructor(generic, generic2) { + this.generic = generic; + } + + method(generic, generic2) {} + + }, (_applyDecoratedDescriptor(_class2.prototype, "method", [Run, _dec3, _dec4, _dec5], Object.getOwnPropertyDescriptor(_class2.prototype, "method"), _class2.prototype)), _class2)) || _class) || _class) || _class);"## +); + test!( ts(), |_| decorators(Config { From d264faa4b9655835eb8bafd342bdba822215df1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 Aug 2020 16:37:45 +0900 Subject: [PATCH 04/31] emitDecoratorMetadata for class parameters --- .../src/proposals/decorators/legacy.rs | 5 + .../proposals/decorators/legacy/metadata.rs | 120 ++++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs diff --git a/ecmascript/transforms/src/proposals/decorators/legacy.rs b/ecmascript/transforms/src/proposals/decorators/legacy.rs index 75f71028c6c4..03baa70a1d10 100644 --- a/ecmascript/transforms/src/proposals/decorators/legacy.rs +++ b/ecmascript/transforms/src/proposals/decorators/legacy.rs @@ -1,3 +1,4 @@ +use self::metadata::{Metadata, ParamMetadata}; use super::usage::DecoratorFinder; use crate::util::{ alias_if_required, default_constructor, prepend, prop_name_to_expr_value, undefined, @@ -9,6 +10,8 @@ use swc_common::{util::move_map::MoveMap, DUMMY_SP}; use swc_ecma_ast::*; use swc_ecma_visit::{Fold, FoldWith, VisitWith}; +mod metadata; + #[derive(Debug)] pub(super) struct Legacy { metadata: bool, @@ -207,6 +210,8 @@ impl Legacy { impl Legacy { fn handle(&mut self, mut c: ClassExpr) -> Box { + c = c.fold_with(&mut ParamMetadata).fold_with(&mut Metadata); + let cls_ident = private_ident!("_class"); let cls_name = c.ident.clone(); diff --git a/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs b/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs new file mode 100644 index 000000000000..3803b2ae7468 --- /dev/null +++ b/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs @@ -0,0 +1,120 @@ +use swc_common::{util::move_map::MoveMap, DUMMY_SP}; +use swc_ecma_ast::*; +use swc_ecma_utils::ExprFactory; +use swc_ecma_visit::{Fold, FoldWith}; + +/// https://github.com/leonardfactory/babel-plugin-transform-typescript-metadata/blob/master/src/parameter/parameterVisitor.ts +pub(super) struct ParamMetadata; + +impl Fold for ParamMetadata { + fn fold_class(&mut self, mut cls: Class) -> Class { + cls = cls.fold_children_with(self); + + cls.body = cls.body.move_map(|mut m| match m { + ClassMember::Constructor(c) => { + for (idx, param) in c.params.iter_mut().enumerate() { + // + match param { + ParamOrTsParamProp::TsParamProp(p) => { + for decorator in p.decorators.drain(..) { + let new_dec = + self.create_param_decorator(idx, decorator.expr, true); + cls.decorators.push(new_dec); + } + } + ParamOrTsParamProp::Param(param) => { + for decorator in param.decorators.drain(..) { + let new_dec = + self.create_param_decorator(idx, decorator.expr, true); + cls.decorators.push(new_dec); + } + } + } + } + + ClassMember::Constructor(c) + } + _ => m, + }); + + cls + } + + fn fold_class_method(&mut self, mut m: ClassMethod) -> ClassMethod { + m = m.fold_children_with(self); + + for (idx, param) in m.function.params.iter_mut().enumerate() { + for decorator in param.decorators.drain(..) { + let new_dec = self.create_param_decorator(idx, decorator.expr, false); + m.function.decorators.push(new_dec); + } + } + + m + } +} + +impl ParamMetadata { + fn create_param_decorator( + &self, + param_index: usize, + decorator_expr: Box, + is_constructor: bool, + ) -> Decorator { + Decorator { + span: DUMMY_SP, + expr: Box::new(Expr::Fn(FnExpr { + ident: None, + function: Function { + params: vec![ + Param { + span: DUMMY_SP, + decorators: Default::default(), + pat: Pat::Ident(quote_ident!("target")), + }, + Param { + span: DUMMY_SP, + decorators: Default::default(), + pat: Pat::Ident(quote_ident!("target")), + }, + ], + body: Some(BlockStmt { + span: DUMMY_SP, + stmts: vec![Stmt::Return(ReturnStmt { + span: DUMMY_SP, + arg: Some(Box::new(Expr::Call(CallExpr { + span: DUMMY_SP, + callee: decorator_expr.as_callee(), + args: vec![ + quote_ident!("target").as_arg(), + if is_constructor { + quote_ident!("undefined").as_arg() + } else { + quote_ident!("key").as_arg() + }, + Lit::Num(Number { + span: DUMMY_SP, + value: param_index as _, + }) + .as_arg(), + ], + type_args: Default::default(), + }))), + })], + }), + decorators: Default::default(), + span: Default::default(), + is_generator: Default::default(), + is_async: Default::default(), + type_params: Default::default(), + return_type: Default::default(), + }, + })), + } + } +} + +/// https://github.com/leonardfactory/babel-plugin-transform-typescript-metadata/blob/master/src/metadata/metadataVisitor.ts +pub(super) struct Metadata; + +impl Fold for Metadata {} From bc18bbbb8873ec0b3e1c708d87269c4d6763d220 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 Aug 2020 16:41:27 +0900 Subject: [PATCH 05/31] fixup! emitDecoratorMetadata for class parameters --- .../transforms/src/proposals/decorators/legacy.rs | 4 +++- .../src/proposals/decorators/legacy/metadata.rs | 10 ++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/ecmascript/transforms/src/proposals/decorators/legacy.rs b/ecmascript/transforms/src/proposals/decorators/legacy.rs index 03baa70a1d10..c14812fba2cd 100644 --- a/ecmascript/transforms/src/proposals/decorators/legacy.rs +++ b/ecmascript/transforms/src/proposals/decorators/legacy.rs @@ -210,7 +210,9 @@ impl Legacy { impl Legacy { fn handle(&mut self, mut c: ClassExpr) -> Box { - c = c.fold_with(&mut ParamMetadata).fold_with(&mut Metadata); + if self.metadata { + c = c.fold_with(&mut ParamMetadata).fold_with(&mut Metadata); + } let cls_ident = private_ident!("_class"); let cls_name = c.ident.clone(); diff --git a/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs b/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs index 3803b2ae7468..5f96cdc97608 100644 --- a/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs +++ b/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs @@ -9,9 +9,10 @@ pub(super) struct ParamMetadata; impl Fold for ParamMetadata { fn fold_class(&mut self, mut cls: Class) -> Class { cls = cls.fold_children_with(self); + let mut decorators = cls.decorators; - cls.body = cls.body.move_map(|mut m| match m { - ClassMember::Constructor(c) => { + cls.body = cls.body.move_map(|m| match m { + ClassMember::Constructor(mut c) => { for (idx, param) in c.params.iter_mut().enumerate() { // match param { @@ -19,14 +20,14 @@ impl Fold for ParamMetadata { for decorator in p.decorators.drain(..) { let new_dec = self.create_param_decorator(idx, decorator.expr, true); - cls.decorators.push(new_dec); + decorators.push(new_dec); } } ParamOrTsParamProp::Param(param) => { for decorator in param.decorators.drain(..) { let new_dec = self.create_param_decorator(idx, decorator.expr, true); - cls.decorators.push(new_dec); + decorators.push(new_dec); } } } @@ -36,6 +37,7 @@ impl Fold for ParamMetadata { } _ => m, }); + cls.decorators = decorators; cls } From f0235fe4b051aa31a4ca54a4e2be3ece468c0791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 Aug 2020 16:44:55 +0900 Subject: [PATCH 06/31] Udpate test --- .../transforms/tests/proposal_decorators.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/ecmascript/transforms/tests/proposal_decorators.rs b/ecmascript/transforms/tests/proposal_decorators.rs index 951e1c92f212..f5b04fa75949 100644 --- a/ecmascript/transforms/tests/proposal_decorators.rs +++ b/ecmascript/transforms/tests/proposal_decorators.rs @@ -4745,17 +4745,20 @@ test!( }), legacy_metadata_generics_1, "@Decorate -class MyClass {}", - r##"let MyClass = (_dec = Reflect.metadata("design:type", Function), _dec2 = Reflect.metadata("design:paramtypes", [typeof Generic === "undefined" ? Object : Generic, typeof Generic === "undefined" ? Object : Generic]), _dec3 = function (target, key) { - return Arg()(target, key, 1); - }, _dec4 = Reflect.metadata("design:type", Function), _dec5 = Reflect.metadata("design:paramtypes", [typeof Inter === "undefined" ? Object : Inter, typeof InterGen === "undefined" ? Object : InterGen]), Decorate(_class = _dec(_class = _dec2(_class = (_class2 = class MyClass { +class MyClass { + constructor( + private generic: Generic, + generic2: Generic + ) {} +}", + r##"var _dec, _dec2, _class; + + let MyClass = (_dec = Reflect.metadata("design:type", Function), _dec2 = Reflect.metadata("design:paramtypes", [typeof Generic === "undefined" ? Object : Generic, typeof Generic === "undefined" ? Object : Generic]), Decorate(_class = _dec(_class = _dec2(_class = class MyClass { constructor(generic, generic2) { this.generic = generic; } - method(generic, generic2) {} - - }, (_applyDecoratedDescriptor(_class2.prototype, "method", [Run, _dec3, _dec4, _dec5], Object.getOwnPropertyDescriptor(_class2.prototype, "method"), _class2.prototype)), _class2)) || _class) || _class) || _class);"## + }) || _class) || _class) || _class);"## ); test!( From 744a3e03ee7ae1b7a9635278a5f4ecd6d7bcfd34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 Aug 2020 17:04:31 +0900 Subject: [PATCH 07/31] Metadata is almost done --- .../proposals/decorators/legacy/metadata.rs | 118 +++++++++++++++++- 1 file changed, 115 insertions(+), 3 deletions(-) diff --git a/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs b/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs index 5f96cdc97608..f24038d54669 100644 --- a/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs +++ b/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs @@ -43,8 +43,6 @@ impl Fold for ParamMetadata { } fn fold_class_method(&mut self, mut m: ClassMethod) -> ClassMethod { - m = m.fold_children_with(self); - for (idx, param) in m.function.params.iter_mut().enumerate() { for decorator in param.decorators.drain(..) { let new_dec = self.create_param_decorator(idx, decorator.expr, false); @@ -119,4 +117,118 @@ impl ParamMetadata { /// https://github.com/leonardfactory/babel-plugin-transform-typescript-metadata/blob/master/src/metadata/metadataVisitor.ts pub(super) struct Metadata; -impl Fold for Metadata {} +impl Fold for Metadata { + fn fold_class(&mut self, mut c: Class) -> Class { + c = c.fold_children_with(self); + + if c.decorators.is_empty() { + return c; + } + + let constructor = c.body.iter().find_map(|m| match m { + ClassMember::Constructor(c) => Some(c), + _ => None, + }); + if constructor.is_none() { + return c; + } + + { + let dec = self + .create_metadata_design_decorator("design:type", quote_ident!("Function").as_arg()); + c.decorators.push(dec); + } + { + let dec = self.create_metadata_design_decorator( + "design:paramtypes", + ArrayLit { + span: DUMMY_SP, + elems: constructor + .as_ref() + .unwrap() + .params + .iter() + .map(|v| match v { + ParamOrTsParamProp::TsParamProp(p) => Some(serialize_type().as_arg()), + ParamOrTsParamProp::Param(p) => Some(serialize_type().as_arg()), + }) + .collect(), + } + .as_arg(), + ); + c.decorators.push(dec); + } + c + } + + fn fold_class_method(&mut self, mut m: ClassMethod) -> ClassMethod { + if m.function.decorators.is_empty() { + return m; + } + + { + let dec = self + .create_metadata_design_decorator("design:type", quote_ident!("Function").as_arg()); + m.function.decorators.push(dec); + } + { + let dec = self.create_metadata_design_decorator( + "design:paramtypes", + ArrayLit { + span: DUMMY_SP, + elems: m + .function + .params + .iter() + .map(|v| Some(serialize_type().as_arg())) + .collect(), + } + .as_arg(), + ); + m.function.decorators.push(dec); + } + m + } + + fn fold_class_prop(&mut self, mut p: ClassProp) -> ClassProp { + if p.decorators.is_empty() { + return p; + } + + if p.type_ann.is_none() { + return p; + } + + let dec = self.create_metadata_design_decorator( + "design:type", + serialize_type(classPath, field).as_arg(), + ); + + p + } +} + +impl Metadata { + fn create_metadata_design_decorator(&self, design: &str, type_arg: ExprOrSpread) -> Decorator { + Decorator { + span: DUMMY_SP, + expr: Box::new(Expr::Call(CallExpr { + span: DUMMY_SP, + callee: member_expr!(DUMMY_SP, Reflect.metadata).as_callee(), + args: vec![ + Str { + span: DUMMY_SP, + value: design.into(), + has_escape: false, + } + .as_arg(), + type_arg, + ], + + type_args: Default::default(), + })), + } + } +} + +fn serialize_type() -> Expr {} From 8dd05a8ed83f55398a6a224e0800c18ac50279cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 Aug 2020 17:10:55 +0900 Subject: [PATCH 08/31] ClassExpr / ClassDecl --- .../proposals/decorators/legacy/metadata.rs | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs b/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs index f24038d54669..f165e79ec9a1 100644 --- a/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs +++ b/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs @@ -117,8 +117,8 @@ impl ParamMetadata { /// https://github.com/leonardfactory/babel-plugin-transform-typescript-metadata/blob/master/src/metadata/metadataVisitor.ts pub(super) struct Metadata; -impl Fold for Metadata { - fn fold_class(&mut self, mut c: Class) -> Class { +impl Metadata { + fn handle_class(&mut self, mut c: Class, class_name: Option<&Ident>) -> Class { c = c.fold_children_with(self); if c.decorators.is_empty() { @@ -160,6 +160,20 @@ impl Fold for Metadata { } c } +} + +impl Fold for Metadata { + fn fold_class_decl(&mut self, mut c: ClassDecl) -> ClassDecl { + let class = self.handle_class(c.class, Some(&c.ident)); + c.class = class; + c + } + + fn fold_class_expr(&mut self, mut c: ClassExpr) -> ClassExpr { + let class = self.handle_class(c.class, c.ident.as_ref()); + c.class = class; + c + } fn fold_class_method(&mut self, mut m: ClassMethod) -> ClassMethod { if m.function.decorators.is_empty() { @@ -231,4 +245,6 @@ impl Metadata { } } -fn serialize_type() -> Expr {} +fn serialize_type(decl: &Class, class_name: Option<&Ident>, param: Param) -> Expr { + // +} From eee1f0eea9b5af01ce63804b4664dc275807449b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 Aug 2020 17:42:17 +0900 Subject: [PATCH 09/31] WIP: type serializer --- .../src/proposals/decorators/legacy.rs | 4 +- .../proposals/decorators/legacy/metadata.rs | 150 +++++++++++++++--- 2 files changed, 130 insertions(+), 24 deletions(-) diff --git a/ecmascript/transforms/src/proposals/decorators/legacy.rs b/ecmascript/transforms/src/proposals/decorators/legacy.rs index c14812fba2cd..273793c0e049 100644 --- a/ecmascript/transforms/src/proposals/decorators/legacy.rs +++ b/ecmascript/transforms/src/proposals/decorators/legacy.rs @@ -211,7 +211,9 @@ impl Legacy { impl Legacy { fn handle(&mut self, mut c: ClassExpr) -> Box { if self.metadata { - c = c.fold_with(&mut ParamMetadata).fold_with(&mut Metadata); + c = c.fold_with(&mut ParamMetadata).fold_with(&mut Metadata { + class_name: c.ident.as_ref(), + }); } let cls_ident = private_ident!("_class"); diff --git a/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs b/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs index f165e79ec9a1..2332fa6459ac 100644 --- a/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs +++ b/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs @@ -1,6 +1,6 @@ -use swc_common::{util::move_map::MoveMap, DUMMY_SP}; +use swc_common::{util::move_map::MoveMap, Spanned, DUMMY_SP}; use swc_ecma_ast::*; -use swc_ecma_utils::ExprFactory; +use swc_ecma_utils::{undefined, ExprFactory}; use swc_ecma_visit::{Fold, FoldWith}; /// https://github.com/leonardfactory/babel-plugin-transform-typescript-metadata/blob/master/src/parameter/parameterVisitor.ts @@ -115,10 +115,12 @@ impl ParamMetadata { } /// https://github.com/leonardfactory/babel-plugin-transform-typescript-metadata/blob/master/src/metadata/metadataVisitor.ts -pub(super) struct Metadata; +pub(super) struct Metadata<'a> { + pub(super) class_name: Option<&'a Ident>, +} -impl Metadata { - fn handle_class(&mut self, mut c: Class, class_name: Option<&Ident>) -> Class { +impl Fold for Metadata<'_> { + fn fold_class(&mut self, mut c: Class) -> Class { c = c.fold_children_with(self); if c.decorators.is_empty() { @@ -160,20 +162,6 @@ impl Metadata { } c } -} - -impl Fold for Metadata { - fn fold_class_decl(&mut self, mut c: ClassDecl) -> ClassDecl { - let class = self.handle_class(c.class, Some(&c.ident)); - c.class = class; - c - } - - fn fold_class_expr(&mut self, mut c: ClassExpr) -> ClassExpr { - let class = self.handle_class(c.class, c.ident.as_ref()); - c.class = class; - c - } fn fold_class_method(&mut self, mut m: ClassMethod) -> ClassMethod { if m.function.decorators.is_empty() { @@ -215,14 +203,14 @@ impl Fold for Metadata { let dec = self.create_metadata_design_decorator( "design:type", - serialize_type(classPath, field).as_arg(), + serialize_type(&c, self.class_name, p).as_arg(), ); p } } -impl Metadata { +impl Metadata<'_> { fn create_metadata_design_decorator(&self, design: &str, type_arg: ExprOrSpread) -> Decorator { Decorator { span: DUMMY_SP, @@ -245,6 +233,122 @@ impl Metadata { } } -fn serialize_type(decl: &Class, class_name: Option<&Ident>, param: Param) -> Expr { - // +fn serialize_type(decl: &Class, class_name: Option<&Ident>, param: Option) -> Expr { + fn serialize_type_ref(class_name: &str, ty: TsTypeRef) -> Expr {} + + fn serialize_type_list(class_name: &str, types: Vec>) -> Expr {} + + fn serialize_type_node(class_name: &str, ty: TsType) -> Expr { + let span = ty.span(); + match ty { + TsType::TsKeywordType(TsKeywordType { + kind: TsKeywordTypeKind::TsVoidKeyword, + .. + }) + | TsType::TsKeywordType(TsKeywordType { + kind: TsKeywordTypeKind::TsUndefinedKeyword, + .. + }) + | TsType::TsKeywordType(TsKeywordType { + kind: TsKeywordTypeKind::TsNullKeyword, + .. + }) + | TsType::TsKeywordType(TsKeywordType { + kind: TsKeywordTypeKind::TsNeverKeyword, + .. + }) => return *undefined(span), + + TsType::TsParenthesizedType(ty) => serialize_type_node(class_name, *ty.type_ann), + + TsType::TsFnOrConstructorType(_) => quote_ident!("Function").into(), + + TsType::TsArrayType(_) | TsType::TsTupleType(_) => quote_ident!("Array").into(), + + TsType::TsLitType(TsLitType { + lit: TsLit::Bool(..), + .. + }) + | TsType::TsTypePredicate(_) + | TsType::TsKeywordType(TsKeywordType { + kind: TsKeywordTypeKind::TsBooleanKeyword, + .. + }) => quote_ident!("Boolean").into(), + + TsType::TsLitType(TsLitType { + lit: TsLit::Str(..), + .. + }) + | TsType::TsKeywordType(TsKeywordType { + kind: TsKeywordTypeKind::TsStringKeyword, + .. + }) => quote_ident!("String").into(), + + TsType::TsKeywordType(TsKeywordType { + kind: TsKeywordTypeKind::TsObjectKeyword, + .. + }) => quote_ident!("Object").into(), + + TsType::TsLitType(TsLitType { + lit: TsLit::Number(..), + .. + }) + | TsType::TsKeywordType(TsKeywordType { + kind: TsKeywordTypeKind::TsNumberKeyword, + .. + }) + | TsType::TsKeywordType(TsKeywordType { + kind: TsKeywordTypeKind::TsBigIntKeyword, + .. + }) => quote_ident!("Number").into(), + + TsType::TsLitType(ty) => { + // TODO: Proper error reporting + panic!("Bad type for decoration: {:?}", ty); + } + + TsType::TsKeywordType(TsKeywordType { + kind: TsKeywordTypeKind::TsBigIntKeyword, + .. + }) => quote_ident!("Symbol").into(), + + TsType::TsTypeQuery(_) + | TsType::TsTypeOperator(_) + | TsType::TsIndexedAccessType(_) + | TsType::TsTypeLit(_) + | TsType::TsMappedType(_) + | TsType::TsKeywordType(TsKeywordType { + kind: TsKeywordTypeKind::TsBigIntKeyword, + .. + }) + | TsType::TsKeywordType(TsKeywordType { + kind: TsKeywordTypeKind::TsBigIntKeyword, + .. + }) + | TsType::TsThisType(..) => quote_ident!("Object").into(), + + TsType::TsUnionOrIntersectionType(ty) => match ty { + TsUnionOrIntersectionType::TsUnionType(ty) => { + serialize_type_list(class_name, ty.types) + } + TsUnionOrIntersectionType::TsIntersectionType(ty) => { + serialize_type_list(class_name, ty.types) + } + }, + + TsType::TsConditionalType(ty) => { + serialize_type_list(class_name, vec![ty.true_type, ty.false_type]) + } + + TsType::TsTypeRef(ty) => serialize_type_ref(class_name, ty), + + _ => panic!("Bad type for decorator: {:?}", ty), + } + } + + let param = match param { + Some(v) => v.type_ann, + None => return *undefined(decl.span), + }; + + serialize_type_node(class_name.map(|v| &*v.sym).unwrap_or(""), *param) } From b51f3f6b212c689f385ee1f12096a94e31b4888e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 Aug 2020 17:54:18 +0900 Subject: [PATCH 10/31] fixup! WIP: type serializer --- .../proposals/decorators/legacy/metadata.rs | 52 +++++++++++++++---- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs b/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs index 2332fa6459ac..c24299ee56e1 100644 --- a/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs +++ b/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs @@ -151,8 +151,20 @@ impl Fold for Metadata<'_> { .params .iter() .map(|v| match v { - ParamOrTsParamProp::TsParamProp(p) => Some(serialize_type().as_arg()), - ParamOrTsParamProp::Param(p) => Some(serialize_type().as_arg()), + ParamOrTsParamProp::TsParamProp(p) => Some( + serialize_type( + self.class_name, + match p.param { + TsParamPropParam::Ident(i) => i.type_ann.as_ref(), + TsParamPropParam::Assign(a) => get_type_ann_of_pat(&a.left), + }, + ) + .as_arg(), + ), + ParamOrTsParamProp::Param(p) => Some( + serialize_type(self.class_name, get_type_ann_of_pat(&p.pat)) + .as_arg(), + ), }) .collect(), } @@ -182,7 +194,12 @@ impl Fold for Metadata<'_> { .function .params .iter() - .map(|v| Some(serialize_type().as_arg())) + .map(|v| { + Some( + serialize_type(self.class_name, get_type_ann_of_pat(&v.pat)) + .as_arg(), + ) + }) .collect(), } .as_arg(), @@ -203,7 +220,7 @@ impl Fold for Metadata<'_> { let dec = self.create_metadata_design_decorator( "design:type", - serialize_type(&c, self.class_name, p).as_arg(), + serialize_type(self.class_name, p.type_ann.as_ref()).as_arg(), ); p @@ -233,12 +250,12 @@ impl Metadata<'_> { } } -fn serialize_type(decl: &Class, class_name: Option<&Ident>, param: Option) -> Expr { - fn serialize_type_ref(class_name: &str, ty: TsTypeRef) -> Expr {} +fn serialize_type(class_name: Option<&Ident>, param: Option<&TsTypeAnn>) -> Expr { + fn serialize_type_ref(class_name: &str, ty: &TsTypeRef) -> Expr {} fn serialize_type_list(class_name: &str, types: Vec>) -> Expr {} - fn serialize_type_node(class_name: &str, ty: TsType) -> Expr { + fn serialize_type_node(class_name: &str, ty: &TsType) -> Expr { let span = ty.span(); match ty { TsType::TsKeywordType(TsKeywordType { @@ -258,7 +275,7 @@ fn serialize_type(decl: &Class, class_name: Option<&Ident>, param: Option return *undefined(span), - TsType::TsParenthesizedType(ty) => serialize_type_node(class_name, *ty.type_ann), + TsType::TsParenthesizedType(ty) => serialize_type_node(class_name, &*ty.type_ann), TsType::TsFnOrConstructorType(_) => quote_ident!("Function").into(), @@ -346,9 +363,22 @@ fn serialize_type(decl: &Class, class_name: Option<&Ident>, param: Option v.type_ann, - None => return *undefined(decl.span), + Some(v) => &v.type_ann, + None => return *undefined(DUMMY_SP), }; - serialize_type_node(class_name.map(|v| &*v.sym).unwrap_or(""), *param) + serialize_type_node(class_name.map(|v| &*v.sym).unwrap_or(""), &**param) +} + +fn get_type_ann_of_pat(p: &Pat) -> Option<&TsTypeAnn> { + match p { + Pat::Ident(p) => &p.type_ann, + Pat::Array(p) => &p.type_ann, + Pat::Rest(p) => &p.type_ann, + Pat::Object(p) => &p.type_ann, + Pat::Assign(p) => &p.type_ann, + Pat::Invalid(_) => return None, + Pat::Expr(_) => return None, + } + .as_ref() } From 79b1ababc1acc07b6d850a7b9600435efbaa0266 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 Aug 2020 18:01:03 +0900 Subject: [PATCH 11/31] fixup! WIP: type serializer --- .../proposals/decorators/legacy/metadata.rs | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs b/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs index c24299ee56e1..d190b3a6cc47 100644 --- a/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs +++ b/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs @@ -251,7 +251,38 @@ impl Metadata<'_> { } fn serialize_type(class_name: Option<&Ident>, param: Option<&TsTypeAnn>) -> Expr { - fn serialize_type_ref(class_name: &str, ty: &TsTypeRef) -> Expr {} + fn serialize_type_ref(class_name: &str, ty: &TsTypeRef) -> Expr { + match &ty.type_name { + // We should omit references to self (class) since it will throw a ReferenceError at + // runtime due to babel transpile output. + TsEntityName::Ident(i) if *i.sym == class_name => return quote_ident!("Object").into(), + _ => {} + } + + let member_expr = {}; + + // We don't know if type is just a type (interface, etc.) or a concrete value + // (class, etc.) + // + // `typeof` operator allows us to use the expression even if it is not defined, + // fallback is just `Object`. + + Expr::Cond(CondExpr { + span: DUMMY_SP, + test: Box::new(Expr::Bin(BinExpr { + span: DUMMY_SP, + left: Box::new(Expr::Unary(UnaryExpr { + span: DUMMY_SP, + op: op!("typeof"), + arg: Box::new(member_expr), + })), + op: op!("==="), + right: undefined(DUMMY_SP), + })), + cons: Box::new(quote_ident!("Object").into()), + alt: member_expr, + }) + } fn serialize_type_list(class_name: &str, types: Vec>) -> Expr {} From f8d10204efa4fde1fc5e054582699363f0252c35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 Aug 2020 18:06:52 +0900 Subject: [PATCH 12/31] fixup! WIP: type serializer --- .../proposals/decorators/legacy/metadata.rs | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs b/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs index d190b3a6cc47..c0fea816a291 100644 --- a/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs +++ b/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs @@ -255,11 +255,13 @@ fn serialize_type(class_name: Option<&Ident>, param: Option<&TsTypeAnn>) -> Expr match &ty.type_name { // We should omit references to self (class) since it will throw a ReferenceError at // runtime due to babel transpile output. - TsEntityName::Ident(i) if *i.sym == class_name => return quote_ident!("Object").into(), + TsEntityName::Ident(i) if &*i.sym == class_name => { + return quote_ident!("Object").into() + } _ => {} } - let member_expr = {}; + let member_expr = ts_entity_to_member_expr(&ty.type_name); // We don't know if type is just a type (interface, etc.) or a concrete value // (class, etc.) @@ -280,7 +282,7 @@ fn serialize_type(class_name: Option<&Ident>, param: Option<&TsTypeAnn>) -> Expr right: undefined(DUMMY_SP), })), cons: Box::new(quote_ident!("Object").into()), - alt: member_expr, + alt: Box::new(member_expr), }) } @@ -401,6 +403,22 @@ fn serialize_type(class_name: Option<&Ident>, param: Option<&TsTypeAnn>) -> Expr serialize_type_node(class_name.map(|v| &*v.sym).unwrap_or(""), &**param) } +fn ts_entity_to_member_expr(type_name: &TsEntityName) -> Expr { + match type_name { + TsEntityName::TsQualifiedName(q) => { + let obj = ts_entity_to_member_expr(&q.left); + + Expr::Member(MemberExpr { + span: DUMMY_SP, + obj: obj.as_obj(), + prop: Box::new(Expr::Ident(q.right.clone())), + computed: false, + }) + } + TsEntityName::Ident(i) => Expr::Ident(i.clone()), + } +} + fn get_type_ann_of_pat(p: &Pat) -> Option<&TsTypeAnn> { match p { Pat::Ident(p) => &p.type_ann, From 62104cf5753acd3d89d859adc29237f36c4373c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 Aug 2020 18:17:55 +0900 Subject: [PATCH 13/31] fixup! WIP: type serializer --- .../proposals/decorators/legacy/metadata.rs | 73 ++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs b/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs index c0fea816a291..3de1a428ae37 100644 --- a/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs +++ b/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs @@ -286,7 +286,78 @@ fn serialize_type(class_name: Option<&Ident>, param: Option<&TsTypeAnn>) -> Expr }) } - fn serialize_type_list(class_name: &str, types: Vec>) -> Expr {} + fn serialize_type_list(class_name: &str, types: &[Box]) -> Expr { + let mut u = None; + + for ty in types { + // Skip parens if need be + let ty = match &**ty { + TsType::TsParenthesizedType(ty) => &ty.type_ann, + _ => ty, + }; + + match ty { + // Always elide `never` from the union/intersection if possible + TsType::TsKeywordType(TsKeywordType { + kind: TsKeywordTypeKind::TsNeverKeyword, + .. + }) => { + continue; + } + + // Elide null and undefined from unions for metadata, just like what we did prior to + // the implementation of strict null checks + TsType::TsKeywordType(TsKeywordType { + kind: TsKeywordTypeKind::TsNullKeyword, + .. + }) + | TsType::TsKeywordType(TsKeywordType { + kind: TsKeywordTypeKind::TsUndefinedKeyword, + .. + }) => { + continue; + } + + _ => {} + } + + let item = serialize_type_node(class_name, &ty); + + // One of the individual is global object, return immediately + match item { + Expr::Ident(Ident { + sym: js_word!("Object"), + .. + }) => return item, + _ => {} + } + + // If there exists union that is not void 0 expression, check if the + // the common type is identifier. anything more complex + // and we will just default to Object + + // + match &u { + None => { + u = Some(item); + } + + Some(prev) => { + // Check for different types + match prev { + Expr::Ident(prev) => match &item { + Expr::Ident(item) if prev.sym == item.sym => {} + _ => quote_ident!("Object").into(), + }, + + _ => quote_ident!("Object").into(), + } + } + } + } + + u.unwrap() + } fn serialize_type_node(class_name: &str, ty: &TsType) -> Expr { let span = ty.span(); From eaa69714fb262b2bc70c4e19fe91b7b1fe3640a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 Aug 2020 18:22:10 +0900 Subject: [PATCH 14/31] Done? --- .../proposals/decorators/legacy/metadata.rs | 38 +++++++++---------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs b/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs index 3de1a428ae37..25697fd9021c 100644 --- a/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs +++ b/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs @@ -151,16 +151,13 @@ impl Fold for Metadata<'_> { .params .iter() .map(|v| match v { - ParamOrTsParamProp::TsParamProp(p) => Some( - serialize_type( - self.class_name, - match p.param { - TsParamPropParam::Ident(i) => i.type_ann.as_ref(), - TsParamPropParam::Assign(a) => get_type_ann_of_pat(&a.left), - }, - ) - .as_arg(), - ), + ParamOrTsParamProp::TsParamProp(p) => { + let ann = match &p.param { + TsParamPropParam::Ident(i) => i.type_ann.as_ref(), + TsParamPropParam::Assign(a) => get_type_ann_of_pat(&a.left), + }; + Some(serialize_type(self.class_name, ann).as_arg()) + } ParamOrTsParamProp::Param(p) => Some( serialize_type(self.class_name, get_type_ann_of_pat(&p.pat)) .as_arg(), @@ -222,6 +219,7 @@ impl Fold for Metadata<'_> { "design:type", serialize_type(self.class_name, p.type_ann.as_ref()).as_arg(), ); + p.decorators.push(dec); p } @@ -276,7 +274,7 @@ fn serialize_type(class_name: Option<&Ident>, param: Option<&TsTypeAnn>) -> Expr left: Box::new(Expr::Unary(UnaryExpr { span: DUMMY_SP, op: op!("typeof"), - arg: Box::new(member_expr), + arg: Box::new(member_expr.clone()), })), op: op!("==="), right: undefined(DUMMY_SP), @@ -296,7 +294,7 @@ fn serialize_type(class_name: Option<&Ident>, param: Option<&TsTypeAnn>) -> Expr _ => ty, }; - match ty { + match &**ty { // Always elide `never` from the union/intersection if possible TsType::TsKeywordType(TsKeywordType { kind: TsKeywordTypeKind::TsNeverKeyword, @@ -347,10 +345,10 @@ fn serialize_type(class_name: Option<&Ident>, param: Option<&TsTypeAnn>) -> Expr match prev { Expr::Ident(prev) => match &item { Expr::Ident(item) if prev.sym == item.sym => {} - _ => quote_ident!("Object").into(), + _ => return quote_ident!("Object").into(), }, - _ => quote_ident!("Object").into(), + _ => return quote_ident!("Object").into(), } } } @@ -428,7 +426,7 @@ fn serialize_type(class_name: Option<&Ident>, param: Option<&TsTypeAnn>) -> Expr } TsType::TsKeywordType(TsKeywordType { - kind: TsKeywordTypeKind::TsBigIntKeyword, + kind: TsKeywordTypeKind::TsSymbolKeyword, .. }) => quote_ident!("Symbol").into(), @@ -438,26 +436,26 @@ fn serialize_type(class_name: Option<&Ident>, param: Option<&TsTypeAnn>) -> Expr | TsType::TsTypeLit(_) | TsType::TsMappedType(_) | TsType::TsKeywordType(TsKeywordType { - kind: TsKeywordTypeKind::TsBigIntKeyword, + kind: TsKeywordTypeKind::TsAnyKeyword, .. }) | TsType::TsKeywordType(TsKeywordType { - kind: TsKeywordTypeKind::TsBigIntKeyword, + kind: TsKeywordTypeKind::TsUnknownKeyword, .. }) | TsType::TsThisType(..) => quote_ident!("Object").into(), TsType::TsUnionOrIntersectionType(ty) => match ty { TsUnionOrIntersectionType::TsUnionType(ty) => { - serialize_type_list(class_name, ty.types) + serialize_type_list(class_name, &ty.types) } TsUnionOrIntersectionType::TsIntersectionType(ty) => { - serialize_type_list(class_name, ty.types) + serialize_type_list(class_name, &ty.types) } }, TsType::TsConditionalType(ty) => { - serialize_type_list(class_name, vec![ty.true_type, ty.false_type]) + serialize_type_list(class_name, &[ty.true_type.clone(), ty.false_type.clone()]) } TsType::TsTypeRef(ty) => serialize_type_ref(class_name, ty), From c01e02c3ed6eed8af42da531a7689b8d2729e062 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 Aug 2020 18:23:59 +0900 Subject: [PATCH 15/31] fixup! Done? --- ecmascript/transforms/src/proposals/decorators/legacy.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ecmascript/transforms/src/proposals/decorators/legacy.rs b/ecmascript/transforms/src/proposals/decorators/legacy.rs index 273793c0e049..8902828fb700 100644 --- a/ecmascript/transforms/src/proposals/decorators/legacy.rs +++ b/ecmascript/transforms/src/proposals/decorators/legacy.rs @@ -211,8 +211,10 @@ impl Legacy { impl Legacy { fn handle(&mut self, mut c: ClassExpr) -> Box { if self.metadata { + let i = c.ident.clone(); + c = c.fold_with(&mut ParamMetadata).fold_with(&mut Metadata { - class_name: c.ident.as_ref(), + class_name: i.as_ref(), }); } From ff48c8241fd5c0356a9cf9ebf61c2c0a62458b85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 Aug 2020 18:27:44 +0900 Subject: [PATCH 16/31] Update test ref --- .../transforms/tests/proposal_decorators.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/ecmascript/transforms/tests/proposal_decorators.rs b/ecmascript/transforms/tests/proposal_decorators.rs index f5b04fa75949..e688e39e0e75 100644 --- a/ecmascript/transforms/tests/proposal_decorators.rs +++ b/ecmascript/transforms/tests/proposal_decorators.rs @@ -4751,14 +4751,15 @@ class MyClass { generic2: Generic ) {} }", - r##"var _dec, _dec2, _class; - - let MyClass = (_dec = Reflect.metadata("design:type", Function), _dec2 = Reflect.metadata("design:paramtypes", [typeof Generic === "undefined" ? Object : Generic, typeof Generic === "undefined" ? Object : Generic]), Decorate(_class = _dec(_class = _dec2(_class = class MyClass { - constructor(generic, generic2) { - this.generic = generic; - } - - }) || _class) || _class) || _class);"## + "var _class; +var _dec = Reflect.metadata(\"design:paramtypes\", [ + typeof Generic === void 0 ? Object : Generic, + typeof Generic === void 0 ? Object : Generic +]), _dec1 = Reflect.metadata(\"design:type\", Function); +let MyClass = Decorate(_dec1(_dec((_class = class MyClass { + constructor(private generic: Generic, generic2: Generic){ + } +}) || _class)));" ); test!( From c98102212689adb3233493c0def85cbaddd16e42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 Aug 2020 18:28:49 +0900 Subject: [PATCH 17/31] Update test --- .../transforms/tests/proposal_decorators.rs | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/ecmascript/transforms/tests/proposal_decorators.rs b/ecmascript/transforms/tests/proposal_decorators.rs index e688e39e0e75..f42207055f44 100644 --- a/ecmascript/transforms/tests/proposal_decorators.rs +++ b/ecmascript/transforms/tests/proposal_decorators.rs @@ -4734,7 +4734,29 @@ test!( @Arg() generic2: InterGen ) {} }", - "" + r#" + var _class, _dec, _dec1, _dec2; + var _dec3 = Reflect.metadata("design:paramtypes", [ + typeof Generic === void 0 ? Object : Generic, + typeof Generic === void 0 ? Object : Generic + ]), _dec4 = Reflect.metadata("design:type", Function); + let MyClass = Decorate(_dec4(_dec3(((_class = class MyClass { + constructor(private generic: Generic, generic2: Generic){ + } + method(generic: Inter, generic2: InterGen) { + } + }) || _class, _dec = function(target, target) { + return Arg()(target, key, 1); + }, _dec1 = Reflect.metadata("design:type", Function), _dec2 = Reflect.metadata("design:paramtypes", [ + typeof Inter === void 0 ? Object : Inter, + typeof InterGen === void 0 ? Object : InterGen + ]), _applyDecoratedDescriptor(_class.prototype, "method", [ + Run, + _dec, + _dec1, + _dec2 + ], Object.getOwnPropertyDescriptor(_class.prototype, "method"), _class.prototype), _class)))); +"# ); test!( From 76943425ae31174329aa76c8ce075d624e270a37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 Aug 2020 18:31:14 +0900 Subject: [PATCH 18/31] Bump node version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b03f6ec4c5bf..9bbbf9446fd6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@swc/core", - "version": "1.2.12", + "version": "1.2.13", "description": "Super-fast alternative for babel", "main": "./index.js", "author": "강동윤 ", From 5bf295f140139e1d6e3eb4af5d0561b924a31ec6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 Aug 2020 18:32:37 +0900 Subject: [PATCH 19/31] Update tests using decorators --- .../transforms/tests/es2015_function_name.rs | 80 +++++++++++++++---- .../tests/es2020_class_properties.rs | 10 ++- 2 files changed, 72 insertions(+), 18 deletions(-) diff --git a/ecmascript/transforms/tests/es2015_function_name.rs b/ecmascript/transforms/tests/es2015_function_name.rs index fb855a5b5d35..197a142e469b 100644 --- a/ecmascript/transforms/tests/es2015_function_name.rs +++ b/ecmascript/transforms/tests/es2015_function_name.rs @@ -154,7 +154,10 @@ test!( syntax(), |_| chain!( resolver(), - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), Classes::default(), function_name(), ), @@ -275,7 +278,10 @@ test!( syntax(), |_| chain!( resolver(), - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), Classes::default(), function_name(), ), @@ -333,7 +339,10 @@ test!( syntax(), |_| chain!( resolver(), - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), Classes::default(), function_name(), common_js(Mark::fresh(Mark::root()), Default::default()) @@ -456,7 +465,10 @@ test!( syntax(), |_| chain!( resolver(), - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), Classes::default(), function_name(), ), @@ -482,7 +494,10 @@ test!( syntax(), |_| chain!( resolver(), - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), Classes::default(), function_name(), ), @@ -540,7 +555,10 @@ test!( syntax(), |_| chain!( resolver(), - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), Classes::default(), function_name(), ), @@ -638,7 +656,10 @@ test!( resolver(), function_name(), Classes::default(), - decorators(decorators::Config { legacy: true }) + decorators(decorators::Config { + legacy: true, + ..Default::default() + }) ), function_name_object, r#" @@ -696,7 +717,10 @@ test!( resolver(), function_name(), Classes::default(), - decorators(decorators::Config { legacy: true }) + decorators(decorators::Config { + legacy: true, + ..Default::default() + }) ), function_name_export, r#" @@ -755,7 +779,10 @@ test!( syntax(), |_| chain!( resolver(), - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), function_name(), Classes::default(), ), @@ -823,7 +850,10 @@ test!( syntax(), |_| chain!( resolver(), - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), Classes::default(), function_name(), common_js(Mark::fresh(Mark::root()), Default::default()), @@ -875,7 +905,10 @@ test!( resolver(), function_name(), Classes::default(), - decorators(decorators::Config { legacy: true }) + decorators(decorators::Config { + legacy: true, + ..Default::default() + }) ), function_name_eval, r#" @@ -903,7 +936,10 @@ test!( resolver(), function_name(), Classes::default(), - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), common_js(Mark::fresh(Mark::root()), Default::default()) ), function_name_modules_3, @@ -957,7 +993,10 @@ test!( syntax(), |_| chain!( resolver(), - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), Classes::default(), function_name(), ), @@ -1116,7 +1155,10 @@ test!( syntax(), |_| chain!( resolver(), - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), function_name(), Classes::default() ), @@ -1181,7 +1223,10 @@ test!( syntax(), |_| chain!( resolver(), - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), Classes::default(), function_name(), ), @@ -1206,7 +1251,10 @@ test!( syntax(), |_| chain!( resolver(), - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), Classes::default(), function_name(), ), diff --git a/ecmascript/transforms/tests/es2020_class_properties.rs b/ecmascript/transforms/tests/es2020_class_properties.rs index c6b6ed159b17..30e13ca05e95 100644 --- a/ecmascript/transforms/tests/es2020_class_properties.rs +++ b/ecmascript/transforms/tests/es2020_class_properties.rs @@ -3548,7 +3548,10 @@ test!( ignore, syntax(), |_| chain!( - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), class_properties(), Classes::default(), ), @@ -4433,7 +4436,10 @@ test!( ignore, syntax(), |_| chain!( - decorators(decorators::Config { legacy: true }), + decorators(decorators::Config { + legacy: true, + ..Default::default() + }), class_properties(), Classes::default() ), From d066c6ddcf42b830f5c5c06abe5b0ae6fb2ad877 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 Aug 2020 18:32:42 +0900 Subject: [PATCH 20/31] Fix swc --- src/config.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/config.rs b/src/config.rs index 8cc5dabf785d..6825e8f5c805 100644 --- a/src/config.rs +++ b/src/config.rs @@ -226,16 +226,18 @@ impl Options { let pass = chain!( // handle jsx Optional::new(react::react(cm.clone(), transform.react), syntax.jsx()), - Optional::new(typescript::strip(), syntax.typescript()), - resolver_with_mark(root_mark), - const_modules, - optimization, + // Decorators may use type information Optional::new( decorators(decorators::Config { - legacy: transform.legacy_decorator + legacy: transform.legacy_decorator, + emit_metadata: transform.decorator_metadata, }), syntax.decorators() ), + Optional::new(typescript::strip(), syntax.typescript()), + resolver_with_mark(root_mark), + const_modules, + optimization, Optional::new( export(), syntax.export_default_from() || syntax.export_namespace_from() @@ -570,6 +572,9 @@ pub struct TransformConfig { #[serde(default)] pub legacy_decorator: bool, + + #[serde(default)] + pub decorator_metadata: bool, } #[derive(Debug, Default, Clone, Serialize, Deserialize)] From 7e240f90c871111af3caf6e7cafa64447779bf0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 Aug 2020 18:34:40 +0900 Subject: [PATCH 21/31] Bump versions --- ecmascript/Cargo.toml | 4 ++-- ecmascript/transforms/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ecmascript/Cargo.toml b/ecmascript/Cargo.toml index d9f7296e55c3..9a8f4c3a240d 100644 --- a/ecmascript/Cargo.toml +++ b/ecmascript/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "swc_ecmascript" -version = "0.2.0" +version = "0.3.0" authors = ["강동윤 "] license = "Apache-2.0/MIT" repository = "https://github.com/swc-project/swc.git" @@ -20,7 +20,7 @@ swc_ecma_ast = { version = "0.28.0", path ="./ast" } swc_ecma_codegen = { version = "0.31.0", path ="./codegen", optional = true } swc_ecma_parser = { version = "0.33.0", path ="./parser", optional = true } swc_ecma_utils = { version = "0.17.0", path ="./utils", optional = true } -swc_ecma_transforms = { version = "0.18.0", path ="./transforms", optional = true } +swc_ecma_transforms = { version = "0.19.0", path ="./transforms", optional = true } swc_ecma_visit = { version = "0.13.0", path ="./visit", optional = true } [dev-dependencies] diff --git a/ecmascript/transforms/Cargo.toml b/ecmascript/transforms/Cargo.toml index e3b2d285b1d8..25f2915f12dc 100644 --- a/ecmascript/transforms/Cargo.toml +++ b/ecmascript/transforms/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "swc_ecma_transforms" -version = "0.18.1" +version = "0.19.0" authors = ["강동윤 "] license = "Apache-2.0/MIT" repository = "https://github.com/swc-project/swc.git" From 9c19336c024467c0f9caa768053b27eb21786791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 Aug 2020 20:14:14 +0900 Subject: [PATCH 22/31] _class = dec() || _class --- .../src/proposals/decorators/legacy.rs | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/ecmascript/transforms/src/proposals/decorators/legacy.rs b/ecmascript/transforms/src/proposals/decorators/legacy.rs index 8902828fb700..187e0de4291a 100644 --- a/ecmascript/transforms/src/proposals/decorators/legacy.rs +++ b/ecmascript/transforms/src/proposals/decorators/legacy.rs @@ -684,12 +684,13 @@ impl Legacy { })); let expr = self.apply( + cls_ident, if extra_exprs.is_empty() { var_init } else { extra_exprs.insert(0, var_init); // Return value. - extra_exprs.push(Box::new(Expr::Ident(cls_ident))); + extra_exprs.push(Box::new(Expr::Ident(cls_ident.clone()))); Box::new(Expr::Seq(SeqExpr { span: DUMMY_SP, @@ -703,7 +704,12 @@ impl Legacy { } /// Apply class decorators. - fn apply(&mut self, mut expr: Box, decorators: Vec) -> Box { + fn apply( + &mut self, + class_ident: &Ident, + mut expr: Box, + decorators: Vec, + ) -> Box { for dec in decorators.into_iter().rev() { let (i, aliased) = alias_if_required(&dec.expr, "_dec"); if aliased { @@ -715,10 +721,18 @@ impl Legacy { }); } + // _class = dec(_class = funciton() {}) || _class + let cls_expr = Box::new(Expr::Bin(BinExpr { + span: DUMMY_SP, + left: expr, + op: op!("||"), + right: Box::new(Expr::Ident(class_ident.clone())), + })); + expr = Box::new(Expr::Call(CallExpr { span: DUMMY_SP, callee: i.as_callee(), - args: vec![expr.as_arg()], + args: vec![cls_expr.as_arg()], type_args: None, })); } From 7cf3e4cbe18901231965f0236c5a348e558c07e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 Aug 2020 20:25:38 +0900 Subject: [PATCH 23/31] Done --- .../src/proposals/decorators/legacy.rs | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/ecmascript/transforms/src/proposals/decorators/legacy.rs b/ecmascript/transforms/src/proposals/decorators/legacy.rs index 187e0de4291a..f26160506ff0 100644 --- a/ecmascript/transforms/src/proposals/decorators/legacy.rs +++ b/ecmascript/transforms/src/proposals/decorators/legacy.rs @@ -684,7 +684,7 @@ impl Legacy { })); let expr = self.apply( - cls_ident, + &cls_ident, if extra_exprs.is_empty() { var_init } else { @@ -721,20 +721,27 @@ impl Legacy { }); } - // _class = dec(_class = funciton() {}) || _class - let cls_expr = Box::new(Expr::Bin(BinExpr { + let dec_call_expr = Box::new(Expr::Call(CallExpr { span: DUMMY_SP, - left: expr, - op: op!("||"), - right: Box::new(Expr::Ident(class_ident.clone())), + callee: i.as_callee(), + args: vec![expr.as_arg()], + type_args: None, })); - expr = Box::new(Expr::Call(CallExpr { + // _class = dec(_class = funciton() {}) || _class + let class_expr = Box::new(Expr::Assign(AssignExpr { span: DUMMY_SP, - callee: i.as_callee(), - args: vec![cls_expr.as_arg()], - type_args: None, + left: PatOrExpr::Pat(Box::new(Pat::Ident(class_ident.clone()))), + op: op!("="), + right: Box::new(Expr::Bin(BinExpr { + span: DUMMY_SP, + left: dec_call_expr, + op: op!("||"), + right: Box::new(Expr::Ident(class_ident.clone())), + })), })); + + expr = class_expr; } expr From 1a070e63057b8a636b2d79425821a9f29ac859bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 Aug 2020 20:29:38 +0900 Subject: [PATCH 24/31] Fix tests --- ecmascript/transforms/tests/proposal_decorators.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ecmascript/transforms/tests/proposal_decorators.rs b/ecmascript/transforms/tests/proposal_decorators.rs index f42207055f44..8fe995705e31 100644 --- a/ecmascript/transforms/tests/proposal_decorators.rs +++ b/ecmascript/transforms/tests/proposal_decorators.rs @@ -4488,7 +4488,7 @@ var _dec = PrimaryGeneratedColumn('uuid'), _dec1 = Column(), _dec2 = Column({ ), _dec5 = OneToMany(()=>Discount , (discount)=>discount.product ), _dec6 = Entity(); -export let Product = _dec6(((_class = function() { +export let Product = _class = _dec6(((_class = function() { class Product extends TimestampedEntity { constructor(...args){ super(...args); @@ -4555,7 +4555,7 @@ export let Product = _dec6(((_class = function() { initializer: function() { return; } -}), _class)); +}), _class)) || _class; " ); @@ -4570,7 +4570,7 @@ export class Product extends TimestampedEntity { } ", "var _class, _descriptor; -var _dec = PrimaryGeneratedColumn('uuid'), _dec1 = Entity(); +var _dec = _class = PrimaryGeneratedColumn('uuid'), _dec1 = Entity(); export let Product = _dec1(((_class = function() { class Product extends TimestampedEntity { constructor(...args){ @@ -4588,7 +4588,7 @@ export let Product = _dec1(((_class = function() { initializer: function() { return; } -}), _class)); +}), _class)) || _class; " ); From 44881dba0167a0efbac33a6b6be424d10353a751 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 Aug 2020 20:33:01 +0900 Subject: [PATCH 25/31] Use undefined for default --- .../transforms/src/proposals/decorators/legacy/metadata.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs b/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs index 25697fd9021c..9b955f5c763a 100644 --- a/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs +++ b/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs @@ -354,7 +354,7 @@ fn serialize_type(class_name: Option<&Ident>, param: Option<&TsTypeAnn>) -> Expr } } - u.unwrap() + *undefined(DUMMY_SP) } fn serialize_type_node(class_name: &str, ty: &TsType) -> Expr { From 2cfe2f5de44cb7ffad9f735854a1987565a19891 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 Aug 2020 20:33:08 +0900 Subject: [PATCH 26/31] Updage more references --- ecmascript/transforms/tests/proposal_decorators.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/ecmascript/transforms/tests/proposal_decorators.rs b/ecmascript/transforms/tests/proposal_decorators.rs index 8fe995705e31..6a5e92484972 100644 --- a/ecmascript/transforms/tests/proposal_decorators.rs +++ b/ecmascript/transforms/tests/proposal_decorators.rs @@ -2497,11 +2497,10 @@ export default @dec class A {} @dec class B {} "#, r#" -var _class, _class1; -export default dec((_class = class A{ -}) || _class); -let B = dec((_class1 = class B{ -}) || _class1); + export default _class = dec((_class = class A { + }) || _class) || _class; + let B = _class1 = dec((_class1 = class B { + }) || _class1) || _class1; "# ); @@ -4570,8 +4569,8 @@ export class Product extends TimestampedEntity { } ", "var _class, _descriptor; -var _dec = _class = PrimaryGeneratedColumn('uuid'), _dec1 = Entity(); -export let Product = _dec1(((_class = function() { + var _dec = PrimaryGeneratedColumn(\"uuid\"), _dec1 = Entity(); + export let Product = _class = _dec1(((_class = function() { class Product extends TimestampedEntity { constructor(...args){ super(...args); From d51a655a476f45ca70af64fe9ce1af81b54ac350 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 Aug 2020 20:52:52 +0900 Subject: [PATCH 27/31] fixup! Updage more references --- .../transforms/tests/proposal_decorators.rs | 149 +++++++++++++++++- 1 file changed, 147 insertions(+), 2 deletions(-) diff --git a/ecmascript/transforms/tests/proposal_decorators.rs b/ecmascript/transforms/tests/proposal_decorators.rs index 6a5e92484972..9a75d75500ee 100644 --- a/ecmascript/transforms/tests/proposal_decorators.rs +++ b/ecmascript/transforms/tests/proposal_decorators.rs @@ -4845,7 +4845,79 @@ test!( @decorate('example') method(@inject() param: string) {} }", - "" + r##"var _class, _class1, _dec, _dec1, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _class2, _dec8, _dec9, _dec10, _dec11; + class Injected { + } + var _dec12 = Reflect.metadata("design:paramtypes", [ + typeof Injected === void 0 ? Object : Injected + ]), _dec13 = Reflect.metadata("design:type", Function), _dec14 = function(target, target) { + return inject()(target, undefined, 0); + }; + let MyClass = _class = _dec14(_class = _dec13(_class = _dec12((_class = class MyClass { + constructor(parameter: Injected){ + } + }) || _class) || _class) || _class) || _class; + var _dec15 = Reflect.metadata("design:paramtypes", [ + typeof Injected === void 0 ? Object : Injected, + typeof Injected === void 0 ? Object : Injected + ]), _dec16 = Reflect.metadata("design:type", Function), _dec17 = function(target, target) { + return inject("KIND")(target, undefined, 1); + }, _dec18 = function(target, target) { + return inject()(target, undefined, 0); + }; + let MyOtherClass = _class1 = _dec18(_class1 = _dec17(_class1 = _dec16(_class1 = _dec15(((_class1 = class MyOtherClass { + constructor(private readonly parameter: Injected, otherParam: Injected){ + } + methodUndecorated(param: string, otherParam) { + } + method(param: Injected, schema: Schema) { + } + }) || _class1, _dec = function(target, target) { + return demo()(target, key, 0); + }, _dec1 = Reflect.metadata("design:type", Function), _dec2 = Reflect.metadata("design:paramtypes", [ + String, + void 0 + ]), _applyDecoratedDescriptor(_class1.prototype, "methodUndecorated", [ + _dec, + _dec1, + _dec2 + ], Object.getOwnPropertyDescriptor(_class1.prototype, "methodUndecorated"), _class1.prototype), _dec3 = decorate("named"), _dec4 = function(target, target) { + return inject()(target, key, 0); + }, _dec5 = function(target, target) { + return arg()(target, key, 1); + }, _dec6 = Reflect.metadata("design:type", Function), _dec7 = Reflect.metadata("design:paramtypes", [ + typeof Injected === void 0 ? Object : Injected, + typeof Schema === void 0 ? Object : Schema + ]), _applyDecoratedDescriptor(_class1.prototype, "method", [ + _dec3, + _dec4, + _dec5, + _dec6, + _dec7 + ], Object.getOwnPropertyDescriptor(_class1.prototype, "method"), _class1.prototype), _class1)) || _class1) || _class1) || _class1) || _class1; + var _dec35 = Reflect.metadata("design:paramtypes", [ + typeof Injected === void 0 ? Object : Injected, + typeof Injected === void 0 ? Object : Injected + ]), _dec36 = Reflect.metadata("design:type", Function), _dec37 = function(target, target) { + return inject()(target, undefined, 1); + }, _dec38 = function(target, target) { + return inject()(target, undefined, 0); + }; + let DecoratedClass = _class2 = Decorate(_class2 = _dec38(_class2 = _dec37(_class2 = _dec36(_class2 = _dec35(((_class2 = class DecoratedClass { + constructor(private readonly module: Injected, otherModule: Injected){ + } + method(param: string) { + } + }) || _class2, _dec8 = decorate("example"), _dec9 = function(target, target) { + return inject()(target, key, 0); + }, _dec10 = Reflect.metadata("design:type", Function), _dec11 = Reflect.metadata("design:paramtypes", [ + String + ]), _applyDecoratedDescriptor(_class2.prototype, "method", [ + _dec8, + _dec9, + _dec10, + _dec11 + ], Object.getOwnPropertyDescriptor(_class2.prototype, "method"), _class2.prototype), _class2)) || _class2) || _class2) || _class2) || _class2) || _class2;"## ); test!( @@ -4923,5 +4995,78 @@ test!( p0: string = 'abc' ) {} }", - "" + r##"var _class, _dec, _dec1, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _dec8; + import { Service } from "./service"; + import { Decorate } from "./Decorate"; + const sym = Symbol(); + var _dec9 = Reflect.metadata("design:paramtypes", [ + typeof String === void 0 ? Object : String, + typeof Number === void 0 ? Object : Number, + Number, + String, + Boolean, + String, + Number, + typeof Object === void 0 ? Object : Object, + Function, + void 0, + Object, + typeof Function === void 0 ? Object : Function, + void 0, + void 0, + Object, + Function, + Boolean, + Boolean, + void 0 + ]), _dec10 = Reflect.metadata("design:type", Function), _dec11 = Decorate(); + let Sample = _class = _dec11(_class = _dec10(_class = _dec9(((_class = class Sample { + constructor(private p0: String, p1: Number, p2: 10, p3: "ABC", p4: boolean, p5: string, p6: number, p7: Object, p8: () => any, p9: "abc" | "def", p10: String | Number, p11: Function, p12: null, p13: undefined, p14: any, p15: (abc: any) => void, p16: falsee, p17: true, p18: string = "abc"){ + } + method(p0: Symbol, p1: typeof sym, p2: string | null, p3: never, p4: string | never, p5: (string | null), p6: Maybe, p7: Object | string, p8: string & MyStringType, p9: string[], p10: [string, number], p11: void, p12: this is number, p13: null | undefined, p14: (string | (string | null)), p15: Object, p16: any, p17: bigint) { + } + method2(p0: Decorate.Name. = "abc", p1: Decorate.Name.) { + } + assignments(p0: string = "abc") { + } + }) || _class, _dec = function(target, target) { + return Arg()(target, key, 0); + }, _dec1 = Reflect.metadata("design:type", Function), _dec2 = Reflect.metadata("design:paramtypes", [ + typeof Symbol === void 0 ? Object : Symbol, + Object, + void 0, + void 0, + void 0, + void 0, + typeof Maybe === void 0 ? Object : Maybe, + Object, + Object, + Array, + Array, + void 0, + Boolean, + void 0, + Object, + typeof Object === void 0 ? Object : Object, + Object, + Number + ]), _applyDecoratedDescriptor(_class.prototype, "method", [ + Decorate, + _dec, + _dec1, + _dec2 + ], Object.getOwnPropertyDescriptor(_class.prototype, "method"), _class.prototype), _dec3 = Decorate(), _dec4 = Reflect.metadata("design:type", Function), _dec5 = Reflect.metadata("design:paramtypes", [ + void 0, + typeof Decorate.Name === void 0 ? Object : Decorate.Name + ]), _applyDecoratedDescriptor(_class.prototype, "method2", [ + _dec3, + _dec4, + _dec5 + ], Object.getOwnPropertyDescriptor(_class.prototype, "method2"), _class.prototype), _dec6 = Decorate(), _dec7 = Reflect.metadata("design:type", Function), _dec8 = Reflect.metadata("design:paramtypes", [ + void 0 + ]), _applyDecoratedDescriptor(_class.prototype, "assignments", [ + _dec6, + _dec7, + _dec8 + ], Object.getOwnPropertyDescriptor(_class.prototype, "assignments"), _class.prototype), _class)) || _class) || _class) || _class;"## ); From 4db873957ed477198c479bcbf4ddca5bc71194a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 Aug 2020 20:54:27 +0900 Subject: [PATCH 28/31] fixup! Updage more references --- .../transforms/tests/proposal_decorators.rs | 151 +++++++++--------- 1 file changed, 76 insertions(+), 75 deletions(-) diff --git a/ecmascript/transforms/tests/proposal_decorators.rs b/ecmascript/transforms/tests/proposal_decorators.rs index 9a75d75500ee..6846ad168ac4 100644 --- a/ecmascript/transforms/tests/proposal_decorators.rs +++ b/ecmascript/transforms/tests/proposal_decorators.rs @@ -2096,8 +2096,8 @@ export default class {} var _class; function myDecorator(decoratee) { } -let _class1 = myDecorator((_class = class{ -}) || _class); +let _class1 = _class = myDecorator((_class = class { +}) || _class) || _class; export { _class1 as default } @@ -4996,77 +4996,78 @@ test!( ) {} }", r##"var _class, _dec, _dec1, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _dec8; - import { Service } from "./service"; - import { Decorate } from "./Decorate"; - const sym = Symbol(); - var _dec9 = Reflect.metadata("design:paramtypes", [ - typeof String === void 0 ? Object : String, - typeof Number === void 0 ? Object : Number, - Number, - String, - Boolean, - String, - Number, - typeof Object === void 0 ? Object : Object, - Function, - void 0, - Object, - typeof Function === void 0 ? Object : Function, - void 0, - void 0, - Object, - Function, - Boolean, - Boolean, - void 0 - ]), _dec10 = Reflect.metadata("design:type", Function), _dec11 = Decorate(); - let Sample = _class = _dec11(_class = _dec10(_class = _dec9(((_class = class Sample { - constructor(private p0: String, p1: Number, p2: 10, p3: "ABC", p4: boolean, p5: string, p6: number, p7: Object, p8: () => any, p9: "abc" | "def", p10: String | Number, p11: Function, p12: null, p13: undefined, p14: any, p15: (abc: any) => void, p16: falsee, p17: true, p18: string = "abc"){ - } - method(p0: Symbol, p1: typeof sym, p2: string | null, p3: never, p4: string | never, p5: (string | null), p6: Maybe, p7: Object | string, p8: string & MyStringType, p9: string[], p10: [string, number], p11: void, p12: this is number, p13: null | undefined, p14: (string | (string | null)), p15: Object, p16: any, p17: bigint) { - } - method2(p0: Decorate.Name. = "abc", p1: Decorate.Name.) { - } - assignments(p0: string = "abc") { - } - }) || _class, _dec = function(target, target) { - return Arg()(target, key, 0); - }, _dec1 = Reflect.metadata("design:type", Function), _dec2 = Reflect.metadata("design:paramtypes", [ - typeof Symbol === void 0 ? Object : Symbol, - Object, - void 0, - void 0, - void 0, - void 0, - typeof Maybe === void 0 ? Object : Maybe, - Object, - Object, - Array, - Array, - void 0, - Boolean, - void 0, - Object, - typeof Object === void 0 ? Object : Object, - Object, - Number - ]), _applyDecoratedDescriptor(_class.prototype, "method", [ - Decorate, - _dec, - _dec1, - _dec2 - ], Object.getOwnPropertyDescriptor(_class.prototype, "method"), _class.prototype), _dec3 = Decorate(), _dec4 = Reflect.metadata("design:type", Function), _dec5 = Reflect.metadata("design:paramtypes", [ - void 0, - typeof Decorate.Name === void 0 ? Object : Decorate.Name - ]), _applyDecoratedDescriptor(_class.prototype, "method2", [ - _dec3, - _dec4, - _dec5 - ], Object.getOwnPropertyDescriptor(_class.prototype, "method2"), _class.prototype), _dec6 = Decorate(), _dec7 = Reflect.metadata("design:type", Function), _dec8 = Reflect.metadata("design:paramtypes", [ - void 0 - ]), _applyDecoratedDescriptor(_class.prototype, "assignments", [ - _dec6, - _dec7, - _dec8 - ], Object.getOwnPropertyDescriptor(_class.prototype, "assignments"), _class.prototype), _class)) || _class) || _class) || _class;"## +import { Service } from "./service"; +import { Decorate } from "./Decorate"; +const sym = Symbol(); +var _dec9 = Reflect.metadata("design:paramtypes", [ + typeof String === void 0 ? Object : String, + typeof Number === void 0 ? Object : Number, + Number, + String, + Boolean, + String, + Number, + typeof Object === void 0 ? Object : Object, + Function, + void 0, + Object, + typeof Function === void 0 ? Object : Function, + void 0, + void 0, + Object, + Function, + Boolean, + Boolean, + void 0 +]), _dec10 = Reflect.metadata("design:type", Function), _dec11 = Decorate(); +let Sample = _class = _dec11(_class = _dec10(_class = _dec9(((_class = class Sample { + constructor(private p0: String, p1: Number, p2: 10, p3: "ABC", p4: boolean, p5: string, p6: number, p7: Object, p8: () => any, p9: "abc" | "def", p10: String | Number, p11: Function, p12: null, p13: undefined, p14: any, p15: (abc: any) => void, p16: falsee, p17: true, p18: string = "abc"){ + } + method(p0: Symbol, p1: typeof sym, p2: string | null, p3: never, p4: string | never, p5: (string | null), p6: Maybe, p7: Object | string, p8: string & MyStringType, p9: string[], p10: [string, number], p11: void, p12: this is number, p13: null | undefined, p14: (string | (string | null)), p15: Object, p16: any, p17: bigint) { + } + method2(p0: Decorate.Name. = "abc", p1: Decorate.Name.) { + } + assignments(p0: string = "abc") { + } +}) || _class, _dec = function(target, target) { + return Arg()(target, key, 0); +}, _dec1 = Reflect.metadata("design:type", Function), _dec2 = Reflect.metadata("design:paramtypes", [ + typeof Symbol === void 0 ? Object : Symbol, + Object, + void 0, + void 0, + void 0, + void 0, + typeof Maybe === void 0 ? Object : Maybe, + Object, + Object, + Array, + Array, + void 0, + Boolean, + void 0, + Object, + typeof Object === void 0 ? Object : Object, + Object, + Number +]), _applyDecoratedDescriptor(_class.prototype, "method", [ + Decorate, + _dec, + _dec1, + _dec2 +], Object.getOwnPropertyDescriptor(_class.prototype, "method"), _class.prototype), _dec3 = Decorate(), _dec4 = Reflect.metadata("design:type", Function), _dec5 = Reflect.metadata("design:paramtypes", [ + void 0, + typeof Decorate.Name === void 0 ? Object : Decorate.Name +]), _applyDecoratedDescriptor(_class.prototype, "method2", [ + _dec3, + _dec4, + _dec5 +], Object.getOwnPropertyDescriptor(_class.prototype, "method2"), _class.prototype), _dec6 = Decorate(), _dec7 = Reflect.metadata("design:type", Function), _dec8 = Reflect.metadata("design:paramtypes", [ + void 0 +]), _applyDecoratedDescriptor(_class.prototype, "assignments", [ + _dec6, + _dec7, + _dec8 +], Object.getOwnPropertyDescriptor(_class.prototype, "assignments"), _class.prototype), _class)) || _class) || _class) || _class;"##, + ok_if_code_eq ); From 7e1ae93ba6a98c1d82d68422f2769d8711b2f9a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 Aug 2020 20:56:03 +0900 Subject: [PATCH 29/31] fixup! Updage more references --- .../transforms/tests/proposal_decorators.rs | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/ecmascript/transforms/tests/proposal_decorators.rs b/ecmascript/transforms/tests/proposal_decorators.rs index 6846ad168ac4..b06d1691c715 100644 --- a/ecmascript/transforms/tests/proposal_decorators.rs +++ b/ecmascript/transforms/tests/proposal_decorators.rs @@ -4735,26 +4735,26 @@ test!( }", r#" var _class, _dec, _dec1, _dec2; - var _dec3 = Reflect.metadata("design:paramtypes", [ - typeof Generic === void 0 ? Object : Generic, - typeof Generic === void 0 ? Object : Generic - ]), _dec4 = Reflect.metadata("design:type", Function); - let MyClass = Decorate(_dec4(_dec3(((_class = class MyClass { - constructor(private generic: Generic, generic2: Generic){ - } - method(generic: Inter, generic2: InterGen) { - } - }) || _class, _dec = function(target, target) { - return Arg()(target, key, 1); - }, _dec1 = Reflect.metadata("design:type", Function), _dec2 = Reflect.metadata("design:paramtypes", [ - typeof Inter === void 0 ? Object : Inter, - typeof InterGen === void 0 ? Object : InterGen - ]), _applyDecoratedDescriptor(_class.prototype, "method", [ - Run, - _dec, - _dec1, - _dec2 - ], Object.getOwnPropertyDescriptor(_class.prototype, "method"), _class.prototype), _class)))); +var _dec3 = Reflect.metadata("design:paramtypes", [ + typeof Generic === void 0 ? Object : Generic, + typeof Generic === void 0 ? Object : Generic +]), _dec4 = Reflect.metadata("design:type", Function); +let MyClass = _class = Decorate(_class = _dec4(_class = _dec3(((_class = class MyClass { + constructor(private generic: Generic, generic2: Generic){ + } + method(generic: Inter, generic2: InterGen) { + } +}) || _class, _dec = function(target, target) { + return Arg()(target, key, 1); +}, _dec1 = Reflect.metadata("design:type", Function), _dec2 = Reflect.metadata("design:paramtypes", [ + typeof Inter === void 0 ? Object : Inter, + typeof InterGen === void 0 ? Object : InterGen +]), _applyDecoratedDescriptor(_class.prototype, "method", [ + Run, + _dec, + _dec1, + _dec2 +], Object.getOwnPropertyDescriptor(_class.prototype, "method"), _class.prototype), _class)) || _class) || _class) || _class; "# ); From cb2595e969f1982db81738f3ef19409625401583 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 Aug 2020 20:57:26 +0900 Subject: [PATCH 30/31] fixup! Updage more references --- .../transforms/tests/proposal_decorators.rs | 58 +++++++++++++++---- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/ecmascript/transforms/tests/proposal_decorators.rs b/ecmascript/transforms/tests/proposal_decorators.rs index b06d1691c715..eb6d66c401f1 100644 --- a/ecmascript/transforms/tests/proposal_decorators.rs +++ b/ecmascript/transforms/tests/proposal_decorators.rs @@ -4772,15 +4772,16 @@ class MyClass { generic2: Generic ) {} }", - "var _class; -var _dec = Reflect.metadata(\"design:paramtypes\", [ - typeof Generic === void 0 ? Object : Generic, - typeof Generic === void 0 ? Object : Generic -]), _dec1 = Reflect.metadata(\"design:type\", Function); -let MyClass = Decorate(_dec1(_dec((_class = class MyClass { - constructor(private generic: Generic, generic2: Generic){ - } -}) || _class)));" + r#"var _class; + var _dec = Reflect.metadata("design:paramtypes", [ + typeof Generic === void 0 ? Object : Generic, + typeof Generic === void 0 ? Object : Generic + ]), _dec1 = Reflect.metadata("design:type", Function); + let MyClass = _class = Decorate(_class = _dec1(_class = _dec((_class = class MyClass { + constructor(private generic: Generic, generic2: Generic){ + } + }) || _class) || _class) || _class) || _class; + "# ); test!( @@ -4807,7 +4808,44 @@ test!( return this.appService.getHello(); } }", - "" + r#"var _class, _descriptor, _descriptor1, _dec, _dec1, _dec2; + import { AppService } from "./app.service"; + var _dec3 = Inject(), _dec4 = Reflect.metadata("design:type", typeof AppService === void 0 ? Object : AppService), _dec5 = Inject(), _dec6 = Reflect.metadata("design:type", typeof AppService === void 0 ? Object : AppService), _dec7 = Reflect.metadata("design:paramtypes", [ + typeof AppService === void 0 ? Object : AppService + ]), _dec8 = Reflect.metadata("design:type", Function), _dec9 = Controller(); + export let AppController = _class = _dec9(_class = _dec8(_class = _dec7(((_class = class AppController { + constructor(private appService: AppService){ + _initializerDefineProperty(this, "appService", _descriptor, this); + _initializerDefineProperty(this, "appService2", _descriptor1, this); + } + getHello(): string { + return this.appService.getHello(); + } + }) || _class, _descriptor = _applyDecoratedDescriptor(_class.prototype, "appService", [ + _dec3, + _dec4 + ], { + configurable: true, + enumerable: true, + writable: true, + initializer: function() { + return; + } + }), _descriptor1 = _applyDecoratedDescriptor(_class.prototype, "appService2", [ + _dec5, + _dec6 + ], { + configurable: true, + enumerable: true, + writable: true, + initializer: function() { + return; + } + }), _dec = Get(), _dec1 = Reflect.metadata("design:type", Function), _dec2 = Reflect.metadata("design:paramtypes", []), _applyDecoratedDescriptor(_class.prototype, "getHello", [ + _dec, + _dec1, + _dec2 + ], Object.getOwnPropertyDescriptor(_class.prototype, "getHello"), _class.prototype), _class)) || _class) || _class) || _class;"# ); test!( From e26d9920fa9abfd11fd1cccc5377548446511787 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 Aug 2020 20:57:57 +0900 Subject: [PATCH 31/31] fixup! Updage more references --- ecmascript/transforms/tests/proposal_decorators.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/ecmascript/transforms/tests/proposal_decorators.rs b/ecmascript/transforms/tests/proposal_decorators.rs index eb6d66c401f1..178590f060ee 100644 --- a/ecmascript/transforms/tests/proposal_decorators.rs +++ b/ecmascript/transforms/tests/proposal_decorators.rs @@ -2497,6 +2497,7 @@ export default @dec class A {} @dec class B {} "#, r#" + var _class, _class1; export default _class = dec((_class = class A { }) || _class) || _class; let B = _class1 = dec((_class1 = class B {