Skip to content

Commit

Permalink
fix(es/typescrupt): Fix ASI issue in fast ts strip (#9332)
Browse files Browse the repository at this point in the history
**Related issue:**

- Closes #9331
  • Loading branch information
magic-akari committed Jul 25, 2024
1 parent 95af17f commit 57146cf
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/long-bears-joke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
swc_fast_ts_strip: patch
---

fix(es/typescrupt): Fix ASI issue in fast ts strip
58 changes: 57 additions & 1 deletion crates/swc_fast_ts_strip/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -375,6 +375,44 @@ 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: prev_token,
span: prev_span,
..
} = &self.tokens[index - 1];

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) => {
if prev_token == &Token::Semi {
self.add_overwrite(prev_span.lo, b';');
return;
}

self.add_overwrite(span.lo, b';');
}

_ => {}
}
}
}

impl Visit for TsStrip {
Expand Down Expand Up @@ -469,6 +507,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;
}

Expand Down Expand Up @@ -549,12 +588,19 @@ 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);
}

fn visit_export_all(&mut self, n: &ExportAll) {
if n.type_only {
self.add_replacement(n.span);
self.fix_asi(n.span);
return;
}

Expand All @@ -568,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);
}

_ => {
Expand All @@ -587,6 +634,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;
}

Expand All @@ -613,6 +661,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;
}

Expand Down Expand Up @@ -672,6 +721,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;
}

Expand All @@ -695,6 +745,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;
}

Expand All @@ -718,11 +769,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;
}

Expand All @@ -737,6 +790,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;
}

Expand Down Expand Up @@ -771,6 +825,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) {
Expand Down Expand Up @@ -803,6 +858,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;
}

Expand Down
45 changes: 45 additions & 0 deletions crates/swc_fast_ts_strip/tests/fixture/issue-9331.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
f
;
(1)

function f() { }


f
;
(1)

f
;
(1)

5
;
-1


f
;


[1].map(() => 1)

f
;
/1/

f
;

/1/


class foo {
static;

foo() { }
}

2
;
+ 3
24 changes: 24 additions & 0 deletions crates/swc_fast_ts_strip/tests/fixture/issue-9331.transform.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
f;
1;
function f() {}
f;
1;
f;
1;
5;
-1;
f;
[
1
].map(()=>1);
f;
/1/;
f;
/1/;
class foo {
static;
foo() {}
}
2;
+3;
export { };
45 changes: 45 additions & 0 deletions crates/swc_fast_ts_strip/tests/fixture/issue-9331.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
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 x: string;
/1/

f
declare var y: string;
declare var z: string;
/1/


class foo {
static: any
declare x: any
foo() { }
}

2
export type { }
+ 3

0 comments on commit 57146cf

Please sign in to comment.