swc_ecma_transforms_module/
rewriter.rs

1use 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
10/// Import rewriter, which rewrites imports as es modules.
11pub 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}