Skip to content

Commit 121b5fe

Browse files
authoredJan 15, 2025··
fix(es/ts_strip): Handle ASI hazard in return statement (#9882)
**Related issue:** - Closes #9878
1 parent 92fd3d2 commit 121b5fe

File tree

5 files changed

+101
-9
lines changed

5 files changed

+101
-9
lines changed
 

‎.changeset/curly-poems-dance.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
swc_fast_ts_strip: minor
3+
---
4+
5+
fix(es/ts_strip): Handle ASI hazard in return statement

‎crates/swc_fast_ts_strip/src/lib.rs

+51-9
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@ use swc_ecma_ast::{
1515
Constructor, Decl, DefaultDecl, DoWhileStmt, EsVersion, ExportAll, ExportDecl,
1616
ExportDefaultDecl, ExportSpecifier, FnDecl, ForInStmt, ForOfStmt, ForStmt, GetterProp, IfStmt,
1717
ImportDecl, ImportSpecifier, NamedExport, ObjectPat, Param, Pat, PrivateMethod, PrivateProp,
18-
Program, SetterProp, Stmt, TsAsExpr, TsConstAssertion, TsEnumDecl, TsExportAssignment,
19-
TsImportEqualsDecl, TsIndexSignature, TsInstantiation, TsModuleDecl, TsModuleName,
20-
TsNamespaceDecl, TsNonNullExpr, TsParamPropParam, TsSatisfiesExpr, TsTypeAliasDecl, TsTypeAnn,
21-
TsTypeAssertion, TsTypeParamDecl, TsTypeParamInstantiation, VarDeclarator, WhileStmt,
18+
Program, ReturnStmt, SetterProp, Stmt, TsAsExpr, TsConstAssertion, TsEnumDecl,
19+
TsExportAssignment, TsImportEqualsDecl, TsIndexSignature, TsInstantiation, TsModuleDecl,
20+
TsModuleName, TsNamespaceDecl, TsNonNullExpr, TsParamPropParam, TsSatisfiesExpr,
21+
TsTypeAliasDecl, TsTypeAnn, TsTypeAssertion, TsTypeParamDecl, TsTypeParamInstantiation,
22+
VarDeclarator, WhileStmt,
2223
};
2324
use swc_ecma_parser::{
2425
lexer::Lexer,
@@ -610,11 +611,6 @@ impl Visit for TsStrip {
610611
}
611612

612613
fn visit_arrow_expr(&mut self, n: &ArrowExpr) {
613-
#[inline(always)]
614-
fn is_new_line(c: char) -> bool {
615-
matches!(c, '\u{000A}' | '\u{000D}' | '\u{2028}' | '\u{2029}')
616-
}
617-
618614
'type_params: {
619615
// ```TypeScript
620616
// let f = async <
@@ -692,6 +688,48 @@ impl Visit for TsStrip {
692688
n.body.visit_with(self);
693689
}
694690

691+
fn visit_return_stmt(&mut self, n: &ReturnStmt) {
692+
let Some(arg) = n.arg.as_deref() else {
693+
return;
694+
};
695+
696+
arg.visit_with(self);
697+
698+
if let Some(arrow_expr) = arg.as_arrow() {
699+
if arrow_expr.is_async {
700+
// We have already handled type parameters in `visit_arrow_expr`.
701+
return;
702+
}
703+
704+
// ```TypeScript
705+
// return <T>
706+
// (v: T) => v;
707+
// ```
708+
//
709+
// ```TypeScript
710+
// return (
711+
// v ) => v;
712+
// ```
713+
714+
if let Some(tp) = &arrow_expr.type_params {
715+
let l_paren = self.get_next_token(tp.span.hi);
716+
debug_assert_eq!(l_paren.token, Token::LParen);
717+
718+
let slice = self.get_src_slice(tp.span.with_hi(l_paren.span.lo));
719+
720+
if !slice.chars().any(is_new_line) {
721+
return;
722+
}
723+
724+
let l_paren_pos = l_paren.span.lo;
725+
let l_lt_pos = tp.span.lo;
726+
727+
self.add_overwrite(l_paren_pos, b' ');
728+
self.add_overwrite(l_lt_pos, b'(');
729+
}
730+
}
731+
}
732+
695733
fn visit_binding_ident(&mut self, n: &BindingIdent) {
696734
n.visit_children_with(self);
697735

@@ -1303,6 +1341,10 @@ impl Visit for TsStrip {
13031341
}
13041342
}
13051343

1344+
#[inline(always)]
1345+
fn is_new_line(c: char) -> bool {
1346+
matches!(c, '\u{000A}' | '\u{000D}' | '\u{2028}' | '\u{2029}')
1347+
}
13061348
trait IsTsDecl {
13071349
fn is_ts_declare(&self) -> bool;
13081350
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
function f() {
2+
return (
3+
x )=>x;
4+
}
5+
6+
function f2() {
7+
return (
8+
9+
x )=>x;
10+
}
11+
12+
13+
function f3() {
14+
return (
15+
16+
x
17+
)=>x;
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
function f() {
2+
return (x)=>x;
3+
}
4+
function f2() {
5+
return (x)=>x;
6+
}
7+
function f3() {
8+
return (x)=>x;
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
function f() {
2+
return <T>
3+
(x: T)=>x;
4+
}
5+
6+
function f2() {
7+
return <T
8+
>
9+
(x: T)=>x;
10+
}
11+
12+
13+
function f3() {
14+
return <T
15+
>
16+
(x: T): Promise<
17+
T>=>x;
18+
}

0 commit comments

Comments
 (0)
Please sign in to comment.