From c44b85ef78130793256ea87e93f2928197cb06e3 Mon Sep 17 00:00:00 2001 From: magic-akari Date: Mon, 12 Aug 2024 13:42:12 +0800 Subject: [PATCH 1/7] fix(es/typescript): Add `classProperties` to skip reordering of class properties inits --- .../src/config.rs | 4 ++ .../src/transform.rs | 49 ++++++++++++++++++- .../src/typescript.rs | 1 + crates/swc_fast_ts_strip/src/lib.rs | 21 ++++++++ 4 files changed, 73 insertions(+), 2 deletions(-) diff --git a/crates/swc_ecma_transforms_typescript/src/config.rs b/crates/swc_ecma_transforms_typescript/src/config.rs index d04c0e3e88fe..cf12bb24e795 100644 --- a/crates/swc_ecma_transforms_typescript/src/config.rs +++ b/crates/swc_ecma_transforms_typescript/src/config.rs @@ -6,6 +6,10 @@ pub struct Config { #[serde(default)] pub verbatim_module_syntax: bool, + /// Native class properties support + #[serde(default)] + pub class_properties: bool, + #[serde(default)] pub import_not_used_as_values: ImportsNotUsedAsValues, diff --git a/crates/swc_ecma_transforms_typescript/src/transform.rs b/crates/swc_ecma_transforms_typescript/src/transform.rs index 91720cdfb902..5e71943e3728 100644 --- a/crates/swc_ecma_transforms_typescript/src/transform.rs +++ b/crates/swc_ecma_transforms_typescript/src/transform.rs @@ -59,6 +59,7 @@ pub(crate) struct Transform { import_export_assign_config: TsImportExportAssignConfig, ts_enum_is_mutable: bool, verbatim_module_syntax: bool, + class_properties: bool, namespace_id: Option, record: TsEnumRecord, @@ -74,6 +75,7 @@ pub fn transform( import_export_assign_config: TsImportExportAssignConfig, ts_enum_is_mutable: bool, verbatim_module_syntax: bool, + class_properties: bool, ) -> impl Fold + VisitMut { as_folder(Transform { unresolved_mark, @@ -82,6 +84,7 @@ pub fn transform( import_export_assign_config, ts_enum_is_mutable, verbatim_module_syntax, + class_properties, ..Default::default() }) } @@ -139,7 +142,11 @@ impl VisitMut for Transform { let init_list = mem::replace(&mut self.in_class_prop_init, init_list); if !prop_list.is_empty() { - self.reorder_class_prop_decls(n, prop_list, init_list); + if self.class_properties { + self.reorder_class_prop_decls(n, prop_list, init_list); + } else { + self.reorder_class_prop_decls_and_inits(n, prop_list, init_list); + } } } @@ -728,7 +735,7 @@ impl Transform { } impl Transform { - fn reorder_class_prop_decls( + fn reorder_class_prop_decls_and_inits( &mut self, class_member_list: &mut Vec, prop_list: Vec, @@ -829,6 +836,44 @@ impl Transform { .map(ClassMember::ClassProp), ); } + + fn reorder_class_prop_decls( + &mut self, + class_member_list: &mut Vec, + prop_list: Vec, + init_list: Vec>, + ) { + if let Some(constructor) = class_member_list + .iter_mut() + .find_map(|m| m.as_mut_constructor()) + { + inject_after_super(constructor, init_list); + } + + class_member_list.splice( + 0..0, + prop_list + .into_iter() + .map(Ident::from) + .map(PropName::from) + .map(|key| ClassProp { + span: DUMMY_SP, + key, + value: None, + type_ann: None, + is_static: false, + decorators: Vec::new(), + accessibility: None, + is_abstract: false, + is_optional: false, + is_override: false, + readonly: false, + declare: false, + definite: false, + }) + .map(ClassMember::ClassProp), + ); + } } impl Transform { diff --git a/crates/swc_ecma_transforms_typescript/src/typescript.rs b/crates/swc_ecma_transforms_typescript/src/typescript.rs index e9b161749784..3a47ba2e48fe 100644 --- a/crates/swc_ecma_transforms_typescript/src/typescript.rs +++ b/crates/swc_ecma_transforms_typescript/src/typescript.rs @@ -57,6 +57,7 @@ impl VisitMut for TypeScript { self.config.import_export_assign_config, self.config.ts_enum_is_mutable, self.config.verbatim_module_syntax, + self.config.class_properties, )); if let Some(span) = was_module { diff --git a/crates/swc_fast_ts_strip/src/lib.rs b/crates/swc_fast_ts_strip/src/lib.rs index d67bfd499a82..0c7e5674e5af 100644 --- a/crates/swc_fast_ts_strip/src/lib.rs +++ b/crates/swc_fast_ts_strip/src/lib.rs @@ -69,10 +69,31 @@ interface Options { } interface TransformConfig { + /** + * @see https://www.typescriptlang.org/tsconfig#verbatimModuleSyntax + */ verbatimModuleSyntax?: boolean; + /** + * Native class properties support + */ + classProperties?: boolean; importNotUsedAsValues?: "remove" | "preserve"; + /** + * Don't create `export {}`. + * By default, strip creates `export {}` for modules to preserve module + * context. + * + * @see https://github.com/swc-project/swc/issues/1698 + */ noEmptyExport?: boolean; importExportAssignConfig?: "Classic" | "Preserve" | "NodeNext" | "EsNext"; + /** + * Disables an optimization that inlines TS enum member values + * within the same module that assumes the enum member values + * are never modified. + * + * Defaults to false. + */ tsEnumIsMutable?: boolean; } "#; From 04c22a5b989e10809df70d4590cf2b3df0fd378b Mon Sep 17 00:00:00 2001 From: magic-akari Date: Mon, 12 Aug 2024 13:52:58 +0800 Subject: [PATCH 2/7] chore: Update test cases --- crates/swc_fast_ts_strip/tests/fixture.rs | 4 ++++ .../swc_fast_ts_strip/tests/fixture/class-properties.js | 6 ++++++ .../tests/fixture/class-properties.swc-stderr | 7 +++++++ .../tests/fixture/class-properties.transform.js | 8 ++++++++ .../swc_fast_ts_strip/tests/fixture/class-properties.ts | 6 ++++++ 5 files changed, 31 insertions(+) create mode 100644 crates/swc_fast_ts_strip/tests/fixture/class-properties.js create mode 100644 crates/swc_fast_ts_strip/tests/fixture/class-properties.swc-stderr create mode 100644 crates/swc_fast_ts_strip/tests/fixture/class-properties.transform.js create mode 100644 crates/swc_fast_ts_strip/tests/fixture/class-properties.ts diff --git a/crates/swc_fast_ts_strip/tests/fixture.rs b/crates/swc_fast_ts_strip/tests/fixture.rs index 9c54bb131bbe..cd39107837d3 100644 --- a/crates/swc_fast_ts_strip/tests/fixture.rs +++ b/crates/swc_fast_ts_strip/tests/fixture.rs @@ -120,6 +120,10 @@ fn opts(mode: Mode) -> Options { ..Default::default() }, mode, + transform: Some(swc_ecma_transforms_typescript::Config { + class_properties: true, + ..Default::default() + }), ..Default::default() } } diff --git a/crates/swc_fast_ts_strip/tests/fixture/class-properties.js b/crates/swc_fast_ts_strip/tests/fixture/class-properties.js new file mode 100644 index 000000000000..3713bda1fc69 --- /dev/null +++ b/crates/swc_fast_ts_strip/tests/fixture/class-properties.js @@ -0,0 +1,6 @@ +class Foo { + x = console.log(1) + constructor(public y = console.log(2)) { + console.log(3) + } +} \ No newline at end of file diff --git a/crates/swc_fast_ts_strip/tests/fixture/class-properties.swc-stderr b/crates/swc_fast_ts_strip/tests/fixture/class-properties.swc-stderr new file mode 100644 index 000000000000..82c4bf1c5f6c --- /dev/null +++ b/crates/swc_fast_ts_strip/tests/fixture/class-properties.swc-stderr @@ -0,0 +1,7 @@ + x TypeScript parameter property is not supported in strip-only mode + ,-[3:1] + 2 | x = console.log(1) + 3 | constructor(public y = console.log(2)) { + : ^^^^^^^^^^^^^^^^^^ + 4 | console.log(3) + `---- diff --git a/crates/swc_fast_ts_strip/tests/fixture/class-properties.transform.js b/crates/swc_fast_ts_strip/tests/fixture/class-properties.transform.js new file mode 100644 index 000000000000..a81424c21aa4 --- /dev/null +++ b/crates/swc_fast_ts_strip/tests/fixture/class-properties.transform.js @@ -0,0 +1,8 @@ +class Foo { + y; + x = console.log(1); + constructor(y = console.log(2)){ + this.y = y; + console.log(3); + } +} diff --git a/crates/swc_fast_ts_strip/tests/fixture/class-properties.ts b/crates/swc_fast_ts_strip/tests/fixture/class-properties.ts new file mode 100644 index 000000000000..3713bda1fc69 --- /dev/null +++ b/crates/swc_fast_ts_strip/tests/fixture/class-properties.ts @@ -0,0 +1,6 @@ +class Foo { + x = console.log(1) + constructor(public y = console.log(2)) { + console.log(3) + } +} \ No newline at end of file From 8781d5c22193cc622db8339b38cc378d10228fd7 Mon Sep 17 00:00:00 2001 From: magic-akari Date: Mon, 12 Aug 2024 14:00:09 +0800 Subject: [PATCH 3/7] chore: Rename --- crates/swc_ecma_transforms_typescript/src/config.rs | 2 +- crates/swc_ecma_transforms_typescript/src/typescript.rs | 2 +- crates/swc_fast_ts_strip/src/lib.rs | 2 +- crates/swc_fast_ts_strip/tests/fixture.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/swc_ecma_transforms_typescript/src/config.rs b/crates/swc_ecma_transforms_typescript/src/config.rs index cf12bb24e795..b3c06f31bfd2 100644 --- a/crates/swc_ecma_transforms_typescript/src/config.rs +++ b/crates/swc_ecma_transforms_typescript/src/config.rs @@ -8,7 +8,7 @@ pub struct Config { /// Native class properties support #[serde(default)] - pub class_properties: bool, + pub native_class_properties: bool, #[serde(default)] pub import_not_used_as_values: ImportsNotUsedAsValues, diff --git a/crates/swc_ecma_transforms_typescript/src/typescript.rs b/crates/swc_ecma_transforms_typescript/src/typescript.rs index 3a47ba2e48fe..ed3c51844630 100644 --- a/crates/swc_ecma_transforms_typescript/src/typescript.rs +++ b/crates/swc_ecma_transforms_typescript/src/typescript.rs @@ -57,7 +57,7 @@ impl VisitMut for TypeScript { self.config.import_export_assign_config, self.config.ts_enum_is_mutable, self.config.verbatim_module_syntax, - self.config.class_properties, + self.config.native_class_properties, )); if let Some(span) = was_module { diff --git a/crates/swc_fast_ts_strip/src/lib.rs b/crates/swc_fast_ts_strip/src/lib.rs index 0c7e5674e5af..3ac51046b9b4 100644 --- a/crates/swc_fast_ts_strip/src/lib.rs +++ b/crates/swc_fast_ts_strip/src/lib.rs @@ -76,7 +76,7 @@ interface TransformConfig { /** * Native class properties support */ - classProperties?: boolean; + nativeClassProperties?: boolean; importNotUsedAsValues?: "remove" | "preserve"; /** * Don't create `export {}`. diff --git a/crates/swc_fast_ts_strip/tests/fixture.rs b/crates/swc_fast_ts_strip/tests/fixture.rs index cd39107837d3..9f537e35c98e 100644 --- a/crates/swc_fast_ts_strip/tests/fixture.rs +++ b/crates/swc_fast_ts_strip/tests/fixture.rs @@ -121,7 +121,7 @@ fn opts(mode: Mode) -> Options { }, mode, transform: Some(swc_ecma_transforms_typescript::Config { - class_properties: true, + native_class_properties: true, ..Default::default() }), ..Default::default() From 3c0edeae29871f0fe145866ffb0805edbeceb78b Mon Sep 17 00:00:00 2001 From: magic-akari Date: Mon, 12 Aug 2024 14:04:28 +0800 Subject: [PATCH 4/7] chore: Rename --- crates/swc_ecma_transforms_typescript/src/transform.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/swc_ecma_transforms_typescript/src/transform.rs b/crates/swc_ecma_transforms_typescript/src/transform.rs index 5e71943e3728..0264857cc022 100644 --- a/crates/swc_ecma_transforms_typescript/src/transform.rs +++ b/crates/swc_ecma_transforms_typescript/src/transform.rs @@ -59,7 +59,7 @@ pub(crate) struct Transform { import_export_assign_config: TsImportExportAssignConfig, ts_enum_is_mutable: bool, verbatim_module_syntax: bool, - class_properties: bool, + native_class_properties: bool, namespace_id: Option, record: TsEnumRecord, @@ -75,7 +75,7 @@ pub fn transform( import_export_assign_config: TsImportExportAssignConfig, ts_enum_is_mutable: bool, verbatim_module_syntax: bool, - class_properties: bool, + native_class_properties: bool, ) -> impl Fold + VisitMut { as_folder(Transform { unresolved_mark, @@ -84,7 +84,7 @@ pub fn transform( import_export_assign_config, ts_enum_is_mutable, verbatim_module_syntax, - class_properties, + native_class_properties, ..Default::default() }) } @@ -142,7 +142,7 @@ impl VisitMut for Transform { let init_list = mem::replace(&mut self.in_class_prop_init, init_list); if !prop_list.is_empty() { - if self.class_properties { + if self.native_class_properties { self.reorder_class_prop_decls(n, prop_list, init_list); } else { self.reorder_class_prop_decls_and_inits(n, prop_list, init_list); From e08c7511bf1888d678a87f31fb62194ac75a6c3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donny/=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Mon, 12 Aug 2024 15:16:09 +0900 Subject: [PATCH 5/7] Create neat-humans-reply.md --- .changeset/neat-humans-reply.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/neat-humans-reply.md diff --git a/.changeset/neat-humans-reply.md b/.changeset/neat-humans-reply.md new file mode 100644 index 000000000000..a46ad337ff1f --- /dev/null +++ b/.changeset/neat-humans-reply.md @@ -0,0 +1,6 @@ +--- +swc_core: patch +swc_ecma_transforms_typescript: patch +--- + +feat(es/typescript): Add `native_class_properties ` to skip reordering of class properties inits From 9d5be0dcc20ae84a04c1c43245d89fff4ecda52c Mon Sep 17 00:00:00 2001 From: magic-akari Date: Mon, 12 Aug 2024 14:48:19 +0800 Subject: [PATCH 6/7] fix: clippy --- crates/swc_ecma_transforms/tests/deno.rs | 1 + crates/swc_ecma_transforms_typescript/src/config.rs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/crates/swc_ecma_transforms/tests/deno.rs b/crates/swc_ecma_transforms/tests/deno.rs index 6d1573dd40f6..4b00541d3078 100644 --- a/crates/swc_ecma_transforms/tests/deno.rs +++ b/crates/swc_ecma_transforms/tests/deno.rs @@ -36,6 +36,7 @@ fn run_test(input: PathBuf) { typescript( typescript::Config { verbatim_module_syntax: false, + native_class_properties: false, import_not_used_as_values: typescript::ImportsNotUsedAsValues::Remove, no_empty_export: true, import_export_assign_config: diff --git a/crates/swc_ecma_transforms_typescript/src/config.rs b/crates/swc_ecma_transforms_typescript/src/config.rs index b3c06f31bfd2..63fac10a65a8 100644 --- a/crates/swc_ecma_transforms_typescript/src/config.rs +++ b/crates/swc_ecma_transforms_typescript/src/config.rs @@ -3,6 +3,7 @@ use serde::{Deserialize, Serialize}; #[derive(Debug, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct Config { + /// https://www.typescriptlang.org/tsconfig#verbatimModuleSyntax #[serde(default)] pub verbatim_module_syntax: bool, @@ -10,6 +11,7 @@ pub struct Config { #[serde(default)] pub native_class_properties: bool, + /// https://www.typescriptlang.org/tsconfig/#importsNotUsedAsValues #[serde(default)] pub import_not_used_as_values: ImportsNotUsedAsValues, From e4770d51067045cec5f30860689c96a8790db57e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donny/=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Wed, 14 Aug 2024 04:09:46 +0900 Subject: [PATCH 7/7] Update neat-humans-reply.md --- .changeset/neat-humans-reply.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.changeset/neat-humans-reply.md b/.changeset/neat-humans-reply.md index a46ad337ff1f..1cc5896a3f75 100644 --- a/.changeset/neat-humans-reply.md +++ b/.changeset/neat-humans-reply.md @@ -1,6 +1,7 @@ --- swc_core: patch -swc_ecma_transforms_typescript: patch +swc_fast_ts_strip: patch +swc_ecma_transforms_typescript: minor --- feat(es/typescript): Add `native_class_properties ` to skip reordering of class properties inits