fix(es/typescript): Strip declare export in strip-only mode (#9374)

- Closes #9373
This commit is contained in:
magic-akari 2024-08-04 13:19:45 +08:00 committed by GitHub
parent c2e302127f
commit c53cce41da
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 118 additions and 84 deletions

View File

@ -0,0 +1,5 @@
---
swc_fast_ts_strip: patch
---
fix(es/typescript): Strip declare export in strip-only mode

View File

@ -12,12 +12,12 @@ use swc_common::{
}; };
use swc_ecma_ast::{ use swc_ecma_ast::{
ArrowExpr, BindingIdent, Class, ClassDecl, ClassMethod, ClassProp, Decl, DoWhileStmt, ArrowExpr, BindingIdent, Class, ClassDecl, ClassMethod, ClassProp, Decl, DoWhileStmt,
EsVersion, ExportAll, ExportDecl, ExportSpecifier, FnDecl, ForInStmt, ForOfStmt, ForStmt, EsVersion, ExportAll, ExportDecl, ExportDefaultDecl, ExportSpecifier, FnDecl, ForInStmt,
IfStmt, ImportDecl, ImportSpecifier, NamedExport, Param, Pat, Program, Stmt, TsAsExpr, ForOfStmt, ForStmt, IfStmt, ImportDecl, ImportSpecifier, NamedExport, Param, Pat, Program,
TsConstAssertion, TsEnumDecl, TsExportAssignment, TsImportEqualsDecl, TsIndexSignature, Stmt, TsAsExpr, TsConstAssertion, TsEnumDecl, TsExportAssignment, TsImportEqualsDecl,
TsInstantiation, TsInterfaceDecl, TsModuleDecl, TsModuleName, TsNamespaceDecl, TsNonNullExpr, TsIndexSignature, TsInstantiation, TsModuleDecl, TsModuleName, TsNamespaceDecl, TsNonNullExpr,
TsParamPropParam, TsSatisfiesExpr, TsTypeAliasDecl, TsTypeAnn, TsTypeAssertion, TsParamPropParam, TsSatisfiesExpr, TsTypeAliasDecl, TsTypeAnn, TsTypeAssertion,
TsTypeParamDecl, TsTypeParamInstantiation, VarDecl, WhileStmt, TsTypeParamDecl, TsTypeParamInstantiation, WhileStmt,
}; };
use swc_ecma_parser::{ use swc_ecma_parser::{
lexer::Lexer, lexer::Lexer,
@ -532,16 +532,6 @@ impl Visit for TsStrip {
n.visit_children_with(self); 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) { fn visit_class_method(&mut self, n: &ClassMethod) {
if n.function.body.is_none() || n.is_abstract { if n.function.body.is_none() || n.is_abstract {
self.add_replacement(n.span); self.add_replacement(n.span);
@ -636,19 +626,33 @@ impl Visit for TsStrip {
} }
fn visit_export_decl(&mut self, n: &ExportDecl) { fn visit_export_decl(&mut self, n: &ExportDecl) {
match n.decl { if n.decl.is_ts_declare() {
swc_ecma_ast::Decl::TsInterface(_) self.add_replacement(n.span);
| swc_ecma_ast::Decl::TsTypeAlias(_) self.fix_asi(n.span);
| swc_ecma_ast::Decl::TsEnum(_) return;
| swc_ecma_ast::Decl::TsModule(_) => {
self.add_replacement(n.span);
self.fix_asi(n.span);
}
_ => {
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) { fn visit_fn_decl(&mut self, n: &FnDecl) {
@ -756,21 +760,6 @@ impl Visit for TsStrip {
n.expr.visit_children_with(self); 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) { fn visit_ts_export_assignment(&mut self, n: &TsExportAssignment) {
HANDLER.with(|handler| { HANDLER.with(|handler| {
handler.span_err( handler.span_err(
@ -805,18 +794,16 @@ impl Visit for TsStrip {
n.expr.visit_children_with(self); n.expr.visit_children_with(self);
} }
fn visit_ts_interface_decl(&mut self, n: &TsInterfaceDecl) { fn visit_ts_enum_decl(&mut self, e: &TsEnumDecl) {
self.add_replacement(n.span); HANDLER.with(|handler| {
self.fix_asi(n.span); handler.span_err(
e.span,
"TypeScript enum is not supported in strip-only mode",
);
});
} }
fn visit_ts_module_decl(&mut self, n: &TsModuleDecl) { 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.with(|handler| {
handler.span_err( handler.span_err(
n.span(), n.span(),
@ -826,12 +813,6 @@ impl Visit for TsStrip {
} }
fn visit_ts_namespace_decl(&mut self, n: &TsNamespaceDecl) { 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.with(|handler| {
handler.span_err( handler.span_err(
n.span(), n.span(),
@ -904,25 +885,15 @@ impl Visit for TsStrip {
self.add_replacement(span(n.span.lo, n.span.hi)); 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) { fn visit_if_stmt(&mut self, n: &IfStmt) {
n.visit_children_with(self); 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';'); self.add_overwrite(n.cons.span_lo(), b';');
} }
if let Some(alt) = &n.alt { if let Some(alt) = &n.alt {
if alt.is_ts_stmt() { if alt.is_ts_declare() {
self.add_overwrite(alt.span_lo(), b';'); self.add_overwrite(alt.span_lo(), b';');
} }
} }
@ -931,7 +902,7 @@ impl Visit for TsStrip {
fn visit_for_stmt(&mut self, n: &ForStmt) { fn visit_for_stmt(&mut self, n: &ForStmt) {
n.visit_children_with(self); 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';'); self.add_overwrite(n.body.span_lo(), b';');
} }
} }
@ -939,7 +910,7 @@ impl Visit for TsStrip {
fn visit_for_in_stmt(&mut self, n: &ForInStmt) { fn visit_for_in_stmt(&mut self, n: &ForInStmt) {
n.visit_children_with(self); 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';'); self.add_overwrite(n.body.span_lo(), b';');
} }
} }
@ -947,7 +918,7 @@ impl Visit for TsStrip {
fn visit_for_of_stmt(&mut self, n: &ForOfStmt) { fn visit_for_of_stmt(&mut self, n: &ForOfStmt) {
n.visit_children_with(self); 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';'); self.add_overwrite(n.body.span_lo(), b';');
} }
} }
@ -955,7 +926,7 @@ impl Visit for TsStrip {
fn visit_while_stmt(&mut self, n: &WhileStmt) { fn visit_while_stmt(&mut self, n: &WhileStmt) {
n.visit_children_with(self); 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';'); self.add_overwrite(n.body.span_lo(), b';');
} }
} }
@ -963,26 +934,38 @@ impl Visit for TsStrip {
fn visit_do_while_stmt(&mut self, n: &DoWhileStmt) { fn visit_do_while_stmt(&mut self, n: &DoWhileStmt) {
n.visit_children_with(self); 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';'); self.add_overwrite(n.body.span_lo(), b';');
} }
} }
} }
trait IsTsStmt { trait IsTsDecl {
fn is_ts_stmt(&self) -> bool; fn is_ts_declare(&self) -> bool;
} }
impl IsTsStmt for Stmt { impl IsTsDecl for Decl {
fn is_ts_stmt(&self) -> bool { fn is_ts_declare(&self) -> bool {
match self { match self {
Stmt::Decl(Decl::TsInterface { .. } | Decl::TsTypeAlias(..)) => true, Self::TsInterface { .. } | Self::TsTypeAlias(..) => true,
Stmt::Decl(Decl::TsModule(n)) => n.declare || matches!(n.id, TsModuleName::Str(..)),
Stmt::Decl(Decl::TsEnum(e)) => e.declare, 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, _ => false,
} }
} }
} }
impl IsTsDecl for Stmt {
fn is_ts_declare(&self) -> bool {
self.as_decl().map_or(false, IsTsDecl::is_ts_declare)
}
}
trait U8Helper { trait U8Helper {
fn is_utf8_char_boundary(&self) -> bool; fn is_utf8_char_boundary(&self) -> bool;
} }

View File

@ -3,3 +3,9 @@
1 | enum Foo { } 1 | enum Foo { }
: ^^^^^^^^^^^^ : ^^^^^^^^^^^^
`---- `----
x TypeScript enum is not supported in strip-only mode
,-[3:1]
2 |
3 | export enum Bar { }
: ^^^^^^^^^^^^
`----

View File

@ -1 +1,3 @@
enum Foo { } enum Foo { }
export enum Bar { }

View File

@ -3,3 +3,9 @@
1 | module aModuleKeywordNamespace { } 1 | module aModuleKeywordNamespace { }
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
`---- `----
x TypeScript namespace declaration is not supported in strip-only mode
,-[3:1]
2 |
3 | export module aModuleKeywordExportedNamespace { }
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
`----

View File

@ -1 +1,3 @@
module aModuleKeywordNamespace { } module aModuleKeywordNamespace { }
export module aModuleKeywordExportedNamespace { }

View File

@ -3,3 +3,9 @@
1 | namespace Foo { } 1 | namespace Foo { }
: ^^^^^^^^^^^^^^^^^ : ^^^^^^^^^^^^^^^^^
`---- `----
x TypeScript namespace declaration is not supported in strip-only mode
,-[3:1]
2 |
3 | export namespace Bar { }
: ^^^^^^^^^^^^^^^^^
`----

View File

@ -1 +1,3 @@
namespace Foo { } namespace Foo { }
export namespace Bar { }

View File

@ -0,0 +1,8 @@

View File

@ -0,0 +1 @@
export { };

View File

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

View File

@ -0,0 +1,2 @@

View File

@ -0,0 +1 @@
export { };

View File

@ -0,0 +1,2 @@
export default interface Foo {}
export interface Bar {}