Skip to content

Commit

Permalink
fix(es/typescript): Strip declare export in strip-only mode (#9374)
Browse files Browse the repository at this point in the history
- Closes #9373
  • Loading branch information
magic-akari authored Aug 4, 2024
1 parent c2e3021 commit c53cce4
Show file tree
Hide file tree
Showing 14 changed files with 117 additions and 83 deletions.
5 changes: 5 additions & 0 deletions .changeset/few-bats-battle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
swc_fast_ts_strip: patch
---

fix(es/typescript): Strip declare export in strip-only mode
143 changes: 63 additions & 80 deletions crates/swc_fast_ts_strip/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ use swc_common::{
};
use swc_ecma_ast::{
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,
EsVersion, ExportAll, ExportDecl, ExportDefaultDecl, ExportSpecifier, FnDecl, ForInStmt,
ForOfStmt, ForStmt, IfStmt, ImportDecl, ImportSpecifier, NamedExport, Param, Pat, Program,
Stmt, TsAsExpr, TsConstAssertion, TsEnumDecl, TsExportAssignment, TsImportEqualsDecl,
TsIndexSignature, TsInstantiation, TsModuleDecl, TsModuleName, TsNamespaceDecl, TsNonNullExpr,
TsParamPropParam, TsSatisfiesExpr, TsTypeAliasDecl, TsTypeAnn, TsTypeAssertion,
TsTypeParamDecl, TsTypeParamInstantiation, VarDecl, WhileStmt,
TsTypeParamDecl, TsTypeParamInstantiation, WhileStmt,
};
use swc_ecma_parser::{
lexer::Lexer,
Expand Down Expand Up @@ -532,16 +532,6 @@ impl Visit for TsStrip {
n.visit_children_with(self);
}

fn visit_class_decl(&mut self, n: &ClassDecl) {
if n.declare {
self.add_replacement(n.span());
self.fix_asi(n.span());
return;
}

n.visit_children_with(self);
}

fn visit_class_method(&mut self, n: &ClassMethod) {
if n.function.body.is_none() || n.is_abstract {
self.add_replacement(n.span);
Expand Down Expand Up @@ -636,19 +626,33 @@ impl Visit for TsStrip {
}

fn visit_export_decl(&mut self, n: &ExportDecl) {
match n.decl {
swc_ecma_ast::Decl::TsInterface(_)
| swc_ecma_ast::Decl::TsTypeAlias(_)
| swc_ecma_ast::Decl::TsEnum(_)
| swc_ecma_ast::Decl::TsModule(_) => {
self.add_replacement(n.span);
self.fix_asi(n.span);
}
if n.decl.is_ts_declare() {
self.add_replacement(n.span);
self.fix_asi(n.span);
return;
}

_ => {
n.visit_children_with(self);
}
n.visit_children_with(self);
}

fn visit_export_default_decl(&mut self, n: &ExportDefaultDecl) {
if n.decl.is_ts_interface_decl() {
self.add_replacement(n.span);
self.fix_asi(n.span);
return;
}

n.visit_children_with(self);
}

fn visit_decl(&mut self, n: &Decl) {
if n.is_ts_declare() {
self.add_replacement(n.span());
self.fix_asi(n.span());
return;
}

n.visit_children_with(self);
}

fn visit_fn_decl(&mut self, n: &FnDecl) {
Expand Down Expand Up @@ -756,21 +760,6 @@ impl Visit for TsStrip {
n.expr.visit_children_with(self);
}

fn visit_ts_enum_decl(&mut self, e: &TsEnumDecl) {
if e.declare {
self.add_replacement(e.span);
self.fix_asi(e.span);
return;
}

HANDLER.with(|handler| {
handler.span_err(
e.span,
"TypeScript enum is not supported in strip-only mode",
);
});
}

fn visit_ts_export_assignment(&mut self, n: &TsExportAssignment) {
HANDLER.with(|handler| {
handler.span_err(
Expand Down Expand Up @@ -805,18 +794,16 @@ impl Visit for TsStrip {
n.expr.visit_children_with(self);
}

fn visit_ts_interface_decl(&mut self, n: &TsInterfaceDecl) {
self.add_replacement(n.span);
self.fix_asi(n.span);
fn visit_ts_enum_decl(&mut self, e: &TsEnumDecl) {
HANDLER.with(|handler| {
handler.span_err(
e.span,
"TypeScript enum is not supported in strip-only mode",
);
});
}

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

HANDLER.with(|handler| {
handler.span_err(
n.span(),
Expand All @@ -826,12 +813,6 @@ 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;
}

HANDLER.with(|handler| {
handler.span_err(
n.span(),
Expand Down Expand Up @@ -904,25 +885,15 @@ impl Visit for TsStrip {
self.add_replacement(span(n.span.lo, n.span.hi));
}

fn visit_var_decl(&mut self, n: &VarDecl) {
if n.declare {
self.add_replacement(n.span);
self.fix_asi(n.span);
return;
}

n.visit_children_with(self);
}

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

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

if let Some(alt) = &n.alt {
if alt.is_ts_stmt() {
if alt.is_ts_declare() {
self.add_overwrite(alt.span_lo(), b';');
}
}
Expand All @@ -931,58 +902,70 @@ impl Visit for TsStrip {
fn visit_for_stmt(&mut self, n: &ForStmt) {
n.visit_children_with(self);

if n.body.is_ts_stmt() {
if n.body.is_ts_declare() {
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() {
if n.body.is_ts_declare() {
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() {
if n.body.is_ts_declare() {
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() {
if n.body.is_ts_declare() {
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() {
if n.body.is_ts_declare() {
self.add_overwrite(n.body.span_lo(), b';');
}
}
}

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

impl IsTsStmt for Stmt {
fn is_ts_stmt(&self) -> bool {
impl IsTsDecl for Decl {
fn is_ts_declare(&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,
Self::TsInterface { .. } | Self::TsTypeAlias(..) => true,

Self::TsModule(module) => module.declare || matches!(module.id, TsModuleName::Str(..)),
Self::TsEnum(ref r#enum) => r#enum.declare,

Self::Var(ref var) => var.declare,
Self::Fn(FnDecl { declare: true, .. })
| Self::Class(ClassDecl { declare: true, .. }) => true,
_ => false,
}
}
}

impl IsTsDecl for Stmt {
fn is_ts_declare(&self) -> bool {
self.as_decl().map_or(false, IsTsDecl::is_ts_declare)
}
}

trait U8Helper {
fn is_utf8_char_boundary(&self) -> bool;
}
Expand Down
6 changes: 6 additions & 0 deletions crates/swc_fast_ts_strip/tests/errors/enums.swc-stderr
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,9 @@
1 | enum Foo { }
: ^^^^^^^^^^^^
`----
x TypeScript enum is not supported in strip-only mode
,-[3:1]
2 |
3 | export enum Bar { }
: ^^^^^^^^^^^^
`----
4 changes: 3 additions & 1 deletion crates/swc_fast_ts_strip/tests/errors/enums.ts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
enum Foo { }
enum Foo { }

export enum Bar { }
6 changes: 6 additions & 0 deletions crates/swc_fast_ts_strip/tests/errors/modules.swc-stderr
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,9 @@
1 | module aModuleKeywordNamespace { }
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
`----
x TypeScript namespace declaration is not supported in strip-only mode
,-[3:1]
2 |
3 | export module aModuleKeywordExportedNamespace { }
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
`----
4 changes: 3 additions & 1 deletion crates/swc_fast_ts_strip/tests/errors/modules.ts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
module aModuleKeywordNamespace { }
module aModuleKeywordNamespace { }

export module aModuleKeywordExportedNamespace { }
6 changes: 6 additions & 0 deletions crates/swc_fast_ts_strip/tests/errors/namespaces.swc-stderr
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,9 @@
1 | namespace Foo { }
: ^^^^^^^^^^^^^^^^^
`----
x TypeScript namespace declaration is not supported in strip-only mode
,-[3:1]
2 |
3 | export namespace Bar { }
: ^^^^^^^^^^^^^^^^^
`----
4 changes: 3 additions & 1 deletion crates/swc_fast_ts_strip/tests/errors/namespaces.ts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
namespace Foo { }
namespace Foo { }

export namespace Bar { }
8 changes: 8 additions & 0 deletions crates/swc_fast_ts_strip/tests/fixture/export-declare.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@








Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { };
8 changes: 8 additions & 0 deletions crates/swc_fast_ts_strip/tests/fixture/export-declare.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export declare class Foo {}
export declare interface Bar {}
export declare type Baz = {};
export declare enum Qux {}
export declare const Quux = 0;
export declare function Corge(): void;
export declare namespace Grault {}
export declare module Garply {}
2 changes: 2 additions & 0 deletions crates/swc_fast_ts_strip/tests/fixture/export-interface.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@


Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { };
2 changes: 2 additions & 0 deletions crates/swc_fast_ts_strip/tests/fixture/export-interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export default interface Foo {}
export interface Bar {}

0 comments on commit c53cce4

Please sign in to comment.