fix(es/typescript): Handle single type statement in if/for/while (#9364)

- Closes: #9363
This commit is contained in:
magic-akari 2024-08-01 18:49:44 +08:00 committed by GitHub
parent 9fba319c35
commit 221773069b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 146 additions and 7 deletions

View File

@ -0,0 +1,6 @@
---
swc_ecma_transforms_typescript: patch
swc_fast_ts_strip: patch
---
Fix (TypeScript): Handle single type statement in if/for/while

View File

@ -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) {

View File

@ -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,
@ -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;
}

View File

@ -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);

View File

@ -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)

View File

@ -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);