swc_ecma_transforms_module/
rewriter.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;
9
10pub fn 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 let Callee::Import(_) = &e.callee {
25 if let Some(ExprOrSpread { spread: None, expr }) = &mut e.args.get_mut(0) {
26 if let Expr::Lit(Lit::Str(s)) = &mut **expr {
27 let src = self
28 .resolver
29 .resolve_import(&self.base, &s.value)
30 .with_context(|| format!("failed to resolve import `{}`", s.value))
31 .unwrap();
32
33 s.raw = None;
34 s.value = src;
35 }
36 }
37 }
38 }
39
40 fn visit_mut_import_decl(&mut self, i: &mut ImportDecl) {
41 let src = self
42 .resolver
43 .resolve_import(&self.base, &i.src.value)
44 .with_context(|| format!("failed to resolve import `{}`", i.src.value))
45 .unwrap();
46
47 i.src.raw = None;
48 i.src.value = src;
49 }
50
51 fn visit_mut_named_export(&mut self, e: &mut NamedExport) {
52 if let Some(src) = &mut e.src {
53 let new = self
54 .resolver
55 .resolve_import(&self.base, &src.value)
56 .with_context(|| format!("failed to resolve import `{}`", src.value))
57 .unwrap();
58
59 src.raw = None;
60 src.value = new;
61 }
62 }
63
64 fn visit_mut_export_all(&mut self, n: &mut ExportAll) {
65 let src = &mut n.src;
66
67 let new = self
68 .resolver
69 .resolve_import(&self.base, &src.value)
70 .with_context(|| format!("failed to resolve import `{}`", src.value))
71 .unwrap();
72
73 src.raw = None;
74 src.value = new;
75 }
76}