Skip to content

Commit 216d546

Browse files
authored
feat: add type_strip (#325)
1 parent 0efe929 commit 216d546

File tree

6 files changed

+365
-103
lines changed

6 files changed

+365
-103
lines changed

Cargo.lock

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ scopes = ["view", "utils", "visit"]
2424
sourcemap = ["dprint-swc-ext/sourcemap", "swc_sourcemap"]
2525
transforms = ["swc_ecma_loader", "swc_ecma_transforms_base"]
2626
emit = ["base64", "codegen", "sourcemap"]
27+
type_strip = [ "swc_ts_fast_strip" ]
2728
transpiling = ["emit", "proposal", "react", "transforms", "typescript", "utils", "visit"]
2829
typescript = ["transforms", "swc_ecma_transforms_typescript"]
2930
utils = ["swc_ecma_utils"]
@@ -74,6 +75,7 @@ swc_bundler = { version = "=32.0.0", optional = true }
7475
swc_graph_analyzer = { version = "=14.0.1", optional = true }
7576
swc_macros_common = { version = "=1.0.1", optional = true }
7677
swc_sourcemap = { version = "=9.3.4", optional = true }
78+
swc_ts_fast_strip = { version = "=33.0.0", optional = true }
7779
swc_trace_macro = { version = "=2.0.2", optional = true }
7880
swc_visit = { version = "=2.0.1", optional = true }
7981
thiserror = "2.0.12"

src/diagnostics.rs

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::fmt::Display;
77
use std::fmt::Write as _;
88
use std::path::PathBuf;
99

10+
use deno_error::JsError;
1011
use deno_terminal::colors;
1112
use unicode_width::UnicodeWidthStr;
1213

@@ -16,6 +17,8 @@ use crate::SourceRange;
1617
use crate::SourceRanged;
1718
use crate::SourceTextInfo;
1819

20+
use crate::swc::common::errors::Diagnostic as SwcDiagnostic;
21+
1922
pub enum DiagnosticLevel {
2023
Error,
2124
Warning,
@@ -560,6 +563,112 @@ fn specifier_to_file_path(specifier: &ModuleSpecifier) -> Option<PathBuf> {
560563
}
561564
}
562565

566+
pub(crate) type DiagnosticsCell = crate::swc::common::sync::Lrc<
567+
crate::swc::common::sync::Lock<Vec<SwcDiagnostic>>,
568+
>;
569+
570+
#[derive(Default, Clone)]
571+
pub(crate) struct DiagnosticCollector {
572+
diagnostics: DiagnosticsCell,
573+
}
574+
575+
impl DiagnosticCollector {
576+
pub fn into_handler_and_cell(
577+
self,
578+
) -> (crate::swc::common::errors::Handler, DiagnosticsCell) {
579+
let cell = self.diagnostics.clone();
580+
(
581+
crate::swc::common::errors::Handler::with_emitter(
582+
true,
583+
false,
584+
Box::new(self),
585+
),
586+
cell,
587+
)
588+
}
589+
}
590+
591+
impl crate::swc::common::errors::Emitter for DiagnosticCollector {
592+
fn emit(
593+
&mut self,
594+
db: &mut crate::swc::common::errors::DiagnosticBuilder<'_>,
595+
) {
596+
let mut diagnostics = self.diagnostics.lock();
597+
diagnostics.push(db.take());
598+
}
599+
}
600+
601+
#[derive(Debug, JsError)]
602+
#[class(syntax)]
603+
pub struct SwcFoldDiagnosticsError(Vec<String>);
604+
605+
impl std::error::Error for SwcFoldDiagnosticsError {}
606+
607+
impl std::fmt::Display for SwcFoldDiagnosticsError {
608+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
609+
for (i, diagnostic) in self.0.iter().enumerate() {
610+
if i > 0 {
611+
write!(f, "\n\n")?;
612+
}
613+
614+
write!(f, "{}", diagnostic)?
615+
}
616+
617+
Ok(())
618+
}
619+
}
620+
621+
pub(crate) fn ensure_no_fatal_swc_diagnostics(
622+
source_map: &swc_common::SourceMap,
623+
diagnostics: impl Iterator<Item = SwcDiagnostic>,
624+
) -> Result<(), SwcFoldDiagnosticsError> {
625+
let fatal_diagnostics = diagnostics
626+
.filter(is_fatal_swc_diagnostic)
627+
.collect::<Vec<_>>();
628+
if !fatal_diagnostics.is_empty() {
629+
Err(SwcFoldDiagnosticsError(
630+
fatal_diagnostics
631+
.iter()
632+
.map(|d| format_swc_diagnostic(source_map, d))
633+
.collect::<Vec<_>>(),
634+
))
635+
} else {
636+
Ok(())
637+
}
638+
}
639+
640+
fn is_fatal_swc_diagnostic(diagnostic: &SwcDiagnostic) -> bool {
641+
use crate::swc::common::errors::Level;
642+
match diagnostic.level {
643+
Level::Bug
644+
| Level::Cancelled
645+
| Level::FailureNote
646+
| Level::Fatal
647+
| Level::PhaseFatal
648+
| Level::Error => true,
649+
Level::Help | Level::Note | Level::Warning => false,
650+
}
651+
}
652+
653+
fn format_swc_diagnostic(
654+
source_map: &swc_common::SourceMap,
655+
diagnostic: &SwcDiagnostic,
656+
) -> String {
657+
if let Some(span) = &diagnostic.span.primary_span() {
658+
let file_name = source_map.span_to_filename(*span);
659+
let loc = source_map.lookup_char_pos(span.lo);
660+
format!(
661+
"{} at {}:{}:{}",
662+
diagnostic.message(),
663+
file_name,
664+
loc.line,
665+
loc.col_display + 1,
666+
)
667+
} else {
668+
diagnostic.message()
669+
}
670+
}
671+
563672
#[cfg(test)]
564673
mod tests {
565674
use std::borrow::Cow;

src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ mod source_map;
2626
mod text_changes;
2727
#[cfg(feature = "transpiling")]
2828
mod transpiling;
29+
#[cfg(feature = "type_strip")]
30+
mod type_strip;
2931
mod types;
3032

3133
#[cfg(feature = "view")]
@@ -50,6 +52,8 @@ pub use source_map::*;
5052
pub use text_changes::*;
5153
#[cfg(feature = "transpiling")]
5254
pub use transpiling::*;
55+
#[cfg(feature = "type_strip")]
56+
pub use type_strip::*;
5357
pub use types::*;
5458

5559
pub type ModuleSpecifier = url::Url;

src/transpiling/mod.rs

Lines changed: 5 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ use crate::ParseDiagnosticsError;
2323
use crate::ParsedSource;
2424
use crate::ProgramRef;
2525
use crate::SourceMap;
26+
use crate::diagnostics::DiagnosticCollector;
27+
use crate::diagnostics::SwcFoldDiagnosticsError;
28+
use crate::diagnostics::ensure_no_fatal_swc_diagnostics;
2629
use crate::emit;
2730
use crate::swc::ast::Program;
2831
use crate::swc::common::comments::SingleThreadedComments;
29-
use crate::swc::common::errors::Diagnostic as SwcDiagnostic;
30-
use crate::swc::common::sync::Lock;
31-
use crate::swc::common::sync::Lrc;
3232
use crate::swc::ecma_visit::visit_mut_pass;
3333
use crate::swc::parser::error::SyntaxError;
3434
use crate::swc::transforms::fixer;
@@ -667,31 +667,6 @@ fn convert_script_module_to_swc_script(
667667
})
668668
}
669669

670-
#[derive(Default, Clone)]
671-
struct DiagnosticCollector {
672-
diagnostics: Lrc<Lock<Vec<SwcDiagnostic>>>,
673-
}
674-
675-
impl DiagnosticCollector {
676-
pub fn into_handler(self) -> crate::swc::common::errors::Handler {
677-
crate::swc::common::errors::Handler::with_emitter(
678-
true,
679-
false,
680-
Box::new(self),
681-
)
682-
}
683-
}
684-
685-
impl crate::swc::common::errors::Emitter for DiagnosticCollector {
686-
fn emit(
687-
&mut self,
688-
db: &mut crate::swc::common::errors::DiagnosticBuilder<'_>,
689-
) {
690-
let mut diagnostics = self.diagnostics.lock();
691-
diagnostics.push(db.take());
692-
}
693-
}
694-
695670
#[derive(Debug, Error, JsError)]
696671
pub enum FoldProgramError {
697672
#[class(inherit)]
@@ -849,91 +824,18 @@ pub fn fold_program<'a>(
849824
);
850825

851826
let emitter = DiagnosticCollector::default();
852-
let diagnostics_cell = emitter.diagnostics.clone();
853-
let handler = emitter.into_handler();
827+
let (handler, diagnostics_cell) = emitter.into_handler_and_cell();
854828
let result = crate::swc::common::errors::HANDLER.set(&handler, || {
855829
helpers::HELPERS
856830
.set(&helpers::Helpers::new(false), || program.apply(passes))
857831
});
858832

859833
let mut diagnostics = diagnostics_cell.borrow_mut();
860834
let diagnostics = std::mem::take(&mut *diagnostics);
861-
ensure_no_fatal_swc_diagnostics(source_map, diagnostics.into_iter())?;
835+
ensure_no_fatal_swc_diagnostics(source_map.inner(), diagnostics.into_iter())?;
862836
Ok(result)
863837
}
864838

865-
#[derive(Debug, JsError)]
866-
#[class(syntax)]
867-
pub struct SwcFoldDiagnosticsError(Vec<String>);
868-
869-
impl std::error::Error for SwcFoldDiagnosticsError {}
870-
871-
impl std::fmt::Display for SwcFoldDiagnosticsError {
872-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
873-
for (i, diagnostic) in self.0.iter().enumerate() {
874-
if i > 0 {
875-
write!(f, "\n\n")?;
876-
}
877-
878-
write!(f, "{}", diagnostic)?
879-
}
880-
881-
Ok(())
882-
}
883-
}
884-
885-
fn ensure_no_fatal_swc_diagnostics(
886-
source_map: &SourceMap,
887-
diagnostics: impl Iterator<Item = SwcDiagnostic>,
888-
) -> Result<(), SwcFoldDiagnosticsError> {
889-
let fatal_diagnostics = diagnostics
890-
.filter(is_fatal_swc_diagnostic)
891-
.collect::<Vec<_>>();
892-
if !fatal_diagnostics.is_empty() {
893-
Err(SwcFoldDiagnosticsError(
894-
fatal_diagnostics
895-
.iter()
896-
.map(|d| format_swc_diagnostic(source_map, d))
897-
.collect::<Vec<_>>(),
898-
))
899-
} else {
900-
Ok(())
901-
}
902-
}
903-
904-
fn is_fatal_swc_diagnostic(diagnostic: &SwcDiagnostic) -> bool {
905-
use crate::swc::common::errors::Level;
906-
match diagnostic.level {
907-
Level::Bug
908-
| Level::Cancelled
909-
| Level::FailureNote
910-
| Level::Fatal
911-
| Level::PhaseFatal
912-
| Level::Error => true,
913-
Level::Help | Level::Note | Level::Warning => false,
914-
}
915-
}
916-
917-
fn format_swc_diagnostic(
918-
source_map: &SourceMap,
919-
diagnostic: &SwcDiagnostic,
920-
) -> String {
921-
if let Some(span) = &diagnostic.span.primary_span() {
922-
let source_map = source_map.inner();
923-
let file_name = source_map.span_to_filename(*span);
924-
let loc = source_map.lookup_char_pos(span.lo);
925-
format!(
926-
"{} at {}:{}:{}",
927-
diagnostic.message(),
928-
file_name,
929-
loc.line,
930-
loc.col_display + 1,
931-
)
932-
} else {
933-
diagnostic.message()
934-
}
935-
}
936-
937839
fn ensure_no_fatal_diagnostics<'a>(
938840
diagnostics: Box<dyn Iterator<Item = &'a ParseDiagnostic> + 'a>,
939841
) -> Result<(), ParseDiagnosticsError> {

0 commit comments

Comments
 (0)