Skip to content

Commit

Permalink
fix(es/typescript): Strip optional mark and definite mark (#9411)
Browse files Browse the repository at this point in the history
  • Loading branch information
magic-akari authored Aug 9, 2024
1 parent 4b58750 commit 8c161a0
Show file tree
Hide file tree
Showing 24 changed files with 121 additions and 294 deletions.
5 changes: 5 additions & 0 deletions .changeset/lemon-hornets-attend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
swc_fast_ts_strip: patch
---

fix(es/typescript): Strip optional mark and definite mark
159 changes: 116 additions & 43 deletions crates/swc_fast_ts_strip/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ use swc_common::{
BytePos, FileName, Mark, SourceMap, Span, Spanned,
};
use swc_ecma_ast::{
ArrowExpr, AutoAccessor, BindingIdent, Class, ClassDecl, ClassMethod, ClassProp, Constructor,
Decl, DoWhileStmt, EsVersion, ExportAll, ExportDecl, ExportDefaultDecl, ExportSpecifier,
FnDecl, ForInStmt, ForOfStmt, ForStmt, IfStmt, ImportDecl, ImportSpecifier, NamedExport, Param,
Pat, PrivateMethod, PrivateProp, Program, Stmt, TsAsExpr, TsConstAssertion, TsEnumDecl,
TsExportAssignment, TsImportEqualsDecl, TsIndexSignature, TsInstantiation, TsModuleDecl,
TsModuleName, TsNamespaceDecl, TsNonNullExpr, TsParamPropParam, TsSatisfiesExpr,
TsTypeAliasDecl, TsTypeAnn, TsTypeAssertion, TsTypeParamDecl, TsTypeParamInstantiation,
WhileStmt,
ArrayPat, ArrowExpr, AutoAccessor, BindingIdent, Class, ClassDecl, ClassMethod, ClassProp,
Constructor, Decl, DoWhileStmt, EsVersion, ExportAll, ExportDecl, ExportDefaultDecl,
ExportSpecifier, FnDecl, ForInStmt, ForOfStmt, ForStmt, IfStmt, ImportDecl, ImportSpecifier,
NamedExport, ObjectPat, Param, Pat, PrivateMethod, PrivateProp, Program, Stmt, TsAsExpr,
TsConstAssertion, TsEnumDecl, TsExportAssignment, TsImportEqualsDecl, TsIndexSignature,
TsInstantiation, TsModuleDecl, TsModuleName, TsNamespaceDecl, TsNonNullExpr, TsParamPropParam,
TsSatisfiesExpr, TsTypeAliasDecl, TsTypeAnn, TsTypeAssertion, TsTypeParamDecl,
TsTypeParamInstantiation, VarDeclarator, WhileStmt,
};
use swc_ecma_parser::{
lexer::Lexer,
Expand Down Expand Up @@ -495,16 +495,42 @@ impl TsStrip {
}
}
}

fn strip_definite_mark(&mut self, index: usize) {
self.strip_token(index, Token::Bang);
}

fn strip_optional_mark(&mut self, index: usize) {
self.strip_token(index, Token::QuestionMark);
}

fn strip_token(&mut self, index: usize, expected: Token) {
let TokenAndSpan { token, span, .. } = &self.tokens[index];
debug_assert_eq!(*token, expected);

self.add_replacement(*span);
}
}

impl Visit for TsStrip {
fn visit_var_declarator(&mut self, n: &VarDeclarator) {
if n.definite {
if let Some(id) = n.name.as_ident() {
let mark_index = self.get_next_token_index(id.span.hi);
self.strip_definite_mark(mark_index);
};
}

n.visit_children_with(self);
}

fn visit_arrow_expr(&mut self, n: &ArrowExpr) {
if let Some(ret) = &n.return_type {
self.add_replacement(ret.span);

let r_paren = self.get_prev_token(ret.span_lo() - BytePos(1));
let r_paren = self.get_prev_token(ret.span.lo - BytePos(1));
debug_assert_eq!(r_paren.token, Token::RParen);
let arrow = self.get_next_token(ret.span_hi());
let arrow = self.get_next_token(ret.span.hi);
debug_assert_eq!(arrow.token, Token::Arrow);
let span = span(r_paren.span.lo, arrow.span.lo);

Expand All @@ -531,7 +557,7 @@ impl Visit for TsStrip {
// 1;
// ```

let mut pos = ret.span_hi() - BytePos(1);
let mut pos = ret.span.hi - BytePos(1);
while !self.src.as_bytes()[pos.0 as usize - 1].is_utf8_char_boundary() {
self.add_overwrite(pos, b' ');
pos = pos - BytePos(1);
Expand All @@ -550,29 +576,30 @@ impl Visit for TsStrip {
n.visit_children_with(self);

if n.optional {
// https://github.com/swc-project/swc/issues/8856
// let optional_mark = self.get_next_token(n.id.span_hi());

let optional_mark = self.get_next_token(n.span_lo() + BytePos(n.sym.len() as u32));
debug_assert_eq!(optional_mark.token, Token::QuestionMark);
let mark_index = if let Some(type_ann) = &n.type_ann {
self.get_prev_token_index(type_ann.span.lo - BytePos(1))
} else {
self.get_next_token_index(n.span.hi)
};

self.add_replacement(optional_mark.span);
self.strip_optional_mark(mark_index);
}
}

fn visit_class(&mut self, n: &Class) {
if n.is_abstract {
let r#abstract = self.get_next_token(n.span_lo());
debug_assert_eq!(
r#abstract.token,
Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Abstract)))
);
self.add_replacement(r#abstract.span);
let mark_pos = n.decorators.last().map_or(n.span.lo, |d| d.span.hi);
let r#abstract = self.get_next_token_index(mark_pos);

self.strip_token(
r#abstract,
Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Abstract))),
)
}

if !n.implements.is_empty() {
let implements =
self.get_prev_token(n.implements.first().unwrap().span_lo() - BytePos(1));
self.get_prev_token(n.implements.first().unwrap().span.lo - BytePos(1));
debug_assert_eq!(
implements.token,
Token::Word(Word::Ident(IdentLike::Known(KnownIdent::Implements)))
Expand All @@ -592,7 +619,7 @@ impl Visit for TsStrip {
return;
}

self.strip_class_modifier(n.span_lo(), n.key.span_lo());
self.strip_class_modifier(n.span.lo, n.key.span_lo());

n.visit_children_with(self);
}
Expand All @@ -608,10 +635,15 @@ impl Visit for TsStrip {
.function
.decorators
.last()
.map_or(n.span_lo(), |d| d.span_hi());
.map_or(n.span.lo, |d| d.span.hi);

self.strip_class_modifier(start_pos, n.key.span_lo());

if n.is_optional {
let mark_index = self.get_next_token_index(n.key.span_hi());
self.strip_optional_mark(mark_index);
}

n.visit_children_with(self);
}

Expand All @@ -621,22 +653,17 @@ impl Visit for TsStrip {
return;
}

let start_pos = n.decorators.last().map_or(n.span_lo(), |d| d.span_hi());
let start_pos = n.decorators.last().map_or(n.span.lo, |d| d.span.hi);

self.strip_class_modifier(start_pos, n.key.span_lo());

if n.is_optional {
let optional_mark = self.get_next_token(n.key.span_hi());
debug_assert_eq!(optional_mark.token, Token::QuestionMark);

self.add_replacement(optional_mark.span);
let mark_index = self.get_next_token_index(n.key.span_hi());
self.strip_optional_mark(mark_index);
}

if n.definite {
let definite_mark = self.get_next_token(n.key.span_hi());
debug_assert_eq!(definite_mark.token, Token::Bang);

self.add_replacement(definite_mark.span);
let mark_index = self.get_next_token_index(n.key.span_hi());
self.strip_definite_mark(mark_index);
}

if n.value.is_none() && n.key.as_ident().filter(|k| k.sym == "static").is_some() {
Expand All @@ -653,17 +680,32 @@ impl Visit for TsStrip {
.function
.decorators
.last()
.map_or(n.span_lo(), |d| d.span_hi());
.map_or(n.span.lo, |d| d.span.hi);

self.strip_class_modifier(start_pos, n.key.span_lo());
self.strip_class_modifier(start_pos, n.key.span.lo);

if n.is_optional {
let mark_index = self.get_next_token_index(n.key.span.hi);
self.strip_optional_mark(mark_index);
}

n.visit_children_with(self);
}

fn visit_private_prop(&mut self, n: &PrivateProp) {
let start_pos = n.decorators.last().map_or(n.span_lo(), |d| d.span_hi());
let start_pos = n.decorators.last().map_or(n.span.lo, |d| d.span.hi);

self.strip_class_modifier(start_pos, n.key.span_lo());
self.strip_class_modifier(start_pos, n.key.span.lo);

if n.is_optional {
let mark_index = self.get_next_token_index(n.key.span.hi);
self.strip_optional_mark(mark_index);
}

if n.definite {
let mark_index = self.get_next_token_index(n.key.span.hi);
self.strip_definite_mark(mark_index);
}

n.visit_children_with(self);
}
Expand All @@ -674,10 +716,41 @@ impl Visit for TsStrip {
return;
}

let start_pos = n.decorators.last().map_or(n.span_lo(), |d| d.span_hi());
let start_pos = n.decorators.last().map_or(n.span.lo, |d| d.span.hi);

self.strip_class_modifier(start_pos, n.key.span_lo());

if n.definite {
let mark_index = self.get_next_token_index(n.key.span_hi());
self.strip_definite_mark(mark_index);
}

n.visit_children_with(self);
}

fn visit_array_pat(&mut self, n: &ArrayPat) {
if n.optional {
let mark_index = if let Some(type_ann) = &n.type_ann {
self.get_prev_token_index(type_ann.span.lo - BytePos(1))
} else {
self.get_next_token_index(n.span.hi)
};
self.strip_optional_mark(mark_index);
}

n.visit_children_with(self);
}

fn visit_object_pat(&mut self, n: &ObjectPat) {
if n.optional {
let mark_index = if let Some(type_ann) = &n.type_ann {
self.get_prev_token_index(type_ann.span.lo - BytePos(1))
} else {
self.get_next_token_index(n.span.hi)
};
self.strip_optional_mark(mark_index);
}

n.visit_children_with(self);
}

Expand Down Expand Up @@ -736,7 +809,7 @@ impl Visit for TsStrip {
if let ImportSpecifier::Named(import) = import {
if import.is_type_only {
let mut span = import.span;
let comma = self.get_next_token(import.span_hi());
let comma = self.get_next_token(import.span.hi);
if comma.token == Token::Comma {
span = span.with_hi(comma.span.hi);
} else {
Expand All @@ -759,7 +832,7 @@ impl Visit for TsStrip {
if let ExportSpecifier::Named(e) = export {
if e.is_type_only {
let mut span = e.span;
let comma = self.get_next_token(e.span_hi());
let comma = self.get_next_token(e.span.hi);
if comma.token == Token::Comma {
span = span.with_hi(comma.span.hi);
} else {
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

10 changes: 0 additions & 10 deletions crates/swc_fast_ts_strip/tests/tsc/callChainWithSuper.strip.js

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Loading

0 comments on commit 8c161a0

Please sign in to comment.