Skip to content

Commit

Permalink
fix(es/typescript): Handle single type statement in if/for/while (#9364)
Browse files Browse the repository at this point in the history
- Closes: #9363
  • Loading branch information
magic-akari authored Aug 1, 2024
1 parent 9fba319 commit 2217730
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 7 deletions.
6 changes: 6 additions & 0 deletions .changeset/lucky-panthers-cough.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
swc_ecma_transforms_typescript: patch
swc_fast_ts_strip: patch
---

Fix (TypeScript): Handle single type statement in if/for/while
10 changes: 9 additions & 1 deletion crates/swc_ecma_transforms_typescript/src/strip_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,16 @@ impl VisitMut for StripType {
}

fn visit_mut_stmts(&mut self, n: &mut Vec<Stmt>) {
n.retain(should_retain_stmt);
n.visit_mut_children_with(self);
n.retain(|s| !s.is_empty());
}

fn visit_mut_stmt(&mut self, n: &mut Stmt) {
if should_retain_stmt(n) {
n.visit_mut_children_with(self);
} else if !n.is_empty() {
n.take();
}
}

fn visit_mut_ts_import_equals_decl(&mut self, _: &mut TsImportEqualsDecl) {
Expand Down
81 changes: 75 additions & 6 deletions crates/swc_fast_ts_strip/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ use swc_common::{
BytePos, FileName, Mark, SourceMap, Span, Spanned,
};
use swc_ecma_ast::{
ArrowExpr, BindingIdent, Class, ClassDecl, ClassMethod, ClassProp, EsVersion, ExportAll,
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,
TsTypeAssertion, TsTypeParamDecl, TsTypeParamInstantiation, VarDecl,
ArrowExpr, BindingIdent, Class, ClassDecl, ClassMethod, ClassProp, Decl, DoWhileStmt,
EsVersion, ExportAll, ExportDecl, ExportSpecifier, FnDecl, ForInStmt, ForOfStmt, ForStmt,
IfStmt, ImportDecl, ImportSpecifier, NamedExport, Param, Pat, Program, Stmt, TsAsExpr,
TsConstAssertion, TsEnumDecl, TsExportAssignment, TsImportEqualsDecl, TsIndexSignature,
TsInstantiation, TsInterfaceDecl, TsModuleDecl, TsModuleName, TsNamespaceDecl, TsNonNullExpr,
TsParamPropParam, TsSatisfiesExpr, TsTypeAliasDecl, TsTypeAnn, TsTypeAssertion,
TsTypeParamDecl, TsTypeParamInstantiation, VarDecl, WhileStmt,
};
use swc_ecma_parser::{
lexer::Lexer,
Expand Down Expand Up @@ -910,8 +911,76 @@ impl Visit for TsStrip {

n.visit_children_with(self);
}

fn visit_if_stmt(&mut self, n: &IfStmt) {
n.visit_children_with(self);

if n.cons.is_ts_stmt() {
self.add_overwrite(n.cons.span_lo(), b';');
}

if let Some(alt) = &n.alt {
if alt.is_ts_stmt() {
self.add_overwrite(alt.span_lo(), b';');
}
}
}

fn visit_for_stmt(&mut self, n: &ForStmt) {
n.visit_children_with(self);

if n.body.is_ts_stmt() {
self.add_overwrite(n.body.span_lo(), b';');
}
}

fn visit_for_in_stmt(&mut self, n: &ForInStmt) {
n.visit_children_with(self);

if n.body.is_ts_stmt() {
self.add_overwrite(n.body.span_lo(), b';');
}
}

fn visit_for_of_stmt(&mut self, n: &ForOfStmt) {
n.visit_children_with(self);

if n.body.is_ts_stmt() {
self.add_overwrite(n.body.span_lo(), b';');
}
}

fn visit_while_stmt(&mut self, n: &WhileStmt) {
n.visit_children_with(self);

if n.body.is_ts_stmt() {
self.add_overwrite(n.body.span_lo(), b';');
}
}

fn visit_do_while_stmt(&mut self, n: &DoWhileStmt) {
n.visit_children_with(self);

if n.body.is_ts_stmt() {
self.add_overwrite(n.body.span_lo(), b';');
}
}
}

trait IsTsStmt {
fn is_ts_stmt(&self) -> bool;
}

impl IsTsStmt for Stmt {
fn is_ts_stmt(&self) -> bool {
match self {
Stmt::Decl(Decl::TsInterface { .. } | Decl::TsTypeAlias(..)) => true,
Stmt::Decl(Decl::TsModule(n)) => n.declare || matches!(n.id, TsModuleName::Str(..)),
Stmt::Decl(Decl::TsEnum(e)) => e.declare,
_ => false,
}
}
}
trait U8Helper {
fn is_utf8_char_boundary(&self) -> bool;
}
Expand Down
22 changes: 22 additions & 0 deletions crates/swc_fast_ts_strip/tests/fixture/single-ts-stmt.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
if (false) ;
console.log("Hello, World!");

if (false) { }
else ;
console.log("Hello, World!");

for (; false;)
;
console.log("Hello, World!");

for (; false;)
;
console.log("Hello, World!");

while (false)
;
console.log("Hello, World!");

do
;
while (false);
12 changes: 12 additions & 0 deletions crates/swc_fast_ts_strip/tests/fixture/single-ts-stmt.transform.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
if (false) ;
console.log("Hello, World!");
if (false) {} else ;
console.log("Hello, World!");
for(; false;);
console.log("Hello, World!");
for(; false;);
console.log("Hello, World!");
while(false);
console.log("Hello, World!");
do ;
while (false)
22 changes: 22 additions & 0 deletions crates/swc_fast_ts_strip/tests/fixture/single-ts-stmt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
if (false) type Foo = string
console.log("Hello, World!");

if (false) { }
else type Bar = string
console.log("Hello, World!");

for (; false;)
interface X { }
console.log("Hello, World!");

for (; false;)
interface X { }
console.log("Hello, World!");

while (false)
type Baz = string
console.log("Hello, World!");

do
interface X { }
while (false);

0 comments on commit 2217730

Please sign in to comment.