swc_ecma_transforms_module/rewriter/
import_rewriter_swc.rs1use std::sync::Arc;
2
3use anyhow::Context;
4use swc_common::FileName;
5use swc_ecma_ast::*;
6use swc_ecma_visit::{visit_mut_pass, VisitMut, VisitMutWith};
7
8use crate::{path::ImportResolver, wtf8::wtf8_to_cow_str};
9
10pub fn swc_import_rewriter(base: FileName, resolver: Arc<dyn ImportResolver>) -> impl Pass {
12 visit_mut_pass(Rewriter { base, resolver })
13}
14
15struct Rewriter {
16 base: FileName,
17 resolver: Arc<dyn ImportResolver>,
18}
19
20impl VisitMut for Rewriter {
21 fn visit_mut_call_expr(&mut self, e: &mut CallExpr) {
22 e.visit_mut_children_with(self);
23
24 if !e.callee.is_import() {
25 return;
26 }
27
28 if let Some(ExprOrSpread { spread: None, expr }) = &mut e.args.get_mut(0) {
29 if let Expr::Lit(Lit::Str(s)) = &mut **expr {
30 let spec = wtf8_to_cow_str(&s.value);
31 let src = self
32 .resolver
33 .resolve_import(&self.base, &spec)
34 .with_context(|| {
35 format!("failed to resolve import `{}`", s.value.to_string_lossy())
36 })
37 .unwrap();
38
39 s.raw = None;
40 s.value = src.into();
41 }
42 }
43 }
44
45 fn visit_mut_import_decl(&mut self, i: &mut ImportDecl) {
46 let spec = wtf8_to_cow_str(&i.src.value);
47 let src = self
48 .resolver
49 .resolve_import(&self.base, &spec)
50 .with_context(|| {
51 format!(
52 "failed to resolve import `{}`",
53 i.src.value.to_string_lossy()
54 )
55 })
56 .unwrap();
57
58 i.src.raw = None;
59 i.src.value = src.into();
60 }
61
62 fn visit_mut_named_export(&mut self, e: &mut NamedExport) {
63 if let Some(src) = &mut e.src {
64 let spec = wtf8_to_cow_str(&src.value);
65 let new = self
66 .resolver
67 .resolve_import(&self.base, &spec)
68 .with_context(|| {
69 format!("failed to resolve import `{}`", src.value.to_string_lossy())
70 })
71 .unwrap();
72
73 src.raw = None;
74 src.value = new.into();
75 }
76 }
77
78 fn visit_mut_export_all(&mut self, n: &mut ExportAll) {
79 let src = &mut n.src;
80
81 let spec = wtf8_to_cow_str(&src.value);
82 let new = self
83 .resolver
84 .resolve_import(&self.base, &spec)
85 .with_context(|| format!("failed to resolve import `{}`", src.value.to_string_lossy()))
86 .unwrap();
87
88 src.raw = None;
89 src.value = new.into();
90 }
91}