From 94759995a6fec210586754518a951222ab5b8de6 Mon Sep 17 00:00:00 2001 From: magic-akari Date: Thu, 25 Jul 2024 03:07:39 +0800 Subject: [PATCH 1/7] fix(es/typescrupt): Fix ASI issue in fast ts strip --- crates/swc_fast_ts_strip/src/lib.rs | 47 ++++++++++++++++++- .../tests/fixture/issue-9331.js | 29 ++++++++++++ .../tests/fixture/issue-9331.transform.js | 16 +++++++ .../tests/fixture/issue-9331.ts | 29 ++++++++++++ 4 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 crates/swc_fast_ts_strip/tests/fixture/issue-9331.js create mode 100644 crates/swc_fast_ts_strip/tests/fixture/issue-9331.transform.js create mode 100644 crates/swc_fast_ts_strip/tests/fixture/issue-9331.ts diff --git a/crates/swc_fast_ts_strip/src/lib.rs b/crates/swc_fast_ts_strip/src/lib.rs index b5326ec363c7..a07b78e5877b 100644 --- a/crates/swc_fast_ts_strip/src/lib.rs +++ b/crates/swc_fast_ts_strip/src/lib.rs @@ -20,7 +20,7 @@ use swc_ecma_ast::{ }; use swc_ecma_parser::{ lexer::Lexer, - token::{IdentLike, KnownIdent, Token, TokenAndSpan, Word}, + token::{BinOpToken, IdentLike, KnownIdent, Token, TokenAndSpan, Word}, Capturing, Parser, StringInput, Syntax, TsSyntax, }; use swc_ecma_transforms_base::{ @@ -375,6 +375,39 @@ impl TsStrip { fn get_prev_token(&self, pos: BytePos) -> &TokenAndSpan { &self.tokens[self.get_prev_token_index(pos)] } + + fn fix_asi(&mut self, span: Span) { + let index = self.get_prev_token_index(span.lo); + if index == 0 { + // Skip if the token is the first token. + return; + } + + let TokenAndSpan { token, .. } = &self.tokens[index - 1]; + if token == &Token::Semi { + // Skip if the previous token is a semicolon. + return; + } + + let index = self.get_prev_token_index(span.hi); + if index == self.tokens.len() - 1 { + // Skip if the token is the last token. + return; + } + + let TokenAndSpan { token, .. } = &self.tokens[index + 1]; + + // Add a semicolon if the next token is `[`, `(`, `/`, `+`, or `-` + match token { + Token::LParen + | Token::LBracket + | Token::BinOp(BinOpToken::Add | BinOpToken::Sub | BinOpToken::Div) => { + self.add_overwrite(span.lo, b';'); + } + + _ => {} + } + } } impl Visit for TsStrip { @@ -469,6 +502,7 @@ impl Visit for TsStrip { fn visit_class_decl(&mut self, n: &ClassDecl) { if n.declare { self.add_replacement(n.span()); + self.fix_asi(n.span()); return; } @@ -508,6 +542,7 @@ impl Visit for TsStrip { fn visit_class_prop(&mut self, n: &ClassProp) { if n.declare || n.is_abstract { self.add_replacement(n.span); + self.fix_asi(n.span); return; } @@ -555,6 +590,7 @@ impl Visit for TsStrip { fn visit_export_all(&mut self, n: &ExportAll) { if n.type_only { self.add_replacement(n.span); + self.fix_asi(n.span); return; } @@ -587,6 +623,7 @@ impl Visit for TsStrip { fn visit_import_decl(&mut self, n: &ImportDecl) { if n.type_only { self.add_replacement(n.span); + self.fix_asi(n.span); return; } @@ -613,6 +650,7 @@ impl Visit for TsStrip { fn visit_named_export(&mut self, n: &NamedExport) { if n.type_only { self.add_replacement(n.span); + self.fix_asi(n.span); return; } @@ -672,6 +710,7 @@ impl Visit for TsStrip { fn visit_ts_enum_decl(&mut self, e: &TsEnumDecl) { if e.declare { self.add_replacement(e.span); + self.fix_asi(e.span); return; } @@ -695,6 +734,7 @@ impl Visit for TsStrip { fn visit_ts_import_equals_decl(&mut self, n: &TsImportEqualsDecl) { if n.is_type_only { self.add_replacement(n.span); + self.fix_asi(n.span); return; } @@ -718,11 +758,13 @@ impl Visit for TsStrip { fn visit_ts_interface_decl(&mut self, n: &TsInterfaceDecl) { self.add_replacement(n.span); + self.fix_asi(n.span); } fn visit_ts_module_decl(&mut self, n: &TsModuleDecl) { if n.declare || matches!(n.id, TsModuleName::Str(..)) { self.add_replacement(n.span); + self.fix_asi(n.span); return; } @@ -737,6 +779,7 @@ impl Visit for TsStrip { fn visit_ts_namespace_decl(&mut self, n: &TsNamespaceDecl) { if n.declare { self.add_replacement(n.span); + self.fix_asi(n.span); return; } @@ -771,6 +814,7 @@ impl Visit for TsStrip { fn visit_ts_type_alias_decl(&mut self, n: &TsTypeAliasDecl) { self.add_replacement(n.span); + self.fix_asi(n.span); } fn visit_ts_type_ann(&mut self, n: &TsTypeAnn) { @@ -803,6 +847,7 @@ impl Visit for TsStrip { fn visit_var_decl(&mut self, n: &VarDecl) { if n.declare { self.add_replacement(n.span); + self.fix_asi(n.span); return; } diff --git a/crates/swc_fast_ts_strip/tests/fixture/issue-9331.js b/crates/swc_fast_ts_strip/tests/fixture/issue-9331.js new file mode 100644 index 000000000000..2ad976c2f7d1 --- /dev/null +++ b/crates/swc_fast_ts_strip/tests/fixture/issue-9331.js @@ -0,0 +1,29 @@ +f +; +(1) + +function f() { }; + + +f +; +(1) + +f +; +(1) + +5 +; +-1 + + +f +; + + +[1].map(() => 1) + +f +; +/1/ \ No newline at end of file diff --git a/crates/swc_fast_ts_strip/tests/fixture/issue-9331.transform.js b/crates/swc_fast_ts_strip/tests/fixture/issue-9331.transform.js new file mode 100644 index 000000000000..4c0a31437da9 --- /dev/null +++ b/crates/swc_fast_ts_strip/tests/fixture/issue-9331.transform.js @@ -0,0 +1,16 @@ +f; +1; +function f() {} +f; +1; +f; +1; +5; +-1; +f; +[ + 1 +].map(()=>1); +f; +/1/; +export { }; diff --git a/crates/swc_fast_ts_strip/tests/fixture/issue-9331.ts b/crates/swc_fast_ts_strip/tests/fixture/issue-9331.ts new file mode 100644 index 000000000000..2cf1a9c60570 --- /dev/null +++ b/crates/swc_fast_ts_strip/tests/fixture/issue-9331.ts @@ -0,0 +1,29 @@ +f +interface I { } +(1) + +function f() { }; + + +f +type x = any; +(1) + +f +import type { x } from 'foo'; +(1) + +5 +interface I { } +-1 + + +f +declare class name { + constructor(); +} +[1].map(() => 1) + +f +declare var name: string; +/1/ \ No newline at end of file From 07dc5224634d10949cf81d67d799bcd636cff165 Mon Sep 17 00:00:00 2001 From: magic-akari Date: Thu, 25 Jul 2024 03:23:17 +0800 Subject: [PATCH 2/7] fix --- crates/swc_fast_ts_strip/src/lib.rs | 15 ++++++++++----- .../swc_fast_ts_strip/tests/fixture/issue-9331.js | 9 +++++++-- .../tests/fixture/issue-9331.transform.js | 2 ++ .../swc_fast_ts_strip/tests/fixture/issue-9331.ts | 9 +++++++-- 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/crates/swc_fast_ts_strip/src/lib.rs b/crates/swc_fast_ts_strip/src/lib.rs index a07b78e5877b..13f50ea942a9 100644 --- a/crates/swc_fast_ts_strip/src/lib.rs +++ b/crates/swc_fast_ts_strip/src/lib.rs @@ -383,11 +383,11 @@ impl TsStrip { return; } - let TokenAndSpan { token, .. } = &self.tokens[index - 1]; - if token == &Token::Semi { - // Skip if the previous token is a semicolon. - return; - } + let TokenAndSpan { + token: prev_token, + span: prev_span, + .. + } = &self.tokens[index - 1]; let index = self.get_prev_token_index(span.hi); if index == self.tokens.len() - 1 { @@ -402,6 +402,11 @@ impl TsStrip { Token::LParen | Token::LBracket | Token::BinOp(BinOpToken::Add | BinOpToken::Sub | BinOpToken::Div) => { + if prev_token == &Token::Semi { + self.add_overwrite(prev_span.lo, b';'); + return; + } + self.add_overwrite(span.lo, b';'); } diff --git a/crates/swc_fast_ts_strip/tests/fixture/issue-9331.js b/crates/swc_fast_ts_strip/tests/fixture/issue-9331.js index 2ad976c2f7d1..21e29feb8c69 100644 --- a/crates/swc_fast_ts_strip/tests/fixture/issue-9331.js +++ b/crates/swc_fast_ts_strip/tests/fixture/issue-9331.js @@ -2,7 +2,7 @@ f ; (1) -function f() { }; +function f() { } f @@ -25,5 +25,10 @@ f [1].map(() => 1) f -; +; +/1/ + +f + ; + /1/ \ No newline at end of file diff --git a/crates/swc_fast_ts_strip/tests/fixture/issue-9331.transform.js b/crates/swc_fast_ts_strip/tests/fixture/issue-9331.transform.js index 4c0a31437da9..898fb3f1a0b0 100644 --- a/crates/swc_fast_ts_strip/tests/fixture/issue-9331.transform.js +++ b/crates/swc_fast_ts_strip/tests/fixture/issue-9331.transform.js @@ -13,4 +13,6 @@ f; ].map(()=>1); f; /1/; +f; +/1/; export { }; diff --git a/crates/swc_fast_ts_strip/tests/fixture/issue-9331.ts b/crates/swc_fast_ts_strip/tests/fixture/issue-9331.ts index 2cf1a9c60570..14e2ca5a3f69 100644 --- a/crates/swc_fast_ts_strip/tests/fixture/issue-9331.ts +++ b/crates/swc_fast_ts_strip/tests/fixture/issue-9331.ts @@ -2,7 +2,7 @@ f interface I { } (1) -function f() { }; +function f() { } f @@ -25,5 +25,10 @@ declare class name { [1].map(() => 1) f -declare var name: string; +declare var x: string; +/1/ + +f +declare var y: string; +declare var z: string; /1/ \ No newline at end of file From 1d38009c8ea8f7fb1aba65c48f2b0e3681bd1ddb Mon Sep 17 00:00:00 2001 From: magic-akari Date: Thu, 25 Jul 2024 03:41:07 +0800 Subject: [PATCH 3/7] add todo test --- crates/swc_fast_ts_strip/tests/fixture/issue-9331.js | 9 ++++++++- .../tests/fixture/issue-9331.transform.js | 4 ++++ crates/swc_fast_ts_strip/tests/fixture/issue-9331.ts | 9 ++++++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/crates/swc_fast_ts_strip/tests/fixture/issue-9331.js b/crates/swc_fast_ts_strip/tests/fixture/issue-9331.js index 21e29feb8c69..f9fbe6b73b2c 100644 --- a/crates/swc_fast_ts_strip/tests/fixture/issue-9331.js +++ b/crates/swc_fast_ts_strip/tests/fixture/issue-9331.js @@ -31,4 +31,11 @@ f f ; -/1/ \ No newline at end of file +/1/ + + +class foo { + static + ; + foo() { } +} \ No newline at end of file diff --git a/crates/swc_fast_ts_strip/tests/fixture/issue-9331.transform.js b/crates/swc_fast_ts_strip/tests/fixture/issue-9331.transform.js index 898fb3f1a0b0..e08e9ebf9178 100644 --- a/crates/swc_fast_ts_strip/tests/fixture/issue-9331.transform.js +++ b/crates/swc_fast_ts_strip/tests/fixture/issue-9331.transform.js @@ -15,4 +15,8 @@ f; /1/; f; /1/; +class foo { + static; + foo() {} +} export { }; diff --git a/crates/swc_fast_ts_strip/tests/fixture/issue-9331.ts b/crates/swc_fast_ts_strip/tests/fixture/issue-9331.ts index 14e2ca5a3f69..5d56a7a01faf 100644 --- a/crates/swc_fast_ts_strip/tests/fixture/issue-9331.ts +++ b/crates/swc_fast_ts_strip/tests/fixture/issue-9331.ts @@ -31,4 +31,11 @@ declare var x: string; f declare var y: string; declare var z: string; -/1/ \ No newline at end of file +/1/ + + +class foo { + static: any + declare x: any + foo() { } +} \ No newline at end of file From ce9834ca0193daf8b0fb8fac5c391f4c2758af64 Mon Sep 17 00:00:00 2001 From: magic-akari Date: Thu, 25 Jul 2024 03:50:47 +0800 Subject: [PATCH 4/7] fix --- crates/swc_fast_ts_strip/src/lib.rs | 8 +++++++- crates/swc_fast_ts_strip/tests/fixture/issue-9331.js | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/crates/swc_fast_ts_strip/src/lib.rs b/crates/swc_fast_ts_strip/src/lib.rs index 13f50ea942a9..5718cb8b02d7 100644 --- a/crates/swc_fast_ts_strip/src/lib.rs +++ b/crates/swc_fast_ts_strip/src/lib.rs @@ -12,7 +12,7 @@ use swc_common::{ }; use swc_ecma_ast::{ ArrowExpr, BindingIdent, Class, ClassDecl, ClassMethod, ClassProp, EsVersion, ExportAll, - ExportDecl, ExportSpecifier, FnDecl, ImportDecl, ImportSpecifier, NamedExport, Param, Pat, + ExportDecl, ExportSpecifier, FnDecl, ImportDecl, ImportSpecifier, Key, NamedExport, Param, Pat, Program, TsAsExpr, TsConstAssertion, TsEnumDecl, TsExportAssignment, TsImportEqualsDecl, TsIndexSignature, TsInstantiation, TsInterfaceDecl, TsModuleDecl, TsModuleName, TsNamespaceDecl, TsNonNullExpr, TsParamPropParam, TsSatisfiesExpr, TsTypeAliasDecl, TsTypeAnn, @@ -589,6 +589,12 @@ impl Visit for TsStrip { self.add_replacement(definite_mark.span); } + if n.value.is_none() && n.key.as_ident().filter(|k| k.sym == "static").is_some() { + if let Some(type_ann) = &n.type_ann { + self.add_overwrite(type_ann.span.lo, b';'); + } + } + n.visit_children_with(self); } diff --git a/crates/swc_fast_ts_strip/tests/fixture/issue-9331.js b/crates/swc_fast_ts_strip/tests/fixture/issue-9331.js index f9fbe6b73b2c..65d6737955e4 100644 --- a/crates/swc_fast_ts_strip/tests/fixture/issue-9331.js +++ b/crates/swc_fast_ts_strip/tests/fixture/issue-9331.js @@ -35,7 +35,7 @@ f class foo { - static - ; + static; + foo() { } } \ No newline at end of file From d05490bb84f7c7012b9c7eadfbaaafe6f1264876 Mon Sep 17 00:00:00 2001 From: magic-akari Date: Thu, 25 Jul 2024 03:54:21 +0800 Subject: [PATCH 5/7] fix --- crates/swc_fast_ts_strip/src/lib.rs | 2 +- crates/swc_fast_ts_strip/tests/fixture/issue-9331.js | 6 +++++- .../swc_fast_ts_strip/tests/fixture/issue-9331.transform.js | 2 ++ crates/swc_fast_ts_strip/tests/fixture/issue-9331.ts | 6 +++++- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/crates/swc_fast_ts_strip/src/lib.rs b/crates/swc_fast_ts_strip/src/lib.rs index 5718cb8b02d7..88d0190572a4 100644 --- a/crates/swc_fast_ts_strip/src/lib.rs +++ b/crates/swc_fast_ts_strip/src/lib.rs @@ -547,7 +547,6 @@ impl Visit for TsStrip { fn visit_class_prop(&mut self, n: &ClassProp) { if n.declare || n.is_abstract { self.add_replacement(n.span); - self.fix_asi(n.span); return; } @@ -615,6 +614,7 @@ impl Visit for TsStrip { | swc_ecma_ast::Decl::TsEnum(_) | swc_ecma_ast::Decl::TsModule(_) => { self.add_replacement(n.span); + self.fix_asi(n.span); } _ => { diff --git a/crates/swc_fast_ts_strip/tests/fixture/issue-9331.js b/crates/swc_fast_ts_strip/tests/fixture/issue-9331.js index 65d6737955e4..8cc1bd1ef7f7 100644 --- a/crates/swc_fast_ts_strip/tests/fixture/issue-9331.js +++ b/crates/swc_fast_ts_strip/tests/fixture/issue-9331.js @@ -38,4 +38,8 @@ class foo { static; foo() { } -} \ No newline at end of file +} + +2 +; ++ 3 \ No newline at end of file diff --git a/crates/swc_fast_ts_strip/tests/fixture/issue-9331.transform.js b/crates/swc_fast_ts_strip/tests/fixture/issue-9331.transform.js index e08e9ebf9178..983ca73e73c1 100644 --- a/crates/swc_fast_ts_strip/tests/fixture/issue-9331.transform.js +++ b/crates/swc_fast_ts_strip/tests/fixture/issue-9331.transform.js @@ -19,4 +19,6 @@ class foo { static; foo() {} } +2; ++3; export { }; diff --git a/crates/swc_fast_ts_strip/tests/fixture/issue-9331.ts b/crates/swc_fast_ts_strip/tests/fixture/issue-9331.ts index 5d56a7a01faf..7cfb24babfea 100644 --- a/crates/swc_fast_ts_strip/tests/fixture/issue-9331.ts +++ b/crates/swc_fast_ts_strip/tests/fixture/issue-9331.ts @@ -38,4 +38,8 @@ class foo { static: any declare x: any foo() { } -} \ No newline at end of file +} + +2 +export type { } ++ 3 \ No newline at end of file From 6d5f870ce98183a58be40de86269aded5f47558c Mon Sep 17 00:00:00 2001 From: magic-akari Date: Thu, 25 Jul 2024 09:03:42 +0800 Subject: [PATCH 6/7] fix: clippy issue --- crates/swc_fast_ts_strip/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/swc_fast_ts_strip/src/lib.rs b/crates/swc_fast_ts_strip/src/lib.rs index 88d0190572a4..36880b166c9c 100644 --- a/crates/swc_fast_ts_strip/src/lib.rs +++ b/crates/swc_fast_ts_strip/src/lib.rs @@ -12,7 +12,7 @@ use swc_common::{ }; use swc_ecma_ast::{ ArrowExpr, BindingIdent, Class, ClassDecl, ClassMethod, ClassProp, EsVersion, ExportAll, - ExportDecl, ExportSpecifier, FnDecl, ImportDecl, ImportSpecifier, Key, NamedExport, Param, Pat, + ExportDecl, ExportSpecifier, FnDecl, ImportDecl, ImportSpecifier, NamedExport, Param, Pat, Program, TsAsExpr, TsConstAssertion, TsEnumDecl, TsExportAssignment, TsImportEqualsDecl, TsIndexSignature, TsInstantiation, TsInterfaceDecl, TsModuleDecl, TsModuleName, TsNamespaceDecl, TsNonNullExpr, TsParamPropParam, TsSatisfiesExpr, TsTypeAliasDecl, TsTypeAnn, From d7d949df23f54320bf2860b4f5c7399c5810d65c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donny/=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 25 Jul 2024 11:44:58 +0900 Subject: [PATCH 7/7] Create long-bears-joke.md --- .changeset/long-bears-joke.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/long-bears-joke.md diff --git a/.changeset/long-bears-joke.md b/.changeset/long-bears-joke.md new file mode 100644 index 000000000000..1f28bc96f305 --- /dev/null +++ b/.changeset/long-bears-joke.md @@ -0,0 +1,5 @@ +--- +swc_fast_ts_strip: patch +--- + +fix(es/typescrupt): Fix ASI issue in fast ts strip